@@ -193,6 +193,8 @@ New Features
* Added power-saving during polling within the ``rte_event_dequeue_burst()`` API.
* Added support for DMA adapter.
+* **Added setting lanes for hns3 PF driver.**
+ * This feature add support for setting lanes and report lanes.
Removed Items
-------------
@@ -753,7 +753,9 @@ struct hns3_config_mac_mode_cmd {
struct hns3_config_mac_speed_dup_cmd {
uint8_t speed_dup;
uint8_t mac_change_fec_en;
- uint8_t rsv[22];
+ uint8_t rsv[4];
+ uint8_t lanes;
+ uint8_t rsv1[17];
};
#define HNS3_TQP_ENABLE_B 0
@@ -789,12 +791,15 @@ struct hns3_sfp_type {
#define HNS3_FIBER_LINK_SPEED_1G_BIT BIT(0)
#define HNS3_FIBER_LINK_SPEED_10G_BIT BIT(1)
#define HNS3_FIBER_LINK_SPEED_25G_BIT BIT(2)
-#define HNS3_FIBER_LINK_SPEED_50G_BIT BIT(3)
-#define HNS3_FIBER_LINK_SPEED_100G_BIT BIT(4)
+#define HNS3_FIBER_LINK_SPEED_50G_R2_BIT BIT(3)
+#define HNS3_FIBER_LINK_SPEED_100G_R4_BIT BIT(4)
#define HNS3_FIBER_LINK_SPEED_40G_BIT BIT(5)
#define HNS3_FIBER_LINK_SPEED_100M_BIT BIT(6)
#define HNS3_FIBER_LINK_SPEED_10M_BIT BIT(7)
-#define HNS3_FIBER_LINK_SPEED_200G_BIT BIT(8)
+#define HNS3_FIBER_LINK_SPEED_200G_EXT_BIT BIT(8)
+#define HNS3_FIBER_LINK_SPEED_50G_R1_BIT BIT(9)
+#define HNS3_FIBER_LINK_SPEED_100G_R2_BIT BIT(10)
+#define HNS3_FIBER_LINK_SPEED_200G_R4_BIT BIT(11)
#define HNS3_FIBER_FEC_AUTO_BIT BIT(0)
#define HNS3_FIBER_FEC_BASER_BIT BIT(1)
@@ -823,7 +828,7 @@ struct hns3_sfp_info_cmd {
uint32_t supported_speed; /* speed supported by current media */
uint32_t module_type;
uint8_t fec_ability; /* supported fec modes, see HNS3_FIBER_FEC_XXX_BIT */
- uint8_t rsv0;
+ uint8_t lanes;
uint8_t pause_status;
uint8_t rsv1[5];
};
@@ -93,6 +93,8 @@ hns3_dev_infos_get(struct rte_eth_dev *eth_dev, struct rte_eth_dev_info *info)
info->dev_capa = RTE_ETH_DEV_CAPA_FLOW_RULE_KEEP |
RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP;
+ if (!hns->is_vf)
+ info->dev_capa |= RTE_ETH_DEV_CAPA_SETTING_LANES;
if (hns3_dev_get_support(hw, INDEP_TXRX))
info->dev_capa |= RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP |
RTE_ETH_DEV_CAPA_RUNTIME_TX_QUEUE_SETUP;
@@ -63,12 +63,12 @@ struct hns3_intr_state {
uint32_t hw_err_state;
};
-#define HNS3_SPEEDS_SUPP_FEC (RTE_ETH_LINK_SPEED_10G | \
- RTE_ETH_LINK_SPEED_25G | \
- RTE_ETH_LINK_SPEED_40G | \
- RTE_ETH_LINK_SPEED_50G | \
- RTE_ETH_LINK_SPEED_100G | \
- RTE_ETH_LINK_SPEED_200G)
+#define HNS3_SPEED_NUM_10G_BIT RTE_BIT32(1)
+#define HNS3_SPEED_NUM_25G_BIT RTE_BIT32(2)
+#define HNS3_SPEED_NUM_40G_BIT RTE_BIT32(3)
+#define HNS3_SPEED_NUM_50G_BIT RTE_BIT32(4)
+#define HNS3_SPEED_NUM_100G_BIT RTE_BIT32(5)
+#define HNS3_SPEED_NUM_200G_BIT RTE_BIT32(6)
static const struct rte_eth_fec_capa speed_fec_capa_tbl[] = {
{ RTE_ETH_SPEED_NUM_10G, RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
@@ -2234,13 +2234,17 @@ hns3_get_firber_port_speed_capa(uint32_t supported_speed)
if (supported_speed & HNS3_FIBER_LINK_SPEED_25G_BIT)
speed_capa |= RTE_ETH_LINK_SPEED_25G;
if (supported_speed & HNS3_FIBER_LINK_SPEED_40G_BIT)
- speed_capa |= RTE_ETH_LINK_SPEED_40G;
- if (supported_speed & HNS3_FIBER_LINK_SPEED_50G_BIT)
+ speed_capa |= RTE_ETH_LINK_SPEED_40G_4LANES;
+ if (supported_speed & HNS3_FIBER_LINK_SPEED_50G_R1_BIT)
speed_capa |= RTE_ETH_LINK_SPEED_50G;
- if (supported_speed & HNS3_FIBER_LINK_SPEED_100G_BIT)
- speed_capa |= RTE_ETH_LINK_SPEED_100G;
- if (supported_speed & HNS3_FIBER_LINK_SPEED_200G_BIT)
- speed_capa |= RTE_ETH_LINK_SPEED_200G;
+ if (supported_speed & HNS3_FIBER_LINK_SPEED_50G_R2_BIT)
+ speed_capa |= RTE_ETH_LINK_SPEED_50G_2LANES;
+ if (supported_speed & HNS3_FIBER_LINK_SPEED_100G_R4_BIT)
+ speed_capa |= RTE_ETH_LINK_SPEED_100G_4LANES;
+ if (supported_speed & HNS3_FIBER_LINK_SPEED_100G_R2_BIT)
+ speed_capa |= RTE_ETH_LINK_SPEED_100G_2LANES;
+ if (supported_speed & HNS3_FIBER_LINK_SPEED_200G_R4_BIT)
+ speed_capa |= RTE_ETH_LINK_SPEED_200G_4LANES;
return speed_capa;
}
@@ -2308,6 +2312,7 @@ hns3_setup_linkstatus(struct rte_eth_dev *eth_dev,
if (!mac->link_status)
new_link->link_speed = RTE_ETH_SPEED_NUM_NONE;
+ new_link->link_lanes = mac->link_lanes;
new_link->link_duplex = mac->link_duplex;
new_link->link_status = mac->link_status ? RTE_ETH_LINK_UP : RTE_ETH_LINK_DOWN;
new_link->link_autoneg = mac->link_autoneg;
@@ -2934,7 +2939,8 @@ hns3_map_tqp(struct hns3_hw *hw)
}
static int
-hns3_cfg_mac_speed_dup_hw(struct hns3_hw *hw, uint32_t speed, uint8_t duplex)
+hns3_cfg_mac_speed_dup_hw(struct hns3_hw *hw, uint32_t speed, uint8_t lanes,
+ uint8_t duplex)
{
struct hns3_config_mac_speed_dup_cmd *req;
struct hns3_cmd_desc desc;
@@ -2989,6 +2995,7 @@ hns3_cfg_mac_speed_dup_hw(struct hns3_hw *hw, uint32_t speed, uint8_t duplex)
}
hns3_set_bit(req->mac_change_fec_en, HNS3_CFG_MAC_SPEED_CHANGE_EN_B, 1);
+ req->lanes = lanes;
ret = hns3_cmd_send(hw, &desc, 1);
if (ret)
@@ -3643,7 +3650,10 @@ hns3_mac_init(struct hns3_hw *hw)
pf->support_sfp_query = true;
mac->link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
- ret = hns3_cfg_mac_speed_dup_hw(hw, mac->link_speed, mac->link_duplex);
+ /* If lane is set to 0, the firmware selects the default lane. */
+ mac->link_lanes = RTE_ETH_LANES_UNKNOWN;
+ ret = hns3_cfg_mac_speed_dup_hw(hw, mac->link_speed, mac->link_lanes,
+ mac->link_duplex);
if (ret) {
PMD_INIT_LOG(ERR, "Config mac speed dup fail ret = %d", ret);
return ret;
@@ -4052,6 +4062,7 @@ hns3_get_sfp_info(struct hns3_hw *hw, struct hns3_mac *mac_info)
return 0;
mac_info->link_speed = rte_le_to_cpu_32(resp->sfp_speed);
+ mac_info->link_lanes = resp->lanes;
/*
* if resp->supported_speed is 0, it means it's an old version
* firmware, do not update these params.
@@ -4088,16 +4099,18 @@ hns3_check_speed_dup(uint8_t duplex, uint32_t speed)
}
static int
-hns3_cfg_mac_speed_dup(struct hns3_hw *hw, uint32_t speed, uint8_t duplex)
+hns3_cfg_mac_speed_dup(struct hns3_hw *hw, uint32_t speed, uint8_t lanes,
+ uint8_t duplex)
{
struct hns3_mac *mac = &hw->mac;
int ret;
duplex = hns3_check_speed_dup(duplex, speed);
- if (mac->link_speed == speed && mac->link_duplex == duplex)
+ if (mac->link_speed == speed && mac->link_lanes == lanes &&
+ mac->link_duplex == duplex)
return 0;
- ret = hns3_cfg_mac_speed_dup_hw(hw, speed, duplex);
+ ret = hns3_cfg_mac_speed_dup_hw(hw, speed, lanes, duplex);
if (ret)
return ret;
@@ -4106,6 +4119,7 @@ hns3_cfg_mac_speed_dup(struct hns3_hw *hw, uint32_t speed, uint8_t duplex)
return ret;
mac->link_speed = speed;
+ mac->link_lanes = lanes;
mac->link_duplex = duplex;
return 0;
@@ -4150,6 +4164,7 @@ hns3_update_fiber_link_info(struct hns3_hw *hw)
}
mac->link_speed = mac_info.link_speed;
+ mac->link_lanes = mac_info.link_lanes;
mac->supported_speed = mac_info.supported_speed;
mac->support_autoneg = mac_info.support_autoneg;
mac->link_autoneg = mac_info.link_autoneg;
@@ -4161,7 +4176,7 @@ hns3_update_fiber_link_info(struct hns3_hw *hw)
}
/* Config full duplex for SFP */
- return hns3_cfg_mac_speed_dup(hw, mac_info.link_speed,
+ return hns3_cfg_mac_speed_dup(hw, mac_info.link_speed, mac_info.link_lanes,
RTE_ETH_LINK_FULL_DUPLEX);
}
@@ -4512,11 +4527,11 @@ hns3_set_firber_default_support_speed(struct hns3_hw *hw)
case RTE_ETH_SPEED_NUM_40G:
return HNS3_FIBER_LINK_SPEED_40G_BIT;
case RTE_ETH_SPEED_NUM_50G:
- return HNS3_FIBER_LINK_SPEED_50G_BIT;
+ return HNS3_FIBER_LINK_SPEED_50G_R2_BIT;
case RTE_ETH_SPEED_NUM_100G:
- return HNS3_FIBER_LINK_SPEED_100G_BIT;
+ return HNS3_FIBER_LINK_SPEED_100G_R4_BIT;
case RTE_ETH_SPEED_NUM_200G:
- return HNS3_FIBER_LINK_SPEED_200G_BIT;
+ return HNS3_FIBER_LINK_SPEED_200G_R4_BIT;
default:
hns3_warn(hw, "invalid speed %u Mbps.", mac->link_speed);
return 0;
@@ -4769,17 +4784,23 @@ hns3_convert_link_speeds2bitmap_fiber(uint32_t link_speeds)
case RTE_ETH_LINK_SPEED_25G:
speed_bit = HNS3_FIBER_LINK_SPEED_25G_BIT;
break;
- case RTE_ETH_LINK_SPEED_40G:
+ case RTE_ETH_LINK_SPEED_40G_4LANES:
speed_bit = HNS3_FIBER_LINK_SPEED_40G_BIT;
break;
case RTE_ETH_LINK_SPEED_50G:
- speed_bit = HNS3_FIBER_LINK_SPEED_50G_BIT;
+ speed_bit = HNS3_FIBER_LINK_SPEED_50G_R1_BIT;
break;
- case RTE_ETH_LINK_SPEED_100G:
- speed_bit = HNS3_FIBER_LINK_SPEED_100G_BIT;
+ case RTE_ETH_LINK_SPEED_50G_2LANES:
+ speed_bit = HNS3_FIBER_LINK_SPEED_50G_R2_BIT;
break;
- case RTE_ETH_LINK_SPEED_200G:
- speed_bit = HNS3_FIBER_LINK_SPEED_200G_BIT;
+ case RTE_ETH_LINK_SPEED_100G_4LANES:
+ speed_bit = HNS3_FIBER_LINK_SPEED_100G_R4_BIT;
+ break;
+ case RTE_ETH_LINK_SPEED_100G_2LANES:
+ speed_bit = HNS3_FIBER_LINK_SPEED_100G_R2_BIT;
+ break;
+ case RTE_ETH_LINK_SPEED_200G_4LANES:
+ speed_bit = HNS3_FIBER_LINK_SPEED_200G_R4_BIT;
break;
default:
speed_bit = 0;
@@ -4900,7 +4921,7 @@ hns3_set_fiber_port_link_speed(struct hns3_hw *hw,
return 0;
}
- return hns3_cfg_mac_speed_dup(hw, cfg->speed, cfg->duplex);
+ return hns3_cfg_mac_speed_dup(hw, cfg->speed, cfg->lanes, cfg->duplex);
}
const char *
@@ -4954,7 +4975,7 @@ hns3_apply_link_speed(struct hns3_hw *hw)
hns3_err(hw, "failed to parse link mode, ret = %d", ret);
return ret;
}
- cfg.speed = mode_onfo.speed_num;
+ cfg.lanes = mode_info.lanes;
cfg.speed = mode_info.speed_num;
cfg.duplex = mode_info.duplex;
}
@@ -5927,20 +5948,49 @@ hns3_reset_service(void *param)
hns3_msix_process(hns, reset_level);
}
+static uint32_t
+hns3_speed_num_capa_bit(uint32_t speed_num)
+{
+ uint32_t speed_bit;
+
+ switch (speed_num) {
+ case RTE_ETH_SPEED_NUM_10G:
+ speed_bit = HNS3_SPEED_NUM_10G_BIT;
+ break;
+ case RTE_ETH_SPEED_NUM_25G:
+ speed_bit = HNS3_SPEED_NUM_25G_BIT;
+ break;
+ case RTE_ETH_SPEED_NUM_40G:
+ speed_bit = HNS3_SPEED_NUM_40G_BIT;
+ break;
+ case RTE_ETH_SPEED_NUM_50G:
+ speed_bit = HNS3_SPEED_NUM_50G_BIT;
+ break;
+ case RTE_ETH_SPEED_NUM_100G:
+ speed_bit = HNS3_SPEED_NUM_100G_BIT;
+ break;
+ case RTE_ETH_SPEED_NUM_200G:
+ speed_bit = HNS3_SPEED_NUM_200G_BIT;
+ break;
+ default:
+ speed_bit = 0;
+ break;
+ }
+
+ return speed_bit;
+}
+
static uint32_t
hns3_get_speed_fec_capa(struct rte_eth_fec_capa *speed_fec_capa,
- uint32_t speed_capa)
+ uint32_t speed_num_capa)
{
uint32_t speed_bit;
uint32_t num = 0;
uint32_t i;
for (i = 0; i < RTE_DIM(speed_fec_capa_tbl); i++) {
- speed_bit =
- rte_eth_speed_bitflag(speed_fec_capa_tbl[i].speed,
- RTE_ETH_LANES_UNKNOWN,
- RTE_ETH_LINK_FULL_DUPLEX);
- if ((speed_capa & speed_bit) == 0)
+ speed_bit = hns3_speed_num_capa_bit(speed_fec_capa_tbl[i].speed);
+ if ((speed_num_capa & speed_bit) == 0)
continue;
speed_fec_capa[num].speed = speed_fec_capa_tbl[i].speed;
@@ -5951,6 +6001,34 @@ hns3_get_speed_fec_capa(struct rte_eth_fec_capa *speed_fec_capa,
return num;
}
+static uint32_t
+hns3_get_speed_num_capa(struct hns3_hw *hw)
+{
+ uint32_t speed_num_capa = 0;
+ uint32_t speed_capa;
+
+ speed_capa = hns3_get_speed_capa(hw);
+
+ if (speed_capa & RTE_ETH_LINK_SPEED_10G)
+ speed_num_capa |= HNS3_SPEED_NUM_10G_BIT;
+ if (speed_capa & RTE_ETH_LINK_SPEED_25G)
+ speed_num_capa |= HNS3_SPEED_NUM_25G_BIT;
+ if (speed_capa & RTE_ETH_LINK_SPEED_40G_4LANES)
+ speed_num_capa |= HNS3_SPEED_NUM_40G_BIT;
+ if (speed_capa & RTE_ETH_LINK_SPEED_50G)
+ speed_num_capa |= HNS3_SPEED_NUM_50G_BIT;
+ if (speed_capa & RTE_ETH_LINK_SPEED_50G_2LANES)
+ speed_num_capa |= HNS3_SPEED_NUM_50G_BIT;
+ if (speed_capa & RTE_ETH_LINK_SPEED_100G_4LANES)
+ speed_num_capa |= HNS3_SPEED_NUM_100G_BIT;
+ if (speed_capa & RTE_ETH_LINK_SPEED_100G_2LANES)
+ speed_num_capa |= HNS3_SPEED_NUM_100G_BIT;
+ if (speed_capa & RTE_ETH_LINK_SPEED_200G_4LANES)
+ speed_num_capa |= HNS3_SPEED_NUM_200G_BIT;
+
+ return speed_num_capa;
+}
+
static int
hns3_fec_get_capability(struct rte_eth_dev *dev,
struct rte_eth_fec_capa *speed_fec_capa,
@@ -5958,11 +6036,11 @@ hns3_fec_get_capability(struct rte_eth_dev *dev,
{
struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(dev->data->dev_private);
unsigned int speed_num;
- uint32_t speed_capa;
+ uint32_t speed_num_capa;
- speed_capa = hns3_get_speed_capa(hw);
- /* speed_num counts number of speed capabilities */
- speed_num = rte_popcount32(speed_capa & HNS3_SPEEDS_SUPP_FEC);
+ speed_num_capa = hns3_get_speed_num_capa(hw);
+ /* speed_num counts number of speed number capabilities */
+ speed_num = rte_popcount32(speed_num_capa);
if (speed_num == 0)
return -ENOTSUP;
@@ -5975,7 +6053,7 @@ hns3_fec_get_capability(struct rte_eth_dev *dev,
return -EINVAL;
}
- return hns3_get_speed_fec_capa(speed_fec_capa, speed_capa);
+ return hns3_get_speed_fec_capa(speed_fec_capa, speed_num_capa);
}
@@ -168,6 +168,7 @@ struct hns3_set_link_speed_cfg {
uint32_t speed;
uint8_t duplex : 1;
uint8_t autoneg : 1;
+ uint8_t lanes : 4;
};
/* mac media type */
@@ -190,6 +191,7 @@ struct hns3_mac {
uint8_t link_autoneg : 1; /* RTE_ETH_LINK_[AUTONEG/FIXED] */
uint8_t link_status : 1; /* RTE_ETH_LINK_[DOWN/UP] */
uint32_t link_speed; /* RTE_ETH_SPEED_NUM_ */
+ uint8_t link_lanes; /* RTE_ETH_LANES_ */
/*
* Some firmware versions support only the SFP speed query. In addition
* to the SFP speed query, some firmware supports the query of the speed