On 3/2/2021 1:58 PM, Lijun Ou wrote:
> From: Chengchang Tang <tangchengchang@huawei.com>
>
> This patch add support for dumping module EEPROM.
>
> Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
> Signed-off-by: Lijun Ou <oulijun@huawei.com>
> ---
> doc/guides/rel_notes/release_21_05.rst | 4 +
> drivers/net/hns3/hns3_cmd.h | 16 ++++
> drivers/net/hns3/hns3_ethdev.c | 159 +++++++++++++++++++++++++++++++++
> 3 files changed, 179 insertions(+)
Can you please add "Module EEPROM dump" feature to .ini file?
>
> diff --git a/doc/guides/rel_notes/release_21_05.rst b/doc/guides/rel_notes/release_21_05.rst
> index ca28d05..67a0daa 100644
> --- a/doc/guides/rel_notes/release_21_05.rst
> +++ b/doc/guides/rel_notes/release_21_05.rst
> @@ -64,6 +64,10 @@ New Features
> * Added command to display Rx queue used descriptor count.
> ``show port (port_id) rxq (queue_id) desc used count``
>
> +* **Updated Hisilicon hns3 driver.**
> +
> + * Added support for module EEPROM dumping.
> +
The order in the release notes is documented in the section comment, and within
the PMDs we are trying to keep in the vendor alphabetical order, can you please
order accordingly.
With current release notes, "Hisilicon hns3" updates should go as first item in
the section.
在 2021/3/3 21:26, Ferruh Yigit 写道:
> On 3/2/2021 1:58 PM, Lijun Ou wrote:
>> From: Chengchang Tang <tangchengchang@huawei.com>
>>
>> This patch add support for dumping module EEPROM.
>>
>> Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
>> Signed-off-by: Lijun Ou <oulijun@huawei.com>
>> ---
>> doc/guides/rel_notes/release_21_05.rst | 4 +
>> drivers/net/hns3/hns3_cmd.h | 16 ++++
>> drivers/net/hns3/hns3_ethdev.c | 159
>> +++++++++++++++++++++++++++++++++
>> 3 files changed, 179 insertions(+)
>
> Can you please add "Module EEPROM dump" feature to .ini file?
>
thanks. I will fix it
>>
>> diff --git a/doc/guides/rel_notes/release_21_05.rst
>> b/doc/guides/rel_notes/release_21_05.rst
>> index ca28d05..67a0daa 100644
>> --- a/doc/guides/rel_notes/release_21_05.rst
>> +++ b/doc/guides/rel_notes/release_21_05.rst
>> @@ -64,6 +64,10 @@ New Features
>> * Added command to display Rx queue used descriptor count.
>> ``show port (port_id) rxq (queue_id) desc used count``
>> +* **Updated Hisilicon hns3 driver.**
>> +
>> + * Added support for module EEPROM dumping.
>> +
>
> The order in the release notes is documented in the section comment, and
> within the PMDs we are trying to keep in the vendor alphabetical order,
> can you please order accordingly.
>
> With current release notes, "Hisilicon hns3" updates should go as first
> item in the section.
> .
OK, thanks.
>
@@ -64,6 +64,10 @@ New Features
* Added command to display Rx queue used descriptor count.
``show port (port_id) rxq (queue_id) desc used count``
+* **Updated Hisilicon hns3 driver.**
+
+ * Added support for module EEPROM dumping.
+
Removed Items
-------------
@@ -211,6 +211,8 @@ enum hns3_opcode_type {
HNS3_OPC_FIRMWARE_COMPAT_CFG = 0x701A,
/* SFP command */
+ HNS3_OPC_GET_SFP_EEPROM = 0x7100,
+ HNS3_OPC_GET_SFP_EXIST = 0x7101,
HNS3_OPC_SFP_GET_SPEED = 0x7104,
/* Interrupts commands */
@@ -714,6 +716,20 @@ struct hns3_config_auto_neg_cmd {
#define HNS3_MAC_FEC_BASER 1
#define HNS3_MAC_FEC_RS 2
+#define HNS3_SFP_INFO_BD0_LEN 20UL
+#define HNS3_SFP_INFO_BDX_LEN 24UL
+
+struct hns3_sfp_info_bd0_cmd {
+ uint16_t offset;
+ uint16_t read_len;
+ uint8_t data[HNS3_SFP_INFO_BD0_LEN];
+};
+
+struct hns3_sfp_type {
+ uint8_t type;
+ uint8_t ext_type;
+};
+
struct hns3_sfp_speed_cmd {
uint32_t sfp_speed;
uint8_t query_type; /* 0: sfp speed, 1: active fec */
@@ -6172,6 +6172,163 @@ hns3_query_dev_fec_info(struct hns3_hw *hw)
return ret;
}
+static bool
+hns3_optical_module_existed(struct hns3_hw *hw)
+{
+ struct hns3_cmd_desc desc;
+ bool existed;
+ int ret;
+
+ hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_GET_SFP_EXIST, true);
+ ret = hns3_cmd_send(hw, &desc, 1);
+ if (ret) {
+ hns3_err(hw,
+ "fail to get optical module exist state, ret = %d.\n",
+ ret);
+ return false;
+ }
+ existed = !!desc.data[0];
+
+ return existed;
+}
+
+static int
+hns3_get_module_eeprom_data(struct hns3_hw *hw, uint32_t offset,
+ uint32_t len, uint8_t *data)
+{
+#define HNS3_SFP_INFO_CMD_NUM 6
+#define HNS3_SFP_INFO_MAX_LEN \
+ (HNS3_SFP_INFO_BD0_LEN + \
+ (HNS3_SFP_INFO_CMD_NUM - 1) * HNS3_SFP_INFO_BDX_LEN)
+ struct hns3_cmd_desc desc[HNS3_SFP_INFO_CMD_NUM];
+ struct hns3_sfp_info_bd0_cmd *sfp_info_bd0;
+ uint16_t read_len;
+ uint16_t copy_len;
+ int ret;
+ int i;
+
+ for (i = 0; i < HNS3_SFP_INFO_CMD_NUM; i++) {
+ hns3_cmd_setup_basic_desc(&desc[i], HNS3_OPC_GET_SFP_EEPROM,
+ true);
+ if (i < HNS3_SFP_INFO_CMD_NUM - 1)
+ desc[i].flag |= rte_cpu_to_le_16(HNS3_CMD_FLAG_NEXT);
+ }
+
+ sfp_info_bd0 = (struct hns3_sfp_info_bd0_cmd *)desc[0].data;
+ sfp_info_bd0->offset = rte_cpu_to_le_16((uint16_t)offset);
+ read_len = RTE_MIN(len, HNS3_SFP_INFO_MAX_LEN);
+ sfp_info_bd0->read_len = rte_cpu_to_le_16((uint16_t)read_len);
+
+ ret = hns3_cmd_send(hw, desc, HNS3_SFP_INFO_CMD_NUM);
+ if (ret) {
+ hns3_err(hw, "fail to get module EEPROM info, ret = %d.\n",
+ ret);
+ return ret;
+ }
+
+ /* The data format in BD0 is different with the others. */
+ copy_len = RTE_MIN(len, HNS3_SFP_INFO_BD0_LEN);
+ memcpy(data, sfp_info_bd0->data, copy_len);
+ read_len = copy_len;
+
+ for (i = 1; i < HNS3_SFP_INFO_CMD_NUM; i++) {
+ if (read_len >= len)
+ break;
+
+ copy_len = RTE_MIN(len - read_len, HNS3_SFP_INFO_BDX_LEN);
+ memcpy(data + read_len, desc[i].data, copy_len);
+ read_len += copy_len;
+ }
+
+ return (int)read_len;
+}
+
+static int
+hns3_get_module_eeprom(struct rte_eth_dev *dev,
+ struct rte_dev_eeprom_info *info)
+{
+ struct hns3_adapter *hns = dev->data->dev_private;
+ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(hns);
+ uint32_t offset = info->offset;
+ uint32_t len = info->length;
+ uint8_t *data = info->data;
+ uint32_t read_len = 0;
+
+ if (hw->mac.media_type != HNS3_MEDIA_TYPE_FIBER)
+ return -ENOTSUP;
+
+ if (!hns3_optical_module_existed(hw)) {
+ hns3_err(hw, "fail to read module EEPROM: no module is connected.\n");
+ return -EIO;
+ }
+
+ while (read_len < len) {
+ int ret;
+ ret = hns3_get_module_eeprom_data(hw, offset + read_len,
+ len - read_len,
+ data + read_len);
+ if (ret < 0)
+ return -EIO;
+ read_len += ret;
+ }
+
+ return 0;
+}
+
+static int
+hns3_get_module_info(struct rte_eth_dev *dev,
+ struct rte_eth_dev_module_info *modinfo)
+{
+#define HNS3_SFF8024_ID_SFP 0x03
+#define HNS3_SFF8024_ID_QSFP_8438 0x0c
+#define HNS3_SFF8024_ID_QSFP_8436_8636 0x0d
+#define HNS3_SFF8024_ID_QSFP28_8636 0x11
+#define HNS3_SFF_8636_V1_3 0x03
+ struct hns3_adapter *hns = dev->data->dev_private;
+ struct hns3_hw *hw = HNS3_DEV_PRIVATE_TO_HW(hns);
+ struct rte_dev_eeprom_info info;
+ struct hns3_sfp_type sfp_type;
+ int ret;
+
+ memset(&sfp_type, 0, sizeof(sfp_type));
+ memset(&info, 0, sizeof(info));
+ info.data = (uint8_t *)&sfp_type;
+ info.length = sizeof(sfp_type);
+ ret = hns3_get_module_eeprom(dev, &info);
+ if (ret)
+ return ret;
+
+ switch (sfp_type.type) {
+ case HNS3_SFF8024_ID_SFP:
+ modinfo->type = RTE_ETH_MODULE_SFF_8472;
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8472_LEN;
+ break;
+ case HNS3_SFF8024_ID_QSFP_8438:
+ modinfo->type = RTE_ETH_MODULE_SFF_8436;
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8436_MAX_LEN;
+ break;
+ case HNS3_SFF8024_ID_QSFP_8436_8636:
+ if (sfp_type.ext_type < HNS3_SFF_8636_V1_3) {
+ modinfo->type = RTE_ETH_MODULE_SFF_8436;
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8436_MAX_LEN;
+ } else {
+ modinfo->type = RTE_ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8636_MAX_LEN;
+ }
+ break;
+ case HNS3_SFF8024_ID_QSFP28_8636:
+ modinfo->type = RTE_ETH_MODULE_SFF_8636;
+ modinfo->eeprom_len = RTE_ETH_MODULE_SFF_8636_MAX_LEN;
+ break;
+ default:
+ hns3_err(hw, "unknown module, type = %u, extra_type = %u.\n",
+ sfp_type.type, sfp_type.ext_type);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static const struct eth_dev_ops hns3_eth_dev_ops = {
.dev_configure = hns3_dev_configure,
.dev_start = hns3_dev_start,
@@ -6223,6 +6380,8 @@ static const struct eth_dev_ops hns3_eth_dev_ops = {
.vlan_offload_set = hns3_vlan_offload_set,
.vlan_pvid_set = hns3_vlan_pvid_set,
.get_reg = hns3_get_regs,
+ .get_module_info = hns3_get_module_info,
+ .get_module_eeprom = hns3_get_module_eeprom,
.get_dcb_info = hns3_get_dcb_info,
.dev_supported_ptypes_get = hns3_dev_supported_ptypes_get,
.fec_get_capability = hns3_fec_get_capability,