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) |