diff options
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 147 |
1 files changed, 84 insertions, 63 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index d2c0d04be723..0cc57293faf9 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -468,9 +468,9 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
468 | 468 | ||
469 | /* serial mode register */ | 469 | /* serial mode register */ |
470 | reg = DATA_BLIND_VAL(DATA_BLIND_DEF) | | 470 | reg = DATA_BLIND_VAL(DATA_BLIND_DEF) | |
471 | GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF); | 471 | GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF); |
472 | 472 | ||
473 | if (hw->dev[port]->mtu > 1500) | 473 | if (hw->dev[port]->mtu > ETH_DATA_LEN) |
474 | reg |= GM_SMOD_JUMBO_ENA; | 474 | reg |= GM_SMOD_JUMBO_ENA; |
475 | 475 | ||
476 | gma_write16(hw, port, GM_SERIAL_MODE, reg); | 476 | gma_write16(hw, port, GM_SERIAL_MODE, reg); |
@@ -515,8 +515,6 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, size_t len) | |||
515 | len /= 8; | 515 | len /= 8; |
516 | end = start + len - 1; | 516 | end = start + len - 1; |
517 | 517 | ||
518 | pr_debug("sky2_ramset start=%d end=%d\n", start, end); | ||
519 | |||
520 | sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR); | 518 | sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR); |
521 | sky2_write32(hw, RB_ADDR(q, RB_START), start); | 519 | sky2_write32(hw, RB_ADDR(q, RB_START), start); |
522 | sky2_write32(hw, RB_ADDR(q, RB_END), end); | 520 | sky2_write32(hw, RB_ADDR(q, RB_END), end); |
@@ -528,7 +526,6 @@ static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, size_t len) | |||
528 | 526 | ||
529 | rxlo = len/2; | 527 | rxlo = len/2; |
530 | rxup = rxlo + len/4; | 528 | rxup = rxlo + len/4; |
531 | pr_debug(" utpp=%d ltpp=%d\n", rxup, rxlo); | ||
532 | 529 | ||
533 | /* Set thresholds on receive queue's */ | 530 | /* Set thresholds on receive queue's */ |
534 | sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), rxup); | 531 | sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), rxup); |
@@ -662,16 +659,44 @@ static void rx_set_checksum(struct sky2_port *sky2) | |||
662 | le->ctrl = 0; | 659 | le->ctrl = 0; |
663 | le->opcode = OP_TCPSTART | HW_OWNER; | 660 | le->opcode = OP_TCPSTART | HW_OWNER; |
664 | 661 | ||
665 | sky2_write16(sky2->hw, Y2_QADDR(rxqaddr[sky2->port], | ||
666 | PREF_UNIT_PUT_IDX), sky2->rx_put); | ||
667 | sky2_read16(sky2->hw, Y2_QADDR(rxqaddr[sky2->port], PREF_UNIT_PUT_IDX)); | ||
668 | mdelay(1); | ||
669 | sky2_write32(sky2->hw, | 662 | sky2_write32(sky2->hw, |
670 | Q_ADDR(rxqaddr[sky2->port], Q_CSR), | 663 | Q_ADDR(rxqaddr[sky2->port], Q_CSR), |
671 | sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); | 664 | sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); |
672 | 665 | ||
673 | } | 666 | } |
674 | 667 | ||
668 | /* | ||
669 | * The RX Stop command will not work for Yukon-2 if the BMU does not | ||
670 | * reach the end of packet and since we can't make sure that we have | ||
671 | * incoming data, we must reset the BMU while it is not doing a DMA | ||
672 | * transfer. Since it is possible that the RX path is still active, | ||
673 | * the RX RAM buffer will be stopped first, so any possible incoming | ||
674 | * data will not trigger a DMA. After the RAM buffer is stopped, the | ||
675 | * BMU is polled until any DMA in progress is ended and only then it | ||
676 | * will be reset. | ||
677 | */ | ||
678 | static void sky2_rx_stop(struct sky2_port *sky2) | ||
679 | { | ||
680 | struct sky2_hw *hw = sky2->hw; | ||
681 | unsigned rxq = rxqaddr[sky2->port]; | ||
682 | int i; | ||
683 | |||
684 | /* disable the RAM Buffer receive queue */ | ||
685 | sky2_write8(hw, RB_ADDR(rxq, RB_CTRL), RB_DIS_OP_MD); | ||
686 | |||
687 | for (i = 0; i < 0xffff; i++) | ||
688 | if (sky2_read8(hw, RB_ADDR(rxq, Q_RSL)) | ||
689 | == sky2_read8(hw, RB_ADDR(rxq, Q_RL))) | ||
690 | goto stopped; | ||
691 | |||
692 | printk(KERN_WARNING PFX "%s: receiver stop failed\n", | ||
693 | sky2->netdev->name); | ||
694 | stopped: | ||
695 | sky2_write32(hw, Q_ADDR(rxq, Q_CSR), BMU_RST_SET | BMU_FIFO_RST); | ||
696 | |||
697 | /* reset the Rx prefetch unit */ | ||
698 | sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET); | ||
699 | } | ||
675 | 700 | ||
676 | /* Cleanout receive buffer area, assumes receiver hardware stopped */ | 701 | /* Cleanout receive buffer area, assumes receiver hardware stopped */ |
677 | static void sky2_rx_clean(struct sky2_port *sky2) | 702 | static void sky2_rx_clean(struct sky2_port *sky2) |
@@ -693,7 +718,7 @@ static void sky2_rx_clean(struct sky2_port *sky2) | |||
693 | } | 718 | } |
694 | 719 | ||
695 | #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) | 720 | #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) |
696 | static inline unsigned sky2_rx_size(const struct sky2_port *sky2) | 721 | static inline unsigned rx_size(const struct sky2_port *sky2) |
697 | { | 722 | { |
698 | return roundup(sky2->netdev->mtu + ETH_HLEN + 4, 8); | 723 | return roundup(sky2->netdev->mtu + ETH_HLEN + 4, 8); |
699 | } | 724 | } |
@@ -709,12 +734,18 @@ static inline unsigned sky2_rx_size(const struct sky2_port *sky2) | |||
709 | * is not aligned. This means we can't use skb_reserve to align | 734 | * is not aligned. This means we can't use skb_reserve to align |
710 | * the IP header. | 735 | * the IP header. |
711 | */ | 736 | */ |
712 | static int sky2_rx_fill(struct sky2_port *sky2) | 737 | static int sky2_rx_start(struct sky2_port *sky2) |
713 | { | 738 | { |
714 | unsigned i; | 739 | struct sky2_hw *hw = sky2->hw; |
715 | unsigned size = sky2_rx_size(sky2); | 740 | unsigned size = rx_size(sky2); |
741 | unsigned rxq = rxqaddr[sky2->port]; | ||
742 | int i; | ||
743 | |||
744 | sky2->rx_put = sky2->rx_next = 0; | ||
745 | sky2_qset(hw, rxq, is_pciex(hw) ? 0x80 : 0x600); | ||
746 | sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); | ||
716 | 747 | ||
717 | pr_debug("rx_fill size=%d\n", size); | 748 | rx_set_checksum(sky2); |
718 | for (i = 0; i < sky2->rx_pending; i++) { | 749 | for (i = 0; i < sky2->rx_pending; i++) { |
719 | struct ring_info *re = sky2->rx_ring + i; | 750 | struct ring_info *re = sky2->rx_ring + i; |
720 | 751 | ||
@@ -722,12 +753,15 @@ static int sky2_rx_fill(struct sky2_port *sky2) | |||
722 | if (!re->skb) | 753 | if (!re->skb) |
723 | goto nomem; | 754 | goto nomem; |
724 | 755 | ||
725 | re->mapaddr = pci_map_single(sky2->hw->pdev, re->skb->data, | 756 | re->mapaddr = pci_map_single(hw->pdev, re->skb->data, |
726 | size, PCI_DMA_FROMDEVICE); | 757 | size, PCI_DMA_FROMDEVICE); |
727 | re->maplen = size; | 758 | re->maplen = size; |
728 | sky2_rx_add(sky2, re); | 759 | sky2_rx_add(sky2, re); |
729 | } | 760 | } |
730 | 761 | ||
762 | /* Tell chip about available buffers */ | ||
763 | sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put); | ||
764 | sky2->rx_last_put = sky2_read16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX)); | ||
731 | return 0; | 765 | return 0; |
732 | nomem: | 766 | nomem: |
733 | sky2_rx_clean(sky2); | 767 | sky2_rx_clean(sky2); |
@@ -792,28 +826,14 @@ static int sky2_up(struct net_device *dev) | |||
792 | sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL), | 826 | sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL), |
793 | RB_RST_SET); | 827 | RB_RST_SET); |
794 | 828 | ||
795 | sky2_qset(hw, rxqaddr[port], is_pciex(hw) ? 0x80 : 0x600); | ||
796 | sky2_qset(hw, txqaddr[port], 0x600); | 829 | sky2_qset(hw, txqaddr[port], 0x600); |
830 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, | ||
831 | TX_RING_SIZE - 1); | ||
797 | 832 | ||
798 | sky2->rx_put = sky2->rx_next = 0; | 833 | err = sky2_rx_start(sky2); |
799 | sky2_prefetch_init(hw, rxqaddr[port], sky2->rx_le_map, RX_LE_SIZE - 1); | ||
800 | |||
801 | rx_set_checksum(sky2); | ||
802 | |||
803 | err = sky2_rx_fill(sky2); | ||
804 | if (err) | 834 | if (err) |
805 | goto err_out; | 835 | goto err_out; |
806 | 836 | ||
807 | /* Give buffers to receiver */ | ||
808 | sky2_write16(sky2->hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_PUT_IDX), | ||
809 | sky2->rx_put); | ||
810 | sky2->rx_last_put = sky2_read16(sky2->hw, | ||
811 | Y2_QADDR(rxqaddr[port], | ||
812 | PREF_UNIT_PUT_IDX)); | ||
813 | |||
814 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, | ||
815 | TX_RING_SIZE - 1); | ||
816 | |||
817 | /* Enable interrupts from phy/mac for port */ | 837 | /* Enable interrupts from phy/mac for port */ |
818 | hw->intr_mask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; | 838 | hw->intr_mask |= (port == 0) ? Y2_IS_PORT_1 : Y2_IS_PORT_2; |
819 | sky2_write32(hw, B0_IMSK, hw->intr_mask); | 839 | sky2_write32(hw, B0_IMSK, hw->intr_mask); |
@@ -1076,7 +1096,6 @@ static int sky2_down(struct net_device *dev) | |||
1076 | struct sky2_hw *hw = sky2->hw; | 1096 | struct sky2_hw *hw = sky2->hw; |
1077 | unsigned port = sky2->port; | 1097 | unsigned port = sky2->port; |
1078 | u16 ctrl; | 1098 | u16 ctrl; |
1079 | int i; | ||
1080 | 1099 | ||
1081 | if (netif_msg_ifdown(sky2)) | 1100 | if (netif_msg_ifdown(sky2)) |
1082 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); | 1101 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); |
@@ -1121,30 +1140,7 @@ static int sky2_down(struct net_device *dev) | |||
1121 | 1140 | ||
1122 | sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET); | 1141 | sky2_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL), RB_RST_SET); |
1123 | 1142 | ||
1124 | /* | 1143 | sky2_rx_stop(sky2); |
1125 | * The RX Stop command will not work for Yukon-2 if the BMU does not | ||
1126 | * reach the end of packet and since we can't make sure that we have | ||
1127 | * incoming data, we must reset the BMU while it is not doing a DMA | ||
1128 | * transfer. Since it is possible that the RX path is still active, | ||
1129 | * the RX RAM buffer will be stopped first, so any possible incoming | ||
1130 | * data will not trigger a DMA. After the RAM buffer is stopped, the | ||
1131 | * BMU is polled until any DMA in progress is ended and only then it | ||
1132 | * will be reset. | ||
1133 | */ | ||
1134 | |||
1135 | /* disable the RAM Buffer receive queue */ | ||
1136 | sky2_write8(hw, RB_ADDR(rxqaddr[port], RB_CTRL), RB_DIS_OP_MD); | ||
1137 | |||
1138 | for (i = 0; i < 0xffff; i++) | ||
1139 | if (sky2_read8(hw, RB_ADDR(rxqaddr[port], Q_RSL)) | ||
1140 | == sky2_read8(hw, RB_ADDR(rxqaddr[port], Q_RL))) | ||
1141 | break; | ||
1142 | |||
1143 | sky2_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), | ||
1144 | BMU_RST_SET | BMU_FIFO_RST); | ||
1145 | /* reset the Rx prefetch unit */ | ||
1146 | sky2_write32(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_CTRL), | ||
1147 | PREF_UNIT_RST_SET); | ||
1148 | 1144 | ||
1149 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); | 1145 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); |
1150 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); | 1146 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); |
@@ -1379,19 +1375,44 @@ static void sky2_tx_timeout(struct net_device *dev) | |||
1379 | 1375 | ||
1380 | static int sky2_change_mtu(struct net_device *dev, int new_mtu) | 1376 | static int sky2_change_mtu(struct net_device *dev, int new_mtu) |
1381 | { | 1377 | { |
1382 | int err = 0; | 1378 | struct sky2_port *sky2 = netdev_priv(dev); |
1379 | struct sky2_hw *hw = sky2->hw; | ||
1380 | int err; | ||
1381 | u16 ctl, mode; | ||
1383 | 1382 | ||
1384 | if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) | 1383 | if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) |
1385 | return -EINVAL; | 1384 | return -EINVAL; |
1386 | 1385 | ||
1387 | if (netif_running(dev)) | 1386 | if (!netif_running(dev)) { |
1388 | sky2_down(dev); | 1387 | dev->mtu = new_mtu; |
1388 | return 0; | ||
1389 | } | ||
1390 | |||
1391 | local_irq_disable(); | ||
1392 | sky2_write32(hw, B0_IMSK, 0); | ||
1393 | |||
1394 | ctl = gma_read16(hw, sky2->port, GM_GP_CTRL); | ||
1395 | gma_write16(hw, sky2->port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA); | ||
1396 | sky2_rx_stop(sky2); | ||
1397 | sky2_rx_clean(sky2); | ||
1389 | 1398 | ||
1390 | dev->mtu = new_mtu; | 1399 | dev->mtu = new_mtu; |
1400 | mode = DATA_BLIND_VAL(DATA_BLIND_DEF) | | ||
1401 | GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF); | ||
1391 | 1402 | ||
1392 | if (netif_running(dev)) | 1403 | if (dev->mtu > ETH_DATA_LEN) |
1393 | err = sky2_up(dev); | 1404 | mode |= GM_SMOD_JUMBO_ENA; |
1405 | |||
1406 | gma_write16(hw, sky2->port, GM_SERIAL_MODE, mode); | ||
1407 | |||
1408 | sky2_write8(hw, RB_ADDR(rxqaddr[sky2->port], RB_CTRL), RB_ENA_OP_MD); | ||
1409 | |||
1410 | err = sky2_rx_start(sky2); | ||
1411 | gma_write16(hw, sky2->port, GM_GP_CTRL, ctl); | ||
1394 | 1412 | ||
1413 | sky2_write32(hw, B0_IMSK, hw->intr_mask); | ||
1414 | sky2_read32(hw, B0_IMSK); | ||
1415 | local_irq_enable(); | ||
1395 | return err; | 1416 | return err; |
1396 | } | 1417 | } |
1397 | 1418 | ||
@@ -1407,7 +1428,7 @@ static struct sk_buff *sky2_receive(struct sky2_hw *hw, unsigned port, | |||
1407 | struct sky2_port *sky2 = netdev_priv(dev); | 1428 | struct sky2_port *sky2 = netdev_priv(dev); |
1408 | struct ring_info *re = sky2->rx_ring + sky2->rx_next; | 1429 | struct ring_info *re = sky2->rx_ring + sky2->rx_next; |
1409 | struct sk_buff *skb = NULL; | 1430 | struct sk_buff *skb = NULL; |
1410 | const unsigned int bufsize = sky2_rx_size(sky2); | 1431 | const unsigned int bufsize = rx_size(sky2); |
1411 | 1432 | ||
1412 | if (unlikely(netif_msg_rx_status(sky2))) | 1433 | if (unlikely(netif_msg_rx_status(sky2))) |
1413 | printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n", | 1434 | printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n", |