diff options
author | Florian Fainelli <florian.fainelli@telecomint.eu> | 2007-12-12 16:55:34 -0500 |
---|---|---|
committer | Francois Romieu <romieu@fr.zoreil.com> | 2008-02-05 17:29:08 -0500 |
commit | b4f1255d6839bd970d5ff20a9c3d73f73c9adaa3 (patch) | |
tree | 3aff83e40c49238aaa962042f1fd0da0161de2b2 /drivers | |
parent | d248fd77902fcf33b0bc49ab521930877d94890f (diff) |
r6040: add helpers to allocate and free the Tx/Rx buffers
r6040_init_ring_desc moves around but it is kept unchanged.
Signed-off-by: Florian Fainelli <florian.fainelli@telecomint.eu>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/r6040.c | 144 |
1 files changed, 84 insertions, 60 deletions
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 325a8e433bd4..24f42d23156c 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c | |||
@@ -234,6 +234,38 @@ static void mdio_write(struct net_device *dev, int mii_id, int reg, int val) | |||
234 | phy_write(ioaddr, lp->phy_addr, reg, val); | 234 | phy_write(ioaddr, lp->phy_addr, reg, val); |
235 | } | 235 | } |
236 | 236 | ||
237 | static void r6040_free_txbufs(struct net_device *dev) | ||
238 | { | ||
239 | struct r6040_private *lp = netdev_priv(dev); | ||
240 | int i; | ||
241 | |||
242 | for (i = 0; i < TX_DCNT; i++) { | ||
243 | if (lp->tx_insert_ptr->skb_ptr) { | ||
244 | pci_unmap_single(lp->pdev, lp->tx_insert_ptr->buf, | ||
245 | MAX_BUF_SIZE, PCI_DMA_TODEVICE); | ||
246 | dev_kfree_skb(lp->tx_insert_ptr->skb_ptr); | ||
247 | lp->rx_insert_ptr->skb_ptr = NULL; | ||
248 | } | ||
249 | lp->tx_insert_ptr = lp->tx_insert_ptr->vndescp; | ||
250 | } | ||
251 | } | ||
252 | |||
253 | static void r6040_free_rxbufs(struct net_device *dev) | ||
254 | { | ||
255 | struct r6040_private *lp = netdev_priv(dev); | ||
256 | int i; | ||
257 | |||
258 | for (i = 0; i < RX_DCNT; i++) { | ||
259 | if (lp->rx_insert_ptr->skb_ptr) { | ||
260 | pci_unmap_single(lp->pdev, lp->rx_insert_ptr->buf, | ||
261 | MAX_BUF_SIZE, PCI_DMA_FROMDEVICE); | ||
262 | dev_kfree_skb(lp->rx_insert_ptr->skb_ptr); | ||
263 | lp->rx_insert_ptr->skb_ptr = NULL; | ||
264 | } | ||
265 | lp->rx_insert_ptr = lp->rx_insert_ptr->vndescp; | ||
266 | } | ||
267 | } | ||
268 | |||
237 | static void r6040_tx_timeout(struct net_device *dev) | 269 | static void r6040_tx_timeout(struct net_device *dev) |
238 | { | 270 | { |
239 | struct r6040_private *priv = netdev_priv(dev); | 271 | struct r6040_private *priv = netdev_priv(dev); |
@@ -247,6 +279,23 @@ static void r6040_tx_timeout(struct net_device *dev) | |||
247 | netif_stop_queue(dev); | 279 | netif_stop_queue(dev); |
248 | } | 280 | } |
249 | 281 | ||
282 | static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring, | ||
283 | dma_addr_t desc_dma, int size) | ||
284 | { | ||
285 | struct r6040_descriptor *desc = desc_ring; | ||
286 | dma_addr_t mapping = desc_dma; | ||
287 | |||
288 | while (size-- > 0) { | ||
289 | mapping += sizeof(sizeof(*desc)); | ||
290 | desc->ndesc = cpu_to_le32(mapping); | ||
291 | desc->vndescp = desc + 1; | ||
292 | desc++; | ||
293 | } | ||
294 | desc--; | ||
295 | desc->ndesc = cpu_to_le32(desc_dma); | ||
296 | desc->vndescp = desc_ring; | ||
297 | } | ||
298 | |||
250 | /* Allocate skb buffer for rx descriptor */ | 299 | /* Allocate skb buffer for rx descriptor */ |
251 | static void rx_buf_alloc(struct r6040_private *lp, struct net_device *dev) | 300 | static void rx_buf_alloc(struct r6040_private *lp, struct net_device *dev) |
252 | { | 301 | { |
@@ -271,6 +320,35 @@ static void rx_buf_alloc(struct r6040_private *lp, struct net_device *dev) | |||
271 | lp->rx_insert_ptr = descptr; | 320 | lp->rx_insert_ptr = descptr; |
272 | } | 321 | } |
273 | 322 | ||
323 | static void r6040_alloc_txbufs(struct net_device *dev) | ||
324 | { | ||
325 | struct r6040_private *lp = netdev_priv(dev); | ||
326 | void __iomem *ioaddr = lp->base; | ||
327 | |||
328 | lp->tx_free_desc = TX_DCNT; | ||
329 | |||
330 | lp->tx_remove_ptr = lp->tx_insert_ptr = lp->tx_ring; | ||
331 | r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT); | ||
332 | |||
333 | iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0); | ||
334 | iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1); | ||
335 | } | ||
336 | |||
337 | static void r6040_alloc_rxbufs(struct net_device *dev) | ||
338 | { | ||
339 | struct r6040_private *lp = netdev_priv(dev); | ||
340 | void __iomem *ioaddr = lp->base; | ||
341 | |||
342 | lp->rx_free_desc = 0; | ||
343 | |||
344 | lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring; | ||
345 | r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT); | ||
346 | |||
347 | rx_buf_alloc(lp, dev); | ||
348 | |||
349 | iowrite16(lp->rx_ring_dma, ioaddr + MRD_SA0); | ||
350 | iowrite16(lp->rx_ring_dma >> 16, ioaddr + MRD_SA1); | ||
351 | } | ||
274 | 352 | ||
275 | static struct net_device_stats *r6040_get_stats(struct net_device *dev) | 353 | static struct net_device_stats *r6040_get_stats(struct net_device *dev) |
276 | { | 354 | { |
@@ -292,7 +370,6 @@ static void r6040_down(struct net_device *dev) | |||
292 | struct r6040_private *lp = netdev_priv(dev); | 370 | struct r6040_private *lp = netdev_priv(dev); |
293 | void __iomem *ioaddr = lp->base; | 371 | void __iomem *ioaddr = lp->base; |
294 | struct pci_dev *pdev = lp->pdev; | 372 | struct pci_dev *pdev = lp->pdev; |
295 | int i; | ||
296 | int limit = 2048; | 373 | int limit = 2048; |
297 | u16 *adrp; | 374 | u16 *adrp; |
298 | u16 cmd; | 375 | u16 cmd; |
@@ -312,27 +389,12 @@ static void r6040_down(struct net_device *dev) | |||
312 | iowrite16(adrp[1], ioaddr + MID_0M); | 389 | iowrite16(adrp[1], ioaddr + MID_0M); |
313 | iowrite16(adrp[2], ioaddr + MID_0H); | 390 | iowrite16(adrp[2], ioaddr + MID_0H); |
314 | free_irq(dev->irq, dev); | 391 | free_irq(dev->irq, dev); |
392 | |||
315 | /* Free RX buffer */ | 393 | /* Free RX buffer */ |
316 | for (i = 0; i < RX_DCNT; i++) { | 394 | r6040_free_rxbufs(dev); |
317 | if (lp->rx_insert_ptr->skb_ptr) { | ||
318 | pci_unmap_single(lp->pdev, lp->rx_insert_ptr->buf, | ||
319 | MAX_BUF_SIZE, PCI_DMA_FROMDEVICE); | ||
320 | dev_kfree_skb(lp->rx_insert_ptr->skb_ptr); | ||
321 | lp->rx_insert_ptr->skb_ptr = NULL; | ||
322 | } | ||
323 | lp->rx_insert_ptr = lp->rx_insert_ptr->vndescp; | ||
324 | } | ||
325 | 395 | ||
326 | /* Free TX buffer */ | 396 | /* Free TX buffer */ |
327 | for (i = 0; i < TX_DCNT; i++) { | 397 | r6040_free_txbufs(dev); |
328 | if (lp->tx_insert_ptr->skb_ptr) { | ||
329 | pci_unmap_single(lp->pdev, lp->tx_insert_ptr->buf, | ||
330 | MAX_BUF_SIZE, PCI_DMA_TODEVICE); | ||
331 | dev_kfree_skb(lp->tx_insert_ptr->skb_ptr); | ||
332 | lp->rx_insert_ptr->skb_ptr = NULL; | ||
333 | } | ||
334 | lp->tx_insert_ptr = lp->tx_insert_ptr->vndescp; | ||
335 | } | ||
336 | 398 | ||
337 | /* Free Descriptor memory */ | 399 | /* Free Descriptor memory */ |
338 | pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma); | 400 | pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma); |
@@ -583,53 +645,15 @@ static void r6040_poll_controller(struct net_device *dev) | |||
583 | } | 645 | } |
584 | #endif | 646 | #endif |
585 | 647 | ||
586 | static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring, | ||
587 | dma_addr_t desc_dma, int size) | ||
588 | { | ||
589 | struct r6040_descriptor *desc = desc_ring; | ||
590 | dma_addr_t mapping = desc_dma; | ||
591 | |||
592 | while (size-- > 0) { | ||
593 | mapping += sizeof(sizeof(*desc)); | ||
594 | desc->ndesc = cpu_to_le32(mapping); | ||
595 | desc->vndescp = desc + 1; | ||
596 | desc++; | ||
597 | } | ||
598 | desc--; | ||
599 | desc->ndesc = cpu_to_le32(desc_dma); | ||
600 | desc->vndescp = desc_ring; | ||
601 | } | ||
602 | |||
603 | /* Init RDC MAC */ | 648 | /* Init RDC MAC */ |
604 | static void r6040_up(struct net_device *dev) | 649 | static void r6040_up(struct net_device *dev) |
605 | { | 650 | { |
606 | struct r6040_private *lp = netdev_priv(dev); | 651 | struct r6040_private *lp = netdev_priv(dev); |
607 | void __iomem *ioaddr = lp->base; | 652 | void __iomem *ioaddr = lp->base; |
608 | 653 | ||
609 | /* Initialize */ | 654 | /* Initialise and alloc RX/TX buffers */ |
610 | lp->tx_free_desc = TX_DCNT; | 655 | r6040_alloc_txbufs(dev); |
611 | lp->rx_free_desc = 0; | 656 | r6040_alloc_rxbufs(dev); |
612 | /* Init descriptor */ | ||
613 | lp->tx_remove_ptr = lp->tx_insert_ptr = lp->tx_ring; | ||
614 | lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring; | ||
615 | /* Init TX descriptor */ | ||
616 | r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT); | ||
617 | |||
618 | /* Init RX descriptor */ | ||
619 | r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT); | ||
620 | |||
621 | /* Allocate buffer for RX descriptor */ | ||
622 | rx_buf_alloc(lp, dev); | ||
623 | |||
624 | /* | ||
625 | * TX and RX descriptor start registers. | ||
626 | * Lower 16-bits to MxD_SA0. Higher 16-bits to MxD_SA1. | ||
627 | */ | ||
628 | iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0); | ||
629 | iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1); | ||
630 | |||
631 | iowrite16(lp->rx_ring_dma, ioaddr + MRD_SA0); | ||
632 | iowrite16(lp->rx_ring_dma >> 16, ioaddr + MRD_SA1); | ||
633 | 657 | ||
634 | /* Buffer Size Register */ | 658 | /* Buffer Size Register */ |
635 | iowrite16(MAX_BUF_SIZE, ioaddr + MR_BSR); | 659 | iowrite16(MAX_BUF_SIZE, ioaddr + MR_BSR); |