From: Long Wu <long...@corigine.com>

Driver sends control message to reset the bond firmware
configuration in flower NIC initialization. Firmware should
reset bond configuration to avoid strange problems caused
by residues.

Signed-off-by: Long Wu <long...@corigine.com>
Reviewed-by: Peng Zhang <peng.zh...@corigine.com>
Reviewed-by: Chaoyong He <chaoyong...@corigine.com>
---
 drivers/net/nfp/flower/nfp_flower.c      | 23 ++++++
 drivers/net/nfp/flower/nfp_flower_bond.c | 90 ++++++++++++++++++++++++
 drivers/net/nfp/flower/nfp_flower_bond.h | 54 ++++++++++++++
 drivers/net/nfp/flower/nfp_flower_cmsg.c | 35 +++++++++
 drivers/net/nfp/flower/nfp_flower_cmsg.h |  3 +
 5 files changed, 205 insertions(+)

diff --git a/drivers/net/nfp/flower/nfp_flower.c 
b/drivers/net/nfp/flower/nfp_flower.c
index 195960e00d..fc3ea84828 100644
--- a/drivers/net/nfp/flower/nfp_flower.c
+++ b/drivers/net/nfp/flower/nfp_flower.c
@@ -589,6 +589,22 @@ nfp_flower_sync_feature_cleanup(struct nfp_app_fw_flower 
*app_fw_flower)
                nfp_flower_bond_feature_cleanup(app_fw_flower);
 }
 
+static int
+nfp_flower_start_features(struct nfp_app_fw_flower *app_flower)
+{
+       int ret;
+
+       if (nfp_flower_support_bond_offload(app_flower)) {
+               ret = nfp_flower_bond_reset(app_flower->nfp_bond);
+               if (ret != 0) {
+                       PMD_INIT_LOG(ERR, "Reset bond feature failed");
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
 static int
 nfp_flower_start_ctrl_vnic(struct nfp_net_hw *net_hw)
 {
@@ -826,6 +842,13 @@ nfp_init_app_fw_flower(struct nfp_pf_dev *pf_dev,
                goto ctrl_vnic_cleanup;
        }
 
+       /* Start up some features */
+       ret = nfp_flower_start_features(app_fw_flower);
+       if (ret != 0) {
+               PMD_INIT_LOG(ERR, "Failed to start features");
+               goto sync_feature_cleanup;
+       }
+
        /* Start up flower services */
        ret = nfp_flower_enable_services(app_fw_flower);
        if (ret != 0) {
diff --git a/drivers/net/nfp/flower/nfp_flower_bond.c 
b/drivers/net/nfp/flower/nfp_flower_bond.c
index bbd2818e68..4ac27f117c 100644
--- a/drivers/net/nfp/flower/nfp_flower_bond.c
+++ b/drivers/net/nfp/flower/nfp_flower_bond.c
@@ -6,8 +6,31 @@
 
 #include <rte_malloc.h>
 
+#include "nfp_flower_cmsg.h"
 #include "nfp_flower_representor.h"
 
+static void
+nfp_fl_bond_cmsg_args_init(struct nfp_flower_bond_cmsg_args *cmsg_args,
+               struct nfp_bond_group *group,
+               struct rte_eth_dev **active_members,
+               uint32_t member_cnt,
+               enum nfp_flower_bond_batch batch)
+{
+       cmsg_args->group = group;
+       cmsg_args->active_members = active_members;
+       cmsg_args->member_cnt = member_cnt;
+       cmsg_args->batch = batch;
+}
+
+static uint32_t
+nfp_fl_get_next_pkt_number(struct nfp_flower_bond *nfp_bond)
+{
+       nfp_bond->pkt_num++;
+       nfp_bond->pkt_num &= NFP_FL_BOND_PKT_NUMBER_MASK;
+
+       return nfp_bond->pkt_num;
+}
+
 static void
 nfp_flower_bond_increment_version(struct nfp_flower_bond *nfp_bond)
 {
@@ -57,3 +80,70 @@ nfp_flower_bond_cleanup(struct nfp_app_fw_flower 
*app_fw_flower)
        rte_free(nfp_bond);
        app_fw_flower->nfp_bond = NULL;
 }
+
+int
+nfp_flower_bond_reset(struct nfp_flower_bond *nfp_bond)
+{
+       struct nfp_app_fw_flower *app_flower;
+       enum nfp_flower_bond_batch batch = NFP_FLOWER_BOND_BATCH_FIRST;
+       struct nfp_flower_bond_cmsg_args init_args;
+
+       app_flower = nfp_bond->app_fw_flower;
+       app_flower->nfp_bond->rst_cfg = true;
+
+       nfp_fl_bond_cmsg_args_init(&init_args, NULL, NULL, 0, batch);
+
+       return nfp_flower_cmsg_bond_config_group(app_flower, &init_args, 
&batch);
+}
+
+enum nfp_flower_bond_batch
+nfp_flower_bond_cmsg_payload(struct nfp_flower_bond *nfp_bond,
+               struct nfp_flower_cmsg_bond_config *msg,
+               struct nfp_flower_bond_cmsg_args *init_args)
+{
+       uint32_t i;
+       uint8_t flags = 0;
+       struct nfp_flower_representor *repr;
+       enum nfp_flower_bond_batch batch = init_args->batch;
+
+       /* Increment batch version for each new batch of config messages. */
+       if (batch == NFP_FLOWER_BOND_BATCH_FIRST) {
+               flags |= NFP_FL_BOND_FIRST;
+               nfp_flower_bond_increment_version(nfp_bond);
+               batch = NFP_FLOWER_BOND_BATCH_MEMBER;
+       }
+
+       /* If it is a reset msg then it is also the end of the batch. */
+       if (nfp_bond->rst_cfg) {
+               flags |= NFP_FL_BOND_RESET;
+               batch = NFP_FLOWER_BOND_BATCH_FINISHED;
+       }
+
+       /*
+        * To signal the end of a batch, both the switch and last flags are set
+        * and the reserved SYNC group ID is used.
+        */
+       if (batch == NFP_FLOWER_BOND_BATCH_FINISHED) {
+               flags |= NFP_FL_BOND_SWITCH | NFP_FL_BOND_LAST;
+               nfp_bond->rst_cfg = false;
+               msg->group_id = rte_cpu_to_be_32(NFP_FL_BOND_SYNC_ID);
+               msg->group_inst = 0;
+       } else {
+               msg->group_id = rte_cpu_to_be_32(init_args->group->group_id);
+               msg->group_inst = 
rte_cpu_to_be_32(init_args->group->group_inst);
+       }
+
+       msg->reserved[0] = 0;
+       msg->reserved[1] = 0;
+       msg->ttl = NFP_FL_BOND_HOST_TTL;
+       msg->ctrl_flags = flags;
+       msg->batch_ver = rte_cpu_to_be_32(nfp_bond->batch_ver);
+       msg->pkt_number = 
rte_cpu_to_be_32(nfp_fl_get_next_pkt_number(nfp_bond));
+
+       for (i = 0; i < init_args->member_cnt; i++) {
+               repr = init_args->active_members[i]->data->dev_private;
+               msg->members[i] = rte_cpu_to_be_32(repr->port_id);
+       }
+
+       return batch;
+}
diff --git a/drivers/net/nfp/flower/nfp_flower_bond.h 
b/drivers/net/nfp/flower/nfp_flower_bond.h
index 9612b2c6cf..bb7ba8a1ad 100644
--- a/drivers/net/nfp/flower/nfp_flower_bond.h
+++ b/drivers/net/nfp/flower/nfp_flower_bond.h
@@ -6,6 +6,7 @@
 #ifndef __NFP_FLOWER_BOND_H__
 #define __NFP_FLOWER_BOND_H__
 
+#include <rte_byteorder.h>
 #include <rte_spinlock.h>
 #include <stdbool.h>
 #include <sys/queue.h>
@@ -13,12 +14,54 @@
 /* The batch version of bond offload packets between firmware and driver */
 #define NFP_FL_BOND_VERSION_MASK       0x007fffff    /* [0, 22] */
 
+#define NFP_FL_BOND_PKT_NUMBER_MASK    0x7fffffff    /* [0, 30] */
+
 #define NFP_FL_ENABLE_BOND             RTE_BIT32(1)
 
 /* ID 0 reserved and IDs 1 to 31 are valid */
 #define NFP_FL_BOND_GROUP_MIN          1
 #define NFP_FL_BOND_GROUP_MAX          32
 
+#define NFP_FL_BOND_HOST_TTL           0xff
+
+/* Use this ID with zero members to ack a batch config */
+#define NFP_FL_BOND_SYNC_ID            0
+
+/* BOND group config flags */
+#define NFP_FL_BOND_LAST               RTE_BIT32(1)
+#define NFP_FL_BOND_FIRST              RTE_BIT32(2)
+#define NFP_FL_BOND_DATA               RTE_BIT32(3)
+#define NFP_FL_BOND_XON                RTE_BIT32(4)
+#define NFP_FL_BOND_SYNC               RTE_BIT32(5)
+#define NFP_FL_BOND_SWITCH             RTE_BIT32(6)
+#define NFP_FL_BOND_RESET              RTE_BIT32(7)
+
+enum nfp_flower_bond_batch {
+       NFP_FLOWER_BOND_BATCH_FIRST,
+       NFP_FLOWER_BOND_BATCH_MEMBER,
+       NFP_FLOWER_BOND_BATCH_FINISHED
+};
+
+/* Control message payload for bond config */
+struct nfp_flower_cmsg_bond_config {
+       /** Configuration flags */
+       uint8_t ctrl_flags;
+       /** Reserved for future use */
+       uint8_t reserved[2];
+       /** Time to live of packet - host always sets to 0xff */
+       uint8_t ttl;
+       /** Config message packet number - increment for each message */
+       rte_be32_t pkt_number;
+       /** Batch version of messages - increment for each batch of messages */
+       rte_be32_t batch_ver;
+       /** Group ID applicable */
+       rte_be32_t group_id;
+       /** Group instance number - increment when group is reused */
+       rte_be32_t group_inst;
+       /** Array of 32-bit words listing all active group members */
+       rte_be32_t members[];
+};
+
 /* List entry for each bond group */
 struct nfp_bond_group {
        /** List entry */
@@ -59,7 +102,18 @@ struct nfp_flower_bond {
        struct nfp_app_fw_flower *app_fw_flower;
 };
 
+struct nfp_flower_bond_cmsg_args {
+       struct nfp_bond_group *group;
+       struct rte_eth_dev **active_members;
+       uint32_t member_cnt;
+       enum nfp_flower_bond_batch batch;
+};
+
 int nfp_flower_bond_init(struct nfp_app_fw_flower *app_fw_flower);
 void nfp_flower_bond_cleanup(struct nfp_app_fw_flower *app_fw_flower);
+int nfp_flower_bond_reset(struct nfp_flower_bond *nfp_bond);
+enum nfp_flower_bond_batch nfp_flower_bond_cmsg_payload(struct nfp_flower_bond 
*nfp_bond,
+               struct nfp_flower_cmsg_bond_config *msg,
+               struct nfp_flower_bond_cmsg_args *init_args);
 
 #endif /* __NFP_FLOWER_BOND_H__ */
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.c 
b/drivers/net/nfp/flower/nfp_flower_cmsg.c
index 8effe9474d..0cf1bf2281 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.c
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.c
@@ -567,3 +567,38 @@ nfp_flower_cmsg_qos_stats(struct nfp_app_fw_flower 
*app_fw_flower,
 
        return 0;
 }
+
+int
+nfp_flower_cmsg_bond_config_group(struct nfp_app_fw_flower *app_flower,
+               struct nfp_flower_bond_cmsg_args *init_args,
+               enum nfp_flower_bond_batch *batch_out)
+{
+       uint16_t cnt;
+       uint32_t size;
+       struct rte_mbuf *mbuf;
+       struct nfp_flower_bond *nfp_bond;
+       struct nfp_flower_cmsg_bond_config *msg;
+
+       mbuf = rte_pktmbuf_alloc(app_flower->ctrl_pktmbuf_pool);
+       if (mbuf == NULL) {
+               PMD_DRV_LOG(DEBUG, "Alloc mbuf for bond config failed");
+               return -ENOMEM;
+       }
+
+       size = sizeof(*msg) + sizeof(rte_be32_t) * init_args->member_cnt;
+       msg = nfp_flower_cmsg_init(app_flower, mbuf,
+                       NFP_FLOWER_CMSG_TYPE_LAG_CONFIG, size);
+
+       nfp_bond = app_flower->nfp_bond;
+
+       *batch_out = nfp_flower_bond_cmsg_payload(nfp_bond, msg, init_args);
+
+       cnt = nfp_flower_ctrl_vnic_xmit(app_flower, mbuf);
+       if (cnt == 0) {
+               PMD_DRV_LOG(ERR, "Send cmsg through ctrl vnic failed.");
+               rte_pktmbuf_free(mbuf);
+               return -EIO;
+       }
+
+       return 0;
+}
diff --git a/drivers/net/nfp/flower/nfp_flower_cmsg.h 
b/drivers/net/nfp/flower/nfp_flower_cmsg.h
index 45543816ae..60ab58a3b1 100644
--- a/drivers/net/nfp/flower/nfp_flower_cmsg.h
+++ b/drivers/net/nfp/flower/nfp_flower_cmsg.h
@@ -988,5 +988,8 @@ int nfp_flower_cmsg_qos_delete(struct nfp_app_fw_flower 
*app_fw_flower,
                struct nfp_profile_conf *conf);
 int nfp_flower_cmsg_qos_stats(struct nfp_app_fw_flower *app_fw_flower,
                struct nfp_cfg_head *head);
+int nfp_flower_cmsg_bond_config_group(struct nfp_app_fw_flower *app_flower,
+               struct nfp_flower_bond_cmsg_args *init_args,
+               enum nfp_flower_bond_batch *batch_out);
 
 #endif /* __NFP_CMSG_H__ */
-- 
2.39.1

Reply via email to