bnxt_en: export a common switchdev PARENT_ID for all reps of an adapter
authorSathya Perla <sathya.perla@broadcom.com>
Wed, 17 Jan 2018 08:21:16 +0000 (03:21 -0500)
committerDavid S. Miller <davem@davemloft.net>
Wed, 17 Jan 2018 19:48:27 +0000 (14:48 -0500)
Currently the driver exports different switchdev PARENT_IDs for
representors belonging to different SR-IOV PF-pools of an adapter.
This is not correct as the adapter can switch across all vports
of an adapter. This patch fixes this by exporting a common switchdev
PARENT_ID for all reps of an adapter. The PCIE DSN is used as the id.

Signed-off-by: Sathya Perla <sathya.perla@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
drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c
drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.h

index 77df92a..6b7e996 100644 (file)
@@ -8149,12 +8149,8 @@ int bnxt_port_attr_get(struct bnxt *bp, struct switchdev_attr *attr)
 
        switch (attr->id) {
        case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
-               /* In SRIOV each PF-pool (PF + child VFs) serves as a
-                * switching domain, the PF's perm mac-addr can be used
-                * as the unique parent-id
-                */
-               attr->u.ppid.id_len = ETH_ALEN;
-               ether_addr_copy(attr->u.ppid.id, bp->pf.mac_addr);
+               attr->u.ppid.id_len = sizeof(bp->switch_id);
+               memcpy(attr->u.ppid.id, bp->switch_id, attr->u.ppid.id_len);
                break;
        default:
                return -EOPNOTSUPP;
index 0b30dcc..1989c47 100644 (file)
@@ -1371,6 +1371,7 @@ struct bnxt {
        enum devlink_eswitch_mode eswitch_mode;
        struct bnxt_vf_rep      **vf_reps; /* array of vf-rep ptrs */
        u16                     *cfa_code_map; /* cfa_code -> vf_idx map */
+       u8                      switch_id[8];
        struct bnxt_tc_info     *tc_info;
 };
 
index 1d9b08c..2ece164 100644 (file)
@@ -43,7 +43,7 @@ static u16 bnxt_flow_get_dst_fid(struct bnxt *pf_bp, struct net_device *dev)
        }
 
        /* Is dev a VF-rep? */
-       if (dev != pf_bp->dev)
+       if (bnxt_dev_is_vf_rep(dev))
                return bnxt_vf_rep_get_fid(dev);
 
        bp = netdev_priv(dev);
index 69186d1..2ca11be 100644 (file)
@@ -241,6 +241,11 @@ static const struct net_device_ops bnxt_vf_rep_netdev_ops = {
        .ndo_get_phys_port_name = bnxt_vf_rep_get_phys_port_name
 };
 
+bool bnxt_dev_is_vf_rep(struct net_device *dev)
+{
+       return dev->netdev_ops == &bnxt_vf_rep_netdev_ops;
+}
+
 /* Called when the parent PF interface is closed:
  * As the mode transition from SWITCHDEV to LEGACY
  * happens under the rtnl_lock() this routine is safe
@@ -376,6 +381,26 @@ static void bnxt_vf_rep_netdev_init(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
        ether_addr_copy(dev->dev_addr, dev->perm_addr);
 }
 
+static int bnxt_pcie_dsn_get(struct bnxt *bp, u8 dsn[])
+{
+       struct pci_dev *pdev = bp->pdev;
+       int pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_DSN);
+       u32 dw;
+
+       if (!pos) {
+               netdev_info(bp->dev, "Unable do read adapter's DSN");
+               return -EOPNOTSUPP;
+       }
+
+       /* DSN (two dw) is at an offset of 4 from the cap pos */
+       pos += 4;
+       pci_read_config_dword(pdev, pos, &dw);
+       put_unaligned_le32(dw, &dsn[0]);
+       pci_read_config_dword(pdev, pos + 4, &dw);
+       put_unaligned_le32(dw, &dsn[4]);
+       return 0;
+}
+
 static int bnxt_vf_reps_create(struct bnxt *bp)
 {
        u16 *cfa_code_map = NULL, num_vfs = pci_num_vf(bp->pdev);
@@ -440,6 +465,11 @@ static int bnxt_vf_reps_create(struct bnxt *bp)
                }
        }
 
+       /* Read the adapter's DSN to use as the eswitch switch_id */
+       rc = bnxt_pcie_dsn_get(bp, bp->switch_id);
+       if (rc)
+               goto err;
+
        /* publish cfa_code_map only after all VF-reps have been initialized */
        bp->cfa_code_map = cfa_code_map;
        bp->eswitch_mode = DEVLINK_ESWITCH_MODE_SWITCHDEV;
index fb06bbe..38b9a75 100644 (file)
@@ -28,6 +28,7 @@ static inline u16 bnxt_vf_rep_get_fid(struct net_device *dev)
        return bp->pf.vf[vf_rep->vf_idx].fw_fid;
 }
 
+bool bnxt_dev_is_vf_rep(struct net_device *dev);
 int bnxt_dl_eswitch_mode_get(struct devlink *devlink, u16 *mode);
 int bnxt_dl_eswitch_mode_set(struct devlink *devlink, u16 mode);
 
@@ -54,5 +55,10 @@ static inline u16 bnxt_vf_rep_get_fid(struct net_device *dev)
 {
        return 0;
 }
+
+static inline bool bnxt_dev_is_vf_rep(struct net_device *dev)
+{
+       return false;
+}
 #endif /* CONFIG_BNXT_SRIOV */
 #endif /* BNXT_VFR_H */