0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/pci.h>
0010 #include <linux/netdevice.h>
0011 #include <linux/etherdevice.h>
0012 #include <linux/rtnetlink.h>
0013 #include <linux/jhash.h>
0014 #include <net/pkt_cls.h>
0015
0016 #include "bnxt_hsi.h"
0017 #include "bnxt.h"
0018 #include "bnxt_hwrm.h"
0019 #include "bnxt_vfr.h"
0020 #include "bnxt_devlink.h"
0021 #include "bnxt_tc.h"
0022
0023 #ifdef CONFIG_BNXT_SRIOV
0024
0025 #define CFA_HANDLE_INVALID 0xffff
0026 #define VF_IDX_INVALID 0xffff
0027
0028 static int hwrm_cfa_vfr_alloc(struct bnxt *bp, u16 vf_idx,
0029 u16 *tx_cfa_action, u16 *rx_cfa_code)
0030 {
0031 struct hwrm_cfa_vfr_alloc_output *resp;
0032 struct hwrm_cfa_vfr_alloc_input *req;
0033 int rc;
0034
0035 rc = hwrm_req_init(bp, req, HWRM_CFA_VFR_ALLOC);
0036 if (!rc) {
0037 req->vf_id = cpu_to_le16(vf_idx);
0038 sprintf(req->vfr_name, "vfr%d", vf_idx);
0039
0040 resp = hwrm_req_hold(bp, req);
0041 rc = hwrm_req_send(bp, req);
0042 if (!rc) {
0043 *tx_cfa_action = le16_to_cpu(resp->tx_cfa_action);
0044 *rx_cfa_code = le16_to_cpu(resp->rx_cfa_code);
0045 netdev_dbg(bp->dev, "tx_cfa_action=0x%x, rx_cfa_code=0x%x",
0046 *tx_cfa_action, *rx_cfa_code);
0047 }
0048 hwrm_req_drop(bp, req);
0049 }
0050 if (rc)
0051 netdev_info(bp->dev, "%s error rc=%d\n", __func__, rc);
0052 return rc;
0053 }
0054
0055 static int hwrm_cfa_vfr_free(struct bnxt *bp, u16 vf_idx)
0056 {
0057 struct hwrm_cfa_vfr_free_input *req;
0058 int rc;
0059
0060 rc = hwrm_req_init(bp, req, HWRM_CFA_VFR_FREE);
0061 if (!rc) {
0062 sprintf(req->vfr_name, "vfr%d", vf_idx);
0063 rc = hwrm_req_send(bp, req);
0064 }
0065 if (rc)
0066 netdev_info(bp->dev, "%s error rc=%d\n", __func__, rc);
0067 return rc;
0068 }
0069
0070 static int bnxt_hwrm_vfr_qcfg(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
0071 u16 *max_mtu)
0072 {
0073 struct hwrm_func_qcfg_output *resp;
0074 struct hwrm_func_qcfg_input *req;
0075 u16 mtu;
0076 int rc;
0077
0078 rc = hwrm_req_init(bp, req, HWRM_FUNC_QCFG);
0079 if (rc)
0080 return rc;
0081
0082 req->fid = cpu_to_le16(bp->pf.vf[vf_rep->vf_idx].fw_fid);
0083 resp = hwrm_req_hold(bp, req);
0084 rc = hwrm_req_send(bp, req);
0085 if (!rc) {
0086 mtu = le16_to_cpu(resp->max_mtu_configured);
0087 if (!mtu)
0088 *max_mtu = BNXT_MAX_MTU;
0089 else
0090 *max_mtu = mtu;
0091 }
0092 hwrm_req_drop(bp, req);
0093 return rc;
0094 }
0095
0096 static int bnxt_vf_rep_open(struct net_device *dev)
0097 {
0098 struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
0099 struct bnxt *bp = vf_rep->bp;
0100
0101
0102 if (netif_running(bp->dev)) {
0103 netif_carrier_on(dev);
0104 netif_tx_start_all_queues(dev);
0105 }
0106 return 0;
0107 }
0108
0109 static int bnxt_vf_rep_close(struct net_device *dev)
0110 {
0111 netif_carrier_off(dev);
0112 netif_tx_disable(dev);
0113
0114 return 0;
0115 }
0116
0117 static netdev_tx_t bnxt_vf_rep_xmit(struct sk_buff *skb,
0118 struct net_device *dev)
0119 {
0120 struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
0121 int rc, len = skb->len;
0122
0123 skb_dst_drop(skb);
0124 dst_hold((struct dst_entry *)vf_rep->dst);
0125 skb_dst_set(skb, (struct dst_entry *)vf_rep->dst);
0126 skb->dev = vf_rep->dst->u.port_info.lower_dev;
0127
0128 rc = dev_queue_xmit(skb);
0129 if (!rc) {
0130 vf_rep->tx_stats.packets++;
0131 vf_rep->tx_stats.bytes += len;
0132 }
0133 return rc;
0134 }
0135
0136 static void
0137 bnxt_vf_rep_get_stats64(struct net_device *dev,
0138 struct rtnl_link_stats64 *stats)
0139 {
0140 struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
0141
0142 stats->rx_packets = vf_rep->rx_stats.packets;
0143 stats->rx_bytes = vf_rep->rx_stats.bytes;
0144 stats->tx_packets = vf_rep->tx_stats.packets;
0145 stats->tx_bytes = vf_rep->tx_stats.bytes;
0146 }
0147
0148 static int bnxt_vf_rep_setup_tc_block_cb(enum tc_setup_type type,
0149 void *type_data,
0150 void *cb_priv)
0151 {
0152 struct bnxt_vf_rep *vf_rep = cb_priv;
0153 struct bnxt *bp = vf_rep->bp;
0154 int vf_fid = bp->pf.vf[vf_rep->vf_idx].fw_fid;
0155
0156 if (!bnxt_tc_flower_enabled(vf_rep->bp) ||
0157 !tc_cls_can_offload_and_chain0(bp->dev, type_data))
0158 return -EOPNOTSUPP;
0159
0160 switch (type) {
0161 case TC_SETUP_CLSFLOWER:
0162 return bnxt_tc_setup_flower(bp, vf_fid, type_data);
0163 default:
0164 return -EOPNOTSUPP;
0165 }
0166 }
0167
0168 static LIST_HEAD(bnxt_vf_block_cb_list);
0169
0170 static int bnxt_vf_rep_setup_tc(struct net_device *dev, enum tc_setup_type type,
0171 void *type_data)
0172 {
0173 struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
0174
0175 switch (type) {
0176 case TC_SETUP_BLOCK:
0177 return flow_block_cb_setup_simple(type_data,
0178 &bnxt_vf_block_cb_list,
0179 bnxt_vf_rep_setup_tc_block_cb,
0180 vf_rep, vf_rep, true);
0181 default:
0182 return -EOPNOTSUPP;
0183 }
0184 }
0185
0186 struct net_device *bnxt_get_vf_rep(struct bnxt *bp, u16 cfa_code)
0187 {
0188 u16 vf_idx;
0189
0190 if (cfa_code && bp->cfa_code_map && BNXT_PF(bp)) {
0191 vf_idx = bp->cfa_code_map[cfa_code];
0192 if (vf_idx != VF_IDX_INVALID)
0193 return bp->vf_reps[vf_idx]->dev;
0194 }
0195 return NULL;
0196 }
0197
0198 void bnxt_vf_rep_rx(struct bnxt *bp, struct sk_buff *skb)
0199 {
0200 struct bnxt_vf_rep *vf_rep = netdev_priv(skb->dev);
0201
0202 vf_rep->rx_stats.bytes += skb->len;
0203 vf_rep->rx_stats.packets++;
0204
0205 netif_receive_skb(skb);
0206 }
0207
0208 static int bnxt_vf_rep_get_phys_port_name(struct net_device *dev, char *buf,
0209 size_t len)
0210 {
0211 struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
0212 struct pci_dev *pf_pdev = vf_rep->bp->pdev;
0213 int rc;
0214
0215 rc = snprintf(buf, len, "pf%dvf%d", PCI_FUNC(pf_pdev->devfn),
0216 vf_rep->vf_idx);
0217 if (rc >= len)
0218 return -EOPNOTSUPP;
0219 return 0;
0220 }
0221
0222 static void bnxt_vf_rep_get_drvinfo(struct net_device *dev,
0223 struct ethtool_drvinfo *info)
0224 {
0225 strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
0226 }
0227
0228 static int bnxt_vf_rep_get_port_parent_id(struct net_device *dev,
0229 struct netdev_phys_item_id *ppid)
0230 {
0231 struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
0232
0233
0234
0235
0236 return bnxt_get_port_parent_id(vf_rep->bp->dev, ppid);
0237 }
0238
0239 static const struct ethtool_ops bnxt_vf_rep_ethtool_ops = {
0240 .get_drvinfo = bnxt_vf_rep_get_drvinfo
0241 };
0242
0243 static const struct net_device_ops bnxt_vf_rep_netdev_ops = {
0244 .ndo_open = bnxt_vf_rep_open,
0245 .ndo_stop = bnxt_vf_rep_close,
0246 .ndo_start_xmit = bnxt_vf_rep_xmit,
0247 .ndo_get_stats64 = bnxt_vf_rep_get_stats64,
0248 .ndo_setup_tc = bnxt_vf_rep_setup_tc,
0249 .ndo_get_port_parent_id = bnxt_vf_rep_get_port_parent_id,
0250 .ndo_get_phys_port_name = bnxt_vf_rep_get_phys_port_name
0251 };
0252
0253 bool bnxt_dev_is_vf_rep(struct net_device *dev)
0254 {
0255 return dev->netdev_ops == &bnxt_vf_rep_netdev_ops;
0256 }
0257
0258
0259
0260
0261
0262
0263 void bnxt_vf_reps_close(struct bnxt *bp)
0264 {
0265 struct bnxt_vf_rep *vf_rep;
0266 u16 num_vfs, i;
0267
0268 if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
0269 return;
0270
0271 num_vfs = pci_num_vf(bp->pdev);
0272 for (i = 0; i < num_vfs; i++) {
0273 vf_rep = bp->vf_reps[i];
0274 if (netif_running(vf_rep->dev))
0275 bnxt_vf_rep_close(vf_rep->dev);
0276 }
0277 }
0278
0279
0280
0281
0282
0283
0284 void bnxt_vf_reps_open(struct bnxt *bp)
0285 {
0286 int i;
0287
0288 if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
0289 return;
0290
0291 for (i = 0; i < pci_num_vf(bp->pdev); i++) {
0292
0293 if (bp->vf_reps[i]->tx_cfa_action != CFA_HANDLE_INVALID)
0294 bnxt_vf_rep_open(bp->vf_reps[i]->dev);
0295 }
0296 }
0297
0298 static void __bnxt_free_one_vf_rep(struct bnxt *bp, struct bnxt_vf_rep *vf_rep)
0299 {
0300 if (!vf_rep)
0301 return;
0302
0303 if (vf_rep->dst) {
0304 dst_release((struct dst_entry *)vf_rep->dst);
0305 vf_rep->dst = NULL;
0306 }
0307 if (vf_rep->tx_cfa_action != CFA_HANDLE_INVALID) {
0308 hwrm_cfa_vfr_free(bp, vf_rep->vf_idx);
0309 vf_rep->tx_cfa_action = CFA_HANDLE_INVALID;
0310 }
0311 }
0312
0313 static void __bnxt_vf_reps_destroy(struct bnxt *bp)
0314 {
0315 u16 num_vfs = pci_num_vf(bp->pdev);
0316 struct bnxt_vf_rep *vf_rep;
0317 int i;
0318
0319 for (i = 0; i < num_vfs; i++) {
0320 vf_rep = bp->vf_reps[i];
0321 if (vf_rep) {
0322 __bnxt_free_one_vf_rep(bp, vf_rep);
0323 if (vf_rep->dev) {
0324
0325
0326
0327 if (vf_rep->dev->netdev_ops)
0328 unregister_netdev(vf_rep->dev);
0329 free_netdev(vf_rep->dev);
0330 }
0331 }
0332 }
0333
0334 kfree(bp->vf_reps);
0335 bp->vf_reps = NULL;
0336 }
0337
0338 void bnxt_vf_reps_destroy(struct bnxt *bp)
0339 {
0340 bool closed = false;
0341
0342 if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
0343 return;
0344
0345 if (!bp->vf_reps)
0346 return;
0347
0348
0349
0350
0351 rtnl_lock();
0352 if (netif_running(bp->dev)) {
0353 bnxt_close_nic(bp, false, false);
0354 closed = true;
0355 }
0356
0357 kfree(bp->cfa_code_map);
0358 bp->cfa_code_map = NULL;
0359 bp->eswitch_mode = DEVLINK_ESWITCH_MODE_LEGACY;
0360
0361 if (closed)
0362 bnxt_open_nic(bp, false, false);
0363 rtnl_unlock();
0364
0365
0366
0367
0368 __bnxt_vf_reps_destroy(bp);
0369 }
0370
0371
0372
0373
0374
0375
0376 void bnxt_vf_reps_free(struct bnxt *bp)
0377 {
0378 u16 num_vfs = pci_num_vf(bp->pdev);
0379 int i;
0380
0381 if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
0382 return;
0383
0384 for (i = 0; i < num_vfs; i++)
0385 __bnxt_free_one_vf_rep(bp, bp->vf_reps[i]);
0386 }
0387
0388 static int bnxt_alloc_vf_rep(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
0389 u16 *cfa_code_map)
0390 {
0391
0392 if (hwrm_cfa_vfr_alloc(bp, vf_rep->vf_idx, &vf_rep->tx_cfa_action,
0393 &vf_rep->rx_cfa_code))
0394 return -ENOLINK;
0395
0396 cfa_code_map[vf_rep->rx_cfa_code] = vf_rep->vf_idx;
0397 vf_rep->dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, GFP_KERNEL);
0398 if (!vf_rep->dst)
0399 return -ENOMEM;
0400
0401
0402 vf_rep->dst->u.port_info.port_id = vf_rep->tx_cfa_action;
0403 vf_rep->dst->u.port_info.lower_dev = bp->dev;
0404
0405 return 0;
0406 }
0407
0408
0409
0410
0411
0412
0413 int bnxt_vf_reps_alloc(struct bnxt *bp)
0414 {
0415 u16 *cfa_code_map = bp->cfa_code_map, num_vfs = pci_num_vf(bp->pdev);
0416 struct bnxt_vf_rep *vf_rep;
0417 int rc, i;
0418
0419 if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
0420 return 0;
0421
0422 if (!cfa_code_map)
0423 return -EINVAL;
0424
0425 for (i = 0; i < MAX_CFA_CODE; i++)
0426 cfa_code_map[i] = VF_IDX_INVALID;
0427
0428 for (i = 0; i < num_vfs; i++) {
0429 vf_rep = bp->vf_reps[i];
0430 vf_rep->vf_idx = i;
0431
0432 rc = bnxt_alloc_vf_rep(bp, vf_rep, cfa_code_map);
0433 if (rc)
0434 goto err;
0435 }
0436
0437 return 0;
0438
0439 err:
0440 netdev_info(bp->dev, "%s error=%d\n", __func__, rc);
0441 bnxt_vf_reps_free(bp);
0442 return rc;
0443 }
0444
0445
0446
0447
0448 static void bnxt_vf_rep_eth_addr_gen(u8 *src_mac, u16 vf_idx, u8 *mac)
0449 {
0450 u32 addr;
0451
0452 ether_addr_copy(mac, src_mac);
0453
0454 addr = jhash(src_mac, ETH_ALEN, 0) + vf_idx;
0455 mac[3] = (u8)(addr & 0xFF);
0456 mac[4] = (u8)((addr >> 8) & 0xFF);
0457 mac[5] = (u8)((addr >> 16) & 0xFF);
0458 }
0459
0460 static void bnxt_vf_rep_netdev_init(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
0461 struct net_device *dev)
0462 {
0463 struct net_device *pf_dev = bp->dev;
0464 u16 max_mtu;
0465
0466 dev->netdev_ops = &bnxt_vf_rep_netdev_ops;
0467 dev->ethtool_ops = &bnxt_vf_rep_ethtool_ops;
0468
0469
0470
0471 dev->hw_features = pf_dev->hw_features;
0472 dev->gso_partial_features = pf_dev->gso_partial_features;
0473 dev->vlan_features = pf_dev->vlan_features;
0474 dev->hw_enc_features = pf_dev->hw_enc_features;
0475 dev->features |= pf_dev->features;
0476 bnxt_vf_rep_eth_addr_gen(bp->pf.mac_addr, vf_rep->vf_idx,
0477 dev->perm_addr);
0478 eth_hw_addr_set(dev, dev->perm_addr);
0479
0480 if (!bnxt_hwrm_vfr_qcfg(bp, vf_rep, &max_mtu))
0481 dev->max_mtu = max_mtu;
0482 dev->min_mtu = ETH_ZLEN;
0483 }
0484
0485 static int bnxt_vf_reps_create(struct bnxt *bp)
0486 {
0487 u16 *cfa_code_map = NULL, num_vfs = pci_num_vf(bp->pdev);
0488 struct bnxt_vf_rep *vf_rep;
0489 struct net_device *dev;
0490 int rc, i;
0491
0492 if (!(bp->flags & BNXT_FLAG_DSN_VALID))
0493 return -ENODEV;
0494
0495 bp->vf_reps = kcalloc(num_vfs, sizeof(vf_rep), GFP_KERNEL);
0496 if (!bp->vf_reps)
0497 return -ENOMEM;
0498
0499
0500 cfa_code_map = kmalloc_array(MAX_CFA_CODE, sizeof(*bp->cfa_code_map),
0501 GFP_KERNEL);
0502 if (!cfa_code_map) {
0503 rc = -ENOMEM;
0504 goto err;
0505 }
0506 for (i = 0; i < MAX_CFA_CODE; i++)
0507 cfa_code_map[i] = VF_IDX_INVALID;
0508
0509 for (i = 0; i < num_vfs; i++) {
0510 dev = alloc_etherdev(sizeof(*vf_rep));
0511 if (!dev) {
0512 rc = -ENOMEM;
0513 goto err;
0514 }
0515
0516 vf_rep = netdev_priv(dev);
0517 bp->vf_reps[i] = vf_rep;
0518 vf_rep->dev = dev;
0519 vf_rep->bp = bp;
0520 vf_rep->vf_idx = i;
0521 vf_rep->tx_cfa_action = CFA_HANDLE_INVALID;
0522
0523 rc = bnxt_alloc_vf_rep(bp, vf_rep, cfa_code_map);
0524 if (rc)
0525 goto err;
0526
0527 bnxt_vf_rep_netdev_init(bp, vf_rep, dev);
0528 rc = register_netdev(dev);
0529 if (rc) {
0530
0531 dev->netdev_ops = NULL;
0532 goto err;
0533 }
0534 }
0535
0536
0537 bp->cfa_code_map = cfa_code_map;
0538 bp->eswitch_mode = DEVLINK_ESWITCH_MODE_SWITCHDEV;
0539 netif_keep_dst(bp->dev);
0540 return 0;
0541
0542 err:
0543 netdev_info(bp->dev, "%s error=%d\n", __func__, rc);
0544 kfree(cfa_code_map);
0545 __bnxt_vf_reps_destroy(bp);
0546 return rc;
0547 }
0548
0549
0550 int bnxt_dl_eswitch_mode_get(struct devlink *devlink, u16 *mode)
0551 {
0552 struct bnxt *bp = bnxt_get_bp_from_dl(devlink);
0553
0554 *mode = bp->eswitch_mode;
0555 return 0;
0556 }
0557
0558 int bnxt_dl_eswitch_mode_set(struct devlink *devlink, u16 mode,
0559 struct netlink_ext_ack *extack)
0560 {
0561 struct bnxt *bp = bnxt_get_bp_from_dl(devlink);
0562
0563 if (bp->eswitch_mode == mode) {
0564 netdev_info(bp->dev, "already in %s eswitch mode\n",
0565 mode == DEVLINK_ESWITCH_MODE_LEGACY ?
0566 "legacy" : "switchdev");
0567 return -EINVAL;
0568 }
0569
0570 switch (mode) {
0571 case DEVLINK_ESWITCH_MODE_LEGACY:
0572 bnxt_vf_reps_destroy(bp);
0573 return 0;
0574
0575 case DEVLINK_ESWITCH_MODE_SWITCHDEV:
0576 if (bp->hwrm_spec_code < 0x10803) {
0577 netdev_warn(bp->dev, "FW does not support SRIOV E-Switch SWITCHDEV mode\n");
0578 return -ENOTSUPP;
0579 }
0580
0581 if (pci_num_vf(bp->pdev) == 0) {
0582 netdev_info(bp->dev, "Enable VFs before setting switchdev mode\n");
0583 return -EPERM;
0584 }
0585 return bnxt_vf_reps_create(bp);
0586
0587 default:
0588 return -EINVAL;
0589 }
0590 }
0591
0592 #endif