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