aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-06-04 20:23:26 -0400
committerJeff Garzik <jeff@garzik.org>2007-07-08 22:16:42 -0400
commit69161611025b261cb64be70723c0dffe26aeb3ab (patch)
tree3d9e55150365b252b9bf6859d188e0cd66db5bbe /drivers/net/sky2.c
parent8f70920f2f2a699b4ad35e625071cd92f4ba6ca3 (diff)
sky2: Yukon Extreme (88e8071) support.
Enable support for Yukon EX chipset (88e8071). Most of changes are related to new commands to chip for transmit, and change in status and checksumming. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c176
1 files changed, 106 insertions, 70 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 1f1b6db434be..da7d9580f742 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -130,7 +130,7 @@ static const struct pci_device_id sky2_id_table[] = {
130 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */ 130 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */
131 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */ 131 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */
132 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */ 132 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */
133// { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */ 133 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
134 { 0 } 134 { 0 }
135}; 135};
136 136
@@ -661,6 +661,30 @@ static void sky2_wol_init(struct sky2_port *sky2)
661 661
662} 662}
663 663
664static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port)
665{
666 if (hw->chip_id == CHIP_ID_YUKON_EX && hw->chip_rev != CHIP_REV_YU_EX_A0) {
667 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
668 TX_STFW_ENA |
669 (hw->dev[port]->mtu > ETH_DATA_LEN) ? TX_JUMBO_ENA : TX_JUMBO_DIS);
670 } else {
671 if (hw->dev[port]->mtu > ETH_DATA_LEN) {
672 /* set Tx GMAC FIFO Almost Empty Threshold */
673 sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
674 (ECU_JUMBO_WM << 16) | ECU_AE_THR);
675
676 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
677 TX_JUMBO_ENA | TX_STFW_DIS);
678
679 /* Can't do offload because of lack of store/forward */
680 hw->dev[port]->features &= ~(NETIF_F_TSO | NETIF_F_SG
681 | NETIF_F_ALL_CSUM);
682 } else
683 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
684 TX_JUMBO_DIS | TX_STFW_ENA);
685 }
686}
687
664static void sky2_mac_init(struct sky2_hw *hw, unsigned port) 688static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
665{ 689{
666 struct sky2_port *sky2 = netdev_priv(hw->dev[port]); 690 struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
@@ -741,8 +765,11 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
741 765
742 /* Configure Rx MAC FIFO */ 766 /* Configure Rx MAC FIFO */
743 sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); 767 sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
744 sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), 768 reg = GMF_OPER_ON | GMF_RX_F_FL_ON;
745 GMF_OPER_ON | GMF_RX_F_FL_ON); 769 if (hw->chip_id == CHIP_ID_YUKON_EX)
770 reg |= GMF_RX_OVER_ON;
771
772 sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), reg);
746 773
747 /* Flush Rx MAC FIFO on any flow control or error */ 774 /* Flush Rx MAC FIFO on any flow control or error */
748 sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); 775 sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
@@ -758,16 +785,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
758 sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8); 785 sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
759 sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8); 786 sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);
760 787
761 /* set Tx GMAC FIFO Almost Empty Threshold */ 788 sky2_set_tx_stfwd(hw, port);
762 sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
763 (ECU_JUMBO_WM << 16) | ECU_AE_THR);
764
765 if (hw->dev[port]->mtu > ETH_DATA_LEN)
766 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
767 TX_JUMBO_ENA | TX_STFW_DIS);
768 else
769 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
770 TX_JUMBO_DIS | TX_STFW_ENA);
771 } 789 }
772 790
773} 791}
@@ -950,14 +968,16 @@ static void rx_set_checksum(struct sky2_port *sky2)
950{ 968{
951 struct sky2_rx_le *le; 969 struct sky2_rx_le *le;
952 970
953 le = sky2_next_rx(sky2); 971 if (sky2->hw->chip_id != CHIP_ID_YUKON_EX) {
954 le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN); 972 le = sky2_next_rx(sky2);
955 le->ctrl = 0; 973 le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN);
956 le->opcode = OP_TCPSTART | HW_OWNER; 974 le->ctrl = 0;
975 le->opcode = OP_TCPSTART | HW_OWNER;
957 976
958 sky2_write32(sky2->hw, 977 sky2_write32(sky2->hw,
959 Q_ADDR(rxqaddr[sky2->port], Q_CSR), 978 Q_ADDR(rxqaddr[sky2->port], Q_CSR),
960 sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); 979 sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
980 }
961 981
962} 982}
963 983
@@ -1296,6 +1316,10 @@ static int sky2_up(struct net_device *dev)
1296 1316
1297 sky2_qset(hw, txqaddr[port]); 1317 sky2_qset(hw, txqaddr[port]);
1298 1318
1319 /* This is copied from sk98lin 10.0.5.3; no one tells me about erratta's */
1320 if (hw->chip_id == CHIP_ID_YUKON_EX && hw->chip_rev == CHIP_REV_YU_EX_B0)
1321 sky2_write32(hw, Q_ADDR(txqaddr[port], Q_TEST), F_TX_CHK_AUTO_OFF);
1322
1299 /* Set almost empty threshold */ 1323 /* Set almost empty threshold */
1300 if (hw->chip_id == CHIP_ID_YUKON_EC_U 1324 if (hw->chip_id == CHIP_ID_YUKON_EC_U
1301 && hw->chip_rev == CHIP_REV_YU_EC_U_A0) 1325 && hw->chip_rev == CHIP_REV_YU_EC_U_A0)
@@ -1404,14 +1428,16 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1404 /* Check for TCP Segmentation Offload */ 1428 /* Check for TCP Segmentation Offload */
1405 mss = skb_shinfo(skb)->gso_size; 1429 mss = skb_shinfo(skb)->gso_size;
1406 if (mss != 0) { 1430 if (mss != 0) {
1407 mss += tcp_optlen(skb); /* TCP options */ 1431 if (hw->chip_id != CHIP_ID_YUKON_EX)
1408 mss += ip_hdrlen(skb) + sizeof(struct tcphdr); 1432 mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb);
1409 mss += ETH_HLEN; 1433
1410 1434 if (mss != sky2->tx_last_mss) {
1411 if (mss != sky2->tx_last_mss) { 1435 le = get_tx_le(sky2);
1412 le = get_tx_le(sky2); 1436 le->addr = cpu_to_le32(mss);
1413 le->addr = cpu_to_le32(mss); 1437 if (hw->chip_id == CHIP_ID_YUKON_EX)
1414 le->opcode = OP_LRGLEN | HW_OWNER; 1438 le->opcode = OP_MSS | HW_OWNER;
1439 else
1440 le->opcode = OP_LRGLEN | HW_OWNER;
1415 sky2->tx_last_mss = mss; 1441 sky2->tx_last_mss = mss;
1416 } 1442 }
1417 } 1443 }
@@ -1433,24 +1459,30 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1433 1459
1434 /* Handle TCP checksum offload */ 1460 /* Handle TCP checksum offload */
1435 if (skb->ip_summed == CHECKSUM_PARTIAL) { 1461 if (skb->ip_summed == CHECKSUM_PARTIAL) {
1436 const unsigned offset = skb_transport_offset(skb); 1462 /* On Yukon EX (some versions) encoding change. */
1437 u32 tcpsum; 1463 if (hw->chip_id == CHIP_ID_YUKON_EX
1438 1464 && hw->chip_rev != CHIP_REV_YU_EX_B0)
1439 tcpsum = offset << 16; /* sum start */ 1465 ctrl |= CALSUM; /* auto checksum */
1440 tcpsum |= offset + skb->csum_offset; /* sum write */ 1466 else {
1441 1467 const unsigned offset = skb_transport_offset(skb);
1442 ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; 1468 u32 tcpsum;
1443 if (ip_hdr(skb)->protocol == IPPROTO_UDP) 1469
1444 ctrl |= UDPTCP; 1470 tcpsum = offset << 16; /* sum start */
1445 1471 tcpsum |= offset + skb->csum_offset; /* sum write */
1446 if (tcpsum != sky2->tx_tcpsum) { 1472
1447 sky2->tx_tcpsum = tcpsum; 1473 ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
1448 1474 if (ip_hdr(skb)->protocol == IPPROTO_UDP)
1449 le = get_tx_le(sky2); 1475 ctrl |= UDPTCP;
1450 le->addr = cpu_to_le32(tcpsum); 1476
1451 le->length = 0; /* initial checksum value */ 1477 if (tcpsum != sky2->tx_tcpsum) {
1452 le->ctrl = 1; /* one packet */ 1478 sky2->tx_tcpsum = tcpsum;
1453 le->opcode = OP_TCPLISW | HW_OWNER; 1479
1480 le = get_tx_le(sky2);
1481 le->addr = cpu_to_le32(tcpsum);
1482 le->length = 0; /* initial checksum value */
1483 le->ctrl = 1; /* one packet */
1484 le->opcode = OP_TCPLISW | HW_OWNER;
1485 }
1454 } 1486 }
1455 } 1487 }
1456 1488
@@ -1924,15 +1956,8 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
1924 1956
1925 synchronize_irq(hw->pdev->irq); 1957 synchronize_irq(hw->pdev->irq);
1926 1958
1927 if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { 1959 if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX)
1928 if (new_mtu > ETH_DATA_LEN) { 1960 sky2_set_tx_stfwd(hw, port);
1929 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
1930 TX_JUMBO_ENA | TX_STFW_DIS);
1931 dev->features &= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM;
1932 } else
1933 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
1934 TX_JUMBO_DIS | TX_STFW_ENA);
1935 }
1936 1961
1937 ctl = gma_read16(hw, port, GM_GP_CTRL); 1962 ctl = gma_read16(hw, port, GM_GP_CTRL);
1938 gma_write16(hw, port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA); 1963 gma_write16(hw, port, GM_GP_CTRL, ctl & ~GM_GPCR_RX_ENA);
@@ -2129,6 +2154,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
2129 2154
2130 while (hw->st_idx != hwidx) { 2155 while (hw->st_idx != hwidx) {
2131 struct sky2_status_le *le = hw->st_le + hw->st_idx; 2156 struct sky2_status_le *le = hw->st_le + hw->st_idx;
2157 unsigned port = le->css & CSS_LINK_BIT;
2132 struct net_device *dev; 2158 struct net_device *dev;
2133 struct sk_buff *skb; 2159 struct sk_buff *skb;
2134 u32 status; 2160 u32 status;
@@ -2136,9 +2162,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
2136 2162
2137 hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE); 2163 hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE);
2138 2164
2139 BUG_ON(le->link >= 2); 2165 dev = hw->dev[port];
2140 dev = hw->dev[le->link];
2141
2142 sky2 = netdev_priv(dev); 2166 sky2 = netdev_priv(dev);
2143 length = le16_to_cpu(le->length); 2167 length = le16_to_cpu(le->length);
2144 status = le32_to_cpu(le->status); 2168 status = le32_to_cpu(le->status);
@@ -2151,6 +2175,16 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
2151 goto force_update; 2175 goto force_update;
2152 } 2176 }
2153 2177
2178 /* This chip reports checksum status differently */
2179 if (hw->chip_id == CHIP_ID_YUKON_EX) {
2180 if (sky2->rx_csum &&
2181 (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) &&
2182 (le->css & CSS_TCPUDPCSOK))
2183 skb->ip_summed = CHECKSUM_UNNECESSARY;
2184 else
2185 skb->ip_summed = CHECKSUM_NONE;
2186 }
2187
2154 skb->protocol = eth_type_trans(skb, dev); 2188 skb->protocol = eth_type_trans(skb, dev);
2155 sky2->net_stats.rx_packets++; 2189 sky2->net_stats.rx_packets++;
2156 sky2->net_stats.rx_bytes += skb->len; 2190 sky2->net_stats.rx_bytes += skb->len;
@@ -2166,10 +2200,10 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
2166 netif_receive_skb(skb); 2200 netif_receive_skb(skb);
2167 2201
2168 /* Update receiver after 16 frames */ 2202 /* Update receiver after 16 frames */
2169 if (++buf_write[le->link] == RX_BUF_WRITE) { 2203 if (++buf_write[port] == RX_BUF_WRITE) {
2170force_update: 2204force_update:
2171 sky2_put_idx(hw, rxqaddr[le->link], sky2->rx_put); 2205 sky2_put_idx(hw, rxqaddr[port], sky2->rx_put);
2172 buf_write[le->link] = 0; 2206 buf_write[port] = 0;
2173 } 2207 }
2174 2208
2175 /* Stop after net poll weight */ 2209 /* Stop after net poll weight */
@@ -2190,6 +2224,9 @@ force_update:
2190 if (!sky2->rx_csum) 2224 if (!sky2->rx_csum)
2191 break; 2225 break;
2192 2226
2227 if (hw->chip_id == CHIP_ID_YUKON_EX)
2228 break;
2229
2193 /* Both checksum counters are programmed to start at 2230 /* Both checksum counters are programmed to start at
2194 * the same offset, so unless there is a problem they 2231 * the same offset, so unless there is a problem they
2195 * should match. This failure is an early indication that 2232 * should match. This failure is an early indication that
@@ -2205,7 +2242,7 @@ force_update:
2205 dev->name, status); 2242 dev->name, status);
2206 sky2->rx_csum = 0; 2243 sky2->rx_csum = 0;
2207 sky2_write32(sky2->hw, 2244 sky2_write32(sky2->hw,
2208 Q_ADDR(rxqaddr[le->link], Q_CSR), 2245 Q_ADDR(rxqaddr[port], Q_CSR),
2209 BMU_DIS_RX_CHKSUM); 2246 BMU_DIS_RX_CHKSUM);
2210 } 2247 }
2211 break; 2248 break;
@@ -2536,10 +2573,6 @@ static int __devinit sky2_init(struct sky2_hw *hw)
2536 return -EOPNOTSUPP; 2573 return -EOPNOTSUPP;
2537 } 2574 }
2538 2575
2539 if (hw->chip_id == CHIP_ID_YUKON_EX)
2540 dev_warn(&hw->pdev->dev, "this driver not yet tested on this chip type\n"
2541 "Please report success or failure to <netdev@vger.kernel.org>\n");
2542
2543 hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; 2576 hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4;
2544 2577
2545 /* This rev is really old, and requires untested workarounds */ 2578 /* This rev is really old, and requires untested workarounds */
@@ -2599,6 +2632,11 @@ static void sky2_reset(struct sky2_hw *hw)
2599 for (i = 0; i < hw->ports; i++) { 2632 for (i = 0; i < hw->ports; i++) {
2600 sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); 2633 sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
2601 sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); 2634 sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
2635
2636 if (hw->chip_id == CHIP_ID_YUKON_EX)
2637 sky2_write16(hw, SK_REG(i, GMAC_CTRL),
2638 GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON
2639 | GMC_BYP_RETR_ON);
2602 } 2640 }
2603 2641
2604 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); 2642 sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
@@ -2745,7 +2783,7 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
2745 2783
2746 sky2->wol = wol->wolopts; 2784 sky2->wol = wol->wolopts;
2747 2785
2748 if (hw->chip_id == CHIP_ID_YUKON_EC_U) 2786 if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX)
2749 sky2_write32(hw, B0_CTST, sky2->wol 2787 sky2_write32(hw, B0_CTST, sky2->wol
2750 ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF); 2788 ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF);
2751 2789
@@ -3371,9 +3409,7 @@ static int no_tx_offload(struct net_device *dev)
3371 const struct sky2_port *sky2 = netdev_priv(dev); 3409 const struct sky2_port *sky2 = netdev_priv(dev);
3372 const struct sky2_hw *hw = sky2->hw; 3410 const struct sky2_hw *hw = sky2->hw;
3373 3411
3374 return dev->mtu > ETH_DATA_LEN && 3412 return dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U;
3375 (hw->chip_id == CHIP_ID_YUKON_EX
3376 || hw->chip_id == CHIP_ID_YUKON_EC_U);
3377} 3413}
3378 3414
3379static int sky2_set_tx_csum(struct net_device *dev, u32 data) 3415static int sky2_set_tx_csum(struct net_device *dev, u32 data)