Commit c124a62f authored by Sathya Perla's avatar Sathya Perla Committed by David S. Miller

bnxt_en: add support for port_attr_get and and get_phys_port_name

This patch adds support for the switchdev_port_attr_get() and
ndo_get_phys_port_name() methods for the PF and the VF-reps.
Using this support a user application can deduce that the PF
(when in the ESWITCH_SWDEV mode) and it's VF-reps form a switch.
Signed-off-by: default avatarSathya Perla <sathya.perla@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ee5c7fb3
...@@ -7546,6 +7546,61 @@ static int bnxt_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh, ...@@ -7546,6 +7546,61 @@ static int bnxt_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh,
return rc; return rc;
} }
static int bnxt_get_phys_port_name(struct net_device *dev, char *buf,
size_t len)
{
struct bnxt *bp = netdev_priv(dev);
int rc;
/* The PF and it's VF-reps only support the switchdev framework */
if (!BNXT_PF(bp))
return -EOPNOTSUPP;
/* The switch-id that the pf belongs to is exported by
* the switchdev ndo. This name is just to distinguish from the
* vf-rep ports.
*/
rc = snprintf(buf, len, "pf%d", bp->pf.port_id);
if (rc >= len)
return -EOPNOTSUPP;
return 0;
}
int bnxt_port_attr_get(struct bnxt *bp, struct switchdev_attr *attr)
{
if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
return -EOPNOTSUPP;
/* The PF and it's VF-reps only support the switchdev framework */
if (!BNXT_PF(bp))
return -EOPNOTSUPP;
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);
break;
default:
return -EOPNOTSUPP;
}
return 0;
}
static int bnxt_swdev_port_attr_get(struct net_device *dev,
struct switchdev_attr *attr)
{
return bnxt_port_attr_get(netdev_priv(dev), attr);
}
static const struct switchdev_ops bnxt_switchdev_ops = {
.switchdev_port_attr_get = bnxt_swdev_port_attr_get
};
static const struct net_device_ops bnxt_netdev_ops = { static const struct net_device_ops bnxt_netdev_ops = {
.ndo_open = bnxt_open, .ndo_open = bnxt_open,
.ndo_start_xmit = bnxt_start_xmit, .ndo_start_xmit = bnxt_start_xmit,
...@@ -7579,6 +7634,7 @@ static const struct net_device_ops bnxt_netdev_ops = { ...@@ -7579,6 +7634,7 @@ static const struct net_device_ops bnxt_netdev_ops = {
.ndo_xdp = bnxt_xdp, .ndo_xdp = bnxt_xdp,
.ndo_bridge_getlink = bnxt_bridge_getlink, .ndo_bridge_getlink = bnxt_bridge_getlink,
.ndo_bridge_setlink = bnxt_bridge_setlink, .ndo_bridge_setlink = bnxt_bridge_setlink,
.ndo_get_phys_port_name = bnxt_get_phys_port_name
}; };
static void bnxt_remove_one(struct pci_dev *pdev) static void bnxt_remove_one(struct pci_dev *pdev)
...@@ -7838,6 +7894,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -7838,6 +7894,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->netdev_ops = &bnxt_netdev_ops; dev->netdev_ops = &bnxt_netdev_ops;
dev->watchdog_timeo = BNXT_TX_TIMEOUT; dev->watchdog_timeo = BNXT_TX_TIMEOUT;
dev->ethtool_ops = &bnxt_ethtool_ops; dev->ethtool_ops = &bnxt_ethtool_ops;
dev->switchdev_ops = &bnxt_switchdev_ops;
pci_set_drvdata(pdev, dev); pci_set_drvdata(pdev, dev);
rc = bnxt_alloc_hwrm_resources(bp); rc = bnxt_alloc_hwrm_resources(bp);
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <net/devlink.h> #include <net/devlink.h>
#include <net/dst_metadata.h> #include <net/dst_metadata.h>
#include <net/switchdev.h>
struct tx_bd { struct tx_bd {
__le32 tx_bd_len_flags_type; __le32 tx_bd_len_flags_type;
...@@ -1350,4 +1351,5 @@ int bnxt_reserve_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs, ...@@ -1350,4 +1351,5 @@ int bnxt_reserve_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
int bnxt_setup_mq_tc(struct net_device *dev, u8 tc); int bnxt_setup_mq_tc(struct net_device *dev, u8 tc);
int bnxt_get_max_rings(struct bnxt *, int *, int *, bool); int bnxt_get_max_rings(struct bnxt *, int *, int *, bool);
void bnxt_restore_pf_fw_resources(struct bnxt *bp); void bnxt_restore_pf_fw_resources(struct bnxt *bp);
int bnxt_port_attr_get(struct bnxt *bp, struct switchdev_attr *attr);
#endif #endif
...@@ -135,6 +135,18 @@ void bnxt_vf_rep_rx(struct bnxt *bp, struct sk_buff *skb) ...@@ -135,6 +135,18 @@ void bnxt_vf_rep_rx(struct bnxt *bp, struct sk_buff *skb)
netif_receive_skb(skb); netif_receive_skb(skb);
} }
static int bnxt_vf_rep_get_phys_port_name(struct net_device *dev, char *buf,
size_t len)
{
struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
int rc;
rc = snprintf(buf, len, "vfr%d", vf_rep->vf_idx);
if (rc >= len)
return -EOPNOTSUPP;
return 0;
}
static void bnxt_vf_rep_get_drvinfo(struct net_device *dev, static void bnxt_vf_rep_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info) struct ethtool_drvinfo *info)
{ {
...@@ -142,6 +154,21 @@ static void bnxt_vf_rep_get_drvinfo(struct net_device *dev, ...@@ -142,6 +154,21 @@ static void bnxt_vf_rep_get_drvinfo(struct net_device *dev,
strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version)); strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
} }
static int bnxt_vf_rep_port_attr_get(struct net_device *dev,
struct switchdev_attr *attr)
{
struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
/* as only PORT_PARENT_ID is supported currently use common code
* between PF and VF-rep for now.
*/
return bnxt_port_attr_get(vf_rep->bp, attr);
}
static const struct switchdev_ops bnxt_vf_rep_switchdev_ops = {
.switchdev_port_attr_get = bnxt_vf_rep_port_attr_get
};
static const struct ethtool_ops bnxt_vf_rep_ethtool_ops = { static const struct ethtool_ops bnxt_vf_rep_ethtool_ops = {
.get_drvinfo = bnxt_vf_rep_get_drvinfo .get_drvinfo = bnxt_vf_rep_get_drvinfo
}; };
...@@ -150,7 +177,8 @@ static const struct net_device_ops bnxt_vf_rep_netdev_ops = { ...@@ -150,7 +177,8 @@ static const struct net_device_ops bnxt_vf_rep_netdev_ops = {
.ndo_open = bnxt_vf_rep_open, .ndo_open = bnxt_vf_rep_open,
.ndo_stop = bnxt_vf_rep_close, .ndo_stop = bnxt_vf_rep_close,
.ndo_start_xmit = bnxt_vf_rep_xmit, .ndo_start_xmit = bnxt_vf_rep_xmit,
.ndo_get_stats64 = bnxt_vf_rep_get_stats64 .ndo_get_stats64 = bnxt_vf_rep_get_stats64,
.ndo_get_phys_port_name = bnxt_vf_rep_get_phys_port_name
}; };
/* Called when the parent PF interface is closed: /* Called when the parent PF interface is closed:
...@@ -274,6 +302,7 @@ static void bnxt_vf_rep_netdev_init(struct bnxt *bp, struct bnxt_vf_rep *vf_rep, ...@@ -274,6 +302,7 @@ static void bnxt_vf_rep_netdev_init(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
dev->netdev_ops = &bnxt_vf_rep_netdev_ops; dev->netdev_ops = &bnxt_vf_rep_netdev_ops;
dev->ethtool_ops = &bnxt_vf_rep_ethtool_ops; dev->ethtool_ops = &bnxt_vf_rep_ethtool_ops;
dev->switchdev_ops = &bnxt_vf_rep_switchdev_ops;
/* Just inherit all the featues of the parent PF as the VF-R /* Just inherit all the featues of the parent PF as the VF-R
* uses the RX/TX rings of the parent PF * uses the RX/TX rings of the parent PF
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment