@@ -199,6 +199,40 @@ struct rteth_ctrl {
199199 struct rteth_tx * tx_data ;
200200};
201201
202+ static void rteth_disable_all_irqs (struct rteth_ctrl * ctrl )
203+ {
204+ int registers = ((ctrl -> r -> rx_rings * 2 + 7 ) / 32 ) + 1 ;
205+
206+ for (int reg = 0 ; reg < registers ; reg ++ ) {
207+ sw_w32 (0 , ctrl -> r -> dma_if_intr_msk + reg * 4 );
208+ sw_w32 (GENMASK (31 , 0 ), ctrl -> r -> dma_if_intr_sts + reg * 4 );
209+ }
210+ }
211+
212+ static void rteth_enable_all_rx_irqs (struct rteth_ctrl * ctrl )
213+ {
214+ int mask , shift , reg ;
215+
216+ /*
217+ * The hardware has several types of interrupts. Basically for rx/tx completion and
218+ * if hardware queues run out. For now the driver only needs notification about new
219+ * incoming packets. Leave everything else disabled.
220+ */
221+ mask = GENMASK (ctrl -> r -> rx_rings - 1 , 0 );
222+ shift = ctrl -> r -> rx_rings % 32 ;
223+ reg = ctrl -> r -> rx_rings / 32 ;
224+ sw_w32_mask (0 , mask << shift , ctrl -> r -> dma_if_intr_msk + reg * 4 );
225+
226+ /*
227+ * RTL839x has additional L2 notification interrupts. Simply activate them. All other
228+ * devices that do not have the feature have adequate reserved bit space and ignore it.
229+ */
230+ mask = GENMASK (2 , 0 );
231+ shift = (ctrl -> r -> rx_rings * 2 + 4 ) % 32 ;
232+ reg = (ctrl -> r -> rx_rings * 2 + 4 ) / 32 ;
233+ sw_w32_mask (0 , mask << shift , ctrl -> r -> dma_if_intr_msk + reg * 4 );
234+ }
235+
202236/* On the RTL93XX, the RTL93XX_DMA_IF_RX_RING_CNTR track the fill level of
203237 * the rings. Writing x into these registers substracts x from its content.
204238 * When the content reaches the ring size, the ASIC no longer adds
@@ -455,10 +489,6 @@ static void rteth_nic_reset(struct rteth_ctrl *ctrl, int reset_mask)
455489
456490static void rteth_838x_hw_reset (struct rteth_ctrl * ctrl )
457491{
458- /* Disable and clear interrupts */
459- sw_w32 (0x00000000 , ctrl -> r -> dma_if_intr_msk );
460- sw_w32 (0xffffffff , ctrl -> r -> dma_if_intr_sts );
461-
462492 rteth_nic_reset (ctrl , 0xc );
463493
464494 /* Free floating rings without space tracking */
@@ -469,10 +499,6 @@ static void rteth_839x_hw_reset(struct rteth_ctrl *ctrl)
469499{
470500 u32 int_saved , nbuf ;
471501
472- /* Disable and clear interrupts */
473- sw_w32 (0x00000000 , ctrl -> r -> dma_if_intr_msk );
474- sw_w32 (0xffffffff , ctrl -> r -> dma_if_intr_sts );
475-
476502 /* Preserve L2 notification and NBUF settings */
477503 int_saved = sw_r32 (ctrl -> r -> dma_if_intr_msk );
478504 nbuf = sw_r32 (RTL839X_DMA_IF_NBUF_BASE_DESC_ADDR_CTRL );
@@ -499,14 +525,6 @@ static void rteth_839x_hw_reset(struct rteth_ctrl *ctrl)
499525
500526static void rteth_93xx_hw_reset (struct rteth_ctrl * ctrl )
501527{
502- /* Disable and clear interrupts */
503- sw_w32 (0x00000000 , ctrl -> r -> dma_if_intr_msk );
504- sw_w32 (0xffffffff , ctrl -> r -> dma_if_intr_sts );
505- sw_w32 (0x00000000 , ctrl -> r -> dma_if_intr_rx_done_msk );
506- sw_w32 (0xffffffff , ctrl -> r -> dma_if_intr_rx_done_sts );
507- sw_w32 (0x00000000 , ctrl -> r -> dma_if_intr_tx_done_msk );
508- sw_w32 (0x0000000f , ctrl -> r -> dma_if_intr_tx_done_sts );
509-
510528 rteth_nic_reset (ctrl , 0x6 );
511529
512530 /* Setup Head of Line */
@@ -580,8 +598,7 @@ static void rtl838x_hw_en_rxtx(struct rteth_ctrl *ctrl)
580598 /* Truncate RX buffer to DEFAULT_MTU bytes, pad TX */
581599 sw_w32 ((DEFAULT_MTU << 16 ) | RX_TRUNCATE_EN_83XX | TX_PAD_EN_838X , ctrl -> r -> dma_if_ctrl );
582600
583- /* Enable RX done and RX overflow, TX done interrupts not needed */
584- sw_w32 (0xffff , ctrl -> r -> dma_if_intr_msk );
601+ rteth_enable_all_rx_irqs (ctrl );
585602
586603 /* Enable DMA, engine expects empty FCS field */
587604 sw_w32_mask (0 , RX_EN | TX_EN , ctrl -> r -> dma_if_ctrl );
@@ -604,8 +621,7 @@ static void rtl839x_hw_en_rxtx(struct rteth_ctrl *ctrl)
604621 /* Setup CPU-Port: RX Buffer */
605622 sw_w32 ((DEFAULT_MTU << 5 ) | RX_TRUNCATE_EN_83XX , ctrl -> r -> dma_if_ctrl );
606623
607- /* Enable Notify, RX done and RX overflow, TX done interrupts not needed */
608- sw_w32 (0x0070ffff , ctrl -> r -> dma_if_intr_msk ); /* Notify IRQ! */
624+ rteth_enable_all_rx_irqs (ctrl );
609625
610626 /* Enable DMA */
611627 sw_w32_mask (0 , RX_EN | TX_EN , ctrl -> r -> dma_if_ctrl );
@@ -640,10 +656,7 @@ static void rtl93xx_hw_en_rxtx(struct rteth_ctrl *ctrl)
640656 sw_w32_mask (0x3ff << pos , v , ctrl -> r -> dma_if_rx_ring_cntr (i ));
641657 }
642658
643- /* Enable Notify, RX done and RX overflow, TX done interrupts not needed */
644- sw_w32 (0xffffffff , ctrl -> r -> dma_if_intr_msk );
645- sw_w32 (0xffffffff , ctrl -> r -> dma_if_intr_rx_done_msk );
646- sw_w32 (0x00000000 , ctrl -> r -> dma_if_intr_tx_done_msk );
659+ rteth_enable_all_rx_irqs (ctrl );
647660
648661 /* Enable DMA */
649662 sw_w32_mask (0 , RX_EN_93XX | TX_EN_93XX , ctrl -> r -> dma_if_ctrl );
@@ -789,7 +802,6 @@ static int rteth_open(struct net_device *ndev)
789802static void rtl838x_hw_stop (struct rteth_ctrl * ctrl )
790803{
791804 u32 force_mac = ctrl -> r -> family_id == RTL8380_FAMILY_ID ? 0x6192C : 0x75 ;
792- u32 clear_irq = ctrl -> r -> family_id == RTL8380_FAMILY_ID ? 0x000fffff : 0x007fffff ;
793805
794806 /* Disable RX/TX from/to CPU-port */
795807 sw_w32_mask (0x3 , 0 , ctrl -> r -> mac_l2_port_ctrl );
@@ -833,18 +845,7 @@ static void rtl838x_hw_stop(struct rteth_ctrl *ctrl)
833845 sw_w32_mask (BIT (0 ) | BIT (9 ), 0 , ctrl -> r -> mac_force_mode_ctrl + ctrl -> r -> cpu_port * 4 );
834846 mdelay (100 );
835847
836- /* Disable all TX/RX interrupts */
837- if (ctrl -> r -> family_id == RTL9300_FAMILY_ID || ctrl -> r -> family_id == RTL9310_FAMILY_ID ) {
838- sw_w32 (0x00000000 , ctrl -> r -> dma_if_intr_msk );
839- sw_w32 (0xffffffff , ctrl -> r -> dma_if_intr_sts );
840- sw_w32 (0x00000000 , ctrl -> r -> dma_if_intr_rx_done_msk );
841- sw_w32 (0xffffffff , ctrl -> r -> dma_if_intr_rx_done_sts );
842- sw_w32 (0x00000000 , ctrl -> r -> dma_if_intr_tx_done_msk );
843- sw_w32 (0x0000000f , ctrl -> r -> dma_if_intr_tx_done_sts );
844- } else {
845- sw_w32 (0x00000000 , ctrl -> r -> dma_if_intr_msk );
846- sw_w32 (clear_irq , ctrl -> r -> dma_if_intr_sts );
847- }
848+ rteth_disable_all_irqs (ctrl );
848849
849850 /* Disable TX/RX DMA */
850851 sw_w32 (0x00000000 , ctrl -> r -> dma_if_ctrl );
@@ -1702,6 +1703,7 @@ static int rtl838x_eth_probe(struct platform_device *pdev)
17021703 if (dev -> irq < 0 )
17031704 return - ENODEV ;
17041705
1706+ rteth_disable_all_irqs (ctrl );
17051707 err = devm_request_irq (& pdev -> dev , dev -> irq , ctrl -> r -> net_irq ,
17061708 IRQF_SHARED , dev -> name , dev );
17071709 if (err ) {
0 commit comments