aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorshemminger@osdl.org <shemminger@osdl.org>2005-09-27 18:02:55 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-09-28 11:49:32 -0400
commit6b1a3aefd897fd9be410d192f950656ef2b59694 (patch)
treeafffd4a23a577b5c21e76d098ed93f849bc013da /drivers
parentecfd7f32aa9e279f3732c2e5049b1a4a13428572 (diff)
[PATCH] sky2: changing mtu doesn't have to reset link
Changing the MTU of the network device doesn't mean the whole link has to be brought down and back up again. Just stopping the receive engine is good enough. Signed-off-by: Stephen Hemminger <shmminger @osdl.org> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/sky2.c147
1 files changed, 84 insertions, 63 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index d2c0d04be72..0cc57293faf 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 */
678static 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);
694stopped:
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 */
677static void sky2_rx_clean(struct sky2_port *sky2) 702static 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))
696static inline unsigned sky2_rx_size(const struct sky2_port *sky2) 721static 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 */
712static int sky2_rx_fill(struct sky2_port *sky2) 737static 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;
732nomem: 766nomem:
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
1380static int sky2_change_mtu(struct net_device *dev, int new_mtu) 1376static 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",