Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'octeontx2-rvu-rep'

Geetha sowjanya says:

====================
Introduce RVU representors

This series adds representor support for each rvu devices.
When switchdev mode is enabled, representor netdev is registered
for each rvu device. In implementation of representor model,
one NIX HW LF with multiple SQ and RQ is reserved, where each
RQ and SQ of the LF are mapped to a representor. A loopback channel
is reserved to support packet path between representors and VFs.
CN10K silicon supports 2 types of MACs, RPM and SDP. This
patch set adds representor support for both RPM and SDP MAC
interfaces.

- Patch 1: Implements basic representor driver.
- Patch 2: Add devlink support to create representor netdevs that
can be used to manage VFs.
- Patch 3: Implements basec netdev_ndo_ops.
- Patch 4: Installs tcam rules to route packets between representor and
VFs.
- Patch 5: Enables fetching VF stats via representor interface
- Patch 6: Adds support to sync link state between representors and VFs .
- Patch 7: Enables configuring VF MTU via representor netdevs.
- Patch 8: Adds representors for sdp MAC.
- Patch 9: Adds devlink port support.
- Patch 10: Implements offload stats.
- Patch 11: Implements tc offload support.
- patch 12: Adds documentation for rvu port representor.

pci/0002:1c:00.0

Command to create PF/VF representor

Rpf1vf0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000 link/ether f6:43:83:ee:26:21 brd ff:ff:ff:ff:ff:ff
Rpf1vf1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000 link/ether 12:b2:54:0e:24:54 brd ff:ff:ff:ff:ff:ff
Rpf1vf2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000 link/ether 4a:12:c4:4c:32:62 brd ff:ff:ff:ff:ff:ff
Rpf1vf3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000 link/ether ca:cb:68:0e:e2:6e brd ff:ff:ff:ff:ff:ff
Rpf2vf0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000 link/ether 06:cc:ad:b4:f0:93 brd ff:ff:ff:ff:ff:ff

~# devlink port
pci/0002:1c:00.0/0: type eth netdev Rpf1vf0 flavour physical port 0 splittable false
pci/0002:1c:00.0/1: type eth netdev Rpf1vf1 flavour pcivf controller 0 pfnum 1 vfnum 1 external false splittable false
pci/0002:1c:00.0/2: type eth netdev Rpf1vf2 flavour pcivf controller 0 pfnum 1 vfnum 2 external false splittable false
pci/0002:1c:00.0/3: type eth netdev Rpf1vf3 flavour pcivf controller 0 pfnum 1 vfnum 3 external false splittable false

-----------
v11:v1:
- Submitted refactoring changes as a separate patch set.
https://lore.kernel.org/netdev/20241023161843.15543-1-gakula@marvell.com/T/
- Moved documentation to a separate patch.
- patch 9: Added code changes to forward updated mac address to VF.
- Implemented TC offload support.

v10-v11:
- As suggested by "Jiri Pirko" adjusted the documentation.
- Added more commit description to patch1.

v9-v10:
- Fixed build warning w.r.t documentation.

v8-v9:
- Updated the documentation.

v7-v8:
- Implemented offload stats ndo.
- Added documentation.

v6-v7:
- Rebased on top net-next branch.

v5-v6:
- Addressed review comments provided by "Simon Horman".
- Added review tag.

v4-v5:
- Patch 3: Removed devm_* usage in rvu_rep_create()
- Patch 3: Fixed build warnings.

v3-v4:
- Patch 2 & 3: Fixed coccinelle reported warnings.
- Patch 10: Added devlink port support.

v2-v3:
- Used extack for error messages.
- As suggested reworked commit messages.
- Fixed sparse warning.

v1-v2:
-Fixed build warnings.
-Address review comments provided by "Kalesh Anakkur Purayil".
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+1942 -131
+91
Documentation/networking/device_drivers/ethernet/marvell/octeontx2.rst
··· 14 14 - `Basic packet flow`_ 15 15 - `Devlink health reporters`_ 16 16 - `Quality of service`_ 17 + - `RVU representors`_ 17 18 18 19 Overview 19 20 ======== ··· 341 340 # tc class add dev <interface> parent 1: classid 1:2 htb rate 10Gbit prio 2 quantum 188416 342 341 343 342 # tc class add dev <interface> parent 1: classid 1:3 htb rate 10Gbit prio 2 quantum 32768 343 + 344 + 345 + RVU Representors 346 + ================ 347 + 348 + RVU representor driver adds support for creation of representor devices for 349 + RVU PFs' VFs in the system. Representor devices are created when user enables 350 + the switchdev mode. 351 + Switchdev mode can be enabled either before or after setting up SRIOV numVFs. 352 + All representor devices share a single NIXLF but each has a dedicated Rx/Tx 353 + queues. RVU PF representor driver registers a separate netdev for each 354 + Rx/Tx queue pair. 355 + 356 + Current HW does not support built-in switch which can do L2 learning and 357 + forwarding packets between representee and representor. Hence, packet path 358 + between representee and it's representor is achieved by setting up appropriate 359 + NPC MCAM filters. 360 + Transmit packets matching these filters will be loopbacked through hardware 361 + loopback channel/interface (i.e, instead of sending them out of MAC interface). 362 + Which will again match the installed filters and will be forwarded. 363 + This way representee => representor and representor => representee packet 364 + path is achieved. These rules get installed when representors are created 365 + and gets active/deactivate based on the representor/representee interface state. 366 + 367 + Usage example: 368 + 369 + - Change device to switchdev mode:: 370 + 371 + # devlink dev eswitch set pci/0002:1c:00.0 mode switchdev 372 + 373 + - List of representor devices on the system:: 374 + 375 + # ip link show 376 + Rpf1vf0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000 link/ether f6:43:83:ee:26:21 brd ff:ff:ff:ff:ff:ff 377 + Rpf1vf1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000 link/ether 12:b2:54:0e:24:54 brd ff:ff:ff:ff:ff:ff 378 + Rpf1vf2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000 link/ether 4a:12:c4:4c:32:62 brd ff:ff:ff:ff:ff:ff 379 + Rpf1vf3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000 link/ether ca:cb:68:0e:e2:6e brd ff:ff:ff:ff:ff:ff 380 + Rpf2vf0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 1000 link/ether 06:cc:ad:b4:f0:93 brd ff:ff:ff:ff:ff:ff 381 + 382 + 383 + To delete the representors devices from the system. Change the device to legacy mode. 384 + 385 + - Change device to legacy mode:: 386 + 387 + # devlink dev eswitch set pci/0002:1c:00.0 mode legacy 388 + 389 + RVU representors can be managed using devlink ports 390 + (see :ref:`Documentation/networking/devlink/devlink-port.rst <devlink_port>`) interface. 391 + 392 + - Show devlink ports of representors:: 393 + 394 + # devlink port 395 + pci/0002:1c:00.0/0: type eth netdev Rpf1vf0 flavour physical port 0 splittable false 396 + pci/0002:1c:00.0/1: type eth netdev Rpf1vf1 flavour pcivf controller 0 pfnum 1 vfnum 1 external false splittable false 397 + pci/0002:1c:00.0/2: type eth netdev Rpf1vf2 flavour pcivf controller 0 pfnum 1 vfnum 2 external false splittable false 398 + pci/0002:1c:00.0/3: type eth netdev Rpf1vf3 flavour pcivf controller 0 pfnum 1 vfnum 3 external false splittable false 399 + 400 + Function attributes 401 + =================== 402 + 403 + The RVU representor support function attributes for representors. 404 + Port function configuration of the representors are supported through devlink eswitch port. 405 + 406 + MAC address setup 407 + ----------------- 408 + 409 + RVU representor driver support devlink port function attr mechanism to setup MAC 410 + address. (refer to Documentation/networking/devlink/devlink-port.rst) 411 + 412 + - To setup MAC address for port 2:: 413 + 414 + # devlink port function set pci/0002:1c:00.0/2 hw_addr 5c:a1:1b:5e:43:11 415 + # devlink port show pci/0002:1c:00.0/2 416 + pci/0002:1c:00.0/2: type eth netdev Rpf1vf2 flavour pcivf controller 0 pfnum 1 vfnum 2 external false splittable false 417 + function: 418 + hw_addr 5c:a1:1b:5e:43:11 419 + 420 + 421 + TC offload 422 + ========== 423 + 424 + The rvu representor driver implements support for offloading tc rules using port representors. 425 + 426 + - Drop packets with vlan id 3:: 427 + 428 + # tc filter add dev Rpf1vf0 protocol 802.1Q parent ffff: flower vlan_id 3 vlan_ethtype ipv4 skip_sw action drop 429 + 430 + - Redirect packets with vlan id 5 and IPv4 packets to eth1, after stripping vlan header.:: 431 + 432 + # tc filter add dev Rpf1vf0 ingress protocol 802.1Q flower vlan_id 5 vlan_ethtype ipv4 skip_sw action vlan pop action mirred ingress redirect dev eth1
+8
drivers/net/ethernet/marvell/octeontx2/Kconfig
··· 46 46 depends on OCTEONTX2_PF 47 47 help 48 48 This driver supports Marvell's OcteonTX2 NIC virtual function. 49 + 50 + config RVU_ESWITCH 51 + tristate "Marvell RVU E-Switch support" 52 + depends on OCTEONTX2_PF 53 + default m 54 + help 55 + This driver supports Marvell's RVU E-Switch that 56 + provides internal SRIOV packet steering and switching.
+2 -1
drivers/net/ethernet/marvell/octeontx2/af/Makefile
··· 11 11 rvu_af-y := cgx.o rvu.o rvu_cgx.o rvu_npa.o rvu_nix.o \ 12 12 rvu_reg.o rvu_npc.o rvu_debugfs.o ptp.o rvu_npc_fs.o \ 13 13 rvu_cpt.o rvu_devlink.o rpm.o rvu_cn10k.o rvu_switch.o \ 14 - rvu_sdp.o rvu_npc_hash.o mcs.o mcs_rvu_if.o mcs_cnf10kb.o 14 + rvu_sdp.o rvu_npc_hash.o mcs.o mcs_rvu_if.o mcs_cnf10kb.o \ 15 + rvu_rep.o
+1
drivers/net/ethernet/marvell/octeontx2/af/common.h
··· 156 156 #define NIC_HW_MIN_FRS 40 157 157 #define NIC_HW_MAX_FRS 9212 158 158 #define SDP_HW_MAX_FRS 65535 159 + #define SDP_HW_MIN_FRS 16 159 160 #define CN10K_LMAC_LINK_MAX_FRS 16380 /* 16k - FCS */ 160 161 #define CN10K_LBK_LINK_MAX_FRS 65535 /* 64k */ 161 162
+75
drivers/net/ethernet/marvell/octeontx2/af/mbox.h
··· 144 144 msg_rsp) \ 145 145 M(SET_VF_PERM, 0x00b, set_vf_perm, set_vf_perm, msg_rsp) \ 146 146 M(PTP_GET_CAP, 0x00c, ptp_get_cap, msg_req, ptp_get_cap_rsp) \ 147 + M(GET_REP_CNT, 0x00d, get_rep_cnt, msg_req, get_rep_cnt_rsp) \ 148 + M(ESW_CFG, 0x00e, esw_cfg, esw_cfg_req, msg_rsp) \ 149 + M(REP_EVENT_NOTIFY, 0x00f, rep_event_notify, rep_event, msg_rsp) \ 147 150 /* CGX mbox IDs (range 0x200 - 0x3FF) */ \ 148 151 M(CGX_START_RXTX, 0x200, cgx_start_rxtx, msg_req, msg_rsp) \ 149 152 M(CGX_STOP_RXTX, 0x201, cgx_stop_rxtx, msg_req, msg_rsp) \ ··· 322 319 M(NIX_MCAST_GRP_UPDATE, 0x802d, nix_mcast_grp_update, \ 323 320 nix_mcast_grp_update_req, \ 324 321 nix_mcast_grp_update_rsp) \ 322 + M(NIX_LF_STATS, 0x802e, nix_lf_stats, nix_stats_req, nix_stats_rsp) \ 325 323 /* MCS mbox IDs (range 0xA000 - 0xBFFF) */ \ 326 324 M(MCS_ALLOC_RESOURCES, 0xa000, mcs_alloc_resources, mcs_alloc_rsrc_req, \ 327 325 mcs_alloc_rsrc_rsp) \ ··· 384 380 #define MBOX_UP_MCS_MESSAGES \ 385 381 M(MCS_INTR_NOTIFY, 0xE00, mcs_intr_notify, mcs_intr_info, msg_rsp) 386 382 383 + #define MBOX_UP_REP_MESSAGES \ 384 + M(REP_EVENT_UP_NOTIFY, 0xEF0, rep_event_up_notify, rep_event, msg_rsp) \ 385 + 387 386 enum { 388 387 #define M(_name, _id, _1, _2, _3) MBOX_MSG_ ## _name = _id, 389 388 MBOX_MESSAGES 390 389 MBOX_UP_CGX_MESSAGES 391 390 MBOX_UP_CPT_MESSAGES 392 391 MBOX_UP_MCS_MESSAGES 392 + MBOX_UP_REP_MESSAGES 393 393 #undef M 394 394 }; 395 395 ··· 1372 1364 u32 policer_timeunit; 1373 1365 }; 1374 1366 1367 + struct nix_stats_req { 1368 + struct mbox_msghdr hdr; 1369 + u8 reset; 1370 + u16 pcifunc; 1371 + u64 rsvd; 1372 + }; 1373 + 1374 + struct nix_stats_rsp { 1375 + struct mbox_msghdr hdr; 1376 + u16 pcifunc; 1377 + struct { 1378 + u64 octs; 1379 + u64 ucast; 1380 + u64 bcast; 1381 + u64 mcast; 1382 + u64 drop; 1383 + u64 drop_octs; 1384 + u64 drop_mcast; 1385 + u64 drop_bcast; 1386 + u64 err; 1387 + u64 rsvd[5]; 1388 + } rx; 1389 + struct { 1390 + u64 ucast; 1391 + u64 bcast; 1392 + u64 mcast; 1393 + u64 drop; 1394 + u64 octs; 1395 + } tx; 1396 + }; 1397 + 1375 1398 /* NPC mbox message structs */ 1376 1399 1377 1400 #define NPC_MCAM_ENTRY_INVALID 0xFFFF ··· 1564 1525 u64 cap; 1565 1526 }; 1566 1527 1528 + struct get_rep_cnt_rsp { 1529 + struct mbox_msghdr hdr; 1530 + u16 rep_cnt; 1531 + u16 rep_pf_map[64]; 1532 + u64 rsvd; 1533 + }; 1534 + 1535 + struct esw_cfg_req { 1536 + struct mbox_msghdr hdr; 1537 + u8 ena; 1538 + u64 rsvd; 1539 + }; 1540 + 1541 + struct rep_evt_data { 1542 + u8 port_state; 1543 + u8 vf_state; 1544 + u16 rx_mode; 1545 + u16 rx_flags; 1546 + u16 mtu; 1547 + u8 mac[ETH_ALEN]; 1548 + u64 rsvd[5]; 1549 + }; 1550 + 1551 + struct rep_event { 1552 + struct mbox_msghdr hdr; 1553 + u16 pcifunc; 1554 + #define RVU_EVENT_PORT_STATE BIT_ULL(0) 1555 + #define RVU_EVENT_PFVF_STATE BIT_ULL(1) 1556 + #define RVU_EVENT_MTU_CHANGE BIT_ULL(2) 1557 + #define RVU_EVENT_RX_MODE_CHANGE BIT_ULL(3) 1558 + #define RVU_EVENT_MAC_ADDR_CHANGE BIT_ULL(4) 1559 + u16 event; 1560 + struct rep_evt_data evt_data; 1561 + }; 1562 + 1567 1563 struct flow_msg { 1568 1564 unsigned char dmac[6]; 1569 1565 unsigned char smac[6]; ··· 1637 1563 u8 icmp_type; 1638 1564 u8 icmp_code; 1639 1565 __be16 tcp_flags; 1566 + u16 sq_id; 1640 1567 }; 1641 1568 1642 1569 struct npc_install_flow_req {
+29 -1
drivers/net/ethernet/marvell/octeontx2/af/rvu.h
··· 513 513 u16 start_entry; 514 514 }; 515 515 516 + struct rep_evtq_ent { 517 + struct list_head node; 518 + struct rep_event event; 519 + }; 520 + 516 521 struct rvu { 517 522 void __iomem *afreg_base; 518 523 void __iomem *pfreg_base; ··· 600 595 spinlock_t cpt_intr_lock; 601 596 602 597 struct mutex mbox_lock; /* Serialize mbox up and down msgs */ 598 + u16 rep_pcifunc; 599 + int rep_cnt; 600 + u16 *rep2pfvf_map; 601 + u8 rep_mode; 602 + struct work_struct rep_evt_work; 603 + struct workqueue_struct *rep_evt_wq; 604 + struct list_head rep_evtq_head; 605 + /* Representor event lock */ 606 + spinlock_t rep_evtq_lock; 603 607 }; 604 608 605 609 static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val) ··· 867 853 bool is_sdp_pf(u16 pcifunc); 868 854 bool is_sdp_vf(struct rvu *rvu, u16 pcifunc); 869 855 856 + static inline bool is_rep_dev(struct rvu *rvu, u16 pcifunc) 857 + { 858 + if (rvu->rep_pcifunc && rvu->rep_pcifunc == pcifunc) 859 + return true; 860 + 861 + return false; 862 + } 863 + 870 864 /* CGX APIs */ 871 865 static inline bool is_pf_cgxmapped(struct rvu *rvu, u8 pf) 872 866 { ··· 1073 1051 /* RVU Switch */ 1074 1052 void rvu_switch_enable(struct rvu *rvu); 1075 1053 void rvu_switch_disable(struct rvu *rvu); 1076 - void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc); 1054 + void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc, bool ena); 1055 + void rvu_switch_enable_lbk_link(struct rvu *rvu, u16 pcifunc, bool ena); 1077 1056 1078 1057 int rvu_npc_set_parse_mode(struct rvu *rvu, u16 pcifunc, u64 mode, u8 dir, 1079 1058 u64 pkind, u8 var_len_off, u8 var_len_off_mask, ··· 1087 1064 void rvu_mcs_ptp_cfg(struct rvu *rvu, u8 rpm_id, u8 lmac_id, bool ena); 1088 1065 void rvu_mcs_exit(struct rvu *rvu); 1089 1066 1067 + /* Representor APIs */ 1068 + int rvu_rep_pf_init(struct rvu *rvu); 1069 + int rvu_rep_install_mcam_rules(struct rvu *rvu); 1070 + void rvu_rep_update_rules(struct rvu *rvu, u16 pcifunc, bool ena); 1071 + int rvu_rep_notify_pfvf_state(struct rvu *rvu, u16 pcifunc, bool enable); 1090 1072 #endif /* RVU_H */
-27
drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
··· 45 45 CGX_STAT18, 46 46 }; 47 47 48 - /* NIX TX stats */ 49 - enum nix_stat_lf_tx { 50 - TX_UCAST = 0x0, 51 - TX_BCAST = 0x1, 52 - TX_MCAST = 0x2, 53 - TX_DROP = 0x3, 54 - TX_OCTS = 0x4, 55 - TX_STATS_ENUM_LAST, 56 - }; 57 - 58 - /* NIX RX stats */ 59 - enum nix_stat_lf_rx { 60 - RX_OCTS = 0x0, 61 - RX_UCAST = 0x1, 62 - RX_BCAST = 0x2, 63 - RX_MCAST = 0x3, 64 - RX_DROP = 0x4, 65 - RX_DROP_OCTS = 0x5, 66 - RX_FCS = 0x6, 67 - RX_ERR = 0x7, 68 - RX_DRP_BCAST = 0x8, 69 - RX_DRP_MCAST = 0x9, 70 - RX_DRP_L3BCAST = 0xa, 71 - RX_DRP_L3MCAST = 0xb, 72 - RX_STATS_ENUM_LAST, 73 - }; 74 - 75 48 static char *cgx_rx_stats_fields[] = { 76 49 [CGX_STAT0] = "Received packets", 77 50 [CGX_STAT1] = "Octets of received packets",
+3
drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c
··· 1500 1500 struct rvu *rvu = rvu_dl->rvu; 1501 1501 struct rvu_switch *rswitch; 1502 1502 1503 + if (rvu->rep_mode) 1504 + return -EOPNOTSUPP; 1505 + 1503 1506 rswitch = &rvu->rswitch; 1504 1507 *mode = rswitch->mode; 1505 1508
+38 -11
drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
··· 31 31 static void nix_clear_ratelimit_aggr(struct rvu *rvu, struct nix_hw *nix_hw, 32 32 u32 leaf_prof); 33 33 static const char *nix_get_ctx_name(int ctype); 34 + static int nix_get_tx_link(struct rvu *rvu, u16 pcifunc); 34 35 35 36 enum mc_tbl_sz { 36 37 MC_TBL_SZ_256, ··· 313 312 314 313 /* TLs aggegating traffic are shared across PF and VFs */ 315 314 if (lvl >= hw->cap.nix_tx_aggr_lvl) { 316 - if (rvu_get_pf(map_func) != rvu_get_pf(pcifunc)) 315 + if ((nix_get_tx_link(rvu, map_func) != 316 + nix_get_tx_link(rvu, pcifunc)) && 317 + (rvu_get_pf(map_func) != rvu_get_pf(pcifunc))) 317 318 return false; 318 319 else 319 320 return true; ··· 363 360 364 361 cgx_set_pkind(rvu_cgx_pdata(cgx_id, rvu), lmac_id, pkind); 365 362 rvu_npc_set_pkind(rvu, pkind, pfvf); 366 - 367 363 break; 368 364 case NIX_INTF_TYPE_LBK: 369 365 vf = (pcifunc & RVU_PFVF_FUNC_MASK) - 1; ··· 585 583 type = is_lbk_vf(rvu, pcifunc) ? NIX_INTF_TYPE_LBK : NIX_INTF_TYPE_CGX; 586 584 if (!is_pf_cgxmapped(rvu, pf) && type != NIX_INTF_TYPE_LBK) 587 585 return 0; 586 + 587 + if (is_sdp_pfvf(pcifunc)) 588 + type = NIX_INTF_TYPE_SDP; 588 589 589 590 pfvf = rvu_get_pfvf(rvu, pcifunc); 590 591 err = nix_get_struct_ptrs(rvu, pcifunc, &nix_hw, &blkaddr); ··· 1619 1614 cfg = NPC_TX_DEF_PKIND; 1620 1615 rvu_write64(rvu, blkaddr, NIX_AF_LFX_TX_PARSE_CFG(nixlf), cfg); 1621 1616 1617 + if (is_rep_dev(rvu, pcifunc)) { 1618 + pfvf->tx_chan_base = RVU_SWITCH_LBK_CHAN; 1619 + pfvf->tx_chan_cnt = 1; 1620 + goto exit; 1621 + } 1622 + 1622 1623 intf = is_lbk_vf(rvu, pcifunc) ? NIX_INTF_TYPE_LBK : NIX_INTF_TYPE_CGX; 1623 1624 if (is_sdp_pfvf(pcifunc)) 1624 1625 intf = NIX_INTF_TYPE_SDP; ··· 1695 1684 if (nixlf < 0) 1696 1685 return NIX_AF_ERR_AF_LF_INVALID; 1697 1686 1687 + if (is_rep_dev(rvu, pcifunc)) 1688 + goto free_lf; 1689 + 1698 1690 if (req->flags & NIX_LF_DISABLE_FLOWS) 1699 1691 rvu_npc_disable_mcam_entries(rvu, pcifunc, nixlf); 1700 1692 else ··· 1709 1695 1710 1696 nix_interface_deinit(rvu, pcifunc, nixlf); 1711 1697 1698 + free_lf: 1712 1699 /* Reset this NIX LF */ 1713 1700 err = rvu_lf_reset(rvu, block, nixlf); 1714 1701 if (err) { ··· 2022 2007 struct rvu_hwinfo *hw = rvu->hw; 2023 2008 int pf = rvu_get_pf(pcifunc); 2024 2009 2025 - if (is_lbk_vf(rvu, pcifunc)) { /* LBK links */ 2010 + /* LBK links */ 2011 + if (is_lbk_vf(rvu, pcifunc) || is_rep_dev(rvu, pcifunc)) { 2026 2012 *start = hw->cap.nix_txsch_per_cgx_lmac * link; 2027 2013 *end = *start + hw->cap.nix_txsch_per_lbk_lmac; 2028 2014 } else if (is_pf_cgxmapped(rvu, pf)) { /* CGX links */ ··· 2776 2760 int schq; 2777 2761 u64 cfg; 2778 2762 2779 - if (!is_pf_cgxmapped(rvu, pf)) 2763 + if (!is_pf_cgxmapped(rvu, pf) && !is_rep_dev(rvu, pcifunc)) 2780 2764 return; 2781 2765 2782 2766 cfg = enable ? (BIT_ULL(12) | RVU_SWITCH_LBK_CHAN) : 0; ··· 4409 4393 if (test_bit(PF_SET_VF_TRUSTED, &pfvf->flags) && from_vf) 4410 4394 ether_addr_copy(pfvf->default_mac, req->mac_addr); 4411 4395 4412 - rvu_switch_update_rules(rvu, pcifunc); 4413 - 4414 4396 return 0; 4415 4397 } 4416 4398 ··· 4569 4555 if (!nix_hw) 4570 4556 return NIX_AF_ERR_INVALID_NIXBLK; 4571 4557 4572 - if (is_lbk_vf(rvu, pcifunc)) 4558 + if (is_lbk_vf(rvu, pcifunc) || is_rep_dev(rvu, pcifunc)) 4573 4559 rvu_get_lbk_link_max_frs(rvu, &max_mtu); 4574 4560 else 4575 4561 rvu_get_lmac_link_max_frs(rvu, &max_mtu); ··· 4597 4583 /* For VFs of PF0 ingress is LBK port, so config LBK link */ 4598 4584 pfvf = rvu_get_pfvf(rvu, pcifunc); 4599 4585 link = hw->cgx_links + pfvf->lbkid; 4586 + } else if (is_rep_dev(rvu, pcifunc)) { 4587 + link = hw->cgx_links + 0; 4600 4588 } 4601 4589 4602 4590 if (link < 0) ··· 4690 4674 if (hw->sdp_links) { 4691 4675 link = hw->cgx_links + hw->lbk_links; 4692 4676 rvu_write64(rvu, blkaddr, NIX_AF_RX_LINKX_CFG(link), 4693 - SDP_HW_MAX_FRS << 16 | NIC_HW_MIN_FRS); 4677 + SDP_HW_MAX_FRS << 16 | SDP_HW_MIN_FRS); 4694 4678 } 4695 4679 4696 4680 /* Get MCS external bypass status for CN10K-B */ ··· 5182 5166 { 5183 5167 u16 pcifunc = req->hdr.pcifunc; 5184 5168 struct rvu_pfvf *pfvf; 5185 - int nixlf, err; 5169 + int nixlf, err, pf; 5186 5170 5187 5171 err = nix_get_nixlf(rvu, pcifunc, &nixlf, NULL); 5188 5172 if (err) ··· 5198 5182 pfvf = rvu_get_pfvf(rvu, pcifunc); 5199 5183 set_bit(NIXLF_INITIALIZED, &pfvf->flags); 5200 5184 5201 - rvu_switch_update_rules(rvu, pcifunc); 5185 + rvu_switch_update_rules(rvu, pcifunc, true); 5186 + 5187 + pf = rvu_get_pf(pcifunc); 5188 + if (is_pf_cgxmapped(rvu, pf) && rvu->rep_mode) 5189 + rvu_rep_notify_pfvf_state(rvu, pcifunc, true); 5202 5190 5203 5191 return rvu_cgx_start_stop_io(rvu, pcifunc, true); 5204 5192 } ··· 5212 5192 { 5213 5193 u16 pcifunc = req->hdr.pcifunc; 5214 5194 struct rvu_pfvf *pfvf; 5215 - int nixlf, err; 5195 + int nixlf, err, pf; 5216 5196 5217 5197 err = nix_get_nixlf(rvu, pcifunc, &nixlf, NULL); 5218 5198 if (err) ··· 5230 5210 if (err) 5231 5211 return err; 5232 5212 5213 + rvu_switch_update_rules(rvu, pcifunc, false); 5233 5214 rvu_cgx_tx_enable(rvu, pcifunc, true); 5234 5215 5216 + pf = rvu_get_pf(pcifunc); 5217 + if (is_pf_cgxmapped(rvu, pf) && rvu->rep_mode) 5218 + rvu_rep_notify_pfvf_state(rvu, pcifunc, false); 5235 5219 return 0; 5236 5220 } 5237 5221 ··· 5262 5238 nix_txschq_free(rvu, pcifunc); 5263 5239 5264 5240 clear_bit(NIXLF_INITIALIZED, &pfvf->flags); 5241 + 5242 + if (is_pf_cgxmapped(rvu, pf) && rvu->rep_mode) 5243 + rvu_rep_notify_pfvf_state(rvu, pcifunc, false); 5265 5244 5266 5245 rvu_cgx_start_stop_io(rvu, pcifunc, false); 5267 5246
+11 -3
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c
··· 1398 1398 struct npc_install_flow_rsp *rsp) 1399 1399 { 1400 1400 bool from_vf = !!(req->hdr.pcifunc & RVU_PFVF_FUNC_MASK); 1401 + bool from_rep_dev = !!is_rep_dev(rvu, req->hdr.pcifunc); 1401 1402 struct rvu_switch *rswitch = &rvu->rswitch; 1402 1403 int blkaddr, nixlf, err; 1403 1404 struct rvu_pfvf *pfvf; ··· 1455 1454 /* AF installing for a PF/VF */ 1456 1455 if (!req->hdr.pcifunc) 1457 1456 target = req->vf; 1457 + 1458 1458 /* PF installing for its VF */ 1459 - else if (!from_vf && req->vf) { 1459 + if (!from_vf && req->vf && !from_rep_dev) { 1460 1460 target = (req->hdr.pcifunc & ~RVU_PFVF_FUNC_MASK) | req->vf; 1461 1461 pf_set_vfs_mac = req->default_rule && 1462 1462 (req->features & BIT_ULL(NPC_DMAC)); 1463 1463 } 1464 - /* msg received from PF/VF */ 1464 + 1465 + /* Representor device installing for a representee */ 1466 + if (from_rep_dev && req->vf) 1467 + target = req->vf; 1465 1468 else 1469 + /* msg received from PF/VF */ 1466 1470 target = req->hdr.pcifunc; 1467 1471 1468 1472 /* ignore chan_mask in case pf func is not AF, revisit later */ ··· 1480 1474 1481 1475 pfvf = rvu_get_pfvf(rvu, target); 1482 1476 1477 + if (from_rep_dev) 1478 + req->channel = pfvf->rx_chan_base; 1483 1479 /* PF installing for its VF */ 1484 - if (req->hdr.pcifunc && !from_vf && req->vf) 1480 + if (req->hdr.pcifunc && !from_vf && req->vf && !from_rep_dev) 1485 1481 set_bit(PF_SET_VF_CFG, &pfvf->flags); 1486 1482 1487 1483 /* update req destination mac addr */
+1
drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h
··· 445 445 446 446 #define NIX_CONST_MAX_BPIDS GENMASK_ULL(23, 12) 447 447 #define NIX_CONST_SDP_CHANS GENMASK_ULL(11, 0) 448 + #define NIX_VLAN_ETYPE_MASK GENMASK_ULL(63, 48) 448 449 449 450 #define NIX_AF_MDQ_PARENT_MASK GENMASK_ULL(24, 16) 450 451 #define NIX_AF_TL4_PARENT_MASK GENMASK_ULL(23, 16)
+468
drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Marvell RVU Admin Function driver 3 + * 4 + * Copyright (C) 2024 Marvell. 5 + * 6 + */ 7 + 8 + #include <linux/bitfield.h> 9 + #include <linux/types.h> 10 + #include <linux/device.h> 11 + #include <linux/module.h> 12 + #include <linux/pci.h> 13 + 14 + #include "rvu.h" 15 + #include "rvu_reg.h" 16 + 17 + #define M(_name, _id, _fn_name, _req_type, _rsp_type) \ 18 + static struct _req_type __maybe_unused \ 19 + *otx2_mbox_alloc_msg_ ## _fn_name(struct rvu *rvu, int devid) \ 20 + { \ 21 + struct _req_type *req; \ 22 + \ 23 + req = (struct _req_type *)otx2_mbox_alloc_msg_rsp( \ 24 + &rvu->afpf_wq_info.mbox_up, devid, sizeof(struct _req_type), \ 25 + sizeof(struct _rsp_type)); \ 26 + if (!req) \ 27 + return NULL; \ 28 + req->hdr.sig = OTX2_MBOX_REQ_SIG; \ 29 + req->hdr.id = _id; \ 30 + return req; \ 31 + } 32 + 33 + MBOX_UP_REP_MESSAGES 34 + #undef M 35 + 36 + static int rvu_rep_up_notify(struct rvu *rvu, struct rep_event *event) 37 + { 38 + struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, event->pcifunc); 39 + struct rep_event *msg; 40 + int pf; 41 + 42 + pf = rvu_get_pf(event->pcifunc); 43 + 44 + if (event->event & RVU_EVENT_MAC_ADDR_CHANGE) 45 + ether_addr_copy(pfvf->mac_addr, event->evt_data.mac); 46 + 47 + mutex_lock(&rvu->mbox_lock); 48 + msg = otx2_mbox_alloc_msg_rep_event_up_notify(rvu, pf); 49 + if (!msg) { 50 + mutex_unlock(&rvu->mbox_lock); 51 + return -ENOMEM; 52 + } 53 + 54 + msg->hdr.pcifunc = event->pcifunc; 55 + msg->event = event->event; 56 + 57 + memcpy(&msg->evt_data, &event->evt_data, sizeof(struct rep_evt_data)); 58 + 59 + otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pf); 60 + 61 + otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pf); 62 + 63 + mutex_unlock(&rvu->mbox_lock); 64 + return 0; 65 + } 66 + 67 + static void rvu_rep_wq_handler(struct work_struct *work) 68 + { 69 + struct rvu *rvu = container_of(work, struct rvu, rep_evt_work); 70 + struct rep_evtq_ent *qentry; 71 + struct rep_event *event; 72 + unsigned long flags; 73 + 74 + do { 75 + spin_lock_irqsave(&rvu->rep_evtq_lock, flags); 76 + qentry = list_first_entry_or_null(&rvu->rep_evtq_head, 77 + struct rep_evtq_ent, 78 + node); 79 + if (qentry) 80 + list_del(&qentry->node); 81 + 82 + spin_unlock_irqrestore(&rvu->rep_evtq_lock, flags); 83 + if (!qentry) 84 + break; /* nothing more to process */ 85 + 86 + event = &qentry->event; 87 + 88 + rvu_rep_up_notify(rvu, event); 89 + kfree(qentry); 90 + } while (1); 91 + } 92 + 93 + int rvu_mbox_handler_rep_event_notify(struct rvu *rvu, struct rep_event *req, 94 + struct msg_rsp *rsp) 95 + { 96 + struct rep_evtq_ent *qentry; 97 + 98 + qentry = kmalloc(sizeof(*qentry), GFP_ATOMIC); 99 + if (!qentry) 100 + return -ENOMEM; 101 + 102 + qentry->event = *req; 103 + spin_lock(&rvu->rep_evtq_lock); 104 + list_add_tail(&qentry->node, &rvu->rep_evtq_head); 105 + spin_unlock(&rvu->rep_evtq_lock); 106 + queue_work(rvu->rep_evt_wq, &rvu->rep_evt_work); 107 + return 0; 108 + } 109 + 110 + int rvu_rep_notify_pfvf_state(struct rvu *rvu, u16 pcifunc, bool enable) 111 + { 112 + struct rep_event *req; 113 + int pf; 114 + 115 + if (!is_pf_cgxmapped(rvu, rvu_get_pf(pcifunc))) 116 + return 0; 117 + 118 + pf = rvu_get_pf(rvu->rep_pcifunc); 119 + 120 + mutex_lock(&rvu->mbox_lock); 121 + req = otx2_mbox_alloc_msg_rep_event_up_notify(rvu, pf); 122 + if (!req) { 123 + mutex_unlock(&rvu->mbox_lock); 124 + return -ENOMEM; 125 + } 126 + 127 + req->hdr.pcifunc = rvu->rep_pcifunc; 128 + req->event |= RVU_EVENT_PFVF_STATE; 129 + req->pcifunc = pcifunc; 130 + req->evt_data.vf_state = enable; 131 + 132 + otx2_mbox_wait_for_zero(&rvu->afpf_wq_info.mbox_up, pf); 133 + otx2_mbox_msg_send_up(&rvu->afpf_wq_info.mbox_up, pf); 134 + 135 + mutex_unlock(&rvu->mbox_lock); 136 + return 0; 137 + } 138 + 139 + #define RVU_LF_RX_STATS(reg) \ 140 + rvu_read64(rvu, blkaddr, NIX_AF_LFX_RX_STATX(nixlf, reg)) 141 + 142 + #define RVU_LF_TX_STATS(reg) \ 143 + rvu_read64(rvu, blkaddr, NIX_AF_LFX_TX_STATX(nixlf, reg)) 144 + 145 + int rvu_mbox_handler_nix_lf_stats(struct rvu *rvu, 146 + struct nix_stats_req *req, 147 + struct nix_stats_rsp *rsp) 148 + { 149 + u16 pcifunc = req->pcifunc; 150 + int nixlf, blkaddr, err; 151 + struct msg_req rst_req; 152 + struct msg_rsp rst_rsp; 153 + 154 + err = nix_get_nixlf(rvu, pcifunc, &nixlf, &blkaddr); 155 + if (err) 156 + return 0; 157 + 158 + if (req->reset) { 159 + rst_req.hdr.pcifunc = pcifunc; 160 + return rvu_mbox_handler_nix_stats_rst(rvu, &rst_req, &rst_rsp); 161 + } 162 + rsp->rx.octs = RVU_LF_RX_STATS(RX_OCTS); 163 + rsp->rx.ucast = RVU_LF_RX_STATS(RX_UCAST); 164 + rsp->rx.bcast = RVU_LF_RX_STATS(RX_BCAST); 165 + rsp->rx.mcast = RVU_LF_RX_STATS(RX_MCAST); 166 + rsp->rx.drop = RVU_LF_RX_STATS(RX_DROP); 167 + rsp->rx.err = RVU_LF_RX_STATS(RX_ERR); 168 + rsp->rx.drop_octs = RVU_LF_RX_STATS(RX_DROP_OCTS); 169 + rsp->rx.drop_mcast = RVU_LF_RX_STATS(RX_DRP_MCAST); 170 + rsp->rx.drop_bcast = RVU_LF_RX_STATS(RX_DRP_BCAST); 171 + 172 + rsp->tx.octs = RVU_LF_TX_STATS(TX_OCTS); 173 + rsp->tx.ucast = RVU_LF_TX_STATS(TX_UCAST); 174 + rsp->tx.bcast = RVU_LF_TX_STATS(TX_BCAST); 175 + rsp->tx.mcast = RVU_LF_TX_STATS(TX_MCAST); 176 + rsp->tx.drop = RVU_LF_TX_STATS(TX_DROP); 177 + 178 + rsp->pcifunc = req->pcifunc; 179 + return 0; 180 + } 181 + 182 + static u16 rvu_rep_get_vlan_id(struct rvu *rvu, u16 pcifunc) 183 + { 184 + int id; 185 + 186 + for (id = 0; id < rvu->rep_cnt; id++) 187 + if (rvu->rep2pfvf_map[id] == pcifunc) 188 + return id; 189 + return 0; 190 + } 191 + 192 + static int rvu_rep_tx_vlan_cfg(struct rvu *rvu, u16 pcifunc, 193 + u16 vlan_tci, int *vidx) 194 + { 195 + struct nix_vtag_config_rsp rsp = {}; 196 + struct nix_vtag_config req = {}; 197 + u64 etype = ETH_P_8021Q; 198 + int err; 199 + 200 + /* Insert vlan tag */ 201 + req.hdr.pcifunc = pcifunc; 202 + req.vtag_size = VTAGSIZE_T4; 203 + req.cfg_type = 0; /* tx vlan cfg */ 204 + req.tx.cfg_vtag0 = true; 205 + req.tx.vtag0 = FIELD_PREP(NIX_VLAN_ETYPE_MASK, etype) | vlan_tci; 206 + 207 + err = rvu_mbox_handler_nix_vtag_cfg(rvu, &req, &rsp); 208 + if (err) { 209 + dev_err(rvu->dev, "Tx vlan config failed\n"); 210 + return err; 211 + } 212 + *vidx = rsp.vtag0_idx; 213 + return 0; 214 + } 215 + 216 + static int rvu_rep_rx_vlan_cfg(struct rvu *rvu, u16 pcifunc) 217 + { 218 + struct nix_vtag_config req = {}; 219 + struct nix_vtag_config_rsp rsp; 220 + 221 + /* config strip, capture and size */ 222 + req.hdr.pcifunc = pcifunc; 223 + req.vtag_size = VTAGSIZE_T4; 224 + req.cfg_type = 1; /* rx vlan cfg */ 225 + req.rx.vtag_type = NIX_AF_LFX_RX_VTAG_TYPE0; 226 + req.rx.strip_vtag = true; 227 + req.rx.capture_vtag = false; 228 + 229 + return rvu_mbox_handler_nix_vtag_cfg(rvu, &req, &rsp); 230 + } 231 + 232 + static int rvu_rep_install_rx_rule(struct rvu *rvu, u16 pcifunc, 233 + u16 entry, bool rte) 234 + { 235 + struct npc_install_flow_req req = {}; 236 + struct npc_install_flow_rsp rsp = {}; 237 + struct rvu_pfvf *pfvf; 238 + u16 vlan_tci, rep_id; 239 + 240 + pfvf = rvu_get_pfvf(rvu, pcifunc); 241 + 242 + /* To steer the traffic from Representee to Representor */ 243 + rep_id = rvu_rep_get_vlan_id(rvu, pcifunc); 244 + if (rte) { 245 + vlan_tci = rep_id | BIT_ULL(8); 246 + req.vf = rvu->rep_pcifunc; 247 + req.op = NIX_RX_ACTIONOP_UCAST; 248 + req.index = rep_id; 249 + } else { 250 + vlan_tci = rep_id; 251 + req.vf = pcifunc; 252 + req.op = NIX_RX_ACTION_DEFAULT; 253 + } 254 + 255 + rvu_rep_rx_vlan_cfg(rvu, req.vf); 256 + req.entry = entry; 257 + req.hdr.pcifunc = 0; /* AF is requester */ 258 + req.features = BIT_ULL(NPC_OUTER_VID) | BIT_ULL(NPC_VLAN_ETYPE_CTAG); 259 + req.vtag0_valid = true; 260 + req.vtag0_type = NIX_AF_LFX_RX_VTAG_TYPE0; 261 + req.packet.vlan_etype = cpu_to_be16(ETH_P_8021Q); 262 + req.mask.vlan_etype = cpu_to_be16(ETH_P_8021Q); 263 + req.packet.vlan_tci = cpu_to_be16(vlan_tci); 264 + req.mask.vlan_tci = cpu_to_be16(0xffff); 265 + 266 + req.channel = RVU_SWITCH_LBK_CHAN; 267 + req.chan_mask = 0xffff; 268 + req.intf = pfvf->nix_rx_intf; 269 + 270 + return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp); 271 + } 272 + 273 + static int rvu_rep_install_tx_rule(struct rvu *rvu, u16 pcifunc, u16 entry, 274 + bool rte) 275 + { 276 + struct npc_install_flow_req req = {}; 277 + struct npc_install_flow_rsp rsp = {}; 278 + struct rvu_pfvf *pfvf; 279 + int vidx, err; 280 + u16 vlan_tci; 281 + u8 lbkid; 282 + 283 + pfvf = rvu_get_pfvf(rvu, pcifunc); 284 + vlan_tci = rvu_rep_get_vlan_id(rvu, pcifunc); 285 + if (rte) 286 + vlan_tci |= BIT_ULL(8); 287 + 288 + err = rvu_rep_tx_vlan_cfg(rvu, pcifunc, vlan_tci, &vidx); 289 + if (err) 290 + return err; 291 + 292 + lbkid = pfvf->nix_blkaddr == BLKADDR_NIX0 ? 0 : 1; 293 + req.hdr.pcifunc = 0; /* AF is requester */ 294 + if (rte) { 295 + req.vf = pcifunc; 296 + } else { 297 + req.vf = rvu->rep_pcifunc; 298 + req.packet.sq_id = vlan_tci; 299 + req.mask.sq_id = 0xffff; 300 + } 301 + 302 + req.entry = entry; 303 + req.intf = pfvf->nix_tx_intf; 304 + req.op = NIX_TX_ACTIONOP_UCAST_CHAN; 305 + req.index = (lbkid << 8) | RVU_SWITCH_LBK_CHAN; 306 + req.set_cntr = 1; 307 + req.vtag0_def = vidx; 308 + req.vtag0_op = 1; 309 + return rvu_mbox_handler_npc_install_flow(rvu, &req, &rsp); 310 + } 311 + 312 + int rvu_rep_install_mcam_rules(struct rvu *rvu) 313 + { 314 + struct rvu_switch *rswitch = &rvu->rswitch; 315 + u16 start = rswitch->start_entry; 316 + struct rvu_hwinfo *hw = rvu->hw; 317 + u16 pcifunc, entry = 0; 318 + int pf, vf, numvfs; 319 + int err, nixlf, i; 320 + u8 rep; 321 + 322 + for (pf = 1; pf < hw->total_pfs; pf++) { 323 + if (!is_pf_cgxmapped(rvu, pf)) 324 + continue; 325 + 326 + pcifunc = pf << RVU_PFVF_PF_SHIFT; 327 + rvu_get_nix_blkaddr(rvu, pcifunc); 328 + rep = true; 329 + for (i = 0; i < 2; i++) { 330 + err = rvu_rep_install_rx_rule(rvu, pcifunc, 331 + start + entry, rep); 332 + if (err) 333 + return err; 334 + rswitch->entry2pcifunc[entry++] = pcifunc; 335 + 336 + err = rvu_rep_install_tx_rule(rvu, pcifunc, 337 + start + entry, rep); 338 + if (err) 339 + return err; 340 + rswitch->entry2pcifunc[entry++] = pcifunc; 341 + rep = false; 342 + } 343 + 344 + rvu_get_pf_numvfs(rvu, pf, &numvfs, NULL); 345 + for (vf = 0; vf < numvfs; vf++) { 346 + pcifunc = pf << RVU_PFVF_PF_SHIFT | 347 + ((vf + 1) & RVU_PFVF_FUNC_MASK); 348 + rvu_get_nix_blkaddr(rvu, pcifunc); 349 + 350 + /* Skip installimg rules if nixlf is not attached */ 351 + err = nix_get_nixlf(rvu, pcifunc, &nixlf, NULL); 352 + if (err) 353 + continue; 354 + rep = true; 355 + for (i = 0; i < 2; i++) { 356 + err = rvu_rep_install_rx_rule(rvu, pcifunc, 357 + start + entry, 358 + rep); 359 + if (err) 360 + return err; 361 + rswitch->entry2pcifunc[entry++] = pcifunc; 362 + 363 + err = rvu_rep_install_tx_rule(rvu, pcifunc, 364 + start + entry, 365 + rep); 366 + if (err) 367 + return err; 368 + rswitch->entry2pcifunc[entry++] = pcifunc; 369 + rep = false; 370 + } 371 + } 372 + } 373 + 374 + /* Initialize the wq for handling REP events */ 375 + spin_lock_init(&rvu->rep_evtq_lock); 376 + INIT_LIST_HEAD(&rvu->rep_evtq_head); 377 + INIT_WORK(&rvu->rep_evt_work, rvu_rep_wq_handler); 378 + rvu->rep_evt_wq = alloc_workqueue("rep_evt_wq", 0, 0); 379 + if (!rvu->rep_evt_wq) { 380 + dev_err(rvu->dev, "REP workqueue allocation failed\n"); 381 + return -ENOMEM; 382 + } 383 + return 0; 384 + } 385 + 386 + void rvu_rep_update_rules(struct rvu *rvu, u16 pcifunc, bool ena) 387 + { 388 + struct rvu_switch *rswitch = &rvu->rswitch; 389 + struct npc_mcam *mcam = &rvu->hw->mcam; 390 + u32 max = rswitch->used_entries; 391 + int blkaddr; 392 + u16 entry; 393 + 394 + if (!rswitch->used_entries) 395 + return; 396 + 397 + blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NPC, 0); 398 + 399 + if (blkaddr < 0) 400 + return; 401 + 402 + rvu_switch_enable_lbk_link(rvu, pcifunc, ena); 403 + mutex_lock(&mcam->lock); 404 + for (entry = 0; entry < max; entry++) { 405 + if (rswitch->entry2pcifunc[entry] == pcifunc) 406 + npc_enable_mcam_entry(rvu, mcam, blkaddr, entry, ena); 407 + } 408 + mutex_unlock(&mcam->lock); 409 + } 410 + 411 + int rvu_rep_pf_init(struct rvu *rvu) 412 + { 413 + u16 pcifunc = rvu->rep_pcifunc; 414 + struct rvu_pfvf *pfvf; 415 + 416 + pfvf = rvu_get_pfvf(rvu, pcifunc); 417 + set_bit(NIXLF_INITIALIZED, &pfvf->flags); 418 + rvu_switch_enable_lbk_link(rvu, pcifunc, true); 419 + rvu_rep_rx_vlan_cfg(rvu, pcifunc); 420 + return 0; 421 + } 422 + 423 + int rvu_mbox_handler_esw_cfg(struct rvu *rvu, struct esw_cfg_req *req, 424 + struct msg_rsp *rsp) 425 + { 426 + if (req->hdr.pcifunc != rvu->rep_pcifunc) 427 + return 0; 428 + 429 + rvu->rep_mode = req->ena; 430 + 431 + if (!rvu->rep_mode) 432 + rvu_npc_free_mcam_entries(rvu, req->hdr.pcifunc, -1); 433 + 434 + return 0; 435 + } 436 + 437 + int rvu_mbox_handler_get_rep_cnt(struct rvu *rvu, struct msg_req *req, 438 + struct get_rep_cnt_rsp *rsp) 439 + { 440 + int pf, vf, numvfs, hwvf, rep = 0; 441 + u16 pcifunc; 442 + 443 + rvu->rep_pcifunc = req->hdr.pcifunc; 444 + rsp->rep_cnt = rvu->cgx_mapped_pfs + rvu->cgx_mapped_vfs; 445 + rvu->rep_cnt = rsp->rep_cnt; 446 + 447 + rvu->rep2pfvf_map = devm_kzalloc(rvu->dev, rvu->rep_cnt * 448 + sizeof(u16), GFP_KERNEL); 449 + if (!rvu->rep2pfvf_map) 450 + return -ENOMEM; 451 + 452 + for (pf = 0; pf < rvu->hw->total_pfs; pf++) { 453 + if (!is_pf_cgxmapped(rvu, pf)) 454 + continue; 455 + pcifunc = pf << RVU_PFVF_PF_SHIFT; 456 + rvu->rep2pfvf_map[rep] = pcifunc; 457 + rsp->rep_pf_map[rep] = pcifunc; 458 + rep++; 459 + rvu_get_pf_numvfs(rvu, pf, &numvfs, &hwvf); 460 + for (vf = 0; vf < numvfs; vf++) { 461 + rvu->rep2pfvf_map[rep] = pcifunc | 462 + ((vf + 1) & RVU_PFVF_FUNC_MASK); 463 + rsp->rep_pf_map[rep] = rvu->rep2pfvf_map[rep]; 464 + rep++; 465 + } 466 + } 467 + return 0; 468 + }
+26
drivers/net/ethernet/marvell/octeontx2/af/rvu_struct.h
··· 823 823 #define VTAG_STRIP BIT_ULL(4) 824 824 #define VTAG_CAPTURE BIT_ULL(5) 825 825 826 + /* NIX TX stats */ 827 + enum nix_stat_lf_tx { 828 + TX_UCAST = 0x0, 829 + TX_BCAST = 0x1, 830 + TX_MCAST = 0x2, 831 + TX_DROP = 0x3, 832 + TX_OCTS = 0x4, 833 + TX_STATS_ENUM_LAST, 834 + }; 835 + 836 + /* NIX RX stats */ 837 + enum nix_stat_lf_rx { 838 + RX_OCTS = 0x0, 839 + RX_UCAST = 0x1, 840 + RX_BCAST = 0x2, 841 + RX_MCAST = 0x3, 842 + RX_DROP = 0x4, 843 + RX_DROP_OCTS = 0x5, 844 + RX_FCS = 0x6, 845 + RX_ERR = 0x7, 846 + RX_DRP_BCAST = 0x8, 847 + RX_DRP_MCAST = 0x9, 848 + RX_DRP_L3BCAST = 0xa, 849 + RX_DRP_L3MCAST = 0xb, 850 + RX_STATS_ENUM_LAST, 851 + }; 826 852 #endif /* RVU_STRUCT_H */
+17 -3
drivers/net/ethernet/marvell/octeontx2/af/rvu_switch.c
··· 8 8 #include <linux/bitfield.h> 9 9 #include "rvu.h" 10 10 11 - static void rvu_switch_enable_lbk_link(struct rvu *rvu, u16 pcifunc, bool enable) 11 + void rvu_switch_enable_lbk_link(struct rvu *rvu, u16 pcifunc, bool enable) 12 12 { 13 13 struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc); 14 14 struct nix_hw *nix_hw; ··· 166 166 167 167 alloc_req.contig = true; 168 168 alloc_req.count = rvu->cgx_mapped_pfs + rvu->cgx_mapped_vfs; 169 + if (rvu->rep_mode) 170 + alloc_req.count = alloc_req.count * 4; 169 171 ret = rvu_mbox_handler_npc_mcam_alloc_entry(rvu, &alloc_req, 170 172 &alloc_rsp); 171 173 if (ret) { ··· 191 189 rswitch->used_entries = alloc_rsp.count; 192 190 rswitch->start_entry = alloc_rsp.entry; 193 191 194 - ret = rvu_switch_install_rules(rvu); 192 + if (rvu->rep_mode) { 193 + rvu_rep_pf_init(rvu); 194 + ret = rvu_rep_install_mcam_rules(rvu); 195 + } else { 196 + ret = rvu_switch_install_rules(rvu); 197 + } 195 198 if (ret) 196 199 goto uninstall_rules; 197 200 ··· 229 222 if (!rswitch->used_entries) 230 223 return; 231 224 225 + if (rvu->rep_mode) 226 + goto free_ents; 227 + 232 228 for (pf = 1; pf < hw->total_pfs; pf++) { 233 229 if (!is_pf_cgxmapped(rvu, pf)) 234 230 continue; ··· 259 249 } 260 250 } 261 251 252 + free_ents: 262 253 uninstall_req.start = rswitch->start_entry; 263 254 uninstall_req.end = rswitch->start_entry + rswitch->used_entries - 1; 264 255 free_req.all = 1; ··· 269 258 kfree(rswitch->entry2pcifunc); 270 259 } 271 260 272 - void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc) 261 + void rvu_switch_update_rules(struct rvu *rvu, u16 pcifunc, bool ena) 273 262 { 274 263 struct rvu_switch *rswitch = &rvu->rswitch; 275 264 u32 max = rswitch->used_entries; 276 265 u16 entry; 266 + 267 + if (rvu->rep_mode) 268 + return rvu_rep_update_rules(rvu, pcifunc, ena); 277 269 278 270 if (!rswitch->used_entries) 279 271 return;
+2
drivers/net/ethernet/marvell/octeontx2/nic/Makefile
··· 5 5 6 6 obj-$(CONFIG_OCTEONTX2_PF) += rvu_nicpf.o otx2_ptp.o 7 7 obj-$(CONFIG_OCTEONTX2_VF) += rvu_nicvf.o otx2_ptp.o 8 + obj-$(CONFIG_RVU_ESWITCH) += rvu_rep.o 8 9 9 10 rvu_nicpf-y := otx2_pf.o otx2_common.o otx2_txrx.o otx2_ethtool.o \ 10 11 otx2_flows.o otx2_tc.o cn10k.o otx2_dmac_flt.o \ 11 12 otx2_devlink.o qos_sq.o qos.o 12 13 rvu_nicvf-y := otx2_vf.o 14 + rvu_rep-y := rep.o 13 15 14 16 rvu_nicpf-$(CONFIG_DCB) += otx2_dcbnl.o 15 17 rvu_nicpf-$(CONFIG_MACSEC) += cn10k_macsec.o
+2 -2
drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c
··· 72 72 } 73 73 EXPORT_SYMBOL(cn10k_lmtst_init); 74 74 75 - int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura) 75 + int cn10k_sq_aq_init(void *dev, u16 qidx, u8 chan_offset, u16 sqb_aura) 76 76 { 77 77 struct nix_cn10k_aq_enq_req *aq; 78 78 struct otx2_nic *pfvf = dev; ··· 88 88 aq->sq.ena = 1; 89 89 aq->sq.smq = otx2_get_smq_idx(pfvf, qidx); 90 90 aq->sq.smq_rr_weight = mtu_to_dwrr_weight(pfvf, pfvf->tx_max_pktlen); 91 - aq->sq.default_chan = pfvf->hw.tx_chan_base; 91 + aq->sq.default_chan = pfvf->hw.tx_chan_base + chan_offset; 92 92 aq->sq.sqe_stype = NIX_STYPE_STF; /* Cache SQB */ 93 93 aq->sq.sqb_aura = sqb_aura; 94 94 aq->sq.sq_int_ena = NIX_SQINT_BITS;
+1 -1
drivers/net/ethernet/marvell/octeontx2/nic/cn10k.h
··· 26 26 27 27 int cn10k_refill_pool_ptrs(void *dev, struct otx2_cq_queue *cq); 28 28 void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, int size, int qidx); 29 - int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura); 29 + int cn10k_sq_aq_init(void *dev, u16 qidx, u8 chan_offset, u16 sqb_aura); 30 30 int cn10k_lmtst_init(struct otx2_nic *pfvf); 31 31 int cn10k_free_all_ipolicers(struct otx2_nic *pfvf); 32 32 int cn10k_alloc_matchall_ipolicer(struct otx2_nic *pfvf);
+43 -11
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
··· 83 83 otx2_nix_rq_op_stats(&rq->stats, pfvf, qidx); 84 84 return 1; 85 85 } 86 + EXPORT_SYMBOL(otx2_update_rq_stats); 86 87 87 88 int otx2_update_sq_stats(struct otx2_nic *pfvf, int qidx) 88 89 { ··· 100 99 otx2_nix_sq_op_stats(&sq->stats, pfvf, qidx); 101 100 return 1; 102 101 } 102 + EXPORT_SYMBOL(otx2_update_sq_stats); 103 103 104 104 void otx2_get_dev_stats(struct otx2_nic *pfvf) 105 105 { ··· 248 246 mutex_unlock(&pfvf->mbox.lock); 249 247 return err; 250 248 } 249 + EXPORT_SYMBOL(otx2_hw_set_mtu); 251 250 252 251 int otx2_config_pause_frm(struct otx2_nic *pfvf) 253 252 { 254 253 struct cgx_pause_frm_cfg *req; 255 254 int err; 256 255 257 - if (is_otx2_lbkvf(pfvf->pdev)) 256 + if (is_otx2_lbkvf(pfvf->pdev) || is_otx2_sdp_rep(pfvf->pdev)) 258 257 return 0; 259 258 260 259 mutex_lock(&pfvf->mbox.lock); ··· 649 646 req->reg[2] = NIX_AF_MDQX_SCHEDULE(schq); 650 647 req->regval[2] = dwrr_val; 651 648 } else if (lvl == NIX_TXSCH_LVL_TL4) { 649 + int sdp_chan = hw->tx_chan_base + prio; 650 + 651 + if (is_otx2_sdp_rep(pfvf->pdev)) 652 + prio = 0; 652 653 parent = schq_list[NIX_TXSCH_LVL_TL3][prio]; 653 654 req->reg[0] = NIX_AF_TL4X_PARENT(schq); 654 655 req->regval[0] = (u64)parent << 16; 655 656 req->num_regs++; 656 657 req->reg[1] = NIX_AF_TL4X_SCHEDULE(schq); 657 658 req->regval[1] = dwrr_val; 659 + if (is_otx2_sdp_rep(pfvf->pdev)) { 660 + req->num_regs++; 661 + req->reg[2] = NIX_AF_TL4X_SDP_LINK_CFG(schq); 662 + req->regval[2] = BIT_ULL(12) | BIT_ULL(13) | 663 + (sdp_chan & 0xff); 664 + } 658 665 } else if (lvl == NIX_TXSCH_LVL_TL3) { 659 666 parent = schq_list[NIX_TXSCH_LVL_TL2][prio]; 660 667 req->reg[0] = NIX_AF_TL3X_PARENT(schq); ··· 672 659 req->num_regs++; 673 660 req->reg[1] = NIX_AF_TL3X_SCHEDULE(schq); 674 661 req->regval[1] = dwrr_val; 675 - if (lvl == hw->txschq_link_cfg_lvl) { 662 + if (lvl == hw->txschq_link_cfg_lvl && 663 + !is_otx2_sdp_rep(pfvf->pdev)) { 676 664 req->num_regs++; 677 665 req->reg[2] = NIX_AF_TL3_TL2X_LINKX_CFG(schq, hw->tx_link); 678 666 /* Enable this queue and backpressure ··· 690 676 req->reg[1] = NIX_AF_TL2X_SCHEDULE(schq); 691 677 req->regval[1] = (u64)hw->txschq_aggr_lvl_rr_prio << 24 | dwrr_val; 692 678 693 - if (lvl == hw->txschq_link_cfg_lvl) { 679 + if (lvl == hw->txschq_link_cfg_lvl && 680 + !is_otx2_sdp_rep(pfvf->pdev)) { 694 681 req->num_regs++; 695 682 req->reg[2] = NIX_AF_TL3_TL2X_LINKX_CFG(schq, hw->tx_link); 696 683 /* Enable this queue and backpressure ··· 750 735 751 736 int otx2_txsch_alloc(struct otx2_nic *pfvf) 752 737 { 738 + int chan_cnt = pfvf->hw.tx_chan_cnt; 753 739 struct nix_txsch_alloc_req *req; 754 740 struct nix_txsch_alloc_rsp *rsp; 755 741 int lvl, schq, rc; ··· 763 747 /* Request one schq per level */ 764 748 for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) 765 749 req->schq[lvl] = 1; 750 + 751 + if (is_otx2_sdp_rep(pfvf->pdev) && chan_cnt > 1) { 752 + req->schq[NIX_TXSCH_LVL_SMQ] = chan_cnt; 753 + req->schq[NIX_TXSCH_LVL_TL4] = chan_cnt; 754 + } 755 + 766 756 rc = otx2_sync_mbox_msg(&pfvf->mbox); 767 757 if (rc) 768 758 return rc; ··· 779 757 return PTR_ERR(rsp); 780 758 781 759 /* Setup transmit scheduler list */ 782 - for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) 760 + for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) { 761 + pfvf->hw.txschq_cnt[lvl] = rsp->schq[lvl]; 783 762 for (schq = 0; schq < rsp->schq[lvl]; schq++) 784 763 pfvf->hw.txschq_list[lvl][schq] = 785 764 rsp->schq_list[lvl][schq]; 765 + } 786 766 787 767 pfvf->hw.txschq_link_cfg_lvl = rsp->link_cfg_lvl; 788 768 pfvf->hw.txschq_aggr_lvl_rr_prio = rsp->aggr_lvl_rr_prio; ··· 822 798 823 799 void otx2_txschq_stop(struct otx2_nic *pfvf) 824 800 { 825 - int lvl, schq; 801 + int lvl, schq, idx; 826 802 827 803 /* free non QOS TLx nodes */ 828 - for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) 829 - otx2_txschq_free_one(pfvf, lvl, 830 - pfvf->hw.txschq_list[lvl][0]); 804 + for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) { 805 + for (idx = 0; idx < pfvf->hw.txschq_cnt[lvl]; idx++) { 806 + otx2_txschq_free_one(pfvf, lvl, 807 + pfvf->hw.txschq_list[lvl][idx]); 808 + } 809 + } 831 810 832 811 /* Clear the txschq list */ 833 812 for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) { ··· 910 883 return otx2_sync_mbox_msg(&pfvf->mbox); 911 884 } 912 885 913 - int otx2_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura) 886 + int otx2_sq_aq_init(void *dev, u16 qidx, u8 chan_offset, u16 sqb_aura) 914 887 { 915 888 struct otx2_nic *pfvf = dev; 916 889 struct otx2_snd_queue *sq; ··· 929 902 aq->sq.ena = 1; 930 903 aq->sq.smq = otx2_get_smq_idx(pfvf, qidx); 931 904 aq->sq.smq_rr_quantum = mtu_to_dwrr_weight(pfvf, pfvf->tx_max_pktlen); 932 - aq->sq.default_chan = pfvf->hw.tx_chan_base; 905 + aq->sq.default_chan = pfvf->hw.tx_chan_base + chan_offset; 933 906 aq->sq.sqe_stype = NIX_STYPE_STF; /* Cache SQB */ 934 907 aq->sq.sqb_aura = sqb_aura; 935 908 aq->sq.sq_int_ena = NIX_SQINT_BITS; ··· 952 925 struct otx2_qset *qset = &pfvf->qset; 953 926 struct otx2_snd_queue *sq; 954 927 struct otx2_pool *pool; 928 + u8 chan_offset; 955 929 int err; 956 930 957 931 pool = &pfvf->qset.pool[sqb_aura]; ··· 999 971 sq->stats.bytes = 0; 1000 972 sq->stats.pkts = 0; 1001 973 1002 - err = pfvf->hw_ops->sq_aq_init(pfvf, qidx, sqb_aura); 974 + chan_offset = qidx % pfvf->hw.tx_chan_cnt; 975 + err = pfvf->hw_ops->sq_aq_init(pfvf, qidx, chan_offset, sqb_aura); 1003 976 if (err) { 1004 977 kfree(sq->sg); 1005 978 sq->sg = NULL; ··· 1767 1738 pfvf->hw.sqb_size = rsp->sqb_size; 1768 1739 pfvf->hw.rx_chan_base = rsp->rx_chan_base; 1769 1740 pfvf->hw.tx_chan_base = rsp->tx_chan_base; 1741 + pfvf->hw.rx_chan_cnt = rsp->rx_chan_cnt; 1742 + pfvf->hw.tx_chan_cnt = rsp->tx_chan_cnt; 1770 1743 pfvf->hw.lso_tsov4_idx = rsp->lso_tsov4_idx; 1771 1744 pfvf->hw.lso_tsov6_idx = rsp->lso_tsov6_idx; 1772 1745 pfvf->hw.cgx_links = rsp->cgx_links; ··· 1813 1782 free_irq(vector, &qset->napi[qidx]); 1814 1783 } 1815 1784 } 1785 + EXPORT_SYMBOL(otx2_free_cints); 1816 1786 1817 1787 void otx2_set_cints_affinity(struct otx2_nic *pfvf) 1818 1788 {
+41 -34
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
··· 29 29 #include "otx2_devlink.h" 30 30 #include <rvu_trace.h> 31 31 #include "qos.h" 32 + #include "rep.h" 32 33 33 34 /* IPv4 flag more fragment bit */ 34 35 #define IPV4_FLAG_MORE 0x20 ··· 41 40 42 41 #define PCI_SUBSYS_DEVID_96XX_RVU_PFVF 0xB200 43 42 #define PCI_SUBSYS_DEVID_CN10K_B_RVU_PFVF 0xBD00 43 + 44 + #define PCI_DEVID_OCTEONTX2_SDP_REP 0xA0F7 44 45 45 46 /* PCI BAR nos */ 46 47 #define PCI_CFG_REG_BAR_NUM 2 ··· 123 120 ERRCODE_IL4_CSUM = 0x22, 124 121 }; 125 122 126 - /* NIX TX stats */ 127 - enum nix_stat_lf_tx { 128 - TX_UCAST = 0x0, 129 - TX_BCAST = 0x1, 130 - TX_MCAST = 0x2, 131 - TX_DROP = 0x3, 132 - TX_OCTS = 0x4, 133 - TX_STATS_ENUM_LAST, 134 - }; 135 - 136 - /* NIX RX stats */ 137 - enum nix_stat_lf_rx { 138 - RX_OCTS = 0x0, 139 - RX_UCAST = 0x1, 140 - RX_BCAST = 0x2, 141 - RX_MCAST = 0x3, 142 - RX_DROP = 0x4, 143 - RX_DROP_OCTS = 0x5, 144 - RX_FCS = 0x6, 145 - RX_ERR = 0x7, 146 - RX_DRP_BCAST = 0x8, 147 - RX_DRP_MCAST = 0x9, 148 - RX_DRP_L3BCAST = 0xa, 149 - RX_DRP_L3MCAST = 0xb, 150 - RX_STATS_ENUM_LAST, 151 - }; 152 - 153 123 struct otx2_dev_stats { 154 124 u64 rx_bytes; 155 125 u64 rx_frames; ··· 200 224 201 225 /* NIX */ 202 226 u8 txschq_link_cfg_lvl; 227 + u8 txschq_cnt[NIX_TXSCH_LVL_CNT]; 203 228 u8 txschq_aggr_lvl_rr_prio; 204 229 u16 txschq_list[NIX_TXSCH_LVL_CNT][MAX_TXSCHQ_PER_FUNC]; 205 230 u16 matchall_ipolicer; ··· 211 234 /* HW settings, coalescing etc */ 212 235 u16 rx_chan_base; 213 236 u16 tx_chan_base; 237 + u8 rx_chan_cnt; 238 + u8 tx_chan_cnt; 214 239 u16 cq_qcount_wait; 215 240 u16 cq_ecount_wait; 216 241 u16 rq_skid; ··· 347 368 }; 348 369 349 370 struct dev_hw_ops { 350 - int (*sq_aq_init)(void *dev, u16 qidx, u16 sqb_aura); 371 + int (*sq_aq_init)(void *dev, u16 qidx, u8 chan_offset, 372 + u16 sqb_aura); 351 373 void (*sqe_flush)(void *dev, struct otx2_snd_queue *sq, 352 374 int size, int qidx); 353 375 int (*refill_pool_ptrs)(void *dev, struct otx2_cq_queue *cq); ··· 446 466 #define OTX2_FLAG_PTP_ONESTEP_SYNC BIT_ULL(15) 447 467 #define OTX2_FLAG_ADPTV_INT_COAL_ENABLED BIT_ULL(16) 448 468 #define OTX2_FLAG_TC_MARK_ENABLED BIT_ULL(17) 469 + #define OTX2_FLAG_REP_MODE_ENABLED BIT_ULL(18) 470 + #define OTX2_FLAG_PORT_UP BIT_ULL(19) 449 471 u64 flags; 450 472 u64 *cq_op_addr; 451 473 ··· 515 533 #if IS_ENABLED(CONFIG_MACSEC) 516 534 struct cn10k_mcs_cfg *macsec_cfg; 517 535 #endif 536 + 537 + #if IS_ENABLED(CONFIG_RVU_ESWITCH) 538 + struct rep_dev **reps; 539 + int rep_cnt; 540 + u16 rep_pf_map[RVU_MAX_REP]; 541 + u16 esw_mode; 542 + #endif 518 543 }; 519 544 520 545 static inline bool is_otx2_lbkvf(struct pci_dev *pdev) 521 546 { 522 - return pdev->device == PCI_DEVID_OCTEONTX2_RVU_AFVF; 547 + return (pdev->device == PCI_DEVID_OCTEONTX2_RVU_AFVF) || 548 + (pdev->device == PCI_DEVID_RVU_REP); 523 549 } 524 550 525 551 static inline bool is_96xx_A0(struct pci_dev *pdev) ··· 540 550 { 541 551 return (pdev->revision == 0x01) && 542 552 (pdev->subsystem_device == PCI_SUBSYS_DEVID_96XX_RVU_PFVF); 553 + } 554 + 555 + static inline bool is_otx2_sdp_rep(struct pci_dev *pdev) 556 + { 557 + return pdev->device == PCI_DEVID_OCTEONTX2_SDP_REP; 543 558 } 544 559 545 560 /* REVID for PCIe devices. ··· 909 914 static inline u16 otx2_get_smq_idx(struct otx2_nic *pfvf, u16 qidx) 910 915 { 911 916 u16 smq; 917 + int idx; 918 + 912 919 #ifdef CONFIG_DCB 913 920 if (qidx < NIX_PF_PFC_PRIO_MAX && pfvf->pfc_alloc_status[qidx]) 914 921 return pfvf->pfc_schq_list[NIX_TXSCH_LVL_SMQ][qidx]; 915 922 #endif 916 923 /* check if qidx falls under QOS queues */ 917 - if (qidx >= pfvf->hw.non_qos_queues) 924 + if (qidx >= pfvf->hw.non_qos_queues) { 918 925 smq = pfvf->qos.qid_to_sqmap[qidx - pfvf->hw.non_qos_queues]; 919 - else 920 - smq = pfvf->hw.txschq_list[NIX_TXSCH_LVL_SMQ][0]; 926 + } else { 927 + idx = qidx % pfvf->hw.txschq_cnt[NIX_TXSCH_LVL_SMQ]; 928 + smq = pfvf->hw.txschq_list[NIX_TXSCH_LVL_SMQ][idx]; 929 + } 921 930 922 931 return smq; 923 932 } ··· 988 989 void otx2_cleanup_rx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq, int qidx); 989 990 void otx2_cleanup_tx_cqes(struct otx2_nic *pfvf, struct otx2_cq_queue *cq); 990 991 int otx2_sq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura); 991 - int otx2_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura); 992 - int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura); 992 + int otx2_sq_aq_init(void *dev, u16 qidx, u8 chan_offset, u16 sqb_aura); 993 + int cn10k_sq_aq_init(void *dev, u16 qidx, u8 chan_offset, u16 sqb_aura); 993 994 int otx2_alloc_buffer(struct otx2_nic *pfvf, struct otx2_cq_queue *cq, 994 995 dma_addr_t *dma); 995 996 int otx2_pool_init(struct otx2_nic *pfvf, u16 pool_id, ··· 1141 1142 int otx2_get_txq_by_classid(struct otx2_nic *pfvf, u16 classid); 1142 1143 void otx2_qos_config_txschq(struct otx2_nic *pfvf); 1143 1144 void otx2_clean_qos_queues(struct otx2_nic *pfvf); 1145 + int rvu_event_up_notify(struct otx2_nic *pf, struct rep_event *info); 1146 + int otx2_setup_tc_cls_flower(struct otx2_nic *nic, 1147 + struct flow_cls_offload *cls_flower); 1148 + 1149 + static inline int mcam_entry_cmp(const void *a, const void *b) 1150 + { 1151 + return *(u16 *)a - *(u16 *)b; 1152 + } 1144 1153 #endif /* OTX2_COMMON_H */
+49
drivers/net/ethernet/marvell/octeontx2/nic/otx2_devlink.c
··· 141 141 otx2_dl_ucast_flt_cnt_validate), 142 142 }; 143 143 144 + #ifdef CONFIG_RVU_ESWITCH 145 + static int otx2_devlink_eswitch_mode_get(struct devlink *devlink, u16 *mode) 146 + { 147 + struct otx2_devlink *otx2_dl = devlink_priv(devlink); 148 + struct otx2_nic *pfvf = otx2_dl->pfvf; 149 + 150 + if (!otx2_rep_dev(pfvf->pdev)) 151 + return -EOPNOTSUPP; 152 + 153 + *mode = pfvf->esw_mode; 154 + 155 + return 0; 156 + } 157 + 158 + static int otx2_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode, 159 + struct netlink_ext_ack *extack) 160 + { 161 + struct otx2_devlink *otx2_dl = devlink_priv(devlink); 162 + struct otx2_nic *pfvf = otx2_dl->pfvf; 163 + int ret = 0; 164 + 165 + if (!otx2_rep_dev(pfvf->pdev)) 166 + return -EOPNOTSUPP; 167 + 168 + if (pfvf->esw_mode == mode) 169 + return 0; 170 + 171 + switch (mode) { 172 + case DEVLINK_ESWITCH_MODE_LEGACY: 173 + rvu_rep_destroy(pfvf); 174 + break; 175 + case DEVLINK_ESWITCH_MODE_SWITCHDEV: 176 + ret = rvu_rep_create(pfvf, extack); 177 + break; 178 + default: 179 + return -EINVAL; 180 + } 181 + 182 + if (!ret) 183 + pfvf->esw_mode = mode; 184 + 185 + return ret; 186 + } 187 + #endif 188 + 144 189 static const struct devlink_ops otx2_devlink_ops = { 190 + #ifdef CONFIG_RVU_ESWITCH 191 + .eswitch_mode_get = otx2_devlink_eswitch_mode_get, 192 + .eswitch_mode_set = otx2_devlink_eswitch_mode_set, 193 + #endif 145 194 }; 146 195 147 196 int otx2_register_dl(struct otx2_nic *pfvf)
-5
drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c
··· 64 64 return 0; 65 65 } 66 66 67 - static int mcam_entry_cmp(const void *a, const void *b) 68 - { 69 - return *(u16 *)a - *(u16 *)b; 70 - } 71 - 72 67 int otx2_alloc_mcam_entries(struct otx2_nic *pfvf, u16 count) 73 68 { 74 69 struct otx2_flow_config *flow_cfg = pfvf->flow_cfg;
+65 -12
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
··· 519 519 520 520 switch (msg->id) { 521 521 case MBOX_MSG_CGX_LINK_EVENT: 522 + case MBOX_MSG_REP_EVENT_UP_NOTIFY: 522 523 break; 523 524 default: 524 525 if (msg->rc) ··· 833 832 struct cgx_link_user_info *linfo = &pf->linfo; 834 833 struct net_device *netdev = pf->netdev; 835 834 835 + if (pf->flags & OTX2_FLAG_PORT_UP) 836 + return; 837 + 836 838 pr_info("%s NIC Link is %s %d Mbps %s duplex\n", netdev->name, 837 839 linfo->link_up ? "UP" : "DOWN", linfo->speed, 838 840 linfo->full_duplex ? "Full" : "Half"); ··· 846 842 netif_tx_stop_all_queues(netdev); 847 843 netif_carrier_off(netdev); 848 844 } 845 + } 846 + 847 + static int otx2_mbox_up_handler_rep_event_up_notify(struct otx2_nic *pf, 848 + struct rep_event *info, 849 + struct msg_rsp *rsp) 850 + { 851 + struct net_device *netdev = pf->netdev; 852 + 853 + if (info->event == RVU_EVENT_MTU_CHANGE) { 854 + netdev->mtu = info->evt_data.mtu; 855 + return 0; 856 + } 857 + 858 + if (info->event == RVU_EVENT_PORT_STATE) { 859 + if (info->evt_data.port_state) { 860 + pf->flags |= OTX2_FLAG_PORT_UP; 861 + netif_carrier_on(netdev); 862 + netif_tx_start_all_queues(netdev); 863 + } else { 864 + pf->flags &= ~OTX2_FLAG_PORT_UP; 865 + netif_tx_stop_all_queues(netdev); 866 + netif_carrier_off(netdev); 867 + } 868 + return 0; 869 + } 870 + #ifdef CONFIG_RVU_ESWITCH 871 + rvu_event_up_notify(pf, info); 872 + #endif 873 + return 0; 849 874 } 850 875 851 876 int otx2_mbox_up_handler_mcs_intr_notify(struct otx2_nic *pf, ··· 946 913 } 947 914 MBOX_UP_CGX_MESSAGES 948 915 MBOX_UP_MCS_MESSAGES 916 + MBOX_UP_REP_MESSAGES 949 917 #undef M 950 918 break; 951 919 default: ··· 1050 1016 otx2_write64(pf, RVU_PF_INT_ENA_W1C, BIT_ULL(0)); 1051 1017 free_irq(vector, pf); 1052 1018 } 1019 + EXPORT_SYMBOL(otx2_disable_mbox_intr); 1053 1020 1054 1021 int otx2_register_mbox_intr(struct otx2_nic *pf, bool probe_af) 1055 1022 { ··· 1111 1076 otx2_mbox_destroy(&mbox->mbox); 1112 1077 otx2_mbox_destroy(&mbox->mbox_up); 1113 1078 } 1079 + EXPORT_SYMBOL(otx2_pfaf_mbox_destroy); 1114 1080 1115 1081 int otx2_pfaf_mbox_init(struct otx2_nic *pf) 1116 1082 { ··· 1434 1398 1435 1399 return IRQ_HANDLED; 1436 1400 } 1401 + EXPORT_SYMBOL(otx2_cq_intr_handler); 1437 1402 1438 1403 void otx2_disable_napi(struct otx2_nic *pf) 1439 1404 { ··· 1452 1415 netif_napi_del(&cq_poll->napi); 1453 1416 } 1454 1417 } 1418 + EXPORT_SYMBOL(otx2_disable_napi); 1455 1419 1456 1420 static void otx2_free_cq_res(struct otx2_nic *pf) 1457 1421 { ··· 1534 1496 hw->sqpool_cnt = otx2_get_total_tx_queues(pf); 1535 1497 hw->pool_cnt = hw->rqpool_cnt + hw->sqpool_cnt; 1536 1498 1537 - /* Maximum hardware supported transmit length */ 1538 - pf->tx_max_pktlen = pf->netdev->max_mtu + OTX2_ETH_HLEN; 1539 - 1540 - pf->rbsize = otx2_get_rbuf_size(pf, pf->netdev->mtu); 1499 + if (!otx2_rep_dev(pf->pdev)) { 1500 + /* Maximum hardware supported transmit length */ 1501 + pf->tx_max_pktlen = pf->netdev->max_mtu + OTX2_ETH_HLEN; 1502 + pf->rbsize = otx2_get_rbuf_size(pf, pf->netdev->mtu); 1503 + } 1541 1504 1542 1505 mutex_lock(&mbox->lock); 1543 1506 /* NPA init */ ··· 1591 1552 } 1592 1553 1593 1554 for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) { 1594 - err = otx2_txschq_config(pf, lvl, 0, false); 1595 - if (err) { 1596 - mutex_unlock(&mbox->lock); 1597 - goto err_free_nix_queues; 1555 + int idx; 1556 + 1557 + for (idx = 0; idx < pf->hw.txschq_cnt[lvl]; idx++) { 1558 + err = otx2_txschq_config(pf, lvl, idx, false); 1559 + if (err) { 1560 + dev_err(pf->dev, "Failed to config TXSCH\n"); 1561 + mutex_unlock(&mbox->lock); 1562 + goto err_free_nix_queues; 1563 + } 1598 1564 } 1599 1565 } 1600 1566 ··· 1648 1604 mutex_unlock(&mbox->lock); 1649 1605 return err; 1650 1606 } 1607 + EXPORT_SYMBOL(otx2_init_hw_resources); 1651 1608 1652 1609 void otx2_free_hw_resources(struct otx2_nic *pf) 1653 1610 { ··· 1672 1627 otx2_pfc_txschq_stop(pf); 1673 1628 #endif 1674 1629 1675 - otx2_clean_qos_queues(pf); 1630 + if (!otx2_rep_dev(pf->pdev)) 1631 + otx2_clean_qos_queues(pf); 1676 1632 1677 1633 mutex_lock(&mbox->lock); 1678 1634 /* Disable backpressure */ 1679 - if (!(pf->pcifunc & RVU_PFVF_FUNC_MASK)) 1635 + if (!is_otx2_lbkvf(pf->pdev)) 1680 1636 otx2_nix_config_bp(pf, false); 1681 1637 mutex_unlock(&mbox->lock); 1682 1638 ··· 1709 1663 otx2_free_cq_res(pf); 1710 1664 1711 1665 /* Free all ingress bandwidth profiles allocated */ 1712 - cn10k_free_all_ipolicers(pf); 1666 + if (!otx2_rep_dev(pf->pdev)) 1667 + cn10k_free_all_ipolicers(pf); 1713 1668 1714 1669 mutex_lock(&mbox->lock); 1715 1670 /* Reset NIX LF */ ··· 1738 1691 } 1739 1692 mutex_unlock(&mbox->lock); 1740 1693 } 1694 + EXPORT_SYMBOL(otx2_free_hw_resources); 1741 1695 1742 1696 static bool otx2_promisc_use_mce_list(struct otx2_nic *pfvf) 1743 1697 { ··· 1832 1784 kfree(qset->napi); 1833 1785 qset->napi = NULL; 1834 1786 } 1787 + EXPORT_SYMBOL(otx2_free_queue_mem); 1835 1788 1836 1789 int otx2_alloc_queue_mem(struct otx2_nic *pf) 1837 1790 { ··· 1879 1830 otx2_free_queue_mem(qset); 1880 1831 return -ENOMEM; 1881 1832 } 1833 + EXPORT_SYMBOL(otx2_alloc_queue_mem); 1882 1834 1883 1835 int otx2_open(struct net_device *netdev) 1884 1836 { ··· 2013 1963 } 2014 1964 2015 1965 pf->flags &= ~OTX2_FLAG_INTF_DOWN; 1966 + pf->flags &= ~OTX2_FLAG_PORT_UP; 2016 1967 /* 'intf_down' may be checked on any cpu */ 2017 1968 smp_wmb(); 2018 1969 ··· 2156 2105 sq = &pf->qset.sq[sq_idx]; 2157 2106 txq = netdev_get_tx_queue(netdev, qidx); 2158 2107 2159 - if (!otx2_sq_append_skb(netdev, sq, skb, qidx)) { 2108 + if (!otx2_sq_append_skb(pf, txq, sq, skb, qidx)) { 2160 2109 netif_tx_stop_queue(txq); 2161 2110 2162 2111 /* Check again, incase SQBs got freed up */ ··· 2912 2861 2913 2862 return otx2_register_mbox_intr(pf, false); 2914 2863 } 2864 + EXPORT_SYMBOL(otx2_realloc_msix_vectors); 2915 2865 2916 2866 static int otx2_sriov_vfcfg_init(struct otx2_nic *pf) 2917 2867 { ··· 3028 2976 3029 2977 return err; 3030 2978 } 2979 + EXPORT_SYMBOL(otx2_init_rsrc); 3031 2980 3032 2981 static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id) 3033 2982 {
+16 -9
drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c
··· 443 443 struct flow_action_entry *act; 444 444 struct net_device *target; 445 445 struct otx2_nic *priv; 446 + struct rep_dev *rdev; 446 447 u32 burst, mark = 0; 447 448 u8 nr_police = 0; 448 449 u8 num_intf = 1; ··· 465 464 return 0; 466 465 case FLOW_ACTION_REDIRECT_INGRESS: 467 466 target = act->dev; 468 - priv = netdev_priv(target); 469 - /* npc_install_flow_req doesn't support passing a target pcifunc */ 470 - if (rvu_get_pf(nic->pcifunc) != rvu_get_pf(priv->pcifunc)) { 471 - NL_SET_ERR_MSG_MOD(extack, 472 - "can't redirect to other pf/vf"); 473 - return -EOPNOTSUPP; 467 + if (target->dev.parent) { 468 + priv = netdev_priv(target); 469 + if (rvu_get_pf(nic->pcifunc) != rvu_get_pf(priv->pcifunc)) { 470 + NL_SET_ERR_MSG_MOD(extack, 471 + "can't redirect to other pf/vf"); 472 + return -EOPNOTSUPP; 473 + } 474 + req->vf = priv->pcifunc & RVU_PFVF_FUNC_MASK; 475 + } else { 476 + rdev = netdev_priv(target); 477 + req->vf = rdev->pcifunc & RVU_PFVF_FUNC_MASK; 474 478 } 475 - req->vf = priv->pcifunc & RVU_PFVF_FUNC_MASK; 476 479 477 480 /* if op is already set; avoid overwriting the same */ 478 481 if (!req->op) ··· 1305 1300 req->channel = nic->hw.rx_chan_base; 1306 1301 req->entry = flow_cfg->flow_ent[mcam_idx]; 1307 1302 req->intf = NIX_INTF_RX; 1303 + req->vf = nic->pcifunc; 1308 1304 req->set_cntr = 1; 1309 1305 new_node->entry = req->entry; 1310 1306 ··· 1406 1400 return 0; 1407 1401 } 1408 1402 1409 - static int otx2_setup_tc_cls_flower(struct otx2_nic *nic, 1410 - struct flow_cls_offload *cls_flower) 1403 + int otx2_setup_tc_cls_flower(struct otx2_nic *nic, 1404 + struct flow_cls_offload *cls_flower) 1411 1405 { 1412 1406 switch (cls_flower->command) { 1413 1407 case FLOW_CLS_REPLACE: ··· 1420 1414 return -EOPNOTSUPP; 1421 1415 } 1422 1416 } 1417 + EXPORT_SYMBOL(otx2_setup_tc_cls_flower); 1423 1418 1424 1419 static int otx2_tc_ingress_matchall_install(struct otx2_nic *nic, 1425 1420 struct tc_cls_matchall_offload *cls)
+21 -8
drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
··· 376 376 } 377 377 otx2_set_rxhash(pfvf, cqe, skb); 378 378 379 - skb_record_rx_queue(skb, cq->cq_idx); 380 - if (pfvf->netdev->features & NETIF_F_RXCSUM) 381 - skb->ip_summed = CHECKSUM_UNNECESSARY; 379 + if (!(pfvf->flags & OTX2_FLAG_REP_MODE_ENABLED)) { 380 + skb_record_rx_queue(skb, cq->cq_idx); 381 + if (pfvf->netdev->features & NETIF_F_RXCSUM) 382 + skb->ip_summed = CHECKSUM_UNNECESSARY; 383 + } 382 384 383 385 if (pfvf->flags & OTX2_FLAG_TC_MARK_ENABLED) 384 386 skb->mark = parse->match_id; ··· 455 453 int tx_pkts = 0, tx_bytes = 0, qidx; 456 454 struct otx2_snd_queue *sq; 457 455 struct nix_cqe_tx_s *cqe; 456 + struct net_device *ndev; 458 457 int processed_cqe = 0; 459 458 460 459 if (cq->pend_cqe >= budget) ··· 496 493 otx2_write64(pfvf, NIX_LF_CQ_OP_DOOR, 497 494 ((u64)cq->cq_idx << 32) | processed_cqe); 498 495 496 + #if IS_ENABLED(CONFIG_RVU_ESWITCH) 497 + if (pfvf->flags & OTX2_FLAG_REP_MODE_ENABLED) 498 + ndev = pfvf->reps[qidx]->netdev; 499 + else 500 + #endif 501 + ndev = pfvf->netdev; 502 + 499 503 if (likely(tx_pkts)) { 500 504 struct netdev_queue *txq; 501 505 ··· 510 500 511 501 if (qidx >= pfvf->hw.tx_queues) 512 502 qidx -= pfvf->hw.xdp_queues; 513 - txq = netdev_get_tx_queue(pfvf->netdev, qidx); 503 + if (pfvf->flags & OTX2_FLAG_REP_MODE_ENABLED) 504 + qidx = 0; 505 + txq = netdev_get_tx_queue(ndev, qidx); 514 506 netdev_tx_completed_queue(txq, tx_pkts, tx_bytes); 515 507 /* Check if queue was stopped earlier due to ring full */ 516 508 smp_mb(); 517 509 if (netif_tx_queue_stopped(txq) && 518 - netif_carrier_ok(pfvf->netdev)) 510 + netif_carrier_ok(ndev)) 519 511 netif_tx_wake_queue(txq); 520 512 } 521 513 return 0; ··· 606 594 } 607 595 return workdone; 608 596 } 597 + EXPORT_SYMBOL(otx2_napi_handler); 609 598 610 599 void otx2_sqe_flush(void *dev, struct otx2_snd_queue *sq, 611 600 int size, int qidx) ··· 1154 1141 } 1155 1142 } 1156 1143 1157 - bool otx2_sq_append_skb(struct net_device *netdev, struct otx2_snd_queue *sq, 1144 + bool otx2_sq_append_skb(void *dev, struct netdev_queue *txq, 1145 + struct otx2_snd_queue *sq, 1158 1146 struct sk_buff *skb, u16 qidx) 1159 1147 { 1160 - struct netdev_queue *txq = netdev_get_tx_queue(netdev, qidx); 1161 - struct otx2_nic *pfvf = netdev_priv(netdev); 1162 1148 int offset, num_segs, free_desc; 1163 1149 struct nix_sqe_hdr_s *sqe_hdr; 1150 + struct otx2_nic *pfvf = dev; 1164 1151 1165 1152 /* Check if there is enough room between producer 1166 1153 * and consumer index.
+2 -1
drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h
··· 167 167 } 168 168 169 169 int otx2_napi_handler(struct napi_struct *napi, int budget); 170 - bool otx2_sq_append_skb(struct net_device *netdev, struct otx2_snd_queue *sq, 170 + bool otx2_sq_append_skb(void *dev, struct netdev_queue *txq, 171 + struct otx2_snd_queue *sq, 171 172 struct sk_buff *skb, u16 qidx); 172 173 void cn10k_sqe_flush(void *dev, struct otx2_snd_queue *sq, 173 174 int size, int qidx);
+12 -2
drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
··· 21 21 static const struct pci_device_id otx2_vf_id_table[] = { 22 22 { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_RVU_AFVF) }, 23 23 { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_RVU_VF) }, 24 + { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_OCTEONTX2_SDP_REP) }, 24 25 { } 25 26 }; 26 27 ··· 372 371 373 372 /* LBKs do not receive link events so tell everyone we are up here */ 374 373 vf = netdev_priv(netdev); 375 - if (is_otx2_lbkvf(vf->pdev)) { 374 + if (is_otx2_lbkvf(vf->pdev) || is_otx2_sdp_rep(vf->pdev)) { 376 375 pr_info("%s NIC Link is UP\n", netdev->name); 377 376 netif_carrier_on(netdev); 378 377 netif_tx_start_all_queues(netdev); ··· 396 395 sq = &vf->qset.sq[qidx]; 397 396 txq = netdev_get_tx_queue(netdev, qidx); 398 397 399 - if (!otx2_sq_append_skb(netdev, sq, skb, qidx)) { 398 + if (!otx2_sq_append_skb(vf, txq, sq, skb, qidx)) { 400 399 netif_tx_stop_queue(txq); 401 400 402 401 /* Check again, incase SQBs got freed up */ ··· 682 681 /* Need to subtract 1 to get proper VF number */ 683 682 n -= 1; 684 683 snprintf(netdev->name, sizeof(netdev->name), "lbk%d", n); 684 + } 685 + 686 + if (is_otx2_sdp_rep(vf->pdev)) { 687 + int n; 688 + 689 + n = vf->pcifunc & RVU_PFVF_FUNC_MASK; 690 + n -= 1; 691 + snprintf(netdev->name, sizeof(netdev->name), "sdp%d-%d", 692 + pdev->bus->number, n); 685 693 } 686 694 687 695 err = register_netdev(netdev);
+864
drivers/net/ethernet/marvell/octeontx2/nic/rep.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Marvell RVU representor driver 3 + * 4 + * Copyright (C) 2024 Marvell. 5 + * 6 + */ 7 + 8 + #include <linux/etherdevice.h> 9 + #include <linux/module.h> 10 + #include <linux/pci.h> 11 + #include <linux/net_tstamp.h> 12 + #include <linux/sort.h> 13 + 14 + #include "otx2_common.h" 15 + #include "cn10k.h" 16 + #include "otx2_reg.h" 17 + #include "rep.h" 18 + 19 + #define DRV_NAME "rvu_rep" 20 + #define DRV_STRING "Marvell RVU Representor Driver" 21 + 22 + static const struct pci_device_id rvu_rep_id_table[] = { 23 + { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM, PCI_DEVID_RVU_REP) }, 24 + { } 25 + }; 26 + 27 + MODULE_AUTHOR("Marvell International Ltd."); 28 + MODULE_DESCRIPTION(DRV_STRING); 29 + MODULE_LICENSE("GPL"); 30 + MODULE_DEVICE_TABLE(pci, rvu_rep_id_table); 31 + 32 + static int rvu_rep_notify_pfvf(struct otx2_nic *priv, u16 event, 33 + struct rep_event *data); 34 + 35 + static int rvu_rep_mcam_flow_init(struct rep_dev *rep) 36 + { 37 + struct npc_mcam_alloc_entry_req *req; 38 + struct npc_mcam_alloc_entry_rsp *rsp; 39 + struct otx2_nic *priv = rep->mdev; 40 + int ent, allocated = 0; 41 + int count; 42 + 43 + rep->flow_cfg = kcalloc(1, sizeof(struct otx2_flow_config), GFP_KERNEL); 44 + 45 + if (!rep->flow_cfg) 46 + return -ENOMEM; 47 + 48 + count = OTX2_DEFAULT_FLOWCOUNT; 49 + 50 + rep->flow_cfg->flow_ent = kcalloc(count, sizeof(u16), GFP_KERNEL); 51 + if (!rep->flow_cfg->flow_ent) 52 + return -ENOMEM; 53 + 54 + while (allocated < count) { 55 + req = otx2_mbox_alloc_msg_npc_mcam_alloc_entry(&priv->mbox); 56 + if (!req) 57 + goto exit; 58 + 59 + req->hdr.pcifunc = rep->pcifunc; 60 + req->contig = false; 61 + req->ref_entry = 0; 62 + req->count = (count - allocated) > NPC_MAX_NONCONTIG_ENTRIES ? 63 + NPC_MAX_NONCONTIG_ENTRIES : count - allocated; 64 + 65 + if (otx2_sync_mbox_msg(&priv->mbox)) 66 + goto exit; 67 + 68 + rsp = (struct npc_mcam_alloc_entry_rsp *)otx2_mbox_get_rsp 69 + (&priv->mbox.mbox, 0, &req->hdr); 70 + 71 + for (ent = 0; ent < rsp->count; ent++) 72 + rep->flow_cfg->flow_ent[ent + allocated] = rsp->entry_list[ent]; 73 + 74 + allocated += rsp->count; 75 + 76 + if (rsp->count != req->count) 77 + break; 78 + } 79 + exit: 80 + /* Multiple MCAM entry alloc requests could result in non-sequential 81 + * MCAM entries in the flow_ent[] array. Sort them in an ascending 82 + * order, otherwise user installed ntuple filter index and MCAM entry 83 + * index will not be in sync. 84 + */ 85 + if (allocated) 86 + sort(&rep->flow_cfg->flow_ent[0], allocated, 87 + sizeof(rep->flow_cfg->flow_ent[0]), mcam_entry_cmp, NULL); 88 + 89 + mutex_unlock(&priv->mbox.lock); 90 + 91 + rep->flow_cfg->max_flows = allocated; 92 + 93 + if (allocated) { 94 + rep->flags |= OTX2_FLAG_MCAM_ENTRIES_ALLOC; 95 + rep->flags |= OTX2_FLAG_NTUPLE_SUPPORT; 96 + rep->flags |= OTX2_FLAG_TC_FLOWER_SUPPORT; 97 + } 98 + 99 + INIT_LIST_HEAD(&rep->flow_cfg->flow_list); 100 + INIT_LIST_HEAD(&rep->flow_cfg->flow_list_tc); 101 + return 0; 102 + } 103 + 104 + static int rvu_rep_setup_tc_cb(enum tc_setup_type type, 105 + void *type_data, void *cb_priv) 106 + { 107 + struct rep_dev *rep = cb_priv; 108 + struct otx2_nic *priv = rep->mdev; 109 + 110 + if (!(rep->flags & RVU_REP_VF_INITIALIZED)) 111 + return -EINVAL; 112 + 113 + if (!(rep->flags & OTX2_FLAG_TC_FLOWER_SUPPORT)) 114 + rvu_rep_mcam_flow_init(rep); 115 + 116 + priv->netdev = rep->netdev; 117 + priv->flags = rep->flags; 118 + priv->pcifunc = rep->pcifunc; 119 + priv->flow_cfg = rep->flow_cfg; 120 + 121 + switch (type) { 122 + case TC_SETUP_CLSFLOWER: 123 + return otx2_setup_tc_cls_flower(priv, type_data); 124 + default: 125 + return -EOPNOTSUPP; 126 + } 127 + } 128 + 129 + static LIST_HEAD(rvu_rep_block_cb_list); 130 + static int rvu_rep_setup_tc(struct net_device *netdev, enum tc_setup_type type, 131 + void *type_data) 132 + { 133 + struct rvu_rep *rep = netdev_priv(netdev); 134 + 135 + switch (type) { 136 + case TC_SETUP_BLOCK: 137 + return flow_block_cb_setup_simple(type_data, 138 + &rvu_rep_block_cb_list, 139 + rvu_rep_setup_tc_cb, 140 + rep, rep, true); 141 + default: 142 + return -EOPNOTSUPP; 143 + } 144 + } 145 + 146 + static int 147 + rvu_rep_sp_stats64(const struct net_device *dev, 148 + struct rtnl_link_stats64 *stats) 149 + { 150 + struct rep_dev *rep = netdev_priv(dev); 151 + struct otx2_nic *priv = rep->mdev; 152 + struct otx2_rcv_queue *rq; 153 + struct otx2_snd_queue *sq; 154 + u16 qidx = rep->rep_id; 155 + 156 + otx2_update_rq_stats(priv, qidx); 157 + rq = &priv->qset.rq[qidx]; 158 + 159 + otx2_update_sq_stats(priv, qidx); 160 + sq = &priv->qset.sq[qidx]; 161 + 162 + stats->tx_bytes = sq->stats.bytes; 163 + stats->tx_packets = sq->stats.pkts; 164 + stats->rx_bytes = rq->stats.bytes; 165 + stats->rx_packets = rq->stats.pkts; 166 + return 0; 167 + } 168 + 169 + static bool 170 + rvu_rep_has_offload_stats(const struct net_device *dev, int attr_id) 171 + { 172 + return attr_id == IFLA_OFFLOAD_XSTATS_CPU_HIT; 173 + } 174 + 175 + static int 176 + rvu_rep_get_offload_stats(int attr_id, const struct net_device *dev, 177 + void *sp) 178 + { 179 + if (attr_id == IFLA_OFFLOAD_XSTATS_CPU_HIT) 180 + return rvu_rep_sp_stats64(dev, (struct rtnl_link_stats64 *)sp); 181 + 182 + return -EINVAL; 183 + } 184 + 185 + static int rvu_rep_dl_port_fn_hw_addr_get(struct devlink_port *port, 186 + u8 *hw_addr, int *hw_addr_len, 187 + struct netlink_ext_ack *extack) 188 + { 189 + struct rep_dev *rep = container_of(port, struct rep_dev, dl_port); 190 + 191 + ether_addr_copy(hw_addr, rep->mac); 192 + *hw_addr_len = ETH_ALEN; 193 + return 0; 194 + } 195 + 196 + static int rvu_rep_dl_port_fn_hw_addr_set(struct devlink_port *port, 197 + const u8 *hw_addr, int hw_addr_len, 198 + struct netlink_ext_ack *extack) 199 + { 200 + struct rep_dev *rep = container_of(port, struct rep_dev, dl_port); 201 + struct otx2_nic *priv = rep->mdev; 202 + struct rep_event evt = {0}; 203 + 204 + eth_hw_addr_set(rep->netdev, hw_addr); 205 + ether_addr_copy(rep->mac, hw_addr); 206 + 207 + ether_addr_copy(evt.evt_data.mac, hw_addr); 208 + evt.pcifunc = rep->pcifunc; 209 + rvu_rep_notify_pfvf(priv, RVU_EVENT_MAC_ADDR_CHANGE, &evt); 210 + return 0; 211 + } 212 + 213 + static const struct devlink_port_ops rvu_rep_dl_port_ops = { 214 + .port_fn_hw_addr_get = rvu_rep_dl_port_fn_hw_addr_get, 215 + .port_fn_hw_addr_set = rvu_rep_dl_port_fn_hw_addr_set, 216 + }; 217 + 218 + static void 219 + rvu_rep_devlink_set_switch_id(struct otx2_nic *priv, 220 + struct netdev_phys_item_id *ppid) 221 + { 222 + struct pci_dev *pdev = priv->pdev; 223 + u64 id; 224 + 225 + id = pci_get_dsn(pdev); 226 + 227 + ppid->id_len = sizeof(id); 228 + put_unaligned_be64(id, &ppid->id); 229 + } 230 + 231 + static void rvu_rep_devlink_port_unregister(struct rep_dev *rep) 232 + { 233 + devlink_port_unregister(&rep->dl_port); 234 + } 235 + 236 + static int rvu_rep_devlink_port_register(struct rep_dev *rep) 237 + { 238 + struct devlink_port_attrs attrs = {}; 239 + struct otx2_nic *priv = rep->mdev; 240 + struct devlink *dl = priv->dl->dl; 241 + int err; 242 + 243 + if (!(rep->pcifunc & RVU_PFVF_FUNC_MASK)) { 244 + attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL; 245 + attrs.phys.port_number = rvu_get_pf(rep->pcifunc); 246 + } else { 247 + attrs.flavour = DEVLINK_PORT_FLAVOUR_PCI_VF; 248 + attrs.pci_vf.pf = rvu_get_pf(rep->pcifunc); 249 + attrs.pci_vf.vf = rep->pcifunc & RVU_PFVF_FUNC_MASK; 250 + } 251 + 252 + rvu_rep_devlink_set_switch_id(priv, &attrs.switch_id); 253 + devlink_port_attrs_set(&rep->dl_port, &attrs); 254 + 255 + err = devl_port_register_with_ops(dl, &rep->dl_port, rep->rep_id, 256 + &rvu_rep_dl_port_ops); 257 + if (err) { 258 + dev_err(rep->mdev->dev, "devlink_port_register failed: %d\n", 259 + err); 260 + return err; 261 + } 262 + return 0; 263 + } 264 + 265 + static int rvu_rep_get_repid(struct otx2_nic *priv, u16 pcifunc) 266 + { 267 + int rep_id; 268 + 269 + for (rep_id = 0; rep_id < priv->rep_cnt; rep_id++) 270 + if (priv->rep_pf_map[rep_id] == pcifunc) 271 + return rep_id; 272 + return -EINVAL; 273 + } 274 + 275 + static int rvu_rep_notify_pfvf(struct otx2_nic *priv, u16 event, 276 + struct rep_event *data) 277 + { 278 + struct rep_event *req; 279 + 280 + mutex_lock(&priv->mbox.lock); 281 + req = otx2_mbox_alloc_msg_rep_event_notify(&priv->mbox); 282 + if (!req) { 283 + mutex_unlock(&priv->mbox.lock); 284 + return -ENOMEM; 285 + } 286 + req->event = event; 287 + req->pcifunc = data->pcifunc; 288 + 289 + memcpy(&req->evt_data, &data->evt_data, sizeof(struct rep_evt_data)); 290 + otx2_sync_mbox_msg(&priv->mbox); 291 + mutex_unlock(&priv->mbox.lock); 292 + return 0; 293 + } 294 + 295 + static void rvu_rep_state_evt_handler(struct otx2_nic *priv, 296 + struct rep_event *info) 297 + { 298 + struct rep_dev *rep; 299 + int rep_id; 300 + 301 + rep_id = rvu_rep_get_repid(priv, info->pcifunc); 302 + rep = priv->reps[rep_id]; 303 + if (info->evt_data.vf_state) 304 + rep->flags |= RVU_REP_VF_INITIALIZED; 305 + else 306 + rep->flags &= ~RVU_REP_VF_INITIALIZED; 307 + } 308 + 309 + int rvu_event_up_notify(struct otx2_nic *pf, struct rep_event *info) 310 + { 311 + if (info->event & RVU_EVENT_PFVF_STATE) 312 + rvu_rep_state_evt_handler(pf, info); 313 + return 0; 314 + } 315 + 316 + static int rvu_rep_change_mtu(struct net_device *dev, int new_mtu) 317 + { 318 + struct rep_dev *rep = netdev_priv(dev); 319 + struct otx2_nic *priv = rep->mdev; 320 + struct rep_event evt = {0}; 321 + 322 + netdev_info(dev, "Changing MTU from %d to %d\n", 323 + dev->mtu, new_mtu); 324 + dev->mtu = new_mtu; 325 + 326 + evt.evt_data.mtu = new_mtu; 327 + evt.pcifunc = rep->pcifunc; 328 + rvu_rep_notify_pfvf(priv, RVU_EVENT_MTU_CHANGE, &evt); 329 + return 0; 330 + } 331 + 332 + static void rvu_rep_get_stats(struct work_struct *work) 333 + { 334 + struct delayed_work *del_work = to_delayed_work(work); 335 + struct nix_stats_req *req; 336 + struct nix_stats_rsp *rsp; 337 + struct rep_stats *stats; 338 + struct otx2_nic *priv; 339 + struct rep_dev *rep; 340 + int err; 341 + 342 + rep = container_of(del_work, struct rep_dev, stats_wrk); 343 + priv = rep->mdev; 344 + 345 + mutex_lock(&priv->mbox.lock); 346 + req = otx2_mbox_alloc_msg_nix_lf_stats(&priv->mbox); 347 + if (!req) { 348 + mutex_unlock(&priv->mbox.lock); 349 + return; 350 + } 351 + req->pcifunc = rep->pcifunc; 352 + err = otx2_sync_mbox_msg_busy_poll(&priv->mbox); 353 + if (err) 354 + goto exit; 355 + 356 + rsp = (struct nix_stats_rsp *) 357 + otx2_mbox_get_rsp(&priv->mbox.mbox, 0, &req->hdr); 358 + 359 + if (IS_ERR(rsp)) { 360 + err = PTR_ERR(rsp); 361 + goto exit; 362 + } 363 + 364 + stats = &rep->stats; 365 + stats->rx_bytes = rsp->rx.octs; 366 + stats->rx_frames = rsp->rx.ucast + rsp->rx.bcast + 367 + rsp->rx.mcast; 368 + stats->rx_drops = rsp->rx.drop; 369 + stats->rx_mcast_frames = rsp->rx.mcast; 370 + stats->tx_bytes = rsp->tx.octs; 371 + stats->tx_frames = rsp->tx.ucast + rsp->tx.bcast + rsp->tx.mcast; 372 + stats->tx_drops = rsp->tx.drop; 373 + exit: 374 + mutex_unlock(&priv->mbox.lock); 375 + } 376 + 377 + static void rvu_rep_get_stats64(struct net_device *dev, 378 + struct rtnl_link_stats64 *stats) 379 + { 380 + struct rep_dev *rep = netdev_priv(dev); 381 + 382 + if (!(rep->flags & RVU_REP_VF_INITIALIZED)) 383 + return; 384 + 385 + stats->rx_packets = rep->stats.rx_frames; 386 + stats->rx_bytes = rep->stats.rx_bytes; 387 + stats->rx_dropped = rep->stats.rx_drops; 388 + stats->multicast = rep->stats.rx_mcast_frames; 389 + 390 + stats->tx_packets = rep->stats.tx_frames; 391 + stats->tx_bytes = rep->stats.tx_bytes; 392 + stats->tx_dropped = rep->stats.tx_drops; 393 + 394 + schedule_delayed_work(&rep->stats_wrk, msecs_to_jiffies(100)); 395 + } 396 + 397 + static int rvu_eswitch_config(struct otx2_nic *priv, u8 ena) 398 + { 399 + struct esw_cfg_req *req; 400 + 401 + mutex_lock(&priv->mbox.lock); 402 + req = otx2_mbox_alloc_msg_esw_cfg(&priv->mbox); 403 + if (!req) { 404 + mutex_unlock(&priv->mbox.lock); 405 + return -ENOMEM; 406 + } 407 + req->ena = ena; 408 + otx2_sync_mbox_msg(&priv->mbox); 409 + mutex_unlock(&priv->mbox.lock); 410 + return 0; 411 + } 412 + 413 + static netdev_tx_t rvu_rep_xmit(struct sk_buff *skb, struct net_device *dev) 414 + { 415 + struct rep_dev *rep = netdev_priv(dev); 416 + struct otx2_nic *pf = rep->mdev; 417 + struct otx2_snd_queue *sq; 418 + struct netdev_queue *txq; 419 + 420 + sq = &pf->qset.sq[rep->rep_id]; 421 + txq = netdev_get_tx_queue(dev, 0); 422 + 423 + if (!otx2_sq_append_skb(pf, txq, sq, skb, rep->rep_id)) { 424 + netif_tx_stop_queue(txq); 425 + 426 + /* Check again, in case SQBs got freed up */ 427 + smp_mb(); 428 + if (((sq->num_sqbs - *sq->aura_fc_addr) * sq->sqe_per_sqb) 429 + > sq->sqe_thresh) 430 + netif_tx_wake_queue(txq); 431 + 432 + return NETDEV_TX_BUSY; 433 + } 434 + return NETDEV_TX_OK; 435 + } 436 + 437 + static int rvu_rep_open(struct net_device *dev) 438 + { 439 + struct rep_dev *rep = netdev_priv(dev); 440 + struct otx2_nic *priv = rep->mdev; 441 + struct rep_event evt = {0}; 442 + 443 + if (!(rep->flags & RVU_REP_VF_INITIALIZED)) 444 + return 0; 445 + 446 + netif_carrier_on(dev); 447 + netif_tx_start_all_queues(dev); 448 + 449 + evt.event = RVU_EVENT_PORT_STATE; 450 + evt.evt_data.port_state = 1; 451 + evt.pcifunc = rep->pcifunc; 452 + rvu_rep_notify_pfvf(priv, RVU_EVENT_PORT_STATE, &evt); 453 + return 0; 454 + } 455 + 456 + static int rvu_rep_stop(struct net_device *dev) 457 + { 458 + struct rep_dev *rep = netdev_priv(dev); 459 + struct otx2_nic *priv = rep->mdev; 460 + struct rep_event evt = {0}; 461 + 462 + if (!(rep->flags & RVU_REP_VF_INITIALIZED)) 463 + return 0; 464 + 465 + netif_carrier_off(dev); 466 + netif_tx_disable(dev); 467 + 468 + evt.event = RVU_EVENT_PORT_STATE; 469 + evt.pcifunc = rep->pcifunc; 470 + rvu_rep_notify_pfvf(priv, RVU_EVENT_PORT_STATE, &evt); 471 + return 0; 472 + } 473 + 474 + static const struct net_device_ops rvu_rep_netdev_ops = { 475 + .ndo_open = rvu_rep_open, 476 + .ndo_stop = rvu_rep_stop, 477 + .ndo_start_xmit = rvu_rep_xmit, 478 + .ndo_get_stats64 = rvu_rep_get_stats64, 479 + .ndo_change_mtu = rvu_rep_change_mtu, 480 + .ndo_has_offload_stats = rvu_rep_has_offload_stats, 481 + .ndo_get_offload_stats = rvu_rep_get_offload_stats, 482 + .ndo_setup_tc = rvu_rep_setup_tc, 483 + }; 484 + 485 + static int rvu_rep_napi_init(struct otx2_nic *priv, 486 + struct netlink_ext_ack *extack) 487 + { 488 + struct otx2_qset *qset = &priv->qset; 489 + struct otx2_cq_poll *cq_poll = NULL; 490 + struct otx2_hw *hw = &priv->hw; 491 + int err = 0, qidx, vec; 492 + char *irq_name; 493 + 494 + qset->napi = kcalloc(hw->cint_cnt, sizeof(*cq_poll), GFP_KERNEL); 495 + if (!qset->napi) 496 + return -ENOMEM; 497 + 498 + /* Register NAPI handler */ 499 + for (qidx = 0; qidx < hw->cint_cnt; qidx++) { 500 + cq_poll = &qset->napi[qidx]; 501 + cq_poll->cint_idx = qidx; 502 + cq_poll->cq_ids[CQ_RX] = 503 + (qidx < hw->rx_queues) ? qidx : CINT_INVALID_CQ; 504 + cq_poll->cq_ids[CQ_TX] = (qidx < hw->tx_queues) ? 505 + qidx + hw->rx_queues : 506 + CINT_INVALID_CQ; 507 + cq_poll->cq_ids[CQ_XDP] = CINT_INVALID_CQ; 508 + cq_poll->cq_ids[CQ_QOS] = CINT_INVALID_CQ; 509 + 510 + cq_poll->dev = (void *)priv; 511 + netif_napi_add(priv->reps[qidx]->netdev, &cq_poll->napi, 512 + otx2_napi_handler); 513 + napi_enable(&cq_poll->napi); 514 + } 515 + /* Register CQ IRQ handlers */ 516 + vec = hw->nix_msixoff + NIX_LF_CINT_VEC_START; 517 + for (qidx = 0; qidx < hw->cint_cnt; qidx++) { 518 + irq_name = &hw->irq_name[vec * NAME_SIZE]; 519 + 520 + snprintf(irq_name, NAME_SIZE, "rep%d-rxtx-%d", qidx, qidx); 521 + 522 + err = request_irq(pci_irq_vector(priv->pdev, vec), 523 + otx2_cq_intr_handler, 0, irq_name, 524 + &qset->napi[qidx]); 525 + if (err) { 526 + NL_SET_ERR_MSG_FMT_MOD(extack, 527 + "RVU REP IRQ registration failed for CQ%d", 528 + qidx); 529 + goto err_free_cints; 530 + } 531 + vec++; 532 + 533 + /* Enable CQ IRQ */ 534 + otx2_write64(priv, NIX_LF_CINTX_INT(qidx), BIT_ULL(0)); 535 + otx2_write64(priv, NIX_LF_CINTX_ENA_W1S(qidx), BIT_ULL(0)); 536 + } 537 + priv->flags &= ~OTX2_FLAG_INTF_DOWN; 538 + return 0; 539 + 540 + err_free_cints: 541 + otx2_free_cints(priv, qidx); 542 + otx2_disable_napi(priv); 543 + return err; 544 + } 545 + 546 + static void rvu_rep_free_cq_rsrc(struct otx2_nic *priv) 547 + { 548 + struct otx2_qset *qset = &priv->qset; 549 + struct otx2_cq_poll *cq_poll = NULL; 550 + int qidx, vec; 551 + 552 + /* Cleanup CQ NAPI and IRQ */ 553 + vec = priv->hw.nix_msixoff + NIX_LF_CINT_VEC_START; 554 + for (qidx = 0; qidx < priv->hw.cint_cnt; qidx++) { 555 + /* Disable interrupt */ 556 + otx2_write64(priv, NIX_LF_CINTX_ENA_W1C(qidx), BIT_ULL(0)); 557 + 558 + synchronize_irq(pci_irq_vector(priv->pdev, vec)); 559 + 560 + cq_poll = &qset->napi[qidx]; 561 + napi_synchronize(&cq_poll->napi); 562 + vec++; 563 + } 564 + otx2_free_cints(priv, priv->hw.cint_cnt); 565 + otx2_disable_napi(priv); 566 + } 567 + 568 + static void rvu_rep_rsrc_free(struct otx2_nic *priv) 569 + { 570 + struct otx2_qset *qset = &priv->qset; 571 + struct delayed_work *work; 572 + int wrk; 573 + 574 + for (wrk = 0; wrk < priv->qset.cq_cnt; wrk++) { 575 + work = &priv->refill_wrk[wrk].pool_refill_work; 576 + cancel_delayed_work_sync(work); 577 + } 578 + devm_kfree(priv->dev, priv->refill_wrk); 579 + 580 + otx2_free_hw_resources(priv); 581 + otx2_free_queue_mem(qset); 582 + } 583 + 584 + static int rvu_rep_rsrc_init(struct otx2_nic *priv) 585 + { 586 + struct otx2_qset *qset = &priv->qset; 587 + int err; 588 + 589 + err = otx2_alloc_queue_mem(priv); 590 + if (err) 591 + return err; 592 + 593 + priv->hw.max_mtu = otx2_get_max_mtu(priv); 594 + priv->tx_max_pktlen = priv->hw.max_mtu + OTX2_ETH_HLEN; 595 + priv->rbsize = ALIGN(priv->hw.rbuf_len, OTX2_ALIGN) + OTX2_HEAD_ROOM; 596 + 597 + err = otx2_init_hw_resources(priv); 598 + if (err) 599 + goto err_free_rsrc; 600 + 601 + /* Set maximum frame size allowed in HW */ 602 + err = otx2_hw_set_mtu(priv, priv->hw.max_mtu); 603 + if (err) { 604 + dev_err(priv->dev, "Failed to set HW MTU\n"); 605 + goto err_free_rsrc; 606 + } 607 + return 0; 608 + 609 + err_free_rsrc: 610 + otx2_free_hw_resources(priv); 611 + otx2_free_queue_mem(qset); 612 + return err; 613 + } 614 + 615 + void rvu_rep_destroy(struct otx2_nic *priv) 616 + { 617 + struct rep_dev *rep; 618 + int rep_id; 619 + 620 + rvu_eswitch_config(priv, false); 621 + priv->flags |= OTX2_FLAG_INTF_DOWN; 622 + rvu_rep_free_cq_rsrc(priv); 623 + for (rep_id = 0; rep_id < priv->rep_cnt; rep_id++) { 624 + rep = priv->reps[rep_id]; 625 + unregister_netdev(rep->netdev); 626 + rvu_rep_devlink_port_unregister(rep); 627 + free_netdev(rep->netdev); 628 + kfree(rep->flow_cfg); 629 + } 630 + kfree(priv->reps); 631 + rvu_rep_rsrc_free(priv); 632 + } 633 + 634 + int rvu_rep_create(struct otx2_nic *priv, struct netlink_ext_ack *extack) 635 + { 636 + int rep_cnt = priv->rep_cnt; 637 + struct net_device *ndev; 638 + struct rep_dev *rep; 639 + int rep_id, err; 640 + u16 pcifunc; 641 + 642 + err = rvu_rep_rsrc_init(priv); 643 + if (err) 644 + return -ENOMEM; 645 + 646 + priv->reps = kcalloc(rep_cnt, sizeof(struct rep_dev *), GFP_KERNEL); 647 + if (!priv->reps) 648 + return -ENOMEM; 649 + 650 + for (rep_id = 0; rep_id < rep_cnt; rep_id++) { 651 + ndev = alloc_etherdev(sizeof(*rep)); 652 + if (!ndev) { 653 + NL_SET_ERR_MSG_FMT_MOD(extack, 654 + "PFVF representor:%d creation failed", 655 + rep_id); 656 + err = -ENOMEM; 657 + goto exit; 658 + } 659 + 660 + rep = netdev_priv(ndev); 661 + priv->reps[rep_id] = rep; 662 + rep->mdev = priv; 663 + rep->netdev = ndev; 664 + rep->rep_id = rep_id; 665 + 666 + ndev->min_mtu = OTX2_MIN_MTU; 667 + ndev->max_mtu = priv->hw.max_mtu; 668 + ndev->netdev_ops = &rvu_rep_netdev_ops; 669 + pcifunc = priv->rep_pf_map[rep_id]; 670 + rep->pcifunc = pcifunc; 671 + 672 + snprintf(ndev->name, sizeof(ndev->name), "Rpf%dvf%d", 673 + rvu_get_pf(pcifunc), (pcifunc & RVU_PFVF_FUNC_MASK)); 674 + 675 + ndev->hw_features = (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | 676 + NETIF_F_IPV6_CSUM | NETIF_F_RXHASH | 677 + NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6); 678 + 679 + ndev->hw_features |= NETIF_F_HW_TC; 680 + ndev->features |= ndev->hw_features; 681 + eth_hw_addr_random(ndev); 682 + err = rvu_rep_devlink_port_register(rep); 683 + if (err) 684 + goto exit; 685 + 686 + SET_NETDEV_DEVLINK_PORT(ndev, &rep->dl_port); 687 + err = register_netdev(ndev); 688 + if (err) { 689 + NL_SET_ERR_MSG_MOD(extack, 690 + "PFVF reprentator registration failed"); 691 + free_netdev(ndev); 692 + goto exit; 693 + } 694 + 695 + INIT_DELAYED_WORK(&rep->stats_wrk, rvu_rep_get_stats); 696 + } 697 + err = rvu_rep_napi_init(priv, extack); 698 + if (err) 699 + goto exit; 700 + 701 + rvu_eswitch_config(priv, true); 702 + return 0; 703 + exit: 704 + while (--rep_id >= 0) { 705 + rep = priv->reps[rep_id]; 706 + unregister_netdev(rep->netdev); 707 + rvu_rep_devlink_port_unregister(rep); 708 + free_netdev(rep->netdev); 709 + } 710 + kfree(priv->reps); 711 + rvu_rep_rsrc_free(priv); 712 + return err; 713 + } 714 + 715 + static int rvu_get_rep_cnt(struct otx2_nic *priv) 716 + { 717 + struct get_rep_cnt_rsp *rsp; 718 + struct mbox_msghdr *msghdr; 719 + struct msg_req *req; 720 + int err, rep; 721 + 722 + mutex_lock(&priv->mbox.lock); 723 + req = otx2_mbox_alloc_msg_get_rep_cnt(&priv->mbox); 724 + if (!req) { 725 + mutex_unlock(&priv->mbox.lock); 726 + return -ENOMEM; 727 + } 728 + err = otx2_sync_mbox_msg(&priv->mbox); 729 + if (err) 730 + goto exit; 731 + 732 + msghdr = otx2_mbox_get_rsp(&priv->mbox.mbox, 0, &req->hdr); 733 + if (IS_ERR(msghdr)) { 734 + err = PTR_ERR(msghdr); 735 + goto exit; 736 + } 737 + 738 + rsp = (struct get_rep_cnt_rsp *)msghdr; 739 + priv->hw.tx_queues = rsp->rep_cnt; 740 + priv->hw.rx_queues = rsp->rep_cnt; 741 + priv->rep_cnt = rsp->rep_cnt; 742 + for (rep = 0; rep < priv->rep_cnt; rep++) 743 + priv->rep_pf_map[rep] = rsp->rep_pf_map[rep]; 744 + 745 + exit: 746 + mutex_unlock(&priv->mbox.lock); 747 + return err; 748 + } 749 + 750 + static int rvu_rep_probe(struct pci_dev *pdev, const struct pci_device_id *id) 751 + { 752 + struct device *dev = &pdev->dev; 753 + struct otx2_nic *priv; 754 + struct otx2_hw *hw; 755 + int err; 756 + 757 + err = pcim_enable_device(pdev); 758 + if (err) { 759 + dev_err(dev, "Failed to enable PCI device\n"); 760 + return err; 761 + } 762 + 763 + err = pci_request_regions(pdev, DRV_NAME); 764 + if (err) { 765 + dev_err(dev, "PCI request regions failed 0x%x\n", err); 766 + return err; 767 + } 768 + 769 + err = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48)); 770 + if (err) { 771 + dev_err(dev, "DMA mask config failed, abort\n"); 772 + goto err_release_regions; 773 + } 774 + 775 + pci_set_master(pdev); 776 + 777 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 778 + if (!priv) { 779 + err = -ENOMEM; 780 + goto err_release_regions; 781 + } 782 + 783 + pci_set_drvdata(pdev, priv); 784 + priv->pdev = pdev; 785 + priv->dev = dev; 786 + priv->flags |= OTX2_FLAG_INTF_DOWN; 787 + priv->flags |= OTX2_FLAG_REP_MODE_ENABLED; 788 + 789 + hw = &priv->hw; 790 + hw->pdev = pdev; 791 + hw->max_queues = OTX2_MAX_CQ_CNT; 792 + hw->rbuf_len = OTX2_DEFAULT_RBUF_LEN; 793 + hw->xqe_size = 128; 794 + 795 + err = otx2_init_rsrc(pdev, priv); 796 + if (err) 797 + goto err_release_regions; 798 + 799 + priv->iommu_domain = iommu_get_domain_for_dev(dev); 800 + 801 + err = rvu_get_rep_cnt(priv); 802 + if (err) 803 + goto err_detach_rsrc; 804 + 805 + err = otx2_register_dl(priv); 806 + if (err) 807 + goto err_detach_rsrc; 808 + 809 + return 0; 810 + 811 + err_detach_rsrc: 812 + if (priv->hw.lmt_info) 813 + free_percpu(priv->hw.lmt_info); 814 + if (test_bit(CN10K_LMTST, &priv->hw.cap_flag)) 815 + qmem_free(priv->dev, priv->dync_lmt); 816 + otx2_detach_resources(&priv->mbox); 817 + otx2_disable_mbox_intr(priv); 818 + otx2_pfaf_mbox_destroy(priv); 819 + pci_free_irq_vectors(pdev); 820 + err_release_regions: 821 + pci_set_drvdata(pdev, NULL); 822 + pci_release_regions(pdev); 823 + return err; 824 + } 825 + 826 + static void rvu_rep_remove(struct pci_dev *pdev) 827 + { 828 + struct otx2_nic *priv = pci_get_drvdata(pdev); 829 + 830 + otx2_unregister_dl(priv); 831 + if (!(priv->flags & OTX2_FLAG_INTF_DOWN)) 832 + rvu_rep_destroy(priv); 833 + otx2_detach_resources(&priv->mbox); 834 + if (priv->hw.lmt_info) 835 + free_percpu(priv->hw.lmt_info); 836 + if (test_bit(CN10K_LMTST, &priv->hw.cap_flag)) 837 + qmem_free(priv->dev, priv->dync_lmt); 838 + otx2_disable_mbox_intr(priv); 839 + otx2_pfaf_mbox_destroy(priv); 840 + pci_free_irq_vectors(priv->pdev); 841 + pci_set_drvdata(pdev, NULL); 842 + pci_release_regions(pdev); 843 + } 844 + 845 + static struct pci_driver rvu_rep_driver = { 846 + .name = DRV_NAME, 847 + .id_table = rvu_rep_id_table, 848 + .probe = rvu_rep_probe, 849 + .remove = rvu_rep_remove, 850 + .shutdown = rvu_rep_remove, 851 + }; 852 + 853 + static int __init rvu_rep_init_module(void) 854 + { 855 + return pci_register_driver(&rvu_rep_driver); 856 + } 857 + 858 + static void __exit rvu_rep_cleanup_module(void) 859 + { 860 + pci_unregister_driver(&rvu_rep_driver); 861 + } 862 + 863 + module_init(rvu_rep_init_module); 864 + module_exit(rvu_rep_cleanup_module);
+54
drivers/net/ethernet/marvell/octeontx2/nic/rep.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* Marvell RVU REPRESENTOR driver 3 + * 4 + * Copyright (C) 2024 Marvell. 5 + * 6 + */ 7 + 8 + #ifndef REP_H 9 + #define REP_H 10 + 11 + #include <linux/pci.h> 12 + 13 + #include "otx2_reg.h" 14 + #include "otx2_txrx.h" 15 + #include "otx2_common.h" 16 + 17 + #define PCI_DEVID_RVU_REP 0xA0E0 18 + 19 + #define RVU_MAX_REP OTX2_MAX_CQ_CNT 20 + 21 + struct rep_stats { 22 + u64 rx_bytes; 23 + u64 rx_frames; 24 + u64 rx_drops; 25 + u64 rx_mcast_frames; 26 + 27 + u64 tx_bytes; 28 + u64 tx_frames; 29 + u64 tx_drops; 30 + }; 31 + 32 + struct rep_dev { 33 + struct otx2_nic *mdev; 34 + struct net_device *netdev; 35 + struct rep_stats stats; 36 + struct delayed_work stats_wrk; 37 + struct devlink_port dl_port; 38 + struct otx2_flow_config *flow_cfg; 39 + #define RVU_REP_VF_INITIALIZED BIT_ULL(0) 40 + u64 flags; 41 + u16 rep_id; 42 + u16 pcifunc; 43 + u8 mac[ETH_ALEN]; 44 + }; 45 + 46 + static inline bool otx2_rep_dev(struct pci_dev *pdev) 47 + { 48 + return pdev->device == PCI_DEVID_RVU_REP; 49 + } 50 + 51 + int rvu_rep_create(struct otx2_nic *priv, struct netlink_ext_ack *extack); 52 + void rvu_rep_destroy(struct otx2_nic *priv); 53 + int rvu_event_up_notify(struct otx2_nic *pf, struct rep_event *info); 54 + #endif /* REP_H */