aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorFlorian Fainelli <florian.fainelli@telecomint.eu>2007-12-12 16:55:34 -0500
committerFrancois Romieu <romieu@fr.zoreil.com>2008-02-05 17:29:08 -0500
commitb4f1255d6839bd970d5ff20a9c3d73f73c9adaa3 (patch)
tree3aff83e40c49238aaa962042f1fd0da0161de2b2 /drivers
parentd248fd77902fcf33b0bc49ab521930877d94890f (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.c144
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
237static 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
253static 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
237static void r6040_tx_timeout(struct net_device *dev) 269static 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
282static 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 */
251static void rx_buf_alloc(struct r6040_private *lp, struct net_device *dev) 300static 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
323static 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
337static 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
275static struct net_device_stats *r6040_get_stats(struct net_device *dev) 353static 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
586static 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 */
604static void r6040_up(struct net_device *dev) 649static 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);