OSDN Git Service

bnxt_en: Read partno and serialno of the board from VPD
authorVasundhara Volam <vasundhara-v.volam@broadcom.com>
Fri, 27 Mar 2020 09:35:49 +0000 (15:05 +0530)
committerDavid S. Miller <davem@davemloft.net>
Fri, 27 Mar 2020 22:34:42 +0000 (15:34 -0700)
Store the part number and serial number information from VPD in
the bnxt structure. Follow up patch will add the support to display
the information via devlink command.

Signed-off-by: Vasundhara Volam <vasundhara-v.volam@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h

index 3861dff..fead64f 100644 (file)
@@ -11752,6 +11752,63 @@ static int bnxt_init_mac_addr(struct bnxt *bp)
        return rc;
 }
 
+#define BNXT_VPD_LEN   512
+static void bnxt_vpd_read_info(struct bnxt *bp)
+{
+       struct pci_dev *pdev = bp->pdev;
+       int i, len, pos, ro_size;
+       ssize_t vpd_size;
+       u8 *vpd_data;
+
+       vpd_data = kmalloc(BNXT_VPD_LEN, GFP_KERNEL);
+       if (!vpd_data)
+               return;
+
+       vpd_size = pci_read_vpd(pdev, 0, BNXT_VPD_LEN, vpd_data);
+       if (vpd_size <= 0) {
+               netdev_err(bp->dev, "Unable to read VPD\n");
+               goto exit;
+       }
+
+       i = pci_vpd_find_tag(vpd_data, 0, vpd_size, PCI_VPD_LRDT_RO_DATA);
+       if (i < 0) {
+               netdev_err(bp->dev, "VPD READ-Only not found\n");
+               goto exit;
+       }
+
+       ro_size = pci_vpd_lrdt_size(&vpd_data[i]);
+       i += PCI_VPD_LRDT_TAG_SIZE;
+       if (i + ro_size > vpd_size)
+               goto exit;
+
+       pos = pci_vpd_find_info_keyword(vpd_data, i, ro_size,
+                                       PCI_VPD_RO_KEYWORD_PARTNO);
+       if (pos < 0)
+               goto read_sn;
+
+       len = pci_vpd_info_field_size(&vpd_data[pos]);
+       pos += PCI_VPD_INFO_FLD_HDR_SIZE;
+       if (len + pos > vpd_size)
+               goto read_sn;
+
+       strlcpy(bp->board_partno, &vpd_data[pos], min(len, BNXT_VPD_FLD_LEN));
+
+read_sn:
+       pos = pci_vpd_find_info_keyword(vpd_data, i, ro_size,
+                                       PCI_VPD_RO_KEYWORD_SERIALNO);
+       if (pos < 0)
+               goto exit;
+
+       len = pci_vpd_info_field_size(&vpd_data[pos]);
+       pos += PCI_VPD_INFO_FLD_HDR_SIZE;
+       if (len + pos > vpd_size)
+               goto exit;
+
+       strlcpy(bp->board_serialno, &vpd_data[pos], min(len, BNXT_VPD_FLD_LEN));
+exit:
+       kfree(vpd_data);
+}
+
 static int bnxt_pcie_dsn_get(struct bnxt *bp, u8 dsn[])
 {
        struct pci_dev *pdev = bp->pdev;
@@ -11809,6 +11866,8 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        dev->ethtool_ops = &bnxt_ethtool_ops;
        pci_set_drvdata(pdev, dev);
 
+       bnxt_vpd_read_info(bp);
+
        rc = bnxt_alloc_hwrm_resources(bp);
        if (rc)
                goto init_err_pci_clean;
index a1e9d33..f2caa27 100644 (file)
@@ -1500,6 +1500,10 @@ struct bnxt {
         (chip_num) == CHIP_NUM_58804 ||        \
         (chip_num) == CHIP_NUM_58808)
 
+#define BNXT_VPD_FLD_LEN       32
+       char                    board_partno[BNXT_VPD_FLD_LEN];
+       char                    board_serialno[BNXT_VPD_FLD_LEN];
+
        struct net_device       *dev;
        struct pci_dev          *pdev;