diff options
Diffstat (limited to 'drivers/net/sky2.c')
| -rw-r--r-- | drivers/net/sky2.c | 224 |
1 files changed, 137 insertions, 87 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index fe01b961b597..b51d73c8f817 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
| @@ -50,7 +50,7 @@ | |||
| 50 | #include "sky2.h" | 50 | #include "sky2.h" |
| 51 | 51 | ||
| 52 | #define DRV_NAME "sky2" | 52 | #define DRV_NAME "sky2" |
| 53 | #define DRV_VERSION "1.14" | 53 | #define DRV_VERSION "1.15" |
| 54 | #define PFX DRV_NAME " " | 54 | #define PFX DRV_NAME " " |
| 55 | 55 | ||
| 56 | /* | 56 | /* |
| @@ -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 | ||
| @@ -217,13 +217,24 @@ static void sky2_power_on(struct sky2_hw *hw) | |||
| 217 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); | 217 | sky2_write8(hw, B2_Y2_CLK_GATE, 0); |
| 218 | 218 | ||
| 219 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { | 219 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { |
| 220 | u32 reg1; | 220 | u32 reg; |
| 221 | 221 | ||
| 222 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); | 222 | reg = sky2_pci_read32(hw, PCI_DEV_REG4); |
| 223 | reg1 = sky2_pci_read32(hw, PCI_DEV_REG4); | 223 | /* set all bits to 0 except bits 15..12 and 8 */ |
| 224 | reg1 &= P_ASPM_CONTROL_MSK; | 224 | reg &= P_ASPM_CONTROL_MSK; |
| 225 | sky2_pci_write32(hw, PCI_DEV_REG4, reg1); | 225 | sky2_pci_write32(hw, PCI_DEV_REG4, reg); |
| 226 | sky2_pci_write32(hw, PCI_DEV_REG5, 0); | 226 | |
| 227 | reg = sky2_pci_read32(hw, PCI_DEV_REG5); | ||
| 228 | /* set all bits to 0 except bits 28 & 27 */ | ||
| 229 | reg &= P_CTL_TIM_VMAIN_AV_MSK; | ||
| 230 | sky2_pci_write32(hw, PCI_DEV_REG5, reg); | ||
| 231 | |||
| 232 | sky2_pci_write32(hw, PCI_CFG_REG_1, 0); | ||
| 233 | |||
| 234 | /* Enable workaround for dev 4.107 on Yukon-Ultra & Extreme */ | ||
| 235 | reg = sky2_read32(hw, B2_GP_IO); | ||
| 236 | reg |= GLB_GPIO_STAT_RACE_DIS; | ||
| 237 | sky2_write32(hw, B2_GP_IO, reg); | ||
| 227 | } | 238 | } |
| 228 | } | 239 | } |
| 229 | 240 | ||
| @@ -650,6 +661,30 @@ static void sky2_wol_init(struct sky2_port *sky2) | |||
| 650 | 661 | ||
| 651 | } | 662 | } |
| 652 | 663 | ||
| 664 | static 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 | |||
| 653 | static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | 688 | static void sky2_mac_init(struct sky2_hw *hw, unsigned port) |
| 654 | { | 689 | { |
| 655 | struct sky2_port *sky2 = netdev_priv(hw->dev[port]); | 690 | struct sky2_port *sky2 = netdev_priv(hw->dev[port]); |
| @@ -730,8 +765,11 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
| 730 | 765 | ||
| 731 | /* Configure Rx MAC FIFO */ | 766 | /* Configure Rx MAC FIFO */ |
| 732 | 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); |
| 733 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), | 768 | reg = GMF_OPER_ON | GMF_RX_F_FL_ON; |
| 734 | 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); | ||
| 735 | 773 | ||
| 736 | /* Flush Rx MAC FIFO on any flow control or error */ | 774 | /* Flush Rx MAC FIFO on any flow control or error */ |
| 737 | 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); |
| @@ -747,16 +785,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
| 747 | 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); |
| 748 | 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); |
| 749 | 787 | ||
| 750 | /* set Tx GMAC FIFO Almost Empty Threshold */ | 788 | sky2_set_tx_stfwd(hw, port); |
| 751 | sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR), | ||
| 752 | (ECU_JUMBO_WM << 16) | ECU_AE_THR); | ||
| 753 | |||
| 754 | if (hw->dev[port]->mtu > ETH_DATA_LEN) | ||
| 755 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | ||
| 756 | TX_JUMBO_ENA | TX_STFW_DIS); | ||
| 757 | else | ||
| 758 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | ||
| 759 | TX_JUMBO_DIS | TX_STFW_ENA); | ||
| 760 | } | 789 | } |
| 761 | 790 | ||
| 762 | } | 791 | } |
| @@ -939,14 +968,16 @@ static void rx_set_checksum(struct sky2_port *sky2) | |||
| 939 | { | 968 | { |
| 940 | struct sky2_rx_le *le; | 969 | struct sky2_rx_le *le; |
| 941 | 970 | ||
| 942 | le = sky2_next_rx(sky2); | 971 | if (sky2->hw->chip_id != CHIP_ID_YUKON_EX) { |
| 943 | le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN); | 972 | le = sky2_next_rx(sky2); |
| 944 | le->ctrl = 0; | 973 | le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN); |
| 945 | le->opcode = OP_TCPSTART | HW_OWNER; | 974 | le->ctrl = 0; |
| 975 | le->opcode = OP_TCPSTART | HW_OWNER; | ||
| 946 | 976 | ||
| 947 | sky2_write32(sky2->hw, | 977 | sky2_write32(sky2->hw, |
| 948 | Q_ADDR(rxqaddr[sky2->port], Q_CSR), | 978 | Q_ADDR(rxqaddr[sky2->port], Q_CSR), |
| 949 | sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); | 979 | sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); |
| 980 | } | ||
| 950 | 981 | ||
| 951 | } | 982 | } |
| 952 | 983 | ||
| @@ -1134,7 +1165,7 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
| 1134 | if (hw->chip_id == CHIP_ID_YUKON_EC_U && | 1165 | if (hw->chip_id == CHIP_ID_YUKON_EC_U && |
| 1135 | (hw->chip_rev == CHIP_REV_YU_EC_U_A1 | 1166 | (hw->chip_rev == CHIP_REV_YU_EC_U_A1 |
| 1136 | || hw->chip_rev == CHIP_REV_YU_EC_U_B0)) | 1167 | || hw->chip_rev == CHIP_REV_YU_EC_U_B0)) |
| 1137 | sky2_write32(hw, Q_ADDR(rxq, Q_F), F_M_RX_RAM_DIS); | 1168 | sky2_write32(hw, Q_ADDR(rxq, Q_TEST), F_M_RX_RAM_DIS); |
| 1138 | 1169 | ||
| 1139 | sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); | 1170 | sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); |
| 1140 | 1171 | ||
| @@ -1285,6 +1316,10 @@ static int sky2_up(struct net_device *dev) | |||
| 1285 | 1316 | ||
| 1286 | sky2_qset(hw, txqaddr[port]); | 1317 | sky2_qset(hw, txqaddr[port]); |
| 1287 | 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 | |||
| 1288 | /* Set almost empty threshold */ | 1323 | /* Set almost empty threshold */ |
| 1289 | if (hw->chip_id == CHIP_ID_YUKON_EC_U | 1324 | if (hw->chip_id == CHIP_ID_YUKON_EC_U |
| 1290 | && hw->chip_rev == CHIP_REV_YU_EC_U_A0) | 1325 | && hw->chip_rev == CHIP_REV_YU_EC_U_A0) |
| @@ -1393,14 +1428,16 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
| 1393 | /* Check for TCP Segmentation Offload */ | 1428 | /* Check for TCP Segmentation Offload */ |
| 1394 | mss = skb_shinfo(skb)->gso_size; | 1429 | mss = skb_shinfo(skb)->gso_size; |
| 1395 | if (mss != 0) { | 1430 | if (mss != 0) { |
| 1396 | mss += tcp_optlen(skb); /* TCP options */ | 1431 | if (hw->chip_id != CHIP_ID_YUKON_EX) |
| 1397 | mss += ip_hdrlen(skb) + sizeof(struct tcphdr); | 1432 | mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb); |
| 1398 | mss += ETH_HLEN; | 1433 | |
| 1399 | 1434 | if (mss != sky2->tx_last_mss) { | |
| 1400 | if (mss != sky2->tx_last_mss) { | 1435 | le = get_tx_le(sky2); |
| 1401 | le = get_tx_le(sky2); | 1436 | le->addr = cpu_to_le32(mss); |
| 1402 | le->addr = cpu_to_le32(mss); | 1437 | if (hw->chip_id == CHIP_ID_YUKON_EX) |
| 1403 | le->opcode = OP_LRGLEN | HW_OWNER; | 1438 | le->opcode = OP_MSS | HW_OWNER; |
| 1439 | else | ||
| 1440 | le->opcode = OP_LRGLEN | HW_OWNER; | ||
| 1404 | sky2->tx_last_mss = mss; | 1441 | sky2->tx_last_mss = mss; |
| 1405 | } | 1442 | } |
| 1406 | } | 1443 | } |
| @@ -1422,24 +1459,30 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
| 1422 | 1459 | ||
| 1423 | /* Handle TCP checksum offload */ | 1460 | /* Handle TCP checksum offload */ |
| 1424 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 1461 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 1425 | const unsigned offset = skb_transport_offset(skb); | 1462 | /* On Yukon EX (some versions) encoding change. */ |
| 1426 | u32 tcpsum; | 1463 | if (hw->chip_id == CHIP_ID_YUKON_EX |
| 1427 | 1464 | && hw->chip_rev != CHIP_REV_YU_EX_B0) | |
| 1428 | tcpsum = offset << 16; /* sum start */ | 1465 | ctrl |= CALSUM; /* auto checksum */ |
| 1429 | tcpsum |= offset + skb->csum_offset; /* sum write */ | 1466 | else { |
| 1430 | 1467 | const unsigned offset = skb_transport_offset(skb); | |
| 1431 | ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; | 1468 | u32 tcpsum; |
| 1432 | if (ip_hdr(skb)->protocol == IPPROTO_UDP) | 1469 | |
| 1433 | ctrl |= UDPTCP; | 1470 | tcpsum = offset << 16; /* sum start */ |
| 1434 | 1471 | tcpsum |= offset + skb->csum_offset; /* sum write */ | |
| 1435 | if (tcpsum != sky2->tx_tcpsum) { | 1472 | |
| 1436 | sky2->tx_tcpsum = tcpsum; | 1473 | ctrl |= CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; |
| 1437 | 1474 | if (ip_hdr(skb)->protocol == IPPROTO_UDP) | |
| 1438 | le = get_tx_le(sky2); | 1475 | ctrl |= UDPTCP; |
| 1439 | le->addr = cpu_to_le32(tcpsum); | 1476 | |
| 1440 | le->length = 0; /* initial checksum value */ | 1477 | if (tcpsum != sky2->tx_tcpsum) { |
| 1441 | le->ctrl = 1; /* one packet */ | 1478 | sky2->tx_tcpsum = tcpsum; |
| 1442 | 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 | } | ||
| 1443 | } | 1486 | } |
| 1444 | } | 1487 | } |
| 1445 | 1488 | ||
| @@ -1913,15 +1956,8 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
| 1913 | 1956 | ||
| 1914 | synchronize_irq(hw->pdev->irq); | 1957 | synchronize_irq(hw->pdev->irq); |
| 1915 | 1958 | ||
| 1916 | 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) |
| 1917 | if (new_mtu > ETH_DATA_LEN) { | 1960 | sky2_set_tx_stfwd(hw, port); |
| 1918 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | ||
| 1919 | TX_JUMBO_ENA | TX_STFW_DIS); | ||
| 1920 | dev->features &= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM; | ||
| 1921 | } else | ||
| 1922 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | ||
| 1923 | TX_JUMBO_DIS | TX_STFW_ENA); | ||
| 1924 | } | ||
| 1925 | 1961 | ||
| 1926 | ctl = gma_read16(hw, port, GM_GP_CTRL); | 1962 | ctl = gma_read16(hw, port, GM_GP_CTRL); |
| 1927 | 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); |
| @@ -2118,6 +2154,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
| 2118 | 2154 | ||
| 2119 | while (hw->st_idx != hwidx) { | 2155 | while (hw->st_idx != hwidx) { |
| 2120 | 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; | ||
| 2121 | struct net_device *dev; | 2158 | struct net_device *dev; |
| 2122 | struct sk_buff *skb; | 2159 | struct sk_buff *skb; |
| 2123 | u32 status; | 2160 | u32 status; |
| @@ -2125,9 +2162,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
| 2125 | 2162 | ||
| 2126 | hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE); | 2163 | hw->st_idx = RING_NEXT(hw->st_idx, STATUS_RING_SIZE); |
| 2127 | 2164 | ||
| 2128 | BUG_ON(le->link >= 2); | 2165 | dev = hw->dev[port]; |
| 2129 | dev = hw->dev[le->link]; | ||
| 2130 | |||
| 2131 | sky2 = netdev_priv(dev); | 2166 | sky2 = netdev_priv(dev); |
| 2132 | length = le16_to_cpu(le->length); | 2167 | length = le16_to_cpu(le->length); |
| 2133 | status = le32_to_cpu(le->status); | 2168 | status = le32_to_cpu(le->status); |
| @@ -2140,6 +2175,16 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
| 2140 | goto force_update; | 2175 | goto force_update; |
| 2141 | } | 2176 | } |
| 2142 | 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 | |||
| 2143 | skb->protocol = eth_type_trans(skb, dev); | 2188 | skb->protocol = eth_type_trans(skb, dev); |
| 2144 | sky2->net_stats.rx_packets++; | 2189 | sky2->net_stats.rx_packets++; |
| 2145 | sky2->net_stats.rx_bytes += skb->len; | 2190 | sky2->net_stats.rx_bytes += skb->len; |
| @@ -2155,10 +2200,10 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
| 2155 | netif_receive_skb(skb); | 2200 | netif_receive_skb(skb); |
| 2156 | 2201 | ||
| 2157 | /* Update receiver after 16 frames */ | 2202 | /* Update receiver after 16 frames */ |
| 2158 | if (++buf_write[le->link] == RX_BUF_WRITE) { | 2203 | if (++buf_write[port] == RX_BUF_WRITE) { |
| 2159 | force_update: | 2204 | force_update: |
| 2160 | sky2_put_idx(hw, rxqaddr[le->link], sky2->rx_put); | 2205 | sky2_put_idx(hw, rxqaddr[port], sky2->rx_put); |
| 2161 | buf_write[le->link] = 0; | 2206 | buf_write[port] = 0; |
| 2162 | } | 2207 | } |
| 2163 | 2208 | ||
| 2164 | /* Stop after net poll weight */ | 2209 | /* Stop after net poll weight */ |
| @@ -2179,6 +2224,9 @@ force_update: | |||
| 2179 | if (!sky2->rx_csum) | 2224 | if (!sky2->rx_csum) |
| 2180 | break; | 2225 | break; |
| 2181 | 2226 | ||
| 2227 | if (hw->chip_id == CHIP_ID_YUKON_EX) | ||
| 2228 | break; | ||
| 2229 | |||
| 2182 | /* Both checksum counters are programmed to start at | 2230 | /* Both checksum counters are programmed to start at |
| 2183 | * the same offset, so unless there is a problem they | 2231 | * the same offset, so unless there is a problem they |
| 2184 | * should match. This failure is an early indication that | 2232 | * should match. This failure is an early indication that |
| @@ -2194,7 +2242,7 @@ force_update: | |||
| 2194 | dev->name, status); | 2242 | dev->name, status); |
| 2195 | sky2->rx_csum = 0; | 2243 | sky2->rx_csum = 0; |
| 2196 | sky2_write32(sky2->hw, | 2244 | sky2_write32(sky2->hw, |
| 2197 | Q_ADDR(rxqaddr[le->link], Q_CSR), | 2245 | Q_ADDR(rxqaddr[port], Q_CSR), |
| 2198 | BMU_DIS_RX_CHKSUM); | 2246 | BMU_DIS_RX_CHKSUM); |
| 2199 | } | 2247 | } |
| 2200 | break; | 2248 | break; |
| @@ -2513,6 +2561,9 @@ static int __devinit sky2_init(struct sky2_hw *hw) | |||
| 2513 | { | 2561 | { |
| 2514 | u8 t8; | 2562 | u8 t8; |
| 2515 | 2563 | ||
| 2564 | /* Enable all clocks */ | ||
| 2565 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); | ||
| 2566 | |||
| 2516 | sky2_write8(hw, B0_CTST, CS_RST_CLR); | 2567 | sky2_write8(hw, B0_CTST, CS_RST_CLR); |
| 2517 | 2568 | ||
| 2518 | hw->chip_id = sky2_read8(hw, B2_CHIP_ID); | 2569 | hw->chip_id = sky2_read8(hw, B2_CHIP_ID); |
| @@ -2522,14 +2573,6 @@ static int __devinit sky2_init(struct sky2_hw *hw) | |||
| 2522 | return -EOPNOTSUPP; | 2573 | return -EOPNOTSUPP; |
| 2523 | } | 2574 | } |
| 2524 | 2575 | ||
| 2525 | if (hw->chip_id == CHIP_ID_YUKON_EX) | ||
| 2526 | dev_warn(&hw->pdev->dev, "this driver not yet tested on this chip type\n" | ||
| 2527 | "Please report success or failure to <netdev@vger.kernel.org>\n"); | ||
| 2528 | |||
| 2529 | /* Make sure and enable all clocks */ | ||
| 2530 | if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U) | ||
| 2531 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); | ||
| 2532 | |||
| 2533 | 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; |
| 2534 | 2577 | ||
| 2535 | /* This rev is really old, and requires untested workarounds */ | 2578 | /* This rev is really old, and requires untested workarounds */ |
| @@ -2589,6 +2632,11 @@ static void sky2_reset(struct sky2_hw *hw) | |||
| 2589 | for (i = 0; i < hw->ports; i++) { | 2632 | for (i = 0; i < hw->ports; i++) { |
| 2590 | 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); |
| 2591 | 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); | ||
| 2592 | } | 2640 | } |
| 2593 | 2641 | ||
| 2594 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); | 2642 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); |
| @@ -2735,7 +2783,7 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
| 2735 | 2783 | ||
| 2736 | sky2->wol = wol->wolopts; | 2784 | sky2->wol = wol->wolopts; |
| 2737 | 2785 | ||
| 2738 | 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) |
| 2739 | sky2_write32(hw, B0_CTST, sky2->wol | 2787 | sky2_write32(hw, B0_CTST, sky2->wol |
| 2740 | ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF); | 2788 | ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF); |
| 2741 | 2789 | ||
| @@ -3330,7 +3378,7 @@ static int sky2_get_regs_len(struct net_device *dev) | |||
| 3330 | 3378 | ||
| 3331 | /* | 3379 | /* |
| 3332 | * Returns copy of control register region | 3380 | * Returns copy of control register region |
| 3333 | * Note: access to the RAM address register set will cause timeouts. | 3381 | * Note: ethtool_get_regs always provides full size (16k) buffer |
| 3334 | */ | 3382 | */ |
| 3335 | static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs, | 3383 | static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs, |
| 3336 | void *p) | 3384 | void *p) |
| @@ -3338,15 +3386,19 @@ static void sky2_get_regs(struct net_device *dev, struct ethtool_regs *regs, | |||
| 3338 | const struct sky2_port *sky2 = netdev_priv(dev); | 3386 | const struct sky2_port *sky2 = netdev_priv(dev); |
| 3339 | const void __iomem *io = sky2->hw->regs; | 3387 | const void __iomem *io = sky2->hw->regs; |
| 3340 | 3388 | ||
| 3341 | BUG_ON(regs->len < B3_RI_WTO_R1); | ||
| 3342 | regs->version = 1; | 3389 | regs->version = 1; |
| 3343 | memset(p, 0, regs->len); | 3390 | memset(p, 0, regs->len); |
| 3344 | 3391 | ||
| 3345 | memcpy_fromio(p, io, B3_RAM_ADDR); | 3392 | memcpy_fromio(p, io, B3_RAM_ADDR); |
| 3346 | 3393 | ||
| 3347 | memcpy_fromio(p + B3_RI_WTO_R1, | 3394 | /* skip diagnostic ram region */ |
| 3348 | io + B3_RI_WTO_R1, | 3395 | memcpy_fromio(p + B3_RI_WTO_R1, io + B3_RI_WTO_R1, 0x2000 - B3_RI_WTO_R1); |
| 3349 | regs->len - B3_RI_WTO_R1); | 3396 | |
| 3397 | /* copy GMAC registers */ | ||
| 3398 | memcpy_fromio(p + BASE_GMAC_1, io + BASE_GMAC_1, 0x1000); | ||
| 3399 | if (sky2->hw->ports > 1) | ||
| 3400 | memcpy_fromio(p + BASE_GMAC_2, io + BASE_GMAC_2, 0x1000); | ||
| 3401 | |||
| 3350 | } | 3402 | } |
| 3351 | 3403 | ||
| 3352 | /* In order to do Jumbo packets on these chips, need to turn off the | 3404 | /* In order to do Jumbo packets on these chips, need to turn off the |
| @@ -3357,9 +3409,7 @@ static int no_tx_offload(struct net_device *dev) | |||
| 3357 | const struct sky2_port *sky2 = netdev_priv(dev); | 3409 | const struct sky2_port *sky2 = netdev_priv(dev); |
| 3358 | const struct sky2_hw *hw = sky2->hw; | 3410 | const struct sky2_hw *hw = sky2->hw; |
| 3359 | 3411 | ||
| 3360 | return dev->mtu > ETH_DATA_LEN && | 3412 | return dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U; |
| 3361 | (hw->chip_id == CHIP_ID_YUKON_EX | ||
| 3362 | || hw->chip_id == CHIP_ID_YUKON_EC_U); | ||
| 3363 | } | 3413 | } |
| 3364 | 3414 | ||
| 3365 | static int sky2_set_tx_csum(struct net_device *dev, u32 data) | 3415 | static int sky2_set_tx_csum(struct net_device *dev, u32 data) |
