1515#include "../libwx/wx_hw.h"
1616#include "../libwx/wx_lib.h"
1717#include "../libwx/wx_ptp.h"
18+ #include "../libwx/wx_mbx.h"
19+ #include "../libwx/wx_sriov.h"
1820#include "ngbe_type.h"
1921#include "ngbe_mdio.h"
2022#include "ngbe_hw.h"
@@ -129,6 +131,10 @@ static int ngbe_sw_init(struct wx *wx)
129131 wx -> tx_work_limit = NGBE_DEFAULT_TX_WORK ;
130132 wx -> rx_work_limit = NGBE_DEFAULT_RX_WORK ;
131133
134+ wx -> mbx .size = WX_VXMAILBOX_SIZE ;
135+ wx -> setup_tc = ngbe_setup_tc ;
136+ set_bit (0 , & wx -> fwd_bitmask );
137+
132138 return 0 ;
133139}
134140
@@ -200,12 +206,10 @@ static irqreturn_t ngbe_intr(int __always_unused irq, void *data)
200206 return IRQ_HANDLED ;
201207}
202208
203- static irqreturn_t ngbe_msix_other ( int __always_unused irq , void * data )
209+ static irqreturn_t __ngbe_msix_misc ( struct wx * wx , u32 eicr )
204210{
205- struct wx * wx = data ;
206- u32 eicr ;
207-
208- eicr = wx_misc_isb (wx , WX_ISB_MISC );
211+ if (eicr & NGBE_PX_MISC_IC_VF_MBOX )
212+ wx_msg_task (wx );
209213
210214 if (unlikely (eicr & NGBE_PX_MISC_IC_TIMESYNC ))
211215 wx_ptp_check_pps_event (wx );
@@ -217,6 +221,35 @@ static irqreturn_t ngbe_msix_other(int __always_unused irq, void *data)
217221 return IRQ_HANDLED ;
218222}
219223
224+ static irqreturn_t ngbe_msix_misc (int __always_unused irq , void * data )
225+ {
226+ struct wx * wx = data ;
227+ u32 eicr ;
228+
229+ eicr = wx_misc_isb (wx , WX_ISB_MISC );
230+
231+ return __ngbe_msix_misc (wx , eicr );
232+ }
233+
234+ static irqreturn_t ngbe_misc_and_queue (int __always_unused irq , void * data )
235+ {
236+ struct wx_q_vector * q_vector ;
237+ struct wx * wx = data ;
238+ u32 eicr ;
239+
240+ eicr = wx_misc_isb (wx , WX_ISB_MISC );
241+ if (!eicr ) {
242+ /* queue */
243+ q_vector = wx -> q_vector [0 ];
244+ napi_schedule_irqoff (& q_vector -> napi );
245+ if (netif_running (wx -> netdev ))
246+ ngbe_irq_enable (wx , true);
247+ return IRQ_HANDLED ;
248+ }
249+
250+ return __ngbe_msix_misc (wx , eicr );
251+ }
252+
220253/**
221254 * ngbe_request_msix_irqs - Initialize MSI-X interrupts
222255 * @wx: board private structure
@@ -249,8 +282,16 @@ static int ngbe_request_msix_irqs(struct wx *wx)
249282 }
250283 }
251284
252- err = request_irq (wx -> msix_entry -> vector ,
253- ngbe_msix_other , 0 , netdev -> name , wx );
285+ /* Due to hardware design, when num_vfs < 7, pf can use 0 for misc and 1
286+ * for queue. But when num_vfs == 7, vector[1] is assigned to vf6.
287+ * Misc and queue should reuse interrupt vector[0].
288+ */
289+ if (wx -> num_vfs == 7 )
290+ err = request_irq (wx -> msix_entry -> vector ,
291+ ngbe_misc_and_queue , 0 , netdev -> name , wx );
292+ else
293+ err = request_irq (wx -> msix_entry -> vector ,
294+ ngbe_msix_misc , 0 , netdev -> name , wx );
254295
255296 if (err ) {
256297 wx_err (wx , "request_irq for msix_other failed: %d\n" , err );
@@ -302,6 +343,22 @@ static void ngbe_disable_device(struct wx *wx)
302343 struct net_device * netdev = wx -> netdev ;
303344 u32 i ;
304345
346+ if (wx -> num_vfs ) {
347+ /* Clear EITR Select mapping */
348+ wr32 (wx , WX_PX_ITRSEL , 0 );
349+
350+ /* Mark all the VFs as inactive */
351+ for (i = 0 ; i < wx -> num_vfs ; i ++ )
352+ wx -> vfinfo [i ].clear_to_send = 0 ;
353+ wx -> notify_down = true;
354+ /* ping all the active vfs to let them know we are going down */
355+ wx_ping_all_vfs_with_link_status (wx , false);
356+ wx -> notify_down = false;
357+
358+ /* Disable all VFTE/VFRE TX/RX */
359+ wx_disable_vf_rx_tx (wx );
360+ }
361+
305362 /* disable all enabled rx queues */
306363 for (i = 0 ; i < wx -> num_rx_queues ; i ++ )
307364 /* this call also flushes the previous write */
@@ -324,12 +381,19 @@ static void ngbe_disable_device(struct wx *wx)
324381 wx_update_stats (wx );
325382}
326383
384+ static void ngbe_reset (struct wx * wx )
385+ {
386+ wx_flush_sw_mac_table (wx );
387+ wx_mac_set_default_filter (wx , wx -> mac .addr );
388+ if (test_bit (WX_STATE_PTP_RUNNING , wx -> state ))
389+ wx_ptp_reset (wx );
390+ }
391+
327392void ngbe_down (struct wx * wx )
328393{
329394 phylink_stop (wx -> phylink );
330395 ngbe_disable_device (wx );
331- if (test_bit (WX_STATE_PTP_RUNNING , wx -> state ))
332- wx_ptp_reset (wx );
396+ ngbe_reset (wx );
333397 wx_clean_all_tx_rings (wx );
334398 wx_clean_all_rx_rings (wx );
335399}
@@ -352,6 +416,11 @@ void ngbe_up(struct wx *wx)
352416 ngbe_sfp_modules_txrx_powerctl (wx , true);
353417
354418 phylink_start (wx -> phylink );
419+ /* Set PF Reset Done bit so PF/VF Mail Ops can work */
420+ wr32m (wx , WX_CFG_PORT_CTL ,
421+ WX_CFG_PORT_CTL_PFRSTD , WX_CFG_PORT_CTL_PFRSTD );
422+ if (wx -> num_vfs )
423+ wx_ping_all_vfs_with_link_status (wx , false);
355424}
356425
357426/**
@@ -596,6 +665,10 @@ static int ngbe_probe(struct pci_dev *pdev,
596665 goto err_pci_release_regions ;
597666 }
598667
668+ /* The emerald supports up to 8 VFs per pf, but physical
669+ * function also need one pool for basic networking.
670+ */
671+ pci_sriov_set_totalvfs (pdev , NGBE_MAX_VFS_DRV_LIMIT );
599672 wx -> driver_name = ngbe_driver_name ;
600673 ngbe_set_ethtool_ops (netdev );
601674 netdev -> netdev_ops = & ngbe_netdev_ops ;
@@ -743,6 +816,7 @@ static void ngbe_remove(struct pci_dev *pdev)
743816 struct net_device * netdev ;
744817
745818 netdev = wx -> netdev ;
819+ wx_disable_sriov (wx );
746820 unregister_netdev (netdev );
747821 phylink_destroy (wx -> phylink );
748822 pci_release_selected_regions (pdev ,
@@ -802,6 +876,7 @@ static struct pci_driver ngbe_driver = {
802876 .suspend = ngbe_suspend ,
803877 .resume = ngbe_resume ,
804878 .shutdown = ngbe_shutdown ,
879+ .sriov_configure = wx_pci_sriov_configure ,
805880};
806881
807882module_pci_driver (ngbe_driver );
0 commit comments