Changeset 47766


Ignore:
Timestamp:
2015-12-04T18:44:06+01:00 (2 years ago)
Author:
nbd
Message:

lantiq: clean up the xrx200 ethernet driver and fix stability issues

Signed-off-by: Felix Fietkau <nbd@…>

Location:
trunk/target/linux/lantiq/patches-4.1
Files:
1 deleted
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/target/linux/lantiq/patches-4.1/0025-NET-MIPS-lantiq-adds-xrx200-net.patch

    r46216 r47766  
    210210--- /dev/null 
    211211+++ b/drivers/net/ethernet/lantiq_xrx200.c 
    212 @@ -0,0 +1,1796 @@ 
     212@@ -0,0 +1,1798 @@ 
    213213+/* 
    214214+ *   This program is free software; you can redistribute it and/or modify it 
     
    356356+#define PMAC_HD_CTL_AS         0x0008 
    357357+#define PMAC_HD_CTL_AC         0x0004 
     358+#define PMAC_HD_CTL_RC         0x0010 
    358359+#define PMAC_HD_CTL_RXSH       0x0040 
    359360+#define PMAC_HD_CTL_AST                0x0080 
     
    10681069+{ 
    10691070+       struct xrx200_priv *priv = netdev_priv(dev); 
    1070 +       unsigned long flags; 
    10711071+       int i; 
    10721072+ 
     
    10741074+               if (!priv->hw->chan[i].dma.irq) 
    10751075+                       continue; 
    1076 +               spin_lock_irqsave(&priv->hw->lock, flags); 
     1076+               spin_lock_bh(&priv->hw->lock); 
    10771077+               if (!priv->hw->chan[i].refcount) { 
    10781078+                       if (XRX200_DMA_IS_RX(i)) 
     
    10811081+               } 
    10821082+               priv->hw->chan[i].refcount++; 
    1083 +               spin_unlock_irqrestore(&priv->hw->lock, flags); 
     1083+               spin_unlock_bh(&priv->hw->lock); 
    10841084+       } 
    10851085+       for (i = 0; i < priv->num_port; i++) 
     
    10941094+{ 
    10951095+       struct xrx200_priv *priv = netdev_priv(dev); 
    1096 +       unsigned long flags; 
    10971096+       int i; 
    10981097+ 
     
    11061105+               if (!priv->hw->chan[i].dma.irq) 
    11071106+                       continue; 
    1108 +               spin_lock_irqsave(&priv->hw->lock, flags); 
     1107+               spin_lock_bh(&priv->hw->lock); 
    11091108+               priv->hw->chan[i].refcount--; 
    11101109+               if (!priv->hw->chan[i].refcount) { 
     
    11131112+                       ltq_dma_close(&priv->hw->chan[XRX200_DMA_RX].dma); 
    11141113+               } 
    1115 +               spin_unlock_irqrestore(&priv->hw->lock, flags); 
     1114+               spin_unlock_bh(&priv->hw->lock); 
    11161115+       } 
    11171116+ 
     
    11241123+       ch->skb[ch->dma.desc] = dev_alloc_skb(XRX200_DMA_DATA_LEN + DMA_PAD); 
    11251124+       if (!ch->skb[ch->dma.desc]) 
    1126 +               return -ENOMEM; 
     1125+               goto skip; 
    11271126+ 
    11281127+       skb_reserve(ch->skb[ch->dma.desc], NET_SKB_PAD); 
     
    11321131+       ch->dma.desc_base[ch->dma.desc].addr = 
    11331132+               CPHYSADDR(ch->skb[ch->dma.desc]->data); 
     1133+       skb_reserve(ch->skb[ch->dma.desc], NET_IP_ALIGN); 
     1134+ 
     1135+skip: 
    11341136+       ch->dma.desc_base[ch->dma.desc].ctl = 
    11351137+               LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) | 
    11361138+               XRX200_DMA_DATA_LEN; 
    1137 +       skb_reserve(ch->skb[ch->dma.desc], NET_IP_ALIGN); 
    11381139+ 
    11391140+       return 0; 
     
    11471148+       struct sk_buff *skb = ch->skb[ch->dma.desc]; 
    11481149+       int len = (desc->ctl & LTQ_DMA_SIZE_MASK); 
    1149 +       unsigned long flags; 
    1150 + 
    1151 +       spin_lock_irqsave(&priv->hw->lock, flags); 
    1152 +       if (xrx200_alloc_skb(ch)) { 
    1153 +               netdev_err(dev, 
    1154 +                       "failed to allocate new rx buffer, stopping DMA\n"); 
    1155 +               ltq_dma_close(&ch->dma); 
    1156 +       } 
     1150+       int ret; 
     1151+ 
     1152+       ret = xrx200_alloc_skb(ch); 
    11571153+ 
    11581154+       ch->dma.desc++; 
    11591155+       ch->dma.desc %= LTQ_DESC_NUM; 
    1160 +       spin_unlock_irqrestore(&priv->hw->lock, flags); 
     1156+ 
     1157+       if (ret) { 
     1158+               netdev_err(dev, 
     1159+                       "failed to allocate new rx buffer\n"); 
     1160+               return 0; 
     1161+       } 
    11611162+ 
    11621163+       skb_put(skb, len); 
     
    11781179+       int rx = 0; 
    11791180+       int complete = 0; 
    1180 +       unsigned long flags; 
    11811181+ 
    11821182+       while ((rx < budget) && !complete) { 
     
    11961196+               } 
    11971197+       } 
     1198+ 
    11981199+       if (complete || !rx) { 
    11991200+               napi_complete(&ch->napi); 
    1200 +               spin_lock_irqsave(&priv->hw->lock, flags); 
    1201 +               ltq_dma_ack_irq(&ch->dma); 
    1202 +               spin_unlock_irqrestore(&priv->hw->lock, flags); 
     1201+               ltq_dma_enable_irq(&ch->dma); 
    12031202+       } 
     1203+ 
    12041204+       return rx; 
    12051205+} 
     
    12091209+       struct xrx200_hw *hw = (struct xrx200_hw *) ptr; 
    12101210+       struct xrx200_chan *ch = &hw->chan[XRX200_DMA_TX]; 
    1211 +       unsigned long flags; 
     1211+       int pkts = 0; 
    12121212+       int i; 
    12131213+ 
    1214 +       spin_lock_irqsave(&hw->lock, flags); 
     1214+       spin_lock_bh(&hw->lock); 
     1215+       ltq_dma_ack_irq(&ch->dma); 
    12151216+       while ((ch->dma.desc_base[ch->tx_free].ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) { 
    1216 +               dev_kfree_skb_any(ch->skb[ch->tx_free]); 
     1217+               struct sk_buff *skb = ch->skb[ch->tx_free]; 
     1218+ 
     1219+               pkts++; 
    12171220+               ch->skb[ch->tx_free] = NULL; 
     1221+               dev_kfree_skb(skb); 
    12181222+               memset(&ch->dma.desc_base[ch->tx_free], 0, 
    12191223+                       sizeof(struct ltq_dma_desc)); 
     
    12211225+               ch->tx_free %= LTQ_DESC_NUM; 
    12221226+       } 
    1223 +       spin_unlock_irqrestore(&hw->lock, flags); 
    1224 + 
    1225 +       for (i = 0; i < XRX200_MAX_DEV && ch->devs[i]; i++) { 
    1226 +               struct netdev_queue *txq = 
    1227 +                       netdev_get_tx_queue(ch->devs[i], 0); 
    1228 +               if (netif_tx_queue_stopped(txq)) 
    1229 +                       netif_tx_start_queue(txq); 
    1230 +       } 
    1231 + 
    1232 +       spin_lock_irqsave(&hw->lock, flags); 
    1233 +       ltq_dma_ack_irq(&ch->dma); 
    1234 +       spin_unlock_irqrestore(&hw->lock, flags); 
     1227+       ltq_dma_enable_irq(&ch->dma); 
     1228+       spin_unlock_bh(&hw->lock); 
     1229+ 
     1230+       if (!pkts) 
     1231+               return; 
     1232+ 
     1233+       for (i = 0; i < XRX200_MAX_DEV && ch->devs[i]; i++) 
     1234+               netif_wake_queue(ch->devs[i]); 
    12351235+} 
    12361236+ 
     
    12541254+static int xrx200_start_xmit(struct sk_buff *skb, struct net_device *dev) 
    12551255+{ 
    1256 +       int queue = skb_get_queue_mapping(skb); 
    1257 +       struct netdev_queue *txq = netdev_get_tx_queue(dev, queue); 
    12581256+       struct xrx200_priv *priv = netdev_priv(dev); 
    12591257+       struct xrx200_chan *ch = &priv->hw->chan[XRX200_DMA_TX]; 
    12601258+       struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc]; 
    1261 +       unsigned long flags; 
    12621259+       u32 byte_offset; 
    12631260+       int len; 
     
    12701267+#endif 
    12711268+ 
     1269+       skb->dev = dev; 
    12721270+       len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; 
    12731271+ 
    12741272+       if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) { 
    12751273+               netdev_err(dev, "tx ring full\n"); 
    1276 +               netif_tx_stop_queue(txq); 
     1274+               netif_stop_queue(dev); 
    12771275+               return NETDEV_TX_BUSY; 
    12781276+       } 
     
    13001298+       dev->trans_start = jiffies; 
    13011299+ 
    1302 +       spin_lock_irqsave(&priv->hw->lock, flags); 
     1300+       spin_lock_bh(&priv->hw->lock); 
    13031301+       desc->addr = ((unsigned int) dma_map_single(NULL, skb->data, len, 
    13041302+                                               DMA_TO_DEVICE)) - byte_offset; 
     
    13081306+       ch->dma.desc++; 
    13091307+       ch->dma.desc %= LTQ_DESC_NUM; 
    1310 +       spin_unlock_irqrestore(&priv->hw->lock, flags); 
    1311 + 
    1312 +       if (ch->dma.desc_base[ch->dma.desc].ctl & LTQ_DMA_OWN) 
    1313 +               netif_tx_stop_queue(txq); 
     1308+       if (ch->dma.desc == ch->tx_free) 
     1309+               netif_stop_queue(dev); 
     1310+ 
     1311+       spin_unlock_bh(&priv->hw->lock); 
    13141312+ 
    13151313+       priv->stats.tx_packets++; 
     
    13221320+{ 
    13231321+       struct xrx200_hw *hw = priv; 
    1324 +       int ch = irq - XRX200_DMA_IRQ; 
    1325 + 
    1326 +       if (ch % 2) 
    1327 +               tasklet_schedule(&hw->chan[ch].tasklet); 
     1322+       int chnr = irq - XRX200_DMA_IRQ; 
     1323+       struct xrx200_chan *ch = &hw->chan[chnr]; 
     1324+ 
     1325+       ltq_dma_disable_irq(&ch->dma); 
     1326+       ltq_dma_ack_irq(&ch->dma); 
     1327+ 
     1328+       if (chnr % 2) 
     1329+               tasklet_schedule(&ch->tasklet); 
    13281330+       else 
    1329 +               napi_schedule(&hw->chan[ch].napi); 
     1331+               napi_schedule(&ch->napi); 
    13301332+ 
    13311333+       return IRQ_HANDLED; 
     
    17151717+       /* enable status header, enable CRC */ 
    17161718+       ltq_pmac_w32_mask(0, 
    1717 +               PMAC_HD_CTL_RST | PMAC_HD_CTL_AST | PMAC_HD_CTL_RXSH | PMAC_HD_CTL_AS | PMAC_HD_CTL_AC, 
     1719+               PMAC_HD_CTL_RST | PMAC_HD_CTL_AST | PMAC_HD_CTL_RXSH | PMAC_HD_CTL_AS | PMAC_HD_CTL_AC | PMAC_HD_CTL_RC, 
    17181720+               PMAC_HD_CTL); 
    17191721+#else 
    17201722+       /* disable status header, enable CRC */ 
    17211723+       ltq_pmac_w32_mask(PMAC_HD_CTL_AST | PMAC_HD_CTL_RXSH | PMAC_HD_CTL_AS, 
    1722 +               PMAC_HD_CTL_AC, 
     1724+               PMAC_HD_CTL_AC | PMAC_HD_CTL_RC, 
    17231725+               PMAC_HD_CTL); 
    17241726+#endif 
Note: See TracChangeset for help on using the changeset viewer.