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.

net: ngbe: add sriov function support

Add sriov_configure for driver ops.
Add mailbox handler wx_msg_task for ngbe in
the interrupt handler.
Add the notification flow when the vfs exist.

Signed-off-by: Mengyuan Lou <mengyuanlou@net-swift.com>
Link: https://patch.msgid.link/C9A0A43732966022+20250408091556.9640-6-mengyuanlou@net-swift.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Mengyuan Lou and committed by
Jakub Kicinski
877253d2 359e41f6

+127 -9
+31
drivers/net/ethernet/wangxun/libwx/wx_sriov.c
··· 834 834 } 835 835 } 836 836 EXPORT_SYMBOL(wx_msg_task); 837 + 838 + void wx_disable_vf_rx_tx(struct wx *wx) 839 + { 840 + wr32(wx, WX_TDM_VFTE_CLR(0), U32_MAX); 841 + wr32(wx, WX_RDM_VFRE_CLR(0), U32_MAX); 842 + if (wx->mac.type != wx_mac_em) { 843 + wr32(wx, WX_TDM_VFTE_CLR(1), U32_MAX); 844 + wr32(wx, WX_RDM_VFRE_CLR(1), U32_MAX); 845 + } 846 + } 847 + EXPORT_SYMBOL(wx_disable_vf_rx_tx); 848 + 849 + void wx_ping_all_vfs_with_link_status(struct wx *wx, bool link_up) 850 + { 851 + u32 msgbuf[2] = {0, 0}; 852 + u16 i; 853 + 854 + if (!wx->num_vfs) 855 + return; 856 + msgbuf[0] = WX_PF_NOFITY_VF_LINK_STATUS | WX_PF_CONTROL_MSG; 857 + if (link_up) 858 + msgbuf[1] = FIELD_PREP(GENMASK(31, 1), wx->speed) | link_up; 859 + if (wx->notify_down) 860 + msgbuf[1] |= WX_PF_NOFITY_VF_NET_NOT_RUNNING; 861 + for (i = 0; i < wx->num_vfs; i++) { 862 + if (wx->vfinfo[i].clear_to_send) 863 + msgbuf[0] |= WX_VT_MSGTYPE_CTS; 864 + wx_write_mbx_pf(wx, msgbuf, 2, i); 865 + } 866 + } 867 + EXPORT_SYMBOL(wx_ping_all_vfs_with_link_status);
+2
drivers/net/ethernet/wangxun/libwx/wx_sriov.h
··· 11 11 void wx_disable_sriov(struct wx *wx); 12 12 int wx_pci_sriov_configure(struct pci_dev *pdev, int num_vfs); 13 13 void wx_msg_task(struct wx *wx); 14 + void wx_disable_vf_rx_tx(struct wx *wx); 15 + void wx_ping_all_vfs_with_link_status(struct wx *wx, bool link_up); 14 16 15 17 #endif /* _WX_SRIOV_H_ */
+2
drivers/net/ethernet/wangxun/libwx/wx_type.h
··· 92 92 /************************* Port Registers ************************************/ 93 93 /* port cfg Registers */ 94 94 #define WX_CFG_PORT_CTL 0x14400 95 + #define WX_CFG_PORT_CTL_PFRSTD BIT(14) 95 96 #define WX_CFG_PORT_CTL_DRV_LOAD BIT(3) 96 97 #define WX_CFG_PORT_CTL_QINQ BIT(2) 97 98 #define WX_CFG_PORT_CTL_D_VLAN BIT(0) /* double vlan*/ ··· 1232 1231 u8 swfw_index; 1233 1232 1234 1233 /* PHY stuff */ 1234 + bool notify_down; 1235 1235 unsigned int link; 1236 1236 int speed; 1237 1237 int duplex;
+84 -9
drivers/net/ethernet/wangxun/ngbe/ngbe_main.c
··· 15 15 #include "../libwx/wx_hw.h" 16 16 #include "../libwx/wx_lib.h" 17 17 #include "../libwx/wx_ptp.h" 18 + #include "../libwx/wx_mbx.h" 19 + #include "../libwx/wx_sriov.h" 18 20 #include "ngbe_type.h" 19 21 #include "ngbe_mdio.h" 20 22 #include "ngbe_hw.h" ··· 131 129 wx->tx_work_limit = NGBE_DEFAULT_TX_WORK; 132 130 wx->rx_work_limit = NGBE_DEFAULT_RX_WORK; 133 131 132 + wx->mbx.size = WX_VXMAILBOX_SIZE; 133 + wx->setup_tc = ngbe_setup_tc; 134 + set_bit(0, &wx->fwd_bitmask); 135 + 134 136 return 0; 135 137 } 136 138 ··· 206 200 return IRQ_HANDLED; 207 201 } 208 202 209 - static irqreturn_t ngbe_msix_other(int __always_unused irq, void *data) 203 + static irqreturn_t __ngbe_msix_misc(struct wx *wx, u32 eicr) 210 204 { 211 - struct wx *wx = data; 212 - u32 eicr; 213 - 214 - eicr = wx_misc_isb(wx, WX_ISB_MISC); 205 + if (eicr & NGBE_PX_MISC_IC_VF_MBOX) 206 + wx_msg_task(wx); 215 207 216 208 if (unlikely(eicr & NGBE_PX_MISC_IC_TIMESYNC)) 217 209 wx_ptp_check_pps_event(wx); ··· 219 215 ngbe_irq_enable(wx, false); 220 216 221 217 return IRQ_HANDLED; 218 + } 219 + 220 + static irqreturn_t ngbe_msix_misc(int __always_unused irq, void *data) 221 + { 222 + struct wx *wx = data; 223 + u32 eicr; 224 + 225 + eicr = wx_misc_isb(wx, WX_ISB_MISC); 226 + 227 + return __ngbe_msix_misc(wx, eicr); 228 + } 229 + 230 + static irqreturn_t ngbe_misc_and_queue(int __always_unused irq, void *data) 231 + { 232 + struct wx_q_vector *q_vector; 233 + struct wx *wx = data; 234 + u32 eicr; 235 + 236 + eicr = wx_misc_isb(wx, WX_ISB_MISC); 237 + if (!eicr) { 238 + /* queue */ 239 + q_vector = wx->q_vector[0]; 240 + napi_schedule_irqoff(&q_vector->napi); 241 + if (netif_running(wx->netdev)) 242 + ngbe_irq_enable(wx, true); 243 + return IRQ_HANDLED; 244 + } 245 + 246 + return __ngbe_msix_misc(wx, eicr); 222 247 } 223 248 224 249 /** ··· 282 249 } 283 250 } 284 251 285 - err = request_irq(wx->msix_entry->vector, 286 - ngbe_msix_other, 0, netdev->name, wx); 252 + /* Due to hardware design, when num_vfs < 7, pf can use 0 for misc and 1 253 + * for queue. But when num_vfs == 7, vector[1] is assigned to vf6. 254 + * Misc and queue should reuse interrupt vector[0]. 255 + */ 256 + if (wx->num_vfs == 7) 257 + err = request_irq(wx->msix_entry->vector, 258 + ngbe_misc_and_queue, 0, netdev->name, wx); 259 + else 260 + err = request_irq(wx->msix_entry->vector, 261 + ngbe_msix_misc, 0, netdev->name, wx); 287 262 288 263 if (err) { 289 264 wx_err(wx, "request_irq for msix_other failed: %d\n", err); ··· 343 302 struct net_device *netdev = wx->netdev; 344 303 u32 i; 345 304 305 + if (wx->num_vfs) { 306 + /* Clear EITR Select mapping */ 307 + wr32(wx, WX_PX_ITRSEL, 0); 308 + 309 + /* Mark all the VFs as inactive */ 310 + for (i = 0; i < wx->num_vfs; i++) 311 + wx->vfinfo[i].clear_to_send = 0; 312 + wx->notify_down = true; 313 + /* ping all the active vfs to let them know we are going down */ 314 + wx_ping_all_vfs_with_link_status(wx, false); 315 + wx->notify_down = false; 316 + 317 + /* Disable all VFTE/VFRE TX/RX */ 318 + wx_disable_vf_rx_tx(wx); 319 + } 320 + 346 321 /* disable all enabled rx queues */ 347 322 for (i = 0; i < wx->num_rx_queues; i++) 348 323 /* this call also flushes the previous write */ ··· 381 324 wx_update_stats(wx); 382 325 } 383 326 327 + static void ngbe_reset(struct wx *wx) 328 + { 329 + wx_flush_sw_mac_table(wx); 330 + wx_mac_set_default_filter(wx, wx->mac.addr); 331 + if (test_bit(WX_STATE_PTP_RUNNING, wx->state)) 332 + wx_ptp_reset(wx); 333 + } 334 + 384 335 void ngbe_down(struct wx *wx) 385 336 { 386 337 phylink_stop(wx->phylink); 387 338 ngbe_disable_device(wx); 388 - if (test_bit(WX_STATE_PTP_RUNNING, wx->state)) 389 - wx_ptp_reset(wx); 339 + ngbe_reset(wx); 390 340 wx_clean_all_tx_rings(wx); 391 341 wx_clean_all_rx_rings(wx); 392 342 } ··· 416 352 ngbe_sfp_modules_txrx_powerctl(wx, true); 417 353 418 354 phylink_start(wx->phylink); 355 + /* Set PF Reset Done bit so PF/VF Mail Ops can work */ 356 + wr32m(wx, WX_CFG_PORT_CTL, 357 + WX_CFG_PORT_CTL_PFRSTD, WX_CFG_PORT_CTL_PFRSTD); 358 + if (wx->num_vfs) 359 + wx_ping_all_vfs_with_link_status(wx, false); 419 360 } 420 361 421 362 /** ··· 665 596 goto err_pci_release_regions; 666 597 } 667 598 599 + /* The emerald supports up to 8 VFs per pf, but physical 600 + * function also need one pool for basic networking. 601 + */ 602 + pci_sriov_set_totalvfs(pdev, NGBE_MAX_VFS_DRV_LIMIT); 668 603 wx->driver_name = ngbe_driver_name; 669 604 ngbe_set_ethtool_ops(netdev); 670 605 netdev->netdev_ops = &ngbe_netdev_ops; ··· 816 743 struct net_device *netdev; 817 744 818 745 netdev = wx->netdev; 746 + wx_disable_sriov(wx); 819 747 unregister_netdev(netdev); 820 748 phylink_destroy(wx->phylink); 821 749 pci_release_selected_regions(pdev, ··· 876 802 .suspend = ngbe_suspend, 877 803 .resume = ngbe_resume, 878 804 .shutdown = ngbe_shutdown, 805 + .sriov_configure = wx_pci_sriov_configure, 879 806 }; 880 807 881 808 module_pci_driver(ngbe_driver);
+5
drivers/net/ethernet/wangxun/ngbe/ngbe_mdio.c
··· 9 9 #include "../libwx/wx_type.h" 10 10 #include "../libwx/wx_ptp.h" 11 11 #include "../libwx/wx_hw.h" 12 + #include "../libwx/wx_sriov.h" 12 13 #include "ngbe_type.h" 13 14 #include "ngbe_mdio.h" 14 15 ··· 71 70 wx->speed = SPEED_UNKNOWN; 72 71 if (test_bit(WX_STATE_PTP_RUNNING, wx->state)) 73 72 wx_ptp_reset_cyclecounter(wx); 73 + /* ping all the active vfs to let them know we are going down */ 74 + wx_ping_all_vfs_with_link_status(wx, false); 74 75 } 75 76 76 77 static void ngbe_mac_link_up(struct phylink_config *config, ··· 117 114 wx->last_rx_ptp_check = jiffies; 118 115 if (test_bit(WX_STATE_PTP_RUNNING, wx->state)) 119 116 wx_ptp_reset_cyclecounter(wx); 117 + /* ping all the active vfs to let them know we are going up */ 118 + wx_ping_all_vfs_with_link_status(wx, true); 120 119 } 121 120 122 121 static const struct phylink_mac_ops ngbe_mac_ops = {
+3
drivers/net/ethernet/wangxun/ngbe/ngbe_type.h
··· 73 73 #define NGBE_PX_MISC_IEN_TIMESYNC BIT(11) 74 74 #define NGBE_PX_MISC_IEN_ETH_LK BIT(18) 75 75 #define NGBE_PX_MISC_IEN_INT_ERR BIT(20) 76 + #define NGBE_PX_MISC_IC_VF_MBOX BIT(23) 76 77 #define NGBE_PX_MISC_IEN_GPIO BIT(26) 77 78 #define NGBE_PX_MISC_IEN_MASK ( \ 78 79 NGBE_PX_MISC_IEN_DEV_RST | \ 79 80 NGBE_PX_MISC_IEN_TIMESYNC | \ 80 81 NGBE_PX_MISC_IEN_ETH_LK | \ 81 82 NGBE_PX_MISC_IEN_INT_ERR | \ 83 + NGBE_PX_MISC_IC_VF_MBOX | \ 82 84 NGBE_PX_MISC_IEN_GPIO) 83 85 84 86 /* Extended Interrupt Cause Read */ ··· 136 134 #define NGBE_MAX_RXD 8192 137 135 #define NGBE_MIN_RXD 128 138 136 137 + #define NGBE_MAX_VFS_DRV_LIMIT 7 139 138 extern char ngbe_driver_name[]; 140 139 141 140 void ngbe_down(struct wx *wx);