Loading drivers/net/mv643xx_eth.c +225 −216 Original line number Diff line number Diff line Loading @@ -73,13 +73,7 @@ static char mv643xx_eth_driver_version[] = "1.0"; #define MAX_DESCS_PER_SKB 1 #endif #define ETH_VLAN_HLEN 4 #define ETH_FCS_LEN 4 #define ETH_HW_IP_ALIGN 2 /* hw aligns IP header */ #define ETH_WRAPPER_LEN (ETH_HW_IP_ALIGN + ETH_HLEN + \ ETH_VLAN_HLEN + ETH_FCS_LEN) #define ETH_RX_SKB_SIZE (dev->mtu + ETH_WRAPPER_LEN + \ dma_get_cache_alignment()) #define ETH_HW_IP_ALIGN 2 /* * Registers shared between all ports. Loading Loading @@ -288,22 +282,32 @@ struct mib_counters { u32 late_collision; }; struct rx_queue { int rx_ring_size; int rx_desc_count; int rx_curr_desc; int rx_used_desc; struct rx_desc *rx_desc_area; dma_addr_t rx_desc_dma; int rx_desc_area_size; struct sk_buff **rx_skb; struct timer_list rx_oom; }; struct mv643xx_eth_private { struct mv643xx_eth_shared_private *shared; int port_num; /* User Ethernet port number */ struct mv643xx_eth_shared_private *shared_smi; u32 rx_sram_addr; /* Base address of rx sram area */ u32 rx_sram_size; /* Size of rx sram area */ u32 tx_sram_addr; /* Base address of tx sram area */ u32 tx_sram_size; /* Size of tx sram area */ /* Tx/Rx rings managment indexes fields. For driver use */ /* Next available and first returning Rx resource */ int rx_curr_desc, rx_used_desc; /* Next available and first returning Tx resource */ int tx_curr_desc, tx_used_desc; Loading @@ -311,11 +315,6 @@ struct mv643xx_eth_private { u32 tx_clean_threshold; #endif struct rx_desc *rx_desc_area; dma_addr_t rx_desc_dma; int rx_desc_area_size; struct sk_buff **rx_skb; struct tx_desc *tx_desc_area; dma_addr_t tx_desc_dma; int tx_desc_area_size; Loading @@ -324,27 +323,25 @@ struct mv643xx_eth_private { struct work_struct tx_timeout_task; struct net_device *dev; struct napi_struct napi; struct mib_counters mib_counters; spinlock_t lock; /* Size of Tx Ring per queue */ int tx_ring_size; /* Number of tx descriptors in use */ int tx_desc_count; /* Size of Rx Ring per queue */ int rx_ring_size; /* Number of rx descriptors in use */ int rx_desc_count; /* * Used in case RX Ring is empty, which can be caused when * system does not have resources (skb's) */ struct timer_list timeout; u32 rx_int_coal; u32 tx_int_coal; struct mii_if_info mii; /* * RX state. */ int default_rx_ring_size; unsigned long rx_desc_sram_addr; int rx_desc_sram_size; struct napi_struct napi; struct rx_queue rxq[1]; }; Loading @@ -361,32 +358,27 @@ static inline void wrl(struct mv643xx_eth_private *mp, int offset, u32 data) /* rxq/txq helper functions *************************************************/ static void mv643xx_eth_port_enable_rx(struct mv643xx_eth_private *mp, unsigned int queues) static struct mv643xx_eth_private *rxq_to_mp(struct rx_queue *rxq) { wrl(mp, RXQ_COMMAND(mp->port_num), queues); return container_of(rxq, struct mv643xx_eth_private, rxq[0]); } static unsigned int mv643xx_eth_port_disable_rx(struct mv643xx_eth_private *mp) static void rxq_enable(struct rx_queue *rxq) { unsigned int port_num = mp->port_num; u32 queues; struct mv643xx_eth_private *mp = rxq_to_mp(rxq); wrl(mp, RXQ_COMMAND(mp->port_num), 1); } /* Stop Rx port activity. Check port Rx activity. */ queues = rdl(mp, RXQ_COMMAND(port_num)) & 0xFF; if (queues) { /* Issue stop command for active queues only */ wrl(mp, RXQ_COMMAND(port_num), (queues << 8)); static void rxq_disable(struct rx_queue *rxq) { struct mv643xx_eth_private *mp = rxq_to_mp(rxq); u8 mask = 1; /* Wait for all Rx activity to terminate. */ /* Check port cause register that all Rx queues are stopped */ while (rdl(mp, RXQ_COMMAND(port_num)) & 0xFF) wrl(mp, RXQ_COMMAND(mp->port_num), mask << 8); while (rdl(mp, RXQ_COMMAND(mp->port_num)) & mask) udelay(10); } return queues; } static void mv643xx_eth_port_enable_tx(struct mv643xx_eth_private *mp, unsigned int queues) { Loading Loading @@ -421,19 +413,29 @@ static unsigned int mv643xx_eth_port_disable_tx(struct mv643xx_eth_private *mp) /* rx ***********************************************************************/ static void mv643xx_eth_free_completed_tx_descs(struct net_device *dev); static void mv643xx_eth_rx_refill_descs(struct net_device *dev) static void rxq_refill(struct rx_queue *rxq) { struct mv643xx_eth_private *mp = netdev_priv(dev); struct mv643xx_eth_private *mp = rxq_to_mp(rxq); unsigned long flags; spin_lock_irqsave(&mp->lock, flags); while (mp->rx_desc_count < mp->rx_ring_size) { while (rxq->rx_desc_count < rxq->rx_ring_size) { int skb_size; struct sk_buff *skb; int unaligned; int rx; skb = dev_alloc_skb(ETH_RX_SKB_SIZE + dma_get_cache_alignment()); /* * Reserve 2+14 bytes for an ethernet header (the * hardware automatically prepends 2 bytes of dummy * data to each received packet), 4 bytes for a VLAN * header, and 4 bytes for the trailing FCS -- 24 * bytes total. */ skb_size = mp->dev->mtu + 24; skb = dev_alloc_skb(skb_size + dma_get_cache_alignment() - 1); if (skb == NULL) break; Loading @@ -441,44 +443,43 @@ static void mv643xx_eth_rx_refill_descs(struct net_device *dev) if (unaligned) skb_reserve(skb, dma_get_cache_alignment() - unaligned); mp->rx_desc_count++; rx = mp->rx_used_desc; mp->rx_used_desc = (rx + 1) % mp->rx_ring_size; rxq->rx_desc_count++; rx = rxq->rx_used_desc; rxq->rx_used_desc = (rx + 1) % rxq->rx_ring_size; mp->rx_desc_area[rx].buf_ptr = dma_map_single(NULL, skb->data, ETH_RX_SKB_SIZE, DMA_FROM_DEVICE); mp->rx_desc_area[rx].buf_size = ETH_RX_SKB_SIZE; mp->rx_skb[rx] = skb; rxq->rx_desc_area[rx].buf_ptr = dma_map_single(NULL, skb->data, skb_size, DMA_FROM_DEVICE); rxq->rx_desc_area[rx].buf_size = skb_size; rxq->rx_skb[rx] = skb; wmb(); mp->rx_desc_area[rx].cmd_sts = BUFFER_OWNED_BY_DMA | rxq->rx_desc_area[rx].cmd_sts = BUFFER_OWNED_BY_DMA | RX_ENABLE_INTERRUPT; wmb(); skb_reserve(skb, ETH_HW_IP_ALIGN); } if (mp->rx_desc_count == 0) { mp->timeout.expires = jiffies + (HZ / 10); add_timer(&mp->timeout); if (rxq->rx_desc_count == 0) { rxq->rx_oom.expires = jiffies + (HZ / 10); add_timer(&rxq->rx_oom); } spin_unlock_irqrestore(&mp->lock, flags); } static inline void mv643xx_eth_rx_refill_descs_timer_wrapper(unsigned long data) static inline void rxq_refill_timer_wrapper(unsigned long data) { mv643xx_eth_rx_refill_descs((struct net_device *)data); rxq_refill((struct rx_queue *)data); } static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) static int rxq_process(struct rx_queue *rxq, int budget) { struct mv643xx_eth_private *mp = netdev_priv(dev); struct net_device_stats *stats = &dev->stats; unsigned int received_packets = 0; struct mv643xx_eth_private *mp = rxq_to_mp(rxq); struct net_device_stats *stats = &mp->dev->stats; int rx; while (budget-- > 0) { rx = 0; while (rx < budget) { struct sk_buff *skb; volatile struct rx_desc *rx_desc; unsigned int cmd_sts; Loading @@ -486,7 +487,7 @@ static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) spin_lock_irqsave(&mp->lock, flags); rx_desc = &mp->rx_desc_area[mp->rx_curr_desc]; rx_desc = &rxq->rx_desc_area[rxq->rx_curr_desc]; cmd_sts = rx_desc->cmd_sts; if (cmd_sts & BUFFER_OWNED_BY_DMA) { Loading @@ -495,17 +496,17 @@ static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) } rmb(); skb = mp->rx_skb[mp->rx_curr_desc]; mp->rx_skb[mp->rx_curr_desc] = NULL; skb = rxq->rx_skb[rxq->rx_curr_desc]; rxq->rx_skb[rxq->rx_curr_desc] = NULL; mp->rx_curr_desc = (mp->rx_curr_desc + 1) % mp->rx_ring_size; rxq->rx_curr_desc = (rxq->rx_curr_desc + 1) % rxq->rx_ring_size; spin_unlock_irqrestore(&mp->lock, flags); dma_unmap_single(NULL, rx_desc->buf_ptr + ETH_HW_IP_ALIGN, ETH_RX_SKB_SIZE, DMA_FROM_DEVICE); mp->rx_desc_count--; received_packets++; mp->dev->mtu + 24, DMA_FROM_DEVICE); rxq->rx_desc_count--; rx++; /* * Update statistics. Loading @@ -528,7 +529,7 @@ static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) printk(KERN_ERR "%s: Received packet spread " "on multiple descriptors\n", dev->name); mp->dev->name); } if (cmd_sts & ERROR_SUMMARY) stats->rx_errors++; Loading @@ -546,48 +547,45 @@ static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) skb->csum = htons( (cmd_sts & 0x0007fff8) >> 3); } skb->protocol = eth_type_trans(skb, dev); skb->protocol = eth_type_trans(skb, mp->dev); #ifdef MV643XX_ETH_NAPI netif_receive_skb(skb); #else netif_rx(skb); #endif } dev->last_rx = jiffies; mp->dev->last_rx = jiffies; } mv643xx_eth_rx_refill_descs(dev); /* Fill RX ring with skb's */ rxq_refill(rxq); return received_packets; return rx; } #ifdef MV643XX_ETH_NAPI static int mv643xx_eth_poll(struct napi_struct *napi, int budget) { struct mv643xx_eth_private *mp = container_of(napi, struct mv643xx_eth_private, napi); struct net_device *dev = mp->dev; unsigned int port_num = mp->port_num; int work_done; struct mv643xx_eth_private *mp; int rx; mp = container_of(napi, struct mv643xx_eth_private, napi); #ifdef MV643XX_ETH_TX_FAST_REFILL if (++mp->tx_clean_threshold > 5) { mv643xx_eth_free_completed_tx_descs(dev); mv643xx_eth_free_completed_tx_descs(mp->dev); mp->tx_clean_threshold = 0; } #endif work_done = 0; if ((rdl(mp, RXQ_CURRENT_DESC_PTR(port_num))) != (u32) mp->rx_used_desc) work_done = mv643xx_eth_receive_queue(dev, budget); rx = rxq_process(mp->rxq, budget); if (work_done < budget) { netif_rx_complete(dev, napi); wrl(mp, INT_CAUSE(port_num), 0); wrl(mp, INT_CAUSE_EXT(port_num), 0); wrl(mp, INT_MASK(port_num), INT_RX | INT_EXT); if (rx < budget) { netif_rx_complete(mp->dev, napi); wrl(mp, INT_CAUSE(mp->port_num), 0); wrl(mp, INT_CAUSE_EXT(mp->port_num), 0); wrl(mp, INT_MASK(mp->port_num), INT_RX | INT_EXT); } return work_done; return rx; } #endif Loading Loading @@ -1252,53 +1250,102 @@ static void mv643xx_eth_set_rx_mode(struct net_device *dev) /* rx/tx queue initialisation ***********************************************/ static void ether_init_rx_desc_ring(struct mv643xx_eth_private *mp) static int rxq_init(struct mv643xx_eth_private *mp) { volatile struct rx_desc *p_rx_desc; int rx_desc_num = mp->rx_ring_size; struct rx_queue *rxq = mp->rxq; struct rx_desc *rx_desc; int size; int i; /* initialize the next_desc_ptr links in the Rx descriptors ring */ p_rx_desc = (struct rx_desc *)mp->rx_desc_area; for (i = 0; i < rx_desc_num; i++) { p_rx_desc[i].next_desc_ptr = mp->rx_desc_dma + ((i + 1) % rx_desc_num) * sizeof(struct rx_desc); rxq->rx_ring_size = mp->default_rx_ring_size; rxq->rx_desc_count = 0; rxq->rx_curr_desc = 0; rxq->rx_used_desc = 0; size = rxq->rx_ring_size * sizeof(struct rx_desc); if (size <= mp->rx_desc_sram_size) { rxq->rx_desc_area = ioremap(mp->rx_desc_sram_addr, mp->rx_desc_sram_size); rxq->rx_desc_dma = mp->rx_desc_sram_addr; } else { rxq->rx_desc_area = dma_alloc_coherent(NULL, size, &rxq->rx_desc_dma, GFP_KERNEL); } if (rxq->rx_desc_area == NULL) { dev_printk(KERN_ERR, &mp->dev->dev, "can't allocate rx ring (%d bytes)\n", size); goto out; } memset(rxq->rx_desc_area, 0, size); rxq->rx_desc_area_size = size; rxq->rx_skb = kmalloc(rxq->rx_ring_size * sizeof(*rxq->rx_skb), GFP_KERNEL); if (rxq->rx_skb == NULL) { dev_printk(KERN_ERR, &mp->dev->dev, "can't allocate rx skb ring\n"); goto out_free; } rx_desc = (struct rx_desc *)rxq->rx_desc_area; for (i = 0; i < rxq->rx_ring_size; i++) { int nexti = (i + 1) % rxq->rx_ring_size; rx_desc[i].next_desc_ptr = rxq->rx_desc_dma + nexti * sizeof(struct rx_desc); } /* Save Rx desc pointer to driver struct. */ mp->rx_curr_desc = 0; mp->rx_used_desc = 0; init_timer(&rxq->rx_oom); rxq->rx_oom.data = (unsigned long)rxq; rxq->rx_oom.function = rxq_refill_timer_wrapper; mp->rx_desc_area_size = rx_desc_num * sizeof(struct rx_desc); return 0; out_free: if (size <= mp->rx_desc_sram_size) iounmap(rxq->rx_desc_area); else dma_free_coherent(NULL, size, rxq->rx_desc_area, rxq->rx_desc_dma); out: return -ENOMEM; } static void mv643xx_eth_free_rx_rings(struct net_device *dev) static void rxq_deinit(struct rx_queue *rxq) { struct mv643xx_eth_private *mp = netdev_priv(dev); int curr; struct mv643xx_eth_private *mp = rxq_to_mp(rxq); int i; rxq_disable(rxq); /* Stop RX Queues */ mv643xx_eth_port_disable_rx(mp); del_timer_sync(&rxq->rx_oom); /* Free preallocated skb's on RX rings */ for (curr = 0; mp->rx_desc_count && curr < mp->rx_ring_size; curr++) { if (mp->rx_skb[curr]) { dev_kfree_skb(mp->rx_skb[curr]); mp->rx_desc_count--; for (i = 0; i < rxq->rx_ring_size; i++) { if (rxq->rx_skb[i]) { dev_kfree_skb(rxq->rx_skb[i]); rxq->rx_desc_count--; } } if (mp->rx_desc_count) printk(KERN_ERR "%s: Error in freeing Rx Ring. %d skb's still" " stuck in RX Ring - ignoring them\n", dev->name, mp->rx_desc_count); /* Free RX ring */ if (mp->rx_sram_size) iounmap(mp->rx_desc_area); if (rxq->rx_desc_count) { dev_printk(KERN_ERR, &mp->dev->dev, "error freeing rx ring -- %d skbs stuck\n", rxq->rx_desc_count); } if (rxq->rx_desc_area_size <= mp->rx_desc_sram_size) iounmap(rxq->rx_desc_area); else dma_free_coherent(NULL, mp->rx_desc_area_size, mp->rx_desc_area, mp->rx_desc_dma); dma_free_coherent(NULL, rxq->rx_desc_area_size, rxq->rx_desc_area, rxq->rx_desc_dma); kfree(rxq->rx_skb); } static void ether_init_tx_desc_ring(struct mv643xx_eth_private *mp) Loading Loading @@ -1510,7 +1557,7 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id) } #else if (int_cause & INT_RX) mv643xx_eth_receive_queue(dev, INT_MAX); rxq_process(mp->rxq, INT_MAX); #endif if (int_cause_ext & INT_EXT_TX) mv643xx_eth_free_completed_tx_descs(dev); Loading Loading @@ -1544,20 +1591,30 @@ static void phy_reset(struct mv643xx_eth_private *mp) static void port_start(struct net_device *dev) { struct mv643xx_eth_private *mp = netdev_priv(dev); unsigned int port_num = mp->port_num; int tx_curr_desc, rx_curr_desc; u32 pscr; struct ethtool_cmd ethtool_cmd; int i; /* Assignment of Tx CTRP of given queue */ tx_curr_desc = mp->tx_curr_desc; wrl(mp, TXQ_CURRENT_DESC_PTR(port_num), (u32)((struct tx_desc *)mp->tx_desc_dma + tx_curr_desc)); /* * Configure basic link parameters. */ pscr = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num)); pscr &= ~(SERIAL_PORT_ENABLE | FORCE_LINK_PASS); wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr); pscr |= DISABLE_AUTO_NEG_FOR_FLOW_CTRL | DISABLE_AUTO_NEG_SPEED_GMII | DISABLE_AUTO_NEG_FOR_DUPLEX | DO_NOT_FORCE_LINK_FAIL | SERIAL_PORT_CONTROL_RESERVED; wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr); pscr |= SERIAL_PORT_ENABLE; wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr); /* Assignment of Rx CRDP of given queue */ rx_curr_desc = mp->rx_curr_desc; wrl(mp, RXQ_CURRENT_DESC_PTR(port_num), (u32)((struct rx_desc *)mp->rx_desc_dma + rx_curr_desc)); wrl(mp, SDMA_CONFIG(mp->port_num), PORT_SDMA_CONFIG_DEFAULT_VALUE); mv643xx_eth_get_settings(dev, ðtool_cmd); phy_reset(mp); mv643xx_eth_set_settings(dev, ðtool_cmd); /* Add the assigned Ethernet address to the port's address table */ uc_addr_set(mp, dev->dev_addr); Loading @@ -1566,42 +1623,34 @@ static void port_start(struct net_device *dev) * Receive all unmatched unicast, TCP, UDP, BPDU and broadcast * frames to RX queue #0. */ wrl(mp, PORT_CONFIG(port_num), 0x00000000); wrl(mp, PORT_CONFIG(mp->port_num), 0x00000000); /* * Treat BPDUs as normal multicasts, and disable partition mode. */ wrl(mp, PORT_CONFIG_EXT(port_num), 0x00000000); wrl(mp, PORT_CONFIG_EXT(mp->port_num), 0x00000000); pscr = rdl(mp, PORT_SERIAL_CONTROL(port_num)); pscr &= ~(SERIAL_PORT_ENABLE | FORCE_LINK_PASS); wrl(mp, PORT_SERIAL_CONTROL(port_num), pscr); pscr |= DISABLE_AUTO_NEG_FOR_FLOW_CTRL | DISABLE_AUTO_NEG_SPEED_GMII | DISABLE_AUTO_NEG_FOR_DUPLEX | DO_NOT_FORCE_LINK_FAIL | SERIAL_PORT_CONTROL_RESERVED; /* * Enable the receive queue. */ for (i = 0; i < 1; i++) { struct rx_queue *rxq = mp->rxq; int off = RXQ_CURRENT_DESC_PTR(mp->port_num); u32 addr; wrl(mp, PORT_SERIAL_CONTROL(port_num), pscr); addr = (u32)rxq->rx_desc_dma; addr += rxq->rx_curr_desc * sizeof(struct rx_desc); wrl(mp, off, addr); pscr |= SERIAL_PORT_ENABLE; wrl(mp, PORT_SERIAL_CONTROL(port_num), pscr); rxq_enable(rxq); } /* Assign port SDMA configuration */ wrl(mp, SDMA_CONFIG(port_num), PORT_SDMA_CONFIG_DEFAULT_VALUE); /* Enable port Rx. */ mv643xx_eth_port_enable_rx(mp, 1); wrl(mp, TXQ_CURRENT_DESC_PTR(mp->port_num), (u32)((struct tx_desc *)mp->tx_desc_dma + mp->tx_curr_desc)); /* Disable port bandwidth limits by clearing MTU register */ wrl(mp, TX_BW_MTU(port_num), 0); /* save phy settings across reset */ mv643xx_eth_get_settings(dev, ðtool_cmd); phy_reset(mp); mv643xx_eth_set_settings(dev, ðtool_cmd); wrl(mp, TX_BW_MTU(mp->port_num), 0); } #ifdef MV643XX_ETH_COAL Loading Loading @@ -1661,18 +1710,11 @@ static int mv643xx_eth_open(struct net_device *dev) port_init(mp); memset(&mp->timeout, 0, sizeof(struct timer_list)); mp->timeout.function = mv643xx_eth_rx_refill_descs_timer_wrapper; mp->timeout.data = (unsigned long)dev; /* Allocate RX and TX skb rings */ mp->rx_skb = kmalloc(sizeof(*mp->rx_skb) * mp->rx_ring_size, GFP_KERNEL); if (!mp->rx_skb) { printk(KERN_ERR "%s: Cannot allocate Rx skb ring\n", dev->name); err = -ENOMEM; err = rxq_init(mp); if (err) goto out_free_irq; } rxq_refill(mp->rxq); mp->tx_skb = kmalloc(sizeof(*mp->tx_skb) * mp->tx_ring_size, GFP_KERNEL); if (!mp->tx_skb) { Loading Loading @@ -1706,39 +1748,6 @@ static int mv643xx_eth_open(struct net_device *dev) ether_init_tx_desc_ring(mp); /* Allocate RX ring */ mp->rx_desc_count = 0; size = mp->rx_ring_size * sizeof(struct rx_desc); mp->rx_desc_area_size = size; if (mp->rx_sram_size) { mp->rx_desc_area = ioremap(mp->rx_sram_addr, mp->rx_sram_size); mp->rx_desc_dma = mp->rx_sram_addr; } else mp->rx_desc_area = dma_alloc_coherent(NULL, size, &mp->rx_desc_dma, GFP_KERNEL); if (!mp->rx_desc_area) { printk(KERN_ERR "%s: Cannot allocate Rx ring (size %d bytes)\n", dev->name, size); printk(KERN_ERR "%s: Freeing previously allocated TX queues...", dev->name); if (mp->rx_sram_size) iounmap(mp->tx_desc_area); else dma_free_coherent(NULL, mp->tx_desc_area_size, mp->tx_desc_area, mp->tx_desc_dma); err = -ENOMEM; goto out_free_tx_skb; } memset((void *)mp->rx_desc_area, 0, size); ether_init_rx_desc_ring(mp); mv643xx_eth_rx_refill_descs(dev); /* Fill RX ring with skb's */ #ifdef MV643XX_ETH_NAPI napi_enable(&mp->napi); #endif Loading @@ -1764,7 +1773,7 @@ static int mv643xx_eth_open(struct net_device *dev) out_free_tx_skb: kfree(mp->tx_skb); out_free_rx_skb: kfree(mp->rx_skb); rxq_deinit(mp->rxq); out_free_irq: free_irq(dev->irq, dev); Loading @@ -1777,7 +1786,7 @@ static void port_reset(struct mv643xx_eth_private *mp) unsigned int reg_data; mv643xx_eth_port_disable_tx(mp); mv643xx_eth_port_disable_rx(mp); rxq_disable(mp->rxq); /* Clear all MIB counters */ clear_mib_counters(mp); Loading Loading @@ -1809,7 +1818,7 @@ static int mv643xx_eth_stop(struct net_device *dev) port_reset(mp); mv643xx_eth_free_tx_rings(dev); mv643xx_eth_free_rx_rings(dev); rxq_deinit(mp->rxq); free_irq(dev->irq, dev); Loading Loading @@ -2162,7 +2171,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev) /* set default config values */ uc_addr_get(mp, dev->dev_addr); mp->rx_ring_size = DEFAULT_RX_QUEUE_SIZE; mp->tx_ring_size = DEFAULT_TX_QUEUE_SIZE; if (is_valid_ether_addr(pd->mac_addr)) Loading @@ -2171,8 +2179,9 @@ static int mv643xx_eth_probe(struct platform_device *pdev) if (pd->phy_addr || pd->force_phy_addr) phy_addr_set(mp, pd->phy_addr); mp->default_rx_ring_size = DEFAULT_RX_QUEUE_SIZE; if (pd->rx_queue_size) mp->rx_ring_size = pd->rx_queue_size; mp->default_rx_ring_size = pd->rx_queue_size; if (pd->tx_queue_size) mp->tx_ring_size = pd->tx_queue_size; Loading @@ -2183,8 +2192,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev) } if (pd->rx_sram_size) { mp->rx_sram_size = pd->rx_sram_size; mp->rx_sram_addr = pd->rx_sram_addr; mp->rx_desc_sram_addr = pd->rx_sram_addr; mp->rx_desc_sram_size = pd->rx_sram_size; } duplex = pd->duplex; Loading Loading
drivers/net/mv643xx_eth.c +225 −216 Original line number Diff line number Diff line Loading @@ -73,13 +73,7 @@ static char mv643xx_eth_driver_version[] = "1.0"; #define MAX_DESCS_PER_SKB 1 #endif #define ETH_VLAN_HLEN 4 #define ETH_FCS_LEN 4 #define ETH_HW_IP_ALIGN 2 /* hw aligns IP header */ #define ETH_WRAPPER_LEN (ETH_HW_IP_ALIGN + ETH_HLEN + \ ETH_VLAN_HLEN + ETH_FCS_LEN) #define ETH_RX_SKB_SIZE (dev->mtu + ETH_WRAPPER_LEN + \ dma_get_cache_alignment()) #define ETH_HW_IP_ALIGN 2 /* * Registers shared between all ports. Loading Loading @@ -288,22 +282,32 @@ struct mib_counters { u32 late_collision; }; struct rx_queue { int rx_ring_size; int rx_desc_count; int rx_curr_desc; int rx_used_desc; struct rx_desc *rx_desc_area; dma_addr_t rx_desc_dma; int rx_desc_area_size; struct sk_buff **rx_skb; struct timer_list rx_oom; }; struct mv643xx_eth_private { struct mv643xx_eth_shared_private *shared; int port_num; /* User Ethernet port number */ struct mv643xx_eth_shared_private *shared_smi; u32 rx_sram_addr; /* Base address of rx sram area */ u32 rx_sram_size; /* Size of rx sram area */ u32 tx_sram_addr; /* Base address of tx sram area */ u32 tx_sram_size; /* Size of tx sram area */ /* Tx/Rx rings managment indexes fields. For driver use */ /* Next available and first returning Rx resource */ int rx_curr_desc, rx_used_desc; /* Next available and first returning Tx resource */ int tx_curr_desc, tx_used_desc; Loading @@ -311,11 +315,6 @@ struct mv643xx_eth_private { u32 tx_clean_threshold; #endif struct rx_desc *rx_desc_area; dma_addr_t rx_desc_dma; int rx_desc_area_size; struct sk_buff **rx_skb; struct tx_desc *tx_desc_area; dma_addr_t tx_desc_dma; int tx_desc_area_size; Loading @@ -324,27 +323,25 @@ struct mv643xx_eth_private { struct work_struct tx_timeout_task; struct net_device *dev; struct napi_struct napi; struct mib_counters mib_counters; spinlock_t lock; /* Size of Tx Ring per queue */ int tx_ring_size; /* Number of tx descriptors in use */ int tx_desc_count; /* Size of Rx Ring per queue */ int rx_ring_size; /* Number of rx descriptors in use */ int rx_desc_count; /* * Used in case RX Ring is empty, which can be caused when * system does not have resources (skb's) */ struct timer_list timeout; u32 rx_int_coal; u32 tx_int_coal; struct mii_if_info mii; /* * RX state. */ int default_rx_ring_size; unsigned long rx_desc_sram_addr; int rx_desc_sram_size; struct napi_struct napi; struct rx_queue rxq[1]; }; Loading @@ -361,32 +358,27 @@ static inline void wrl(struct mv643xx_eth_private *mp, int offset, u32 data) /* rxq/txq helper functions *************************************************/ static void mv643xx_eth_port_enable_rx(struct mv643xx_eth_private *mp, unsigned int queues) static struct mv643xx_eth_private *rxq_to_mp(struct rx_queue *rxq) { wrl(mp, RXQ_COMMAND(mp->port_num), queues); return container_of(rxq, struct mv643xx_eth_private, rxq[0]); } static unsigned int mv643xx_eth_port_disable_rx(struct mv643xx_eth_private *mp) static void rxq_enable(struct rx_queue *rxq) { unsigned int port_num = mp->port_num; u32 queues; struct mv643xx_eth_private *mp = rxq_to_mp(rxq); wrl(mp, RXQ_COMMAND(mp->port_num), 1); } /* Stop Rx port activity. Check port Rx activity. */ queues = rdl(mp, RXQ_COMMAND(port_num)) & 0xFF; if (queues) { /* Issue stop command for active queues only */ wrl(mp, RXQ_COMMAND(port_num), (queues << 8)); static void rxq_disable(struct rx_queue *rxq) { struct mv643xx_eth_private *mp = rxq_to_mp(rxq); u8 mask = 1; /* Wait for all Rx activity to terminate. */ /* Check port cause register that all Rx queues are stopped */ while (rdl(mp, RXQ_COMMAND(port_num)) & 0xFF) wrl(mp, RXQ_COMMAND(mp->port_num), mask << 8); while (rdl(mp, RXQ_COMMAND(mp->port_num)) & mask) udelay(10); } return queues; } static void mv643xx_eth_port_enable_tx(struct mv643xx_eth_private *mp, unsigned int queues) { Loading Loading @@ -421,19 +413,29 @@ static unsigned int mv643xx_eth_port_disable_tx(struct mv643xx_eth_private *mp) /* rx ***********************************************************************/ static void mv643xx_eth_free_completed_tx_descs(struct net_device *dev); static void mv643xx_eth_rx_refill_descs(struct net_device *dev) static void rxq_refill(struct rx_queue *rxq) { struct mv643xx_eth_private *mp = netdev_priv(dev); struct mv643xx_eth_private *mp = rxq_to_mp(rxq); unsigned long flags; spin_lock_irqsave(&mp->lock, flags); while (mp->rx_desc_count < mp->rx_ring_size) { while (rxq->rx_desc_count < rxq->rx_ring_size) { int skb_size; struct sk_buff *skb; int unaligned; int rx; skb = dev_alloc_skb(ETH_RX_SKB_SIZE + dma_get_cache_alignment()); /* * Reserve 2+14 bytes for an ethernet header (the * hardware automatically prepends 2 bytes of dummy * data to each received packet), 4 bytes for a VLAN * header, and 4 bytes for the trailing FCS -- 24 * bytes total. */ skb_size = mp->dev->mtu + 24; skb = dev_alloc_skb(skb_size + dma_get_cache_alignment() - 1); if (skb == NULL) break; Loading @@ -441,44 +443,43 @@ static void mv643xx_eth_rx_refill_descs(struct net_device *dev) if (unaligned) skb_reserve(skb, dma_get_cache_alignment() - unaligned); mp->rx_desc_count++; rx = mp->rx_used_desc; mp->rx_used_desc = (rx + 1) % mp->rx_ring_size; rxq->rx_desc_count++; rx = rxq->rx_used_desc; rxq->rx_used_desc = (rx + 1) % rxq->rx_ring_size; mp->rx_desc_area[rx].buf_ptr = dma_map_single(NULL, skb->data, ETH_RX_SKB_SIZE, DMA_FROM_DEVICE); mp->rx_desc_area[rx].buf_size = ETH_RX_SKB_SIZE; mp->rx_skb[rx] = skb; rxq->rx_desc_area[rx].buf_ptr = dma_map_single(NULL, skb->data, skb_size, DMA_FROM_DEVICE); rxq->rx_desc_area[rx].buf_size = skb_size; rxq->rx_skb[rx] = skb; wmb(); mp->rx_desc_area[rx].cmd_sts = BUFFER_OWNED_BY_DMA | rxq->rx_desc_area[rx].cmd_sts = BUFFER_OWNED_BY_DMA | RX_ENABLE_INTERRUPT; wmb(); skb_reserve(skb, ETH_HW_IP_ALIGN); } if (mp->rx_desc_count == 0) { mp->timeout.expires = jiffies + (HZ / 10); add_timer(&mp->timeout); if (rxq->rx_desc_count == 0) { rxq->rx_oom.expires = jiffies + (HZ / 10); add_timer(&rxq->rx_oom); } spin_unlock_irqrestore(&mp->lock, flags); } static inline void mv643xx_eth_rx_refill_descs_timer_wrapper(unsigned long data) static inline void rxq_refill_timer_wrapper(unsigned long data) { mv643xx_eth_rx_refill_descs((struct net_device *)data); rxq_refill((struct rx_queue *)data); } static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) static int rxq_process(struct rx_queue *rxq, int budget) { struct mv643xx_eth_private *mp = netdev_priv(dev); struct net_device_stats *stats = &dev->stats; unsigned int received_packets = 0; struct mv643xx_eth_private *mp = rxq_to_mp(rxq); struct net_device_stats *stats = &mp->dev->stats; int rx; while (budget-- > 0) { rx = 0; while (rx < budget) { struct sk_buff *skb; volatile struct rx_desc *rx_desc; unsigned int cmd_sts; Loading @@ -486,7 +487,7 @@ static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) spin_lock_irqsave(&mp->lock, flags); rx_desc = &mp->rx_desc_area[mp->rx_curr_desc]; rx_desc = &rxq->rx_desc_area[rxq->rx_curr_desc]; cmd_sts = rx_desc->cmd_sts; if (cmd_sts & BUFFER_OWNED_BY_DMA) { Loading @@ -495,17 +496,17 @@ static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) } rmb(); skb = mp->rx_skb[mp->rx_curr_desc]; mp->rx_skb[mp->rx_curr_desc] = NULL; skb = rxq->rx_skb[rxq->rx_curr_desc]; rxq->rx_skb[rxq->rx_curr_desc] = NULL; mp->rx_curr_desc = (mp->rx_curr_desc + 1) % mp->rx_ring_size; rxq->rx_curr_desc = (rxq->rx_curr_desc + 1) % rxq->rx_ring_size; spin_unlock_irqrestore(&mp->lock, flags); dma_unmap_single(NULL, rx_desc->buf_ptr + ETH_HW_IP_ALIGN, ETH_RX_SKB_SIZE, DMA_FROM_DEVICE); mp->rx_desc_count--; received_packets++; mp->dev->mtu + 24, DMA_FROM_DEVICE); rxq->rx_desc_count--; rx++; /* * Update statistics. Loading @@ -528,7 +529,7 @@ static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) printk(KERN_ERR "%s: Received packet spread " "on multiple descriptors\n", dev->name); mp->dev->name); } if (cmd_sts & ERROR_SUMMARY) stats->rx_errors++; Loading @@ -546,48 +547,45 @@ static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) skb->csum = htons( (cmd_sts & 0x0007fff8) >> 3); } skb->protocol = eth_type_trans(skb, dev); skb->protocol = eth_type_trans(skb, mp->dev); #ifdef MV643XX_ETH_NAPI netif_receive_skb(skb); #else netif_rx(skb); #endif } dev->last_rx = jiffies; mp->dev->last_rx = jiffies; } mv643xx_eth_rx_refill_descs(dev); /* Fill RX ring with skb's */ rxq_refill(rxq); return received_packets; return rx; } #ifdef MV643XX_ETH_NAPI static int mv643xx_eth_poll(struct napi_struct *napi, int budget) { struct mv643xx_eth_private *mp = container_of(napi, struct mv643xx_eth_private, napi); struct net_device *dev = mp->dev; unsigned int port_num = mp->port_num; int work_done; struct mv643xx_eth_private *mp; int rx; mp = container_of(napi, struct mv643xx_eth_private, napi); #ifdef MV643XX_ETH_TX_FAST_REFILL if (++mp->tx_clean_threshold > 5) { mv643xx_eth_free_completed_tx_descs(dev); mv643xx_eth_free_completed_tx_descs(mp->dev); mp->tx_clean_threshold = 0; } #endif work_done = 0; if ((rdl(mp, RXQ_CURRENT_DESC_PTR(port_num))) != (u32) mp->rx_used_desc) work_done = mv643xx_eth_receive_queue(dev, budget); rx = rxq_process(mp->rxq, budget); if (work_done < budget) { netif_rx_complete(dev, napi); wrl(mp, INT_CAUSE(port_num), 0); wrl(mp, INT_CAUSE_EXT(port_num), 0); wrl(mp, INT_MASK(port_num), INT_RX | INT_EXT); if (rx < budget) { netif_rx_complete(mp->dev, napi); wrl(mp, INT_CAUSE(mp->port_num), 0); wrl(mp, INT_CAUSE_EXT(mp->port_num), 0); wrl(mp, INT_MASK(mp->port_num), INT_RX | INT_EXT); } return work_done; return rx; } #endif Loading Loading @@ -1252,53 +1250,102 @@ static void mv643xx_eth_set_rx_mode(struct net_device *dev) /* rx/tx queue initialisation ***********************************************/ static void ether_init_rx_desc_ring(struct mv643xx_eth_private *mp) static int rxq_init(struct mv643xx_eth_private *mp) { volatile struct rx_desc *p_rx_desc; int rx_desc_num = mp->rx_ring_size; struct rx_queue *rxq = mp->rxq; struct rx_desc *rx_desc; int size; int i; /* initialize the next_desc_ptr links in the Rx descriptors ring */ p_rx_desc = (struct rx_desc *)mp->rx_desc_area; for (i = 0; i < rx_desc_num; i++) { p_rx_desc[i].next_desc_ptr = mp->rx_desc_dma + ((i + 1) % rx_desc_num) * sizeof(struct rx_desc); rxq->rx_ring_size = mp->default_rx_ring_size; rxq->rx_desc_count = 0; rxq->rx_curr_desc = 0; rxq->rx_used_desc = 0; size = rxq->rx_ring_size * sizeof(struct rx_desc); if (size <= mp->rx_desc_sram_size) { rxq->rx_desc_area = ioremap(mp->rx_desc_sram_addr, mp->rx_desc_sram_size); rxq->rx_desc_dma = mp->rx_desc_sram_addr; } else { rxq->rx_desc_area = dma_alloc_coherent(NULL, size, &rxq->rx_desc_dma, GFP_KERNEL); } if (rxq->rx_desc_area == NULL) { dev_printk(KERN_ERR, &mp->dev->dev, "can't allocate rx ring (%d bytes)\n", size); goto out; } memset(rxq->rx_desc_area, 0, size); rxq->rx_desc_area_size = size; rxq->rx_skb = kmalloc(rxq->rx_ring_size * sizeof(*rxq->rx_skb), GFP_KERNEL); if (rxq->rx_skb == NULL) { dev_printk(KERN_ERR, &mp->dev->dev, "can't allocate rx skb ring\n"); goto out_free; } rx_desc = (struct rx_desc *)rxq->rx_desc_area; for (i = 0; i < rxq->rx_ring_size; i++) { int nexti = (i + 1) % rxq->rx_ring_size; rx_desc[i].next_desc_ptr = rxq->rx_desc_dma + nexti * sizeof(struct rx_desc); } /* Save Rx desc pointer to driver struct. */ mp->rx_curr_desc = 0; mp->rx_used_desc = 0; init_timer(&rxq->rx_oom); rxq->rx_oom.data = (unsigned long)rxq; rxq->rx_oom.function = rxq_refill_timer_wrapper; mp->rx_desc_area_size = rx_desc_num * sizeof(struct rx_desc); return 0; out_free: if (size <= mp->rx_desc_sram_size) iounmap(rxq->rx_desc_area); else dma_free_coherent(NULL, size, rxq->rx_desc_area, rxq->rx_desc_dma); out: return -ENOMEM; } static void mv643xx_eth_free_rx_rings(struct net_device *dev) static void rxq_deinit(struct rx_queue *rxq) { struct mv643xx_eth_private *mp = netdev_priv(dev); int curr; struct mv643xx_eth_private *mp = rxq_to_mp(rxq); int i; rxq_disable(rxq); /* Stop RX Queues */ mv643xx_eth_port_disable_rx(mp); del_timer_sync(&rxq->rx_oom); /* Free preallocated skb's on RX rings */ for (curr = 0; mp->rx_desc_count && curr < mp->rx_ring_size; curr++) { if (mp->rx_skb[curr]) { dev_kfree_skb(mp->rx_skb[curr]); mp->rx_desc_count--; for (i = 0; i < rxq->rx_ring_size; i++) { if (rxq->rx_skb[i]) { dev_kfree_skb(rxq->rx_skb[i]); rxq->rx_desc_count--; } } if (mp->rx_desc_count) printk(KERN_ERR "%s: Error in freeing Rx Ring. %d skb's still" " stuck in RX Ring - ignoring them\n", dev->name, mp->rx_desc_count); /* Free RX ring */ if (mp->rx_sram_size) iounmap(mp->rx_desc_area); if (rxq->rx_desc_count) { dev_printk(KERN_ERR, &mp->dev->dev, "error freeing rx ring -- %d skbs stuck\n", rxq->rx_desc_count); } if (rxq->rx_desc_area_size <= mp->rx_desc_sram_size) iounmap(rxq->rx_desc_area); else dma_free_coherent(NULL, mp->rx_desc_area_size, mp->rx_desc_area, mp->rx_desc_dma); dma_free_coherent(NULL, rxq->rx_desc_area_size, rxq->rx_desc_area, rxq->rx_desc_dma); kfree(rxq->rx_skb); } static void ether_init_tx_desc_ring(struct mv643xx_eth_private *mp) Loading Loading @@ -1510,7 +1557,7 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id) } #else if (int_cause & INT_RX) mv643xx_eth_receive_queue(dev, INT_MAX); rxq_process(mp->rxq, INT_MAX); #endif if (int_cause_ext & INT_EXT_TX) mv643xx_eth_free_completed_tx_descs(dev); Loading Loading @@ -1544,20 +1591,30 @@ static void phy_reset(struct mv643xx_eth_private *mp) static void port_start(struct net_device *dev) { struct mv643xx_eth_private *mp = netdev_priv(dev); unsigned int port_num = mp->port_num; int tx_curr_desc, rx_curr_desc; u32 pscr; struct ethtool_cmd ethtool_cmd; int i; /* Assignment of Tx CTRP of given queue */ tx_curr_desc = mp->tx_curr_desc; wrl(mp, TXQ_CURRENT_DESC_PTR(port_num), (u32)((struct tx_desc *)mp->tx_desc_dma + tx_curr_desc)); /* * Configure basic link parameters. */ pscr = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num)); pscr &= ~(SERIAL_PORT_ENABLE | FORCE_LINK_PASS); wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr); pscr |= DISABLE_AUTO_NEG_FOR_FLOW_CTRL | DISABLE_AUTO_NEG_SPEED_GMII | DISABLE_AUTO_NEG_FOR_DUPLEX | DO_NOT_FORCE_LINK_FAIL | SERIAL_PORT_CONTROL_RESERVED; wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr); pscr |= SERIAL_PORT_ENABLE; wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr); /* Assignment of Rx CRDP of given queue */ rx_curr_desc = mp->rx_curr_desc; wrl(mp, RXQ_CURRENT_DESC_PTR(port_num), (u32)((struct rx_desc *)mp->rx_desc_dma + rx_curr_desc)); wrl(mp, SDMA_CONFIG(mp->port_num), PORT_SDMA_CONFIG_DEFAULT_VALUE); mv643xx_eth_get_settings(dev, ðtool_cmd); phy_reset(mp); mv643xx_eth_set_settings(dev, ðtool_cmd); /* Add the assigned Ethernet address to the port's address table */ uc_addr_set(mp, dev->dev_addr); Loading @@ -1566,42 +1623,34 @@ static void port_start(struct net_device *dev) * Receive all unmatched unicast, TCP, UDP, BPDU and broadcast * frames to RX queue #0. */ wrl(mp, PORT_CONFIG(port_num), 0x00000000); wrl(mp, PORT_CONFIG(mp->port_num), 0x00000000); /* * Treat BPDUs as normal multicasts, and disable partition mode. */ wrl(mp, PORT_CONFIG_EXT(port_num), 0x00000000); wrl(mp, PORT_CONFIG_EXT(mp->port_num), 0x00000000); pscr = rdl(mp, PORT_SERIAL_CONTROL(port_num)); pscr &= ~(SERIAL_PORT_ENABLE | FORCE_LINK_PASS); wrl(mp, PORT_SERIAL_CONTROL(port_num), pscr); pscr |= DISABLE_AUTO_NEG_FOR_FLOW_CTRL | DISABLE_AUTO_NEG_SPEED_GMII | DISABLE_AUTO_NEG_FOR_DUPLEX | DO_NOT_FORCE_LINK_FAIL | SERIAL_PORT_CONTROL_RESERVED; /* * Enable the receive queue. */ for (i = 0; i < 1; i++) { struct rx_queue *rxq = mp->rxq; int off = RXQ_CURRENT_DESC_PTR(mp->port_num); u32 addr; wrl(mp, PORT_SERIAL_CONTROL(port_num), pscr); addr = (u32)rxq->rx_desc_dma; addr += rxq->rx_curr_desc * sizeof(struct rx_desc); wrl(mp, off, addr); pscr |= SERIAL_PORT_ENABLE; wrl(mp, PORT_SERIAL_CONTROL(port_num), pscr); rxq_enable(rxq); } /* Assign port SDMA configuration */ wrl(mp, SDMA_CONFIG(port_num), PORT_SDMA_CONFIG_DEFAULT_VALUE); /* Enable port Rx. */ mv643xx_eth_port_enable_rx(mp, 1); wrl(mp, TXQ_CURRENT_DESC_PTR(mp->port_num), (u32)((struct tx_desc *)mp->tx_desc_dma + mp->tx_curr_desc)); /* Disable port bandwidth limits by clearing MTU register */ wrl(mp, TX_BW_MTU(port_num), 0); /* save phy settings across reset */ mv643xx_eth_get_settings(dev, ðtool_cmd); phy_reset(mp); mv643xx_eth_set_settings(dev, ðtool_cmd); wrl(mp, TX_BW_MTU(mp->port_num), 0); } #ifdef MV643XX_ETH_COAL Loading Loading @@ -1661,18 +1710,11 @@ static int mv643xx_eth_open(struct net_device *dev) port_init(mp); memset(&mp->timeout, 0, sizeof(struct timer_list)); mp->timeout.function = mv643xx_eth_rx_refill_descs_timer_wrapper; mp->timeout.data = (unsigned long)dev; /* Allocate RX and TX skb rings */ mp->rx_skb = kmalloc(sizeof(*mp->rx_skb) * mp->rx_ring_size, GFP_KERNEL); if (!mp->rx_skb) { printk(KERN_ERR "%s: Cannot allocate Rx skb ring\n", dev->name); err = -ENOMEM; err = rxq_init(mp); if (err) goto out_free_irq; } rxq_refill(mp->rxq); mp->tx_skb = kmalloc(sizeof(*mp->tx_skb) * mp->tx_ring_size, GFP_KERNEL); if (!mp->tx_skb) { Loading Loading @@ -1706,39 +1748,6 @@ static int mv643xx_eth_open(struct net_device *dev) ether_init_tx_desc_ring(mp); /* Allocate RX ring */ mp->rx_desc_count = 0; size = mp->rx_ring_size * sizeof(struct rx_desc); mp->rx_desc_area_size = size; if (mp->rx_sram_size) { mp->rx_desc_area = ioremap(mp->rx_sram_addr, mp->rx_sram_size); mp->rx_desc_dma = mp->rx_sram_addr; } else mp->rx_desc_area = dma_alloc_coherent(NULL, size, &mp->rx_desc_dma, GFP_KERNEL); if (!mp->rx_desc_area) { printk(KERN_ERR "%s: Cannot allocate Rx ring (size %d bytes)\n", dev->name, size); printk(KERN_ERR "%s: Freeing previously allocated TX queues...", dev->name); if (mp->rx_sram_size) iounmap(mp->tx_desc_area); else dma_free_coherent(NULL, mp->tx_desc_area_size, mp->tx_desc_area, mp->tx_desc_dma); err = -ENOMEM; goto out_free_tx_skb; } memset((void *)mp->rx_desc_area, 0, size); ether_init_rx_desc_ring(mp); mv643xx_eth_rx_refill_descs(dev); /* Fill RX ring with skb's */ #ifdef MV643XX_ETH_NAPI napi_enable(&mp->napi); #endif Loading @@ -1764,7 +1773,7 @@ static int mv643xx_eth_open(struct net_device *dev) out_free_tx_skb: kfree(mp->tx_skb); out_free_rx_skb: kfree(mp->rx_skb); rxq_deinit(mp->rxq); out_free_irq: free_irq(dev->irq, dev); Loading @@ -1777,7 +1786,7 @@ static void port_reset(struct mv643xx_eth_private *mp) unsigned int reg_data; mv643xx_eth_port_disable_tx(mp); mv643xx_eth_port_disable_rx(mp); rxq_disable(mp->rxq); /* Clear all MIB counters */ clear_mib_counters(mp); Loading Loading @@ -1809,7 +1818,7 @@ static int mv643xx_eth_stop(struct net_device *dev) port_reset(mp); mv643xx_eth_free_tx_rings(dev); mv643xx_eth_free_rx_rings(dev); rxq_deinit(mp->rxq); free_irq(dev->irq, dev); Loading Loading @@ -2162,7 +2171,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev) /* set default config values */ uc_addr_get(mp, dev->dev_addr); mp->rx_ring_size = DEFAULT_RX_QUEUE_SIZE; mp->tx_ring_size = DEFAULT_TX_QUEUE_SIZE; if (is_valid_ether_addr(pd->mac_addr)) Loading @@ -2171,8 +2179,9 @@ static int mv643xx_eth_probe(struct platform_device *pdev) if (pd->phy_addr || pd->force_phy_addr) phy_addr_set(mp, pd->phy_addr); mp->default_rx_ring_size = DEFAULT_RX_QUEUE_SIZE; if (pd->rx_queue_size) mp->rx_ring_size = pd->rx_queue_size; mp->default_rx_ring_size = pd->rx_queue_size; if (pd->tx_queue_size) mp->tx_ring_size = pd->tx_queue_size; Loading @@ -2183,8 +2192,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev) } if (pd->rx_sram_size) { mp->rx_sram_size = pd->rx_sram_size; mp->rx_sram_addr = pd->rx_sram_addr; mp->rx_desc_sram_addr = pd->rx_sram_addr; mp->rx_desc_sram_size = pd->rx_sram_size; } duplex = pd->duplex; Loading