diff options
Diffstat (limited to 'drivers/net/spider_net.c')
-rw-r--r-- | drivers/net/spider_net.c | 554 |
1 files changed, 366 insertions, 188 deletions
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index 64ed8ff5b03a..3b91af89e4c7 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c | |||
@@ -1,7 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * Network device driver for Cell Processor-Based Blade | 2 | * Network device driver for Cell Processor-Based Blade and Celleb platform |
3 | * | 3 | * |
4 | * (C) Copyright IBM Corp. 2005 | 4 | * (C) Copyright IBM Corp. 2005 |
5 | * (C) Copyright 2006 TOSHIBA CORPORATION | ||
5 | * | 6 | * |
6 | * Authors : Utz Bacher <utz.bacher@de.ibm.com> | 7 | * Authors : Utz Bacher <utz.bacher@de.ibm.com> |
7 | * Jens Osterkamp <Jens.Osterkamp@de.ibm.com> | 8 | * Jens Osterkamp <Jens.Osterkamp@de.ibm.com> |
@@ -166,6 +167,41 @@ spider_net_read_phy(struct net_device *netdev, int mii_id, int reg) | |||
166 | } | 167 | } |
167 | 168 | ||
168 | /** | 169 | /** |
170 | * spider_net_setup_aneg - initial auto-negotiation setup | ||
171 | * @card: device structure | ||
172 | **/ | ||
173 | static void | ||
174 | spider_net_setup_aneg(struct spider_net_card *card) | ||
175 | { | ||
176 | struct mii_phy *phy = &card->phy; | ||
177 | u32 advertise = 0; | ||
178 | u16 bmcr, bmsr, stat1000, estat; | ||
179 | |||
180 | bmcr = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMCR); | ||
181 | bmsr = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMSR); | ||
182 | stat1000 = spider_net_read_phy(card->netdev, phy->mii_id, MII_STAT1000); | ||
183 | estat = spider_net_read_phy(card->netdev, phy->mii_id, MII_ESTATUS); | ||
184 | |||
185 | if (bmsr & BMSR_10HALF) | ||
186 | advertise |= ADVERTISED_10baseT_Half; | ||
187 | if (bmsr & BMSR_10FULL) | ||
188 | advertise |= ADVERTISED_10baseT_Full; | ||
189 | if (bmsr & BMSR_100HALF) | ||
190 | advertise |= ADVERTISED_100baseT_Half; | ||
191 | if (bmsr & BMSR_100FULL) | ||
192 | advertise |= ADVERTISED_100baseT_Full; | ||
193 | |||
194 | if ((bmsr & BMSR_ESTATEN) && (estat & ESTATUS_1000_TFULL)) | ||
195 | advertise |= SUPPORTED_1000baseT_Full; | ||
196 | if ((bmsr & BMSR_ESTATEN) && (estat & ESTATUS_1000_THALF)) | ||
197 | advertise |= SUPPORTED_1000baseT_Half; | ||
198 | |||
199 | mii_phy_probe(phy, phy->mii_id); | ||
200 | phy->def->ops->setup_aneg(phy, advertise); | ||
201 | |||
202 | } | ||
203 | |||
204 | /** | ||
169 | * spider_net_rx_irq_off - switch off rx irq on this spider card | 205 | * spider_net_rx_irq_off - switch off rx irq on this spider card |
170 | * @card: device structure | 206 | * @card: device structure |
171 | * | 207 | * |
@@ -263,9 +299,9 @@ spider_net_get_mac_address(struct net_device *netdev) | |||
263 | * returns the status as in the dmac_cmd_status field of the descriptor | 299 | * returns the status as in the dmac_cmd_status field of the descriptor |
264 | */ | 300 | */ |
265 | static inline int | 301 | static inline int |
266 | spider_net_get_descr_status(struct spider_net_descr *descr) | 302 | spider_net_get_descr_status(struct spider_net_hw_descr *hwdescr) |
267 | { | 303 | { |
268 | return descr->dmac_cmd_status & SPIDER_NET_DESCR_IND_PROC_MASK; | 304 | return hwdescr->dmac_cmd_status & SPIDER_NET_DESCR_IND_PROC_MASK; |
269 | } | 305 | } |
270 | 306 | ||
271 | /** | 307 | /** |
@@ -283,12 +319,12 @@ spider_net_free_chain(struct spider_net_card *card, | |||
283 | descr = chain->ring; | 319 | descr = chain->ring; |
284 | do { | 320 | do { |
285 | descr->bus_addr = 0; | 321 | descr->bus_addr = 0; |
286 | descr->next_descr_addr = 0; | 322 | descr->hwdescr->next_descr_addr = 0; |
287 | descr = descr->next; | 323 | descr = descr->next; |
288 | } while (descr != chain->ring); | 324 | } while (descr != chain->ring); |
289 | 325 | ||
290 | dma_free_coherent(&card->pdev->dev, chain->num_desc, | 326 | dma_free_coherent(&card->pdev->dev, chain->num_desc, |
291 | chain->ring, chain->dma_addr); | 327 | chain->hwring, chain->dma_addr); |
292 | } | 328 | } |
293 | 329 | ||
294 | /** | 330 | /** |
@@ -307,31 +343,34 @@ spider_net_init_chain(struct spider_net_card *card, | |||
307 | { | 343 | { |
308 | int i; | 344 | int i; |
309 | struct spider_net_descr *descr; | 345 | struct spider_net_descr *descr; |
346 | struct spider_net_hw_descr *hwdescr; | ||
310 | dma_addr_t buf; | 347 | dma_addr_t buf; |
311 | size_t alloc_size; | 348 | size_t alloc_size; |
312 | 349 | ||
313 | alloc_size = chain->num_desc * sizeof (struct spider_net_descr); | 350 | alloc_size = chain->num_desc * sizeof(struct spider_net_hw_descr); |
314 | 351 | ||
315 | chain->ring = dma_alloc_coherent(&card->pdev->dev, alloc_size, | 352 | chain->hwring = dma_alloc_coherent(&card->pdev->dev, alloc_size, |
316 | &chain->dma_addr, GFP_KERNEL); | 353 | &chain->dma_addr, GFP_KERNEL); |
317 | 354 | ||
318 | if (!chain->ring) | 355 | if (!chain->hwring) |
319 | return -ENOMEM; | 356 | return -ENOMEM; |
320 | 357 | ||
321 | descr = chain->ring; | 358 | memset(chain->ring, 0, chain->num_desc * sizeof(struct spider_net_descr)); |
322 | memset(descr, 0, alloc_size); | ||
323 | 359 | ||
324 | /* Set up the hardware pointers in each descriptor */ | 360 | /* Set up the hardware pointers in each descriptor */ |
361 | descr = chain->ring; | ||
362 | hwdescr = chain->hwring; | ||
325 | buf = chain->dma_addr; | 363 | buf = chain->dma_addr; |
326 | for (i=0; i < chain->num_desc; i++, descr++) { | 364 | for (i=0; i < chain->num_desc; i++, descr++, hwdescr++) { |
327 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | 365 | hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |
366 | hwdescr->next_descr_addr = 0; | ||
328 | 367 | ||
368 | descr->hwdescr = hwdescr; | ||
329 | descr->bus_addr = buf; | 369 | descr->bus_addr = buf; |
330 | descr->next_descr_addr = 0; | ||
331 | descr->next = descr + 1; | 370 | descr->next = descr + 1; |
332 | descr->prev = descr - 1; | 371 | descr->prev = descr - 1; |
333 | 372 | ||
334 | buf += sizeof(struct spider_net_descr); | 373 | buf += sizeof(struct spider_net_hw_descr); |
335 | } | 374 | } |
336 | /* do actual circular list */ | 375 | /* do actual circular list */ |
337 | (descr-1)->next = chain->ring; | 376 | (descr-1)->next = chain->ring; |
@@ -357,10 +396,11 @@ spider_net_free_rx_chain_contents(struct spider_net_card *card) | |||
357 | descr = card->rx_chain.head; | 396 | descr = card->rx_chain.head; |
358 | do { | 397 | do { |
359 | if (descr->skb) { | 398 | if (descr->skb) { |
360 | dev_kfree_skb(descr->skb); | 399 | pci_unmap_single(card->pdev, descr->hwdescr->buf_addr, |
361 | pci_unmap_single(card->pdev, descr->buf_addr, | ||
362 | SPIDER_NET_MAX_FRAME, | 400 | SPIDER_NET_MAX_FRAME, |
363 | PCI_DMA_BIDIRECTIONAL); | 401 | PCI_DMA_BIDIRECTIONAL); |
402 | dev_kfree_skb(descr->skb); | ||
403 | descr->skb = NULL; | ||
364 | } | 404 | } |
365 | descr = descr->next; | 405 | descr = descr->next; |
366 | } while (descr != card->rx_chain.head); | 406 | } while (descr != card->rx_chain.head); |
@@ -380,6 +420,7 @@ static int | |||
380 | spider_net_prepare_rx_descr(struct spider_net_card *card, | 420 | spider_net_prepare_rx_descr(struct spider_net_card *card, |
381 | struct spider_net_descr *descr) | 421 | struct spider_net_descr *descr) |
382 | { | 422 | { |
423 | struct spider_net_hw_descr *hwdescr = descr->hwdescr; | ||
383 | dma_addr_t buf; | 424 | dma_addr_t buf; |
384 | int offset; | 425 | int offset; |
385 | int bufsize; | 426 | int bufsize; |
@@ -398,11 +439,11 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, | |||
398 | card->spider_stats.alloc_rx_skb_error++; | 439 | card->spider_stats.alloc_rx_skb_error++; |
399 | return -ENOMEM; | 440 | return -ENOMEM; |
400 | } | 441 | } |
401 | descr->buf_size = bufsize; | 442 | hwdescr->buf_size = bufsize; |
402 | descr->result_size = 0; | 443 | hwdescr->result_size = 0; |
403 | descr->valid_size = 0; | 444 | hwdescr->valid_size = 0; |
404 | descr->data_status = 0; | 445 | hwdescr->data_status = 0; |
405 | descr->data_error = 0; | 446 | hwdescr->data_error = 0; |
406 | 447 | ||
407 | offset = ((unsigned long)descr->skb->data) & | 448 | offset = ((unsigned long)descr->skb->data) & |
408 | (SPIDER_NET_RXBUF_ALIGN - 1); | 449 | (SPIDER_NET_RXBUF_ALIGN - 1); |
@@ -411,21 +452,22 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, | |||
411 | /* iommu-map the skb */ | 452 | /* iommu-map the skb */ |
412 | buf = pci_map_single(card->pdev, descr->skb->data, | 453 | buf = pci_map_single(card->pdev, descr->skb->data, |
413 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); | 454 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); |
414 | descr->buf_addr = buf; | ||
415 | if (pci_dma_mapping_error(buf)) { | 455 | if (pci_dma_mapping_error(buf)) { |
416 | dev_kfree_skb_any(descr->skb); | 456 | dev_kfree_skb_any(descr->skb); |
457 | descr->skb = NULL; | ||
417 | if (netif_msg_rx_err(card) && net_ratelimit()) | 458 | if (netif_msg_rx_err(card) && net_ratelimit()) |
418 | pr_err("Could not iommu-map rx buffer\n"); | 459 | pr_err("Could not iommu-map rx buffer\n"); |
419 | card->spider_stats.rx_iommu_map_error++; | 460 | card->spider_stats.rx_iommu_map_error++; |
420 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | 461 | hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |
421 | } else { | 462 | } else { |
422 | descr->next_descr_addr = 0; | 463 | hwdescr->buf_addr = buf; |
464 | hwdescr->next_descr_addr = 0; | ||
423 | wmb(); | 465 | wmb(); |
424 | descr->dmac_cmd_status = SPIDER_NET_DESCR_CARDOWNED | | 466 | hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_CARDOWNED | |
425 | SPIDER_NET_DMAC_NOINTR_COMPLETE; | 467 | SPIDER_NET_DMAC_NOINTR_COMPLETE; |
426 | 468 | ||
427 | wmb(); | 469 | wmb(); |
428 | descr->prev->next_descr_addr = descr->bus_addr; | 470 | descr->prev->hwdescr->next_descr_addr = descr->bus_addr; |
429 | } | 471 | } |
430 | 472 | ||
431 | return 0; | 473 | return 0; |
@@ -481,7 +523,7 @@ spider_net_refill_rx_chain(struct spider_net_card *card) | |||
481 | if (!spin_trylock_irqsave(&chain->lock, flags)) | 523 | if (!spin_trylock_irqsave(&chain->lock, flags)) |
482 | return; | 524 | return; |
483 | 525 | ||
484 | while (spider_net_get_descr_status(chain->head) == | 526 | while (spider_net_get_descr_status(chain->head->hwdescr) == |
485 | SPIDER_NET_DESCR_NOT_IN_USE) { | 527 | SPIDER_NET_DESCR_NOT_IN_USE) { |
486 | if (spider_net_prepare_rx_descr(card, chain->head)) | 528 | if (spider_net_prepare_rx_descr(card, chain->head)) |
487 | break; | 529 | break; |
@@ -642,7 +684,9 @@ static int | |||
642 | spider_net_prepare_tx_descr(struct spider_net_card *card, | 684 | spider_net_prepare_tx_descr(struct spider_net_card *card, |
643 | struct sk_buff *skb) | 685 | struct sk_buff *skb) |
644 | { | 686 | { |
687 | struct spider_net_descr_chain *chain = &card->tx_chain; | ||
645 | struct spider_net_descr *descr; | 688 | struct spider_net_descr *descr; |
689 | struct spider_net_hw_descr *hwdescr; | ||
646 | dma_addr_t buf; | 690 | dma_addr_t buf; |
647 | unsigned long flags; | 691 | unsigned long flags; |
648 | 692 | ||
@@ -655,32 +699,39 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, | |||
655 | return -ENOMEM; | 699 | return -ENOMEM; |
656 | } | 700 | } |
657 | 701 | ||
658 | spin_lock_irqsave(&card->tx_chain.lock, flags); | 702 | spin_lock_irqsave(&chain->lock, flags); |
659 | descr = card->tx_chain.head; | 703 | descr = card->tx_chain.head; |
660 | card->tx_chain.head = descr->next; | 704 | if (descr->next == chain->tail->prev) { |
705 | spin_unlock_irqrestore(&chain->lock, flags); | ||
706 | pci_unmap_single(card->pdev, buf, skb->len, PCI_DMA_TODEVICE); | ||
707 | return -ENOMEM; | ||
708 | } | ||
709 | hwdescr = descr->hwdescr; | ||
710 | chain->head = descr->next; | ||
661 | 711 | ||
662 | descr->buf_addr = buf; | ||
663 | descr->buf_size = skb->len; | ||
664 | descr->next_descr_addr = 0; | ||
665 | descr->skb = skb; | 712 | descr->skb = skb; |
666 | descr->data_status = 0; | 713 | hwdescr->buf_addr = buf; |
714 | hwdescr->buf_size = skb->len; | ||
715 | hwdescr->next_descr_addr = 0; | ||
716 | hwdescr->data_status = 0; | ||
667 | 717 | ||
668 | descr->dmac_cmd_status = | 718 | hwdescr->dmac_cmd_status = |
669 | SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS; | 719 | SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS; |
670 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); | 720 | spin_unlock_irqrestore(&chain->lock, flags); |
671 | 721 | ||
672 | if (skb->protocol == htons(ETH_P_IP)) | 722 | if (skb->protocol == htons(ETH_P_IP)) |
673 | switch (skb->nh.iph->protocol) { | 723 | switch (skb->nh.iph->protocol) { |
674 | case IPPROTO_TCP: | 724 | case IPPROTO_TCP: |
675 | descr->dmac_cmd_status |= SPIDER_NET_DMAC_TCP; | 725 | hwdescr->dmac_cmd_status |= SPIDER_NET_DMAC_TCP; |
676 | break; | 726 | break; |
677 | case IPPROTO_UDP: | 727 | case IPPROTO_UDP: |
678 | descr->dmac_cmd_status |= SPIDER_NET_DMAC_UDP; | 728 | hwdescr->dmac_cmd_status |= SPIDER_NET_DMAC_UDP; |
679 | break; | 729 | break; |
680 | } | 730 | } |
681 | 731 | ||
682 | /* Chain the bus address, so that the DMA engine finds this descr. */ | 732 | /* Chain the bus address, so that the DMA engine finds this descr. */ |
683 | descr->prev->next_descr_addr = descr->bus_addr; | 733 | wmb(); |
734 | descr->prev->hwdescr->next_descr_addr = descr->bus_addr; | ||
684 | 735 | ||
685 | card->netdev->trans_start = jiffies; /* set netdev watchdog timer */ | 736 | card->netdev->trans_start = jiffies; /* set netdev watchdog timer */ |
686 | return 0; | 737 | return 0; |
@@ -689,16 +740,17 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, | |||
689 | static int | 740 | static int |
690 | spider_net_set_low_watermark(struct spider_net_card *card) | 741 | spider_net_set_low_watermark(struct spider_net_card *card) |
691 | { | 742 | { |
743 | struct spider_net_descr *descr = card->tx_chain.tail; | ||
744 | struct spider_net_hw_descr *hwdescr; | ||
692 | unsigned long flags; | 745 | unsigned long flags; |
693 | int status; | 746 | int status; |
694 | int cnt=0; | 747 | int cnt=0; |
695 | int i; | 748 | int i; |
696 | struct spider_net_descr *descr = card->tx_chain.tail; | ||
697 | 749 | ||
698 | /* Measure the length of the queue. Measurement does not | 750 | /* Measure the length of the queue. Measurement does not |
699 | * need to be precise -- does not need a lock. */ | 751 | * need to be precise -- does not need a lock. */ |
700 | while (descr != card->tx_chain.head) { | 752 | while (descr != card->tx_chain.head) { |
701 | status = descr->dmac_cmd_status & SPIDER_NET_DESCR_NOT_IN_USE; | 753 | status = descr->hwdescr->dmac_cmd_status & SPIDER_NET_DESCR_NOT_IN_USE; |
702 | if (status == SPIDER_NET_DESCR_NOT_IN_USE) | 754 | if (status == SPIDER_NET_DESCR_NOT_IN_USE) |
703 | break; | 755 | break; |
704 | descr = descr->next; | 756 | descr = descr->next; |
@@ -717,10 +769,12 @@ spider_net_set_low_watermark(struct spider_net_card *card) | |||
717 | 769 | ||
718 | /* Set the new watermark, clear the old watermark */ | 770 | /* Set the new watermark, clear the old watermark */ |
719 | spin_lock_irqsave(&card->tx_chain.lock, flags); | 771 | spin_lock_irqsave(&card->tx_chain.lock, flags); |
720 | descr->dmac_cmd_status |= SPIDER_NET_DESCR_TXDESFLG; | 772 | descr->hwdescr->dmac_cmd_status |= SPIDER_NET_DESCR_TXDESFLG; |
721 | if (card->low_watermark && card->low_watermark != descr) | 773 | if (card->low_watermark && card->low_watermark != descr) { |
722 | card->low_watermark->dmac_cmd_status = | 774 | hwdescr = card->low_watermark->hwdescr; |
723 | card->low_watermark->dmac_cmd_status & ~SPIDER_NET_DESCR_TXDESFLG; | 775 | hwdescr->dmac_cmd_status = |
776 | hwdescr->dmac_cmd_status & ~SPIDER_NET_DESCR_TXDESFLG; | ||
777 | } | ||
724 | card->low_watermark = descr; | 778 | card->low_watermark = descr; |
725 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); | 779 | spin_unlock_irqrestore(&card->tx_chain.lock, flags); |
726 | return cnt; | 780 | return cnt; |
@@ -743,16 +797,22 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal) | |||
743 | { | 797 | { |
744 | struct spider_net_descr_chain *chain = &card->tx_chain; | 798 | struct spider_net_descr_chain *chain = &card->tx_chain; |
745 | struct spider_net_descr *descr; | 799 | struct spider_net_descr *descr; |
800 | struct spider_net_hw_descr *hwdescr; | ||
746 | struct sk_buff *skb; | 801 | struct sk_buff *skb; |
747 | u32 buf_addr; | 802 | u32 buf_addr; |
748 | unsigned long flags; | 803 | unsigned long flags; |
749 | int status; | 804 | int status; |
750 | 805 | ||
751 | while (chain->tail != chain->head) { | 806 | while (1) { |
752 | spin_lock_irqsave(&chain->lock, flags); | 807 | spin_lock_irqsave(&chain->lock, flags); |
808 | if (chain->tail == chain->head) { | ||
809 | spin_unlock_irqrestore(&chain->lock, flags); | ||
810 | return 0; | ||
811 | } | ||
753 | descr = chain->tail; | 812 | descr = chain->tail; |
813 | hwdescr = descr->hwdescr; | ||
754 | 814 | ||
755 | status = spider_net_get_descr_status(descr); | 815 | status = spider_net_get_descr_status(hwdescr); |
756 | switch (status) { | 816 | switch (status) { |
757 | case SPIDER_NET_DESCR_COMPLETE: | 817 | case SPIDER_NET_DESCR_COMPLETE: |
758 | card->netdev_stats.tx_packets++; | 818 | card->netdev_stats.tx_packets++; |
@@ -788,9 +848,10 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal) | |||
788 | } | 848 | } |
789 | 849 | ||
790 | chain->tail = descr->next; | 850 | chain->tail = descr->next; |
791 | descr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE; | 851 | hwdescr->dmac_cmd_status |= SPIDER_NET_DESCR_NOT_IN_USE; |
792 | skb = descr->skb; | 852 | skb = descr->skb; |
793 | buf_addr = descr->buf_addr; | 853 | descr->skb = NULL; |
854 | buf_addr = hwdescr->buf_addr; | ||
794 | spin_unlock_irqrestore(&chain->lock, flags); | 855 | spin_unlock_irqrestore(&chain->lock, flags); |
795 | 856 | ||
796 | /* unmap the skb */ | 857 | /* unmap the skb */ |
@@ -826,7 +887,7 @@ spider_net_kick_tx_dma(struct spider_net_card *card) | |||
826 | 887 | ||
827 | descr = card->tx_chain.tail; | 888 | descr = card->tx_chain.tail; |
828 | for (;;) { | 889 | for (;;) { |
829 | if (spider_net_get_descr_status(descr) == | 890 | if (spider_net_get_descr_status(descr->hwdescr) == |
830 | SPIDER_NET_DESCR_CARDOWNED) { | 891 | SPIDER_NET_DESCR_CARDOWNED) { |
831 | spider_net_write_reg(card, SPIDER_NET_GDTDCHA, | 892 | spider_net_write_reg(card, SPIDER_NET_GDTDCHA, |
832 | descr->bus_addr); | 893 | descr->bus_addr); |
@@ -855,13 +916,10 @@ spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
855 | { | 916 | { |
856 | int cnt; | 917 | int cnt; |
857 | struct spider_net_card *card = netdev_priv(netdev); | 918 | struct spider_net_card *card = netdev_priv(netdev); |
858 | struct spider_net_descr_chain *chain = &card->tx_chain; | ||
859 | 919 | ||
860 | spider_net_release_tx_chain(card, 0); | 920 | spider_net_release_tx_chain(card, 0); |
861 | 921 | ||
862 | if ((chain->head->next == chain->tail->prev) || | 922 | if (spider_net_prepare_tx_descr(card, skb) != 0) { |
863 | (spider_net_prepare_tx_descr(card, skb) != 0)) { | ||
864 | |||
865 | card->netdev_stats.tx_dropped++; | 923 | card->netdev_stats.tx_dropped++; |
866 | netif_stop_queue(netdev); | 924 | netif_stop_queue(netdev); |
867 | return NETDEV_TX_BUSY; | 925 | return NETDEV_TX_BUSY; |
@@ -922,17 +980,18 @@ static void | |||
922 | spider_net_pass_skb_up(struct spider_net_descr *descr, | 980 | spider_net_pass_skb_up(struct spider_net_descr *descr, |
923 | struct spider_net_card *card) | 981 | struct spider_net_card *card) |
924 | { | 982 | { |
983 | struct spider_net_hw_descr *hwdescr= descr->hwdescr; | ||
925 | struct sk_buff *skb; | 984 | struct sk_buff *skb; |
926 | struct net_device *netdev; | 985 | struct net_device *netdev; |
927 | u32 data_status, data_error; | 986 | u32 data_status, data_error; |
928 | 987 | ||
929 | data_status = descr->data_status; | 988 | data_status = hwdescr->data_status; |
930 | data_error = descr->data_error; | 989 | data_error = hwdescr->data_error; |
931 | netdev = card->netdev; | 990 | netdev = card->netdev; |
932 | 991 | ||
933 | skb = descr->skb; | 992 | skb = descr->skb; |
934 | skb->dev = netdev; | 993 | skb->dev = netdev; |
935 | skb_put(skb, descr->valid_size); | 994 | skb_put(skb, hwdescr->valid_size); |
936 | 995 | ||
937 | /* the card seems to add 2 bytes of junk in front | 996 | /* the card seems to add 2 bytes of junk in front |
938 | * of the ethernet frame */ | 997 | * of the ethernet frame */ |
@@ -994,23 +1053,25 @@ static void show_rx_chain(struct spider_net_card *card) | |||
994 | #endif | 1053 | #endif |
995 | 1054 | ||
996 | /** | 1055 | /** |
997 | * spider_net_decode_one_descr - processes an rx descriptor | 1056 | * spider_net_decode_one_descr - processes an RX descriptor |
998 | * @card: card structure | 1057 | * @card: card structure |
999 | * | 1058 | * |
1000 | * Returns 1 if a packet has been sent to the stack, otherwise 0 | 1059 | * Returns 1 if a packet has been sent to the stack, otherwise 0. |
1001 | * | 1060 | * |
1002 | * Processes an rx descriptor by iommu-unmapping the data buffer and passing | 1061 | * Processes an RX descriptor by iommu-unmapping the data buffer |
1003 | * the packet up to the stack. This function is called in softirq | 1062 | * and passing the packet up to the stack. This function is called |
1004 | * context, e.g. either bottom half from interrupt or NAPI polling context | 1063 | * in softirq context, e.g. either bottom half from interrupt or |
1064 | * NAPI polling context. | ||
1005 | */ | 1065 | */ |
1006 | static int | 1066 | static int |
1007 | spider_net_decode_one_descr(struct spider_net_card *card) | 1067 | spider_net_decode_one_descr(struct spider_net_card *card) |
1008 | { | 1068 | { |
1009 | struct spider_net_descr_chain *chain = &card->rx_chain; | 1069 | struct spider_net_descr_chain *chain = &card->rx_chain; |
1010 | struct spider_net_descr *descr = chain->tail; | 1070 | struct spider_net_descr *descr = chain->tail; |
1071 | struct spider_net_hw_descr *hwdescr = descr->hwdescr; | ||
1011 | int status; | 1072 | int status; |
1012 | 1073 | ||
1013 | status = spider_net_get_descr_status(descr); | 1074 | status = spider_net_get_descr_status(hwdescr); |
1014 | 1075 | ||
1015 | /* Nothing in the descriptor, or ring must be empty */ | 1076 | /* Nothing in the descriptor, or ring must be empty */ |
1016 | if ((status == SPIDER_NET_DESCR_CARDOWNED) || | 1077 | if ((status == SPIDER_NET_DESCR_CARDOWNED) || |
@@ -1021,7 +1082,7 @@ spider_net_decode_one_descr(struct spider_net_card *card) | |||
1021 | chain->tail = descr->next; | 1082 | chain->tail = descr->next; |
1022 | 1083 | ||
1023 | /* unmap descriptor */ | 1084 | /* unmap descriptor */ |
1024 | pci_unmap_single(card->pdev, descr->buf_addr, | 1085 | pci_unmap_single(card->pdev, hwdescr->buf_addr, |
1025 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); | 1086 | SPIDER_NET_MAX_FRAME, PCI_DMA_FROMDEVICE); |
1026 | 1087 | ||
1027 | if ( (status == SPIDER_NET_DESCR_RESPONSE_ERROR) || | 1088 | if ( (status == SPIDER_NET_DESCR_RESPONSE_ERROR) || |
@@ -1037,34 +1098,33 @@ spider_net_decode_one_descr(struct spider_net_card *card) | |||
1037 | if ( (status != SPIDER_NET_DESCR_COMPLETE) && | 1098 | if ( (status != SPIDER_NET_DESCR_COMPLETE) && |
1038 | (status != SPIDER_NET_DESCR_FRAME_END) ) { | 1099 | (status != SPIDER_NET_DESCR_FRAME_END) ) { |
1039 | if (netif_msg_rx_err(card)) | 1100 | if (netif_msg_rx_err(card)) |
1040 | pr_err("%s: RX descriptor with unkown state %d\n", | 1101 | pr_err("%s: RX descriptor with unknown state %d\n", |
1041 | card->netdev->name, status); | 1102 | card->netdev->name, status); |
1042 | card->spider_stats.rx_desc_unk_state++; | 1103 | card->spider_stats.rx_desc_unk_state++; |
1043 | goto bad_desc; | 1104 | goto bad_desc; |
1044 | } | 1105 | } |
1045 | 1106 | ||
1046 | /* The cases we'll throw away the packet immediately */ | 1107 | /* The cases we'll throw away the packet immediately */ |
1047 | if (descr->data_error & SPIDER_NET_DESTROY_RX_FLAGS) { | 1108 | if (hwdescr->data_error & SPIDER_NET_DESTROY_RX_FLAGS) { |
1048 | if (netif_msg_rx_err(card)) | 1109 | if (netif_msg_rx_err(card)) |
1049 | pr_err("%s: error in received descriptor found, " | 1110 | pr_err("%s: error in received descriptor found, " |
1050 | "data_status=x%08x, data_error=x%08x\n", | 1111 | "data_status=x%08x, data_error=x%08x\n", |
1051 | card->netdev->name, | 1112 | card->netdev->name, |
1052 | descr->data_status, descr->data_error); | 1113 | hwdescr->data_status, hwdescr->data_error); |
1053 | goto bad_desc; | 1114 | goto bad_desc; |
1054 | } | 1115 | } |
1055 | 1116 | ||
1056 | if (descr->dmac_cmd_status & 0xfefe) { | 1117 | if (hwdescr->dmac_cmd_status & 0xfefe) { |
1057 | pr_err("%s: bad status, cmd_status=x%08x\n", | 1118 | pr_err("%s: bad status, cmd_status=x%08x\n", |
1058 | card->netdev->name, | 1119 | card->netdev->name, |
1059 | descr->dmac_cmd_status); | 1120 | hwdescr->dmac_cmd_status); |
1060 | pr_err("buf_addr=x%08x\n", descr->buf_addr); | 1121 | pr_err("buf_addr=x%08x\n", hwdescr->buf_addr); |
1061 | pr_err("buf_size=x%08x\n", descr->buf_size); | 1122 | pr_err("buf_size=x%08x\n", hwdescr->buf_size); |
1062 | pr_err("next_descr_addr=x%08x\n", descr->next_descr_addr); | 1123 | pr_err("next_descr_addr=x%08x\n", hwdescr->next_descr_addr); |
1063 | pr_err("result_size=x%08x\n", descr->result_size); | 1124 | pr_err("result_size=x%08x\n", hwdescr->result_size); |
1064 | pr_err("valid_size=x%08x\n", descr->valid_size); | 1125 | pr_err("valid_size=x%08x\n", hwdescr->valid_size); |
1065 | pr_err("data_status=x%08x\n", descr->data_status); | 1126 | pr_err("data_status=x%08x\n", hwdescr->data_status); |
1066 | pr_err("data_error=x%08x\n", descr->data_error); | 1127 | pr_err("data_error=x%08x\n", hwdescr->data_error); |
1067 | pr_err("bus_addr=x%08x\n", descr->bus_addr); | ||
1068 | pr_err("which=%ld\n", descr - card->rx_chain.ring); | 1128 | pr_err("which=%ld\n", descr - card->rx_chain.ring); |
1069 | 1129 | ||
1070 | card->spider_stats.rx_desc_error++; | 1130 | card->spider_stats.rx_desc_error++; |
@@ -1073,12 +1133,13 @@ spider_net_decode_one_descr(struct spider_net_card *card) | |||
1073 | 1133 | ||
1074 | /* Ok, we've got a packet in descr */ | 1134 | /* Ok, we've got a packet in descr */ |
1075 | spider_net_pass_skb_up(descr, card); | 1135 | spider_net_pass_skb_up(descr, card); |
1076 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | 1136 | hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |
1077 | return 1; | 1137 | return 1; |
1078 | 1138 | ||
1079 | bad_desc: | 1139 | bad_desc: |
1080 | dev_kfree_skb_irq(descr->skb); | 1140 | dev_kfree_skb_irq(descr->skb); |
1081 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | 1141 | descr->skb = NULL; |
1142 | hwdescr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | ||
1082 | return 0; | 1143 | return 0; |
1083 | } | 1144 | } |
1084 | 1145 | ||
@@ -1248,6 +1309,33 @@ spider_net_set_mac(struct net_device *netdev, void *p) | |||
1248 | } | 1309 | } |
1249 | 1310 | ||
1250 | /** | 1311 | /** |
1312 | * spider_net_link_reset | ||
1313 | * @netdev: net device structure | ||
1314 | * | ||
1315 | * This is called when the PHY_LINK signal is asserted. For the blade this is | ||
1316 | * not connected so we should never get here. | ||
1317 | * | ||
1318 | */ | ||
1319 | static void | ||
1320 | spider_net_link_reset(struct net_device *netdev) | ||
1321 | { | ||
1322 | |||
1323 | struct spider_net_card *card = netdev_priv(netdev); | ||
1324 | |||
1325 | del_timer_sync(&card->aneg_timer); | ||
1326 | |||
1327 | /* clear interrupt, block further interrupts */ | ||
1328 | spider_net_write_reg(card, SPIDER_NET_GMACST, | ||
1329 | spider_net_read_reg(card, SPIDER_NET_GMACST)); | ||
1330 | spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0); | ||
1331 | |||
1332 | /* reset phy and setup aneg */ | ||
1333 | spider_net_setup_aneg(card); | ||
1334 | mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER); | ||
1335 | |||
1336 | } | ||
1337 | |||
1338 | /** | ||
1251 | * spider_net_handle_error_irq - handles errors raised by an interrupt | 1339 | * spider_net_handle_error_irq - handles errors raised by an interrupt |
1252 | * @card: card structure | 1340 | * @card: card structure |
1253 | * @status_reg: interrupt status register 0 (GHIINT0STS) | 1341 | * @status_reg: interrupt status register 0 (GHIINT0STS) |
@@ -1359,8 +1447,8 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) | |||
1359 | switch (i) | 1447 | switch (i) |
1360 | { | 1448 | { |
1361 | case SPIDER_NET_GTMFLLINT: | 1449 | case SPIDER_NET_GTMFLLINT: |
1362 | if (netif_msg_intr(card) && net_ratelimit()) | 1450 | /* TX RAM full may happen on a usual case. |
1363 | pr_err("Spider TX RAM full\n"); | 1451 | * Logging is not needed. */ |
1364 | show_error = 0; | 1452 | show_error = 0; |
1365 | break; | 1453 | break; |
1366 | case SPIDER_NET_GRFDFLLINT: /* fallthrough */ | 1454 | case SPIDER_NET_GRFDFLLINT: /* fallthrough */ |
@@ -1500,6 +1588,9 @@ spider_net_interrupt(int irq, void *ptr) | |||
1500 | if (status_reg & SPIDER_NET_TXINT) | 1588 | if (status_reg & SPIDER_NET_TXINT) |
1501 | netif_rx_schedule(netdev); | 1589 | netif_rx_schedule(netdev); |
1502 | 1590 | ||
1591 | if (status_reg & SPIDER_NET_LINKINT) | ||
1592 | spider_net_link_reset(netdev); | ||
1593 | |||
1503 | if (status_reg & SPIDER_NET_ERRINT ) | 1594 | if (status_reg & SPIDER_NET_ERRINT ) |
1504 | spider_net_handle_error_irq(card, status_reg); | 1595 | spider_net_handle_error_irq(card, status_reg); |
1505 | 1596 | ||
@@ -1540,6 +1631,11 @@ spider_net_init_card(struct spider_net_card *card) | |||
1540 | 1631 | ||
1541 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, | 1632 | spider_net_write_reg(card, SPIDER_NET_CKRCTRL, |
1542 | SPIDER_NET_CKRCTRL_RUN_VALUE); | 1633 | SPIDER_NET_CKRCTRL_RUN_VALUE); |
1634 | |||
1635 | /* trigger ETOMOD signal */ | ||
1636 | spider_net_write_reg(card, SPIDER_NET_GMACOPEMD, | ||
1637 | spider_net_read_reg(card, SPIDER_NET_GMACOPEMD) | 0x4); | ||
1638 | |||
1543 | } | 1639 | } |
1544 | 1640 | ||
1545 | /** | 1641 | /** |
@@ -1624,8 +1720,6 @@ spider_net_enable_card(struct spider_net_card *card) | |||
1624 | 1720 | ||
1625 | spider_net_write_reg(card, SPIDER_NET_GMACLENLMT, | 1721 | spider_net_write_reg(card, SPIDER_NET_GMACLENLMT, |
1626 | SPIDER_NET_LENLMT_VALUE); | 1722 | SPIDER_NET_LENLMT_VALUE); |
1627 | spider_net_write_reg(card, SPIDER_NET_GMACMODE, | ||
1628 | SPIDER_NET_MACMODE_VALUE); | ||
1629 | spider_net_write_reg(card, SPIDER_NET_GMACOPEMD, | 1723 | spider_net_write_reg(card, SPIDER_NET_GMACOPEMD, |
1630 | SPIDER_NET_OPMODE_VALUE); | 1724 | SPIDER_NET_OPMODE_VALUE); |
1631 | 1725 | ||
@@ -1642,98 +1736,6 @@ spider_net_enable_card(struct spider_net_card *card) | |||
1642 | } | 1736 | } |
1643 | 1737 | ||
1644 | /** | 1738 | /** |
1645 | * spider_net_open - called upon ifonfig up | ||
1646 | * @netdev: interface device structure | ||
1647 | * | ||
1648 | * returns 0 on success, <0 on failure | ||
1649 | * | ||
1650 | * spider_net_open allocates all the descriptors and memory needed for | ||
1651 | * operation, sets up multicast list and enables interrupts | ||
1652 | */ | ||
1653 | int | ||
1654 | spider_net_open(struct net_device *netdev) | ||
1655 | { | ||
1656 | struct spider_net_card *card = netdev_priv(netdev); | ||
1657 | int result; | ||
1658 | |||
1659 | result = spider_net_init_chain(card, &card->tx_chain); | ||
1660 | if (result) | ||
1661 | goto alloc_tx_failed; | ||
1662 | card->low_watermark = NULL; | ||
1663 | |||
1664 | result = spider_net_init_chain(card, &card->rx_chain); | ||
1665 | if (result) | ||
1666 | goto alloc_rx_failed; | ||
1667 | |||
1668 | /* Allocate rx skbs */ | ||
1669 | if (spider_net_alloc_rx_skbs(card)) | ||
1670 | goto alloc_skbs_failed; | ||
1671 | |||
1672 | spider_net_set_multi(netdev); | ||
1673 | |||
1674 | /* further enhancement: setup hw vlan, if needed */ | ||
1675 | |||
1676 | result = -EBUSY; | ||
1677 | if (request_irq(netdev->irq, spider_net_interrupt, | ||
1678 | IRQF_SHARED, netdev->name, netdev)) | ||
1679 | goto register_int_failed; | ||
1680 | |||
1681 | spider_net_enable_card(card); | ||
1682 | |||
1683 | netif_start_queue(netdev); | ||
1684 | netif_carrier_on(netdev); | ||
1685 | netif_poll_enable(netdev); | ||
1686 | |||
1687 | return 0; | ||
1688 | |||
1689 | register_int_failed: | ||
1690 | spider_net_free_rx_chain_contents(card); | ||
1691 | alloc_skbs_failed: | ||
1692 | spider_net_free_chain(card, &card->rx_chain); | ||
1693 | alloc_rx_failed: | ||
1694 | spider_net_free_chain(card, &card->tx_chain); | ||
1695 | alloc_tx_failed: | ||
1696 | return result; | ||
1697 | } | ||
1698 | |||
1699 | /** | ||
1700 | * spider_net_setup_phy - setup PHY | ||
1701 | * @card: card structure | ||
1702 | * | ||
1703 | * returns 0 on success, <0 on failure | ||
1704 | * | ||
1705 | * spider_net_setup_phy is used as part of spider_net_probe. Sets | ||
1706 | * the PHY to 1000 Mbps | ||
1707 | **/ | ||
1708 | static int | ||
1709 | spider_net_setup_phy(struct spider_net_card *card) | ||
1710 | { | ||
1711 | struct mii_phy *phy = &card->phy; | ||
1712 | |||
1713 | spider_net_write_reg(card, SPIDER_NET_GDTDMASEL, | ||
1714 | SPIDER_NET_DMASEL_VALUE); | ||
1715 | spider_net_write_reg(card, SPIDER_NET_GPCCTRL, | ||
1716 | SPIDER_NET_PHY_CTRL_VALUE); | ||
1717 | phy->mii_id = 1; | ||
1718 | phy->dev = card->netdev; | ||
1719 | phy->mdio_read = spider_net_read_phy; | ||
1720 | phy->mdio_write = spider_net_write_phy; | ||
1721 | |||
1722 | mii_phy_probe(phy, phy->mii_id); | ||
1723 | |||
1724 | if (phy->def->ops->setup_forced) | ||
1725 | phy->def->ops->setup_forced(phy, SPEED_1000, DUPLEX_FULL); | ||
1726 | |||
1727 | phy->def->ops->enable_fiber(phy); | ||
1728 | |||
1729 | phy->def->ops->read_link(phy); | ||
1730 | pr_info("Found %s with %i Mbps, %s-duplex.\n", phy->def->name, | ||
1731 | phy->speed, phy->duplex==1 ? "Full" : "Half"); | ||
1732 | |||
1733 | return 0; | ||
1734 | } | ||
1735 | |||
1736 | /** | ||
1737 | * spider_net_download_firmware - loads firmware into the adapter | 1739 | * spider_net_download_firmware - loads firmware into the adapter |
1738 | * @card: card structure | 1740 | * @card: card structure |
1739 | * @firmware_ptr: pointer to firmware data | 1741 | * @firmware_ptr: pointer to firmware data |
@@ -1852,6 +1854,179 @@ out_err: | |||
1852 | } | 1854 | } |
1853 | 1855 | ||
1854 | /** | 1856 | /** |
1857 | * spider_net_open - called upon ifonfig up | ||
1858 | * @netdev: interface device structure | ||
1859 | * | ||
1860 | * returns 0 on success, <0 on failure | ||
1861 | * | ||
1862 | * spider_net_open allocates all the descriptors and memory needed for | ||
1863 | * operation, sets up multicast list and enables interrupts | ||
1864 | */ | ||
1865 | int | ||
1866 | spider_net_open(struct net_device *netdev) | ||
1867 | { | ||
1868 | struct spider_net_card *card = netdev_priv(netdev); | ||
1869 | int result; | ||
1870 | |||
1871 | result = spider_net_init_firmware(card); | ||
1872 | if (result) | ||
1873 | goto init_firmware_failed; | ||
1874 | |||
1875 | /* start probing with copper */ | ||
1876 | spider_net_setup_aneg(card); | ||
1877 | if (card->phy.def->phy_id) | ||
1878 | mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER); | ||
1879 | |||
1880 | result = spider_net_init_chain(card, &card->tx_chain); | ||
1881 | if (result) | ||
1882 | goto alloc_tx_failed; | ||
1883 | card->low_watermark = NULL; | ||
1884 | |||
1885 | result = spider_net_init_chain(card, &card->rx_chain); | ||
1886 | if (result) | ||
1887 | goto alloc_rx_failed; | ||
1888 | |||
1889 | /* Allocate rx skbs */ | ||
1890 | if (spider_net_alloc_rx_skbs(card)) | ||
1891 | goto alloc_skbs_failed; | ||
1892 | |||
1893 | spider_net_set_multi(netdev); | ||
1894 | |||
1895 | /* further enhancement: setup hw vlan, if needed */ | ||
1896 | |||
1897 | result = -EBUSY; | ||
1898 | if (request_irq(netdev->irq, spider_net_interrupt, | ||
1899 | IRQF_SHARED, netdev->name, netdev)) | ||
1900 | goto register_int_failed; | ||
1901 | |||
1902 | spider_net_enable_card(card); | ||
1903 | |||
1904 | netif_start_queue(netdev); | ||
1905 | netif_carrier_on(netdev); | ||
1906 | netif_poll_enable(netdev); | ||
1907 | |||
1908 | return 0; | ||
1909 | |||
1910 | register_int_failed: | ||
1911 | spider_net_free_rx_chain_contents(card); | ||
1912 | alloc_skbs_failed: | ||
1913 | spider_net_free_chain(card, &card->rx_chain); | ||
1914 | alloc_rx_failed: | ||
1915 | spider_net_free_chain(card, &card->tx_chain); | ||
1916 | alloc_tx_failed: | ||
1917 | del_timer_sync(&card->aneg_timer); | ||
1918 | init_firmware_failed: | ||
1919 | return result; | ||
1920 | } | ||
1921 | |||
1922 | /** | ||
1923 | * spider_net_link_phy | ||
1924 | * @data: used for pointer to card structure | ||
1925 | * | ||
1926 | */ | ||
1927 | static void spider_net_link_phy(unsigned long data) | ||
1928 | { | ||
1929 | struct spider_net_card *card = (struct spider_net_card *)data; | ||
1930 | struct mii_phy *phy = &card->phy; | ||
1931 | |||
1932 | /* if link didn't come up after SPIDER_NET_ANEG_TIMEOUT tries, setup phy again */ | ||
1933 | if (card->aneg_count > SPIDER_NET_ANEG_TIMEOUT) { | ||
1934 | |||
1935 | pr_info("%s: link is down trying to bring it up\n", card->netdev->name); | ||
1936 | |||
1937 | switch (card->medium) { | ||
1938 | case BCM54XX_COPPER: | ||
1939 | /* enable fiber with autonegotiation first */ | ||
1940 | if (phy->def->ops->enable_fiber) | ||
1941 | phy->def->ops->enable_fiber(phy, 1); | ||
1942 | card->medium = BCM54XX_FIBER; | ||
1943 | break; | ||
1944 | |||
1945 | case BCM54XX_FIBER: | ||
1946 | /* fiber didn't come up, try to disable fiber autoneg */ | ||
1947 | if (phy->def->ops->enable_fiber) | ||
1948 | phy->def->ops->enable_fiber(phy, 0); | ||
1949 | card->medium = BCM54XX_UNKNOWN; | ||
1950 | break; | ||
1951 | |||
1952 | case BCM54XX_UNKNOWN: | ||
1953 | /* copper, fiber with and without failed, | ||
1954 | * retry from beginning */ | ||
1955 | spider_net_setup_aneg(card); | ||
1956 | card->medium = BCM54XX_COPPER; | ||
1957 | break; | ||
1958 | } | ||
1959 | |||
1960 | card->aneg_count = 0; | ||
1961 | mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER); | ||
1962 | return; | ||
1963 | } | ||
1964 | |||
1965 | /* link still not up, try again later */ | ||
1966 | if (!(phy->def->ops->poll_link(phy))) { | ||
1967 | card->aneg_count++; | ||
1968 | mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER); | ||
1969 | return; | ||
1970 | } | ||
1971 | |||
1972 | /* link came up, get abilities */ | ||
1973 | phy->def->ops->read_link(phy); | ||
1974 | |||
1975 | spider_net_write_reg(card, SPIDER_NET_GMACST, | ||
1976 | spider_net_read_reg(card, SPIDER_NET_GMACST)); | ||
1977 | spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0x4); | ||
1978 | |||
1979 | if (phy->speed == 1000) | ||
1980 | spider_net_write_reg(card, SPIDER_NET_GMACMODE, 0x00000001); | ||
1981 | else | ||
1982 | spider_net_write_reg(card, SPIDER_NET_GMACMODE, 0); | ||
1983 | |||
1984 | card->aneg_count = 0; | ||
1985 | |||
1986 | pr_debug("Found %s with %i Mbps, %s-duplex %sautoneg.\n", | ||
1987 | phy->def->name, phy->speed, phy->duplex==1 ? "Full" : "Half", | ||
1988 | phy->autoneg==1 ? "" : "no "); | ||
1989 | |||
1990 | return; | ||
1991 | } | ||
1992 | |||
1993 | /** | ||
1994 | * spider_net_setup_phy - setup PHY | ||
1995 | * @card: card structure | ||
1996 | * | ||
1997 | * returns 0 on success, <0 on failure | ||
1998 | * | ||
1999 | * spider_net_setup_phy is used as part of spider_net_probe. | ||
2000 | **/ | ||
2001 | static int | ||
2002 | spider_net_setup_phy(struct spider_net_card *card) | ||
2003 | { | ||
2004 | struct mii_phy *phy = &card->phy; | ||
2005 | |||
2006 | spider_net_write_reg(card, SPIDER_NET_GDTDMASEL, | ||
2007 | SPIDER_NET_DMASEL_VALUE); | ||
2008 | spider_net_write_reg(card, SPIDER_NET_GPCCTRL, | ||
2009 | SPIDER_NET_PHY_CTRL_VALUE); | ||
2010 | |||
2011 | phy->dev = card->netdev; | ||
2012 | phy->mdio_read = spider_net_read_phy; | ||
2013 | phy->mdio_write = spider_net_write_phy; | ||
2014 | |||
2015 | for (phy->mii_id = 1; phy->mii_id <= 31; phy->mii_id++) { | ||
2016 | unsigned short id; | ||
2017 | id = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMSR); | ||
2018 | if (id != 0x0000 && id != 0xffff) { | ||
2019 | if (!mii_phy_probe(phy, phy->mii_id)) { | ||
2020 | pr_info("Found %s.\n", phy->def->name); | ||
2021 | break; | ||
2022 | } | ||
2023 | } | ||
2024 | } | ||
2025 | |||
2026 | return 0; | ||
2027 | } | ||
2028 | |||
2029 | /** | ||
1855 | * spider_net_workaround_rxramfull - work around firmware bug | 2030 | * spider_net_workaround_rxramfull - work around firmware bug |
1856 | * @card: card structure | 2031 | * @card: card structure |
1857 | * | 2032 | * |
@@ -1900,14 +2075,15 @@ spider_net_stop(struct net_device *netdev) | |||
1900 | netif_carrier_off(netdev); | 2075 | netif_carrier_off(netdev); |
1901 | netif_stop_queue(netdev); | 2076 | netif_stop_queue(netdev); |
1902 | del_timer_sync(&card->tx_timer); | 2077 | del_timer_sync(&card->tx_timer); |
2078 | del_timer_sync(&card->aneg_timer); | ||
1903 | 2079 | ||
1904 | /* disable/mask all interrupts */ | 2080 | /* disable/mask all interrupts */ |
1905 | spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0); | 2081 | spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0); |
1906 | spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0); | 2082 | spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0); |
1907 | spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0); | 2083 | spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0); |
2084 | spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0); | ||
1908 | 2085 | ||
1909 | /* free_irq(netdev->irq, netdev);*/ | 2086 | free_irq(netdev->irq, netdev); |
1910 | free_irq(to_pci_dev(netdev->dev.parent)->irq, netdev); | ||
1911 | 2087 | ||
1912 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, | 2088 | spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR, |
1913 | SPIDER_NET_DMA_TX_FEND_VALUE); | 2089 | SPIDER_NET_DMA_TX_FEND_VALUE); |
@@ -1919,8 +2095,6 @@ spider_net_stop(struct net_device *netdev) | |||
1919 | spider_net_release_tx_chain(card, 1); | 2095 | spider_net_release_tx_chain(card, 1); |
1920 | spider_net_free_rx_chain_contents(card); | 2096 | spider_net_free_rx_chain_contents(card); |
1921 | 2097 | ||
1922 | spider_net_free_rx_chain_contents(card); | ||
1923 | |||
1924 | spider_net_free_chain(card, &card->tx_chain); | 2098 | spider_net_free_chain(card, &card->tx_chain); |
1925 | spider_net_free_chain(card, &card->rx_chain); | 2099 | spider_net_free_chain(card, &card->rx_chain); |
1926 | 2100 | ||
@@ -1952,8 +2126,6 @@ spider_net_tx_timeout_task(struct work_struct *work) | |||
1952 | 2126 | ||
1953 | if (spider_net_setup_phy(card)) | 2127 | if (spider_net_setup_phy(card)) |
1954 | goto out; | 2128 | goto out; |
1955 | if (spider_net_init_firmware(card)) | ||
1956 | goto out; | ||
1957 | 2129 | ||
1958 | spider_net_open(netdev); | 2130 | spider_net_open(netdev); |
1959 | spider_net_kick_tx_dma(card); | 2131 | spider_net_kick_tx_dma(card); |
@@ -2046,10 +2218,12 @@ spider_net_setup_netdev(struct spider_net_card *card) | |||
2046 | card->tx_timer.data = (unsigned long) card; | 2218 | card->tx_timer.data = (unsigned long) card; |
2047 | netdev->irq = card->pdev->irq; | 2219 | netdev->irq = card->pdev->irq; |
2048 | 2220 | ||
2049 | card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; | 2221 | card->aneg_count = 0; |
2222 | init_timer(&card->aneg_timer); | ||
2223 | card->aneg_timer.function = spider_net_link_phy; | ||
2224 | card->aneg_timer.data = (unsigned long) card; | ||
2050 | 2225 | ||
2051 | card->tx_chain.num_desc = tx_descriptors; | 2226 | card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; |
2052 | card->rx_chain.num_desc = rx_descriptors; | ||
2053 | 2227 | ||
2054 | spider_net_setup_netdev_ops(netdev); | 2228 | spider_net_setup_netdev_ops(netdev); |
2055 | 2229 | ||
@@ -2098,8 +2272,11 @@ spider_net_alloc_card(void) | |||
2098 | { | 2272 | { |
2099 | struct net_device *netdev; | 2273 | struct net_device *netdev; |
2100 | struct spider_net_card *card; | 2274 | struct spider_net_card *card; |
2275 | size_t alloc_size; | ||
2101 | 2276 | ||
2102 | netdev = alloc_etherdev(sizeof(struct spider_net_card)); | 2277 | alloc_size = sizeof(struct spider_net_card) + |
2278 | (tx_descriptors + rx_descriptors) * sizeof(struct spider_net_descr); | ||
2279 | netdev = alloc_etherdev(alloc_size); | ||
2103 | if (!netdev) | 2280 | if (!netdev) |
2104 | return NULL; | 2281 | return NULL; |
2105 | 2282 | ||
@@ -2110,6 +2287,11 @@ spider_net_alloc_card(void) | |||
2110 | init_waitqueue_head(&card->waitq); | 2287 | init_waitqueue_head(&card->waitq); |
2111 | atomic_set(&card->tx_timeout_task_counter, 0); | 2288 | atomic_set(&card->tx_timeout_task_counter, 0); |
2112 | 2289 | ||
2290 | card->rx_chain.num_desc = rx_descriptors; | ||
2291 | card->rx_chain.ring = card->darray; | ||
2292 | card->tx_chain.num_desc = tx_descriptors; | ||
2293 | card->tx_chain.ring = card->darray + rx_descriptors; | ||
2294 | |||
2113 | return card; | 2295 | return card; |
2114 | } | 2296 | } |
2115 | 2297 | ||
@@ -2220,10 +2402,6 @@ spider_net_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2220 | if (err) | 2402 | if (err) |
2221 | goto out_undo_pci; | 2403 | goto out_undo_pci; |
2222 | 2404 | ||
2223 | err = spider_net_init_firmware(card); | ||
2224 | if (err) | ||
2225 | goto out_undo_pci; | ||
2226 | |||
2227 | err = spider_net_setup_netdev(card); | 2405 | err = spider_net_setup_netdev(card); |
2228 | if (err) | 2406 | if (err) |
2229 | goto out_undo_pci; | 2407 | goto out_undo_pci; |