1111#include <net/ip.h>
1212
1313#include "../libwx/wx_type.h"
14+ #include "../libwx/wx_lib.h"
1415#include "../libwx/wx_hw.h"
1516#include "txgbe_type.h"
1617#include "txgbe_hw.h"
@@ -72,9 +73,158 @@ static int txgbe_enumerate_functions(struct wx *wx)
7273 return physfns ;
7374}
7475
76+ /**
77+ * txgbe_irq_enable - Enable default interrupt generation settings
78+ * @wx: pointer to private structure
79+ * @queues: enable irqs for queues
80+ **/
81+ static void txgbe_irq_enable (struct wx * wx , bool queues )
82+ {
83+ /* unmask interrupt */
84+ wx_intr_enable (wx , TXGBE_INTR_MISC (wx ));
85+ if (queues )
86+ wx_intr_enable (wx , TXGBE_INTR_QALL (wx ));
87+ }
88+
89+ /**
90+ * txgbe_intr - msi/legacy mode Interrupt Handler
91+ * @irq: interrupt number
92+ * @data: pointer to a network interface device structure
93+ **/
94+ static irqreturn_t txgbe_intr (int __always_unused irq , void * data )
95+ {
96+ struct wx_q_vector * q_vector ;
97+ struct wx * wx = data ;
98+ struct pci_dev * pdev ;
99+ u32 eicr ;
100+
101+ q_vector = wx -> q_vector [0 ];
102+ pdev = wx -> pdev ;
103+
104+ eicr = wx_misc_isb (wx , WX_ISB_VEC0 );
105+ if (!eicr ) {
106+ /* shared interrupt alert!
107+ * the interrupt that we masked before the ICR read.
108+ */
109+ if (netif_running (wx -> netdev ))
110+ txgbe_irq_enable (wx , true);
111+ return IRQ_NONE ; /* Not our interrupt */
112+ }
113+ wx -> isb_mem [WX_ISB_VEC0 ] = 0 ;
114+ if (!(pdev -> msi_enabled ))
115+ wr32 (wx , WX_PX_INTA , 1 );
116+
117+ wx -> isb_mem [WX_ISB_MISC ] = 0 ;
118+ /* would disable interrupts here but it is auto disabled */
119+ napi_schedule_irqoff (& q_vector -> napi );
120+
121+ /* re-enable link(maybe) and non-queue interrupts, no flush.
122+ * txgbe_poll will re-enable the queue interrupts
123+ */
124+ if (netif_running (wx -> netdev ))
125+ txgbe_irq_enable (wx , false);
126+
127+ return IRQ_HANDLED ;
128+ }
129+
130+ static irqreturn_t txgbe_msix_other (int __always_unused irq , void * data )
131+ {
132+ struct wx * wx = data ;
133+
134+ /* re-enable the original interrupt state */
135+ if (netif_running (wx -> netdev ))
136+ txgbe_irq_enable (wx , false);
137+
138+ return IRQ_HANDLED ;
139+ }
140+
141+ /**
142+ * txgbe_request_msix_irqs - Initialize MSI-X interrupts
143+ * @wx: board private structure
144+ *
145+ * Allocate MSI-X vectors and request interrupts from the kernel.
146+ **/
147+ static int txgbe_request_msix_irqs (struct wx * wx )
148+ {
149+ struct net_device * netdev = wx -> netdev ;
150+ int vector , err ;
151+
152+ for (vector = 0 ; vector < wx -> num_q_vectors ; vector ++ ) {
153+ struct wx_q_vector * q_vector = wx -> q_vector [vector ];
154+ struct msix_entry * entry = & wx -> msix_entries [vector ];
155+
156+ if (q_vector -> tx .ring && q_vector -> rx .ring )
157+ snprintf (q_vector -> name , sizeof (q_vector -> name ) - 1 ,
158+ "%s-TxRx-%d" , netdev -> name , entry -> entry );
159+ else
160+ /* skip this unused q_vector */
161+ continue ;
162+
163+ err = request_irq (entry -> vector , wx_msix_clean_rings , 0 ,
164+ q_vector -> name , q_vector );
165+ if (err ) {
166+ wx_err (wx , "request_irq failed for MSIX interrupt %s Error: %d\n" ,
167+ q_vector -> name , err );
168+ goto free_queue_irqs ;
169+ }
170+ }
171+
172+ err = request_irq (wx -> msix_entries [vector ].vector ,
173+ txgbe_msix_other , 0 , netdev -> name , wx );
174+ if (err ) {
175+ wx_err (wx , "request_irq for msix_other failed: %d\n" , err );
176+ goto free_queue_irqs ;
177+ }
178+
179+ return 0 ;
180+
181+ free_queue_irqs :
182+ while (vector ) {
183+ vector -- ;
184+ free_irq (wx -> msix_entries [vector ].vector ,
185+ wx -> q_vector [vector ]);
186+ }
187+ wx_reset_interrupt_capability (wx );
188+ return err ;
189+ }
190+
191+ /**
192+ * txgbe_request_irq - initialize interrupts
193+ * @wx: board private structure
194+ *
195+ * Attempt to configure interrupts using the best available
196+ * capabilities of the hardware and kernel.
197+ **/
198+ static int txgbe_request_irq (struct wx * wx )
199+ {
200+ struct net_device * netdev = wx -> netdev ;
201+ struct pci_dev * pdev = wx -> pdev ;
202+ int err ;
203+
204+ if (pdev -> msix_enabled )
205+ err = txgbe_request_msix_irqs (wx );
206+ else if (pdev -> msi_enabled )
207+ err = request_irq (wx -> pdev -> irq , & txgbe_intr , 0 ,
208+ netdev -> name , wx );
209+ else
210+ err = request_irq (wx -> pdev -> irq , & txgbe_intr , IRQF_SHARED ,
211+ netdev -> name , wx );
212+
213+ if (err )
214+ wx_err (wx , "request_irq failed, Error %d\n" , err );
215+
216+ return err ;
217+ }
218+
75219static void txgbe_up_complete (struct wx * wx )
76220{
77221 wx_control_hw (wx , true);
222+ wx_configure_vectors (wx );
223+
224+ /* clear any pending interrupts, may auto mask */
225+ rd32 (wx , WX_PX_IC );
226+ rd32 (wx , WX_PX_MISC_IC );
227+ txgbe_irq_enable (wx , true);
78228}
79229
80230static void txgbe_reset (struct wx * wx )
@@ -104,6 +254,8 @@ static void txgbe_disable_device(struct wx *wx)
104254 netif_carrier_off (netdev );
105255 netif_tx_disable (netdev );
106256
257+ wx_irq_disable (wx );
258+
107259 if (wx -> bus .func < 2 )
108260 wr32m (wx , TXGBE_MIS_PRB_CTL , TXGBE_MIS_PRB_CTL_LAN_UP (wx -> bus .func ), 0 );
109261 else
@@ -132,6 +284,7 @@ static void txgbe_down(struct wx *wx)
132284 **/
133285static int txgbe_sw_init (struct wx * wx )
134286{
287+ u16 msix_count = 0 ;
135288 int err ;
136289
137290 wx -> mac .num_rar_entries = TXGBE_SP_RAR_ENTRIES ;
@@ -156,6 +309,25 @@ static int txgbe_sw_init(struct wx *wx)
156309 break ;
157310 }
158311
312+ /* Set common capability flags and settings */
313+ wx -> max_q_vectors = TXGBE_MAX_MSIX_VECTORS ;
314+ err = wx_get_pcie_msix_counts (wx , & msix_count , TXGBE_MAX_MSIX_VECTORS );
315+ if (err )
316+ wx_err (wx , "Do not support MSI-X\n" );
317+ wx -> mac .max_msix_vectors = msix_count ;
318+
319+ /* enable itr by default in dynamic mode */
320+ wx -> rx_itr_setting = 1 ;
321+ wx -> tx_itr_setting = 1 ;
322+
323+ /* set default ring sizes */
324+ wx -> tx_ring_count = TXGBE_DEFAULT_TXD ;
325+ wx -> rx_ring_count = TXGBE_DEFAULT_RXD ;
326+
327+ /* set default work limits */
328+ wx -> tx_work_limit = TXGBE_DEFAULT_TX_WORK ;
329+ wx -> rx_work_limit = TXGBE_DEFAULT_RX_WORK ;
330+
159331 return 0 ;
160332}
161333
@@ -171,10 +343,28 @@ static int txgbe_sw_init(struct wx *wx)
171343static int txgbe_open (struct net_device * netdev )
172344{
173345 struct wx * wx = netdev_priv (netdev );
346+ int err ;
347+
348+ err = wx_setup_isb_resources (wx );
349+ if (err )
350+ goto err_reset ;
351+
352+ wx_configure (wx );
353+
354+ err = txgbe_request_irq (wx );
355+ if (err )
356+ goto err_free_isb ;
174357
175358 txgbe_up_complete (wx );
176359
177360 return 0 ;
361+
362+ err_free_isb :
363+ wx_free_isb_resources (wx );
364+ err_reset :
365+ txgbe_reset (wx );
366+
367+ return err ;
178368}
179369
180370/**
@@ -187,6 +377,9 @@ static int txgbe_open(struct net_device *netdev)
187377static void txgbe_close_suspend (struct wx * wx )
188378{
189379 txgbe_disable_device (wx );
380+
381+ wx_free_irq (wx );
382+ wx_free_isb_resources (wx );
190383}
191384
192385/**
@@ -205,6 +398,8 @@ static int txgbe_close(struct net_device *netdev)
205398 struct wx * wx = netdev_priv (netdev );
206399
207400 txgbe_down (wx );
401+ wx_free_irq (wx );
402+ wx_free_isb_resources (wx );
208403 wx_control_hw (wx , false);
209404
210405 return 0 ;
@@ -367,6 +562,10 @@ static int txgbe_probe(struct pci_dev *pdev,
367562 eth_hw_addr_set (netdev , wx -> mac .perm_addr );
368563 wx_mac_set_default_filter (wx , wx -> mac .perm_addr );
369564
565+ err = wx_init_interrupt_scheme (wx );
566+ if (err )
567+ goto err_free_mac_table ;
568+
370569 /* Save off EEPROM version number and Option Rom version which
371570 * together make a unique identify for the eeprom
372571 */
@@ -435,6 +634,7 @@ static int txgbe_probe(struct pci_dev *pdev,
435634 return 0 ;
436635
437636err_release_hw :
637+ wx_clear_interrupt_scheme (wx );
438638 wx_control_hw (wx , false);
439639err_free_mac_table :
440640 kfree (wx -> mac_table );
@@ -468,6 +668,7 @@ static void txgbe_remove(struct pci_dev *pdev)
468668 pci_select_bars (pdev , IORESOURCE_MEM ));
469669
470670 kfree (wx -> mac_table );
671+ wx_clear_interrupt_scheme (wx );
471672
472673 pci_disable_pcie_error_reporting (pdev );
473674
0 commit comments