aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c408
1 files changed, 293 insertions, 115 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 5d812de65d90..162489b9f599 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -51,7 +51,7 @@
51#include "sky2.h" 51#include "sky2.h"
52 52
53#define DRV_NAME "sky2" 53#define DRV_NAME "sky2"
54#define DRV_VERSION "1.17" 54#define DRV_VERSION "1.18"
55#define PFX DRV_NAME " " 55#define PFX DRV_NAME " "
56 56
57/* 57/*
@@ -118,12 +118,15 @@ static const struct pci_device_id sky2_id_table[] = {
118 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) }, /* 88E8036 */ 118 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) }, /* 88E8036 */
119 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, /* 88E8038 */ 119 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, /* 88E8038 */
120 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */ 120 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */
121 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4354) }, /* 88E8040 */
121 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */ 122 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */
123 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x435A) }, /* 88E8048 */
122 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) }, /* 88E8052 */ 124 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) }, /* 88E8052 */
123 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */ 125 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */
124 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */ 126 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */
125 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */ 127 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */
126 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */ 128 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */
129 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4365) }, /* 88E8070 */
127 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */ 130 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */
128 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */ 131 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */
129 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */ 132 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */
@@ -147,6 +150,7 @@ static const char *yukon2_name[] = {
147 "Extreme", /* 0xb5 */ 150 "Extreme", /* 0xb5 */
148 "EC", /* 0xb6 */ 151 "EC", /* 0xb6 */
149 "FE", /* 0xb7 */ 152 "FE", /* 0xb7 */
153 "FE+", /* 0xb8 */
150}; 154};
151 155
152static void sky2_set_multicast(struct net_device *dev); 156static void sky2_set_multicast(struct net_device *dev);
@@ -217,8 +221,7 @@ static void sky2_power_on(struct sky2_hw *hw)
217 else 221 else
218 sky2_write8(hw, B2_Y2_CLK_GATE, 0); 222 sky2_write8(hw, B2_Y2_CLK_GATE, 0);
219 223
220 if (hw->chip_id == CHIP_ID_YUKON_EC_U || 224 if (hw->flags & SKY2_HW_ADV_POWER_CTL) {
221 hw->chip_id == CHIP_ID_YUKON_EX) {
222 u32 reg; 225 u32 reg;
223 226
224 sky2_pci_write32(hw, PCI_DEV_REG3, 0); 227 sky2_pci_write32(hw, PCI_DEV_REG3, 0);
@@ -311,10 +314,8 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
311 struct sky2_port *sky2 = netdev_priv(hw->dev[port]); 314 struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
312 u16 ctrl, ct1000, adv, pg, ledctrl, ledover, reg; 315 u16 ctrl, ct1000, adv, pg, ledctrl, ledover, reg;
313 316
314 if (sky2->autoneg == AUTONEG_ENABLE 317 if (sky2->autoneg == AUTONEG_ENABLE &&
315 && !(hw->chip_id == CHIP_ID_YUKON_XL 318 !(hw->flags & SKY2_HW_NEWER_PHY)) {
316 || hw->chip_id == CHIP_ID_YUKON_EC_U
317 || hw->chip_id == CHIP_ID_YUKON_EX)) {
318 u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); 319 u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
319 320
320 ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | 321 ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
@@ -334,9 +335,19 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
334 335
335 ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); 336 ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
336 if (sky2_is_copper(hw)) { 337 if (sky2_is_copper(hw)) {
337 if (hw->chip_id == CHIP_ID_YUKON_FE) { 338 if (!(hw->flags & SKY2_HW_GIGABIT)) {
338 /* enable automatic crossover */ 339 /* enable automatic crossover */
339 ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1; 340 ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1;
341
342 if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
343 hw->chip_rev == CHIP_REV_YU_FE2_A0) {
344 u16 spec;
345
346 /* Enable Class A driver for FE+ A0 */
347 spec = gm_phy_read(hw, port, PHY_MARV_FE_SPEC_2);
348 spec |= PHY_M_FESC_SEL_CL_A;
349 gm_phy_write(hw, port, PHY_MARV_FE_SPEC_2, spec);
350 }
340 } else { 351 } else {
341 /* disable energy detect */ 352 /* disable energy detect */
342 ctrl &= ~PHY_M_PC_EN_DET_MSK; 353 ctrl &= ~PHY_M_PC_EN_DET_MSK;
@@ -346,9 +357,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
346 357
347 /* downshift on PHY 88E1112 and 88E1149 is changed */ 358 /* downshift on PHY 88E1112 and 88E1149 is changed */
348 if (sky2->autoneg == AUTONEG_ENABLE 359 if (sky2->autoneg == AUTONEG_ENABLE
349 && (hw->chip_id == CHIP_ID_YUKON_XL 360 && (hw->flags & SKY2_HW_NEWER_PHY)) {
350 || hw->chip_id == CHIP_ID_YUKON_EC_U
351 || hw->chip_id == CHIP_ID_YUKON_EX)) {
352 /* set downshift counter to 3x and enable downshift */ 361 /* set downshift counter to 3x and enable downshift */
353 ctrl &= ~PHY_M_PC_DSC_MSK; 362 ctrl &= ~PHY_M_PC_DSC_MSK;
354 ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; 363 ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA;
@@ -364,7 +373,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
364 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); 373 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
365 374
366 /* special setup for PHY 88E1112 Fiber */ 375 /* special setup for PHY 88E1112 Fiber */
367 if (hw->chip_id == CHIP_ID_YUKON_XL && !sky2_is_copper(hw)) { 376 if (hw->chip_id == CHIP_ID_YUKON_XL && (hw->flags & SKY2_HW_FIBRE_PHY)) {
368 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); 377 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
369 378
370 /* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */ 379 /* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */
@@ -455,7 +464,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
455 464
456 gma_write16(hw, port, GM_GP_CTRL, reg); 465 gma_write16(hw, port, GM_GP_CTRL, reg);
457 466
458 if (hw->chip_id != CHIP_ID_YUKON_FE) 467 if (hw->flags & SKY2_HW_GIGABIT)
459 gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000); 468 gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);
460 469
461 gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); 470 gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
@@ -479,6 +488,23 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
479 gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl); 488 gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl);
480 break; 489 break;
481 490
491 case CHIP_ID_YUKON_FE_P:
492 /* Enable Link Partner Next Page */
493 ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
494 ctrl |= PHY_M_PC_ENA_LIP_NP;
495
496 /* disable Energy Detect and enable scrambler */
497 ctrl &= ~(PHY_M_PC_ENA_ENE_DT | PHY_M_PC_DIS_SCRAMB);
498 gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
499
500 /* set LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED */
501 ctrl = PHY_M_FELP_LED2_CTRL(LED_PAR_CTRL_ACT_BL) |
502 PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_LINK) |
503 PHY_M_FELP_LED0_CTRL(LED_PAR_CTRL_SPEED);
504
505 gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl);
506 break;
507
482 case CHIP_ID_YUKON_XL: 508 case CHIP_ID_YUKON_XL:
483 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); 509 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
484 510
@@ -548,7 +574,13 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
548 574
549 /* set page register to 0 */ 575 /* set page register to 0 */
550 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0); 576 gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
577 } else if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
578 hw->chip_rev == CHIP_REV_YU_FE2_A0) {
579 /* apply workaround for integrated resistors calibration */
580 gm_phy_write(hw, port, PHY_MARV_PAGE_ADDR, 17);
581 gm_phy_write(hw, port, PHY_MARV_PAGE_DATA, 0x3f60);
551 } else if (hw->chip_id != CHIP_ID_YUKON_EX) { 582 } else if (hw->chip_id != CHIP_ID_YUKON_EX) {
583 /* no effect on Yukon-XL */
552 gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); 584 gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
553 585
554 if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { 586 if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) {
@@ -669,25 +701,25 @@ static void sky2_wol_init(struct sky2_port *sky2)
669 701
670static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port) 702static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port)
671{ 703{
672 if (hw->chip_id == CHIP_ID_YUKON_EX && hw->chip_rev != CHIP_REV_YU_EX_A0) { 704 struct net_device *dev = hw->dev[port];
705
706 if (dev->mtu <= ETH_DATA_LEN)
673 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), 707 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
674 TX_STFW_ENA | 708 TX_JUMBO_DIS | TX_STFW_ENA);
675 (hw->dev[port]->mtu > ETH_DATA_LEN) ? TX_JUMBO_ENA : TX_JUMBO_DIS);
676 } else {
677 if (hw->dev[port]->mtu > ETH_DATA_LEN) {
678 /* set Tx GMAC FIFO Almost Empty Threshold */
679 sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
680 (ECU_JUMBO_WM << 16) | ECU_AE_THR);
681 709
682 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), 710 else if (hw->chip_id != CHIP_ID_YUKON_EC_U)
683 TX_JUMBO_ENA | TX_STFW_DIS); 711 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
712 TX_STFW_ENA | TX_JUMBO_ENA);
713 else {
714 /* set Tx GMAC FIFO Almost Empty Threshold */
715 sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
716 (ECU_JUMBO_WM << 16) | ECU_AE_THR);
684 717
685 /* Can't do offload because of lack of store/forward */ 718 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
686 hw->dev[port]->features &= ~(NETIF_F_TSO | NETIF_F_SG 719 TX_JUMBO_ENA | TX_STFW_DIS);
687 | NETIF_F_ALL_CSUM); 720
688 } else 721 /* Can't do offload because of lack of store/forward */
689 sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), 722 dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | NETIF_F_ALL_CSUM);
690 TX_JUMBO_DIS | TX_STFW_ENA);
691 } 723 }
692} 724}
693 725
@@ -773,7 +805,8 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
773 /* Configure Rx MAC FIFO */ 805 /* Configure Rx MAC FIFO */
774 sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); 806 sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR);
775 rx_reg = GMF_OPER_ON | GMF_RX_F_FL_ON; 807 rx_reg = GMF_OPER_ON | GMF_RX_F_FL_ON;
776 if (hw->chip_id == CHIP_ID_YUKON_EX) 808 if (hw->chip_id == CHIP_ID_YUKON_EX ||
809 hw->chip_id == CHIP_ID_YUKON_FE_P)
777 rx_reg |= GMF_RX_OVER_ON; 810 rx_reg |= GMF_RX_OVER_ON;
778 811
779 sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), rx_reg); 812 sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), rx_reg);
@@ -782,13 +815,19 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
782 sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); 815 sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
783 816
784 /* Set threshold to 0xa (64 bytes) + 1 to workaround pause bug */ 817 /* Set threshold to 0xa (64 bytes) + 1 to workaround pause bug */
785 sky2_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF+1); 818 reg = RX_GMF_FL_THR_DEF + 1;
819 /* Another magic mystery workaround from sk98lin */
820 if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
821 hw->chip_rev == CHIP_REV_YU_FE2_A0)
822 reg = 0x178;
823 sky2_write16(hw, SK_REG(port, RX_GMF_FL_THR), reg);
786 824
787 /* Configure Tx MAC FIFO */ 825 /* Configure Tx MAC FIFO */
788 sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); 826 sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
789 sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); 827 sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
790 828
791 if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { 829 /* On chips without ram buffer, pause is controled by MAC level */
830 if (sky2_read8(hw, B2_E_0) == 0) {
792 sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8); 831 sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
793 sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8); 832 sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);
794 833
@@ -871,6 +910,20 @@ static inline struct sky2_tx_le *get_tx_le(struct sky2_port *sky2)
871 return le; 910 return le;
872} 911}
873 912
913static void tx_init(struct sky2_port *sky2)
914{
915 struct sky2_tx_le *le;
916
917 sky2->tx_prod = sky2->tx_cons = 0;
918 sky2->tx_tcpsum = 0;
919 sky2->tx_last_mss = 0;
920
921 le = get_tx_le(sky2);
922 le->addr = 0;
923 le->opcode = OP_ADDR64 | HW_OWNER;
924 sky2->tx_addr64 = 0;
925}
926
874static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2, 927static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2,
875 struct sky2_tx_le *le) 928 struct sky2_tx_le *le)
876{ 929{
@@ -967,19 +1020,15 @@ static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re)
967 */ 1020 */
968static void rx_set_checksum(struct sky2_port *sky2) 1021static void rx_set_checksum(struct sky2_port *sky2)
969{ 1022{
970 struct sky2_rx_le *le; 1023 struct sky2_rx_le *le = sky2_next_rx(sky2);
971
972 if (sky2->hw->chip_id != CHIP_ID_YUKON_EX) {
973 le = sky2_next_rx(sky2);
974 le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN);
975 le->ctrl = 0;
976 le->opcode = OP_TCPSTART | HW_OWNER;
977 1024
978 sky2_write32(sky2->hw, 1025 le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN);
979 Q_ADDR(rxqaddr[sky2->port], Q_CSR), 1026 le->ctrl = 0;
980 sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); 1027 le->opcode = OP_TCPSTART | HW_OWNER;
981 }
982 1028
1029 sky2_write32(sky2->hw,
1030 Q_ADDR(rxqaddr[sky2->port], Q_CSR),
1031 sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
983} 1032}
984 1033
985/* 1034/*
@@ -1175,7 +1224,8 @@ static int sky2_rx_start(struct sky2_port *sky2)
1175 1224
1176 sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); 1225 sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1);
1177 1226
1178 rx_set_checksum(sky2); 1227 if (!(hw->flags & SKY2_HW_NEW_LE))
1228 rx_set_checksum(sky2);
1179 1229
1180 /* Space needed for frame data + headers rounded up */ 1230 /* Space needed for frame data + headers rounded up */
1181 size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8); 1231 size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8);
@@ -1246,7 +1296,7 @@ static int sky2_up(struct net_device *dev)
1246 struct sky2_port *sky2 = netdev_priv(dev); 1296 struct sky2_port *sky2 = netdev_priv(dev);
1247 struct sky2_hw *hw = sky2->hw; 1297 struct sky2_hw *hw = sky2->hw;
1248 unsigned port = sky2->port; 1298 unsigned port = sky2->port;
1249 u32 ramsize, imask; 1299 u32 imask, ramsize;
1250 int cap, err = -ENOMEM; 1300 int cap, err = -ENOMEM;
1251 struct net_device *otherdev = hw->dev[sky2->port^1]; 1301 struct net_device *otherdev = hw->dev[sky2->port^1];
1252 1302
@@ -1284,7 +1334,8 @@ static int sky2_up(struct net_device *dev)
1284 GFP_KERNEL); 1334 GFP_KERNEL);
1285 if (!sky2->tx_ring) 1335 if (!sky2->tx_ring)
1286 goto err_out; 1336 goto err_out;
1287 sky2->tx_prod = sky2->tx_cons = 0; 1337
1338 tx_init(sky2);
1288 1339
1289 sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES, 1340 sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES,
1290 &sky2->rx_le_map); 1341 &sky2->rx_le_map);
@@ -1303,11 +1354,10 @@ static int sky2_up(struct net_device *dev)
1303 1354
1304 /* Register is number of 4K blocks on internal RAM buffer. */ 1355 /* Register is number of 4K blocks on internal RAM buffer. */
1305 ramsize = sky2_read8(hw, B2_E_0) * 4; 1356 ramsize = sky2_read8(hw, B2_E_0) * 4;
1306 printk(KERN_INFO PFX "%s: ram buffer %dK\n", dev->name, ramsize);
1307
1308 if (ramsize > 0) { 1357 if (ramsize > 0) {
1309 u32 rxspace; 1358 u32 rxspace;
1310 1359
1360 pr_debug(PFX "%s: ram buffer %dK\n", dev->name, ramsize);
1311 if (ramsize < 16) 1361 if (ramsize < 16)
1312 rxspace = ramsize / 2; 1362 rxspace = ramsize / 2;
1313 else 1363 else
@@ -1436,13 +1486,15 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1436 /* Check for TCP Segmentation Offload */ 1486 /* Check for TCP Segmentation Offload */
1437 mss = skb_shinfo(skb)->gso_size; 1487 mss = skb_shinfo(skb)->gso_size;
1438 if (mss != 0) { 1488 if (mss != 0) {
1439 if (hw->chip_id != CHIP_ID_YUKON_EX) 1489
1490 if (!(hw->flags & SKY2_HW_NEW_LE))
1440 mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb); 1491 mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb);
1441 1492
1442 if (mss != sky2->tx_last_mss) { 1493 if (mss != sky2->tx_last_mss) {
1443 le = get_tx_le(sky2); 1494 le = get_tx_le(sky2);
1444 le->addr = cpu_to_le32(mss); 1495 le->addr = cpu_to_le32(mss);
1445 if (hw->chip_id == CHIP_ID_YUKON_EX) 1496
1497 if (hw->flags & SKY2_HW_NEW_LE)
1446 le->opcode = OP_MSS | HW_OWNER; 1498 le->opcode = OP_MSS | HW_OWNER;
1447 else 1499 else
1448 le->opcode = OP_LRGLEN | HW_OWNER; 1500 le->opcode = OP_LRGLEN | HW_OWNER;
@@ -1468,8 +1520,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1468 /* Handle TCP checksum offload */ 1520 /* Handle TCP checksum offload */
1469 if (skb->ip_summed == CHECKSUM_PARTIAL) { 1521 if (skb->ip_summed == CHECKSUM_PARTIAL) {
1470 /* On Yukon EX (some versions) encoding change. */ 1522 /* On Yukon EX (some versions) encoding change. */
1471 if (hw->chip_id == CHIP_ID_YUKON_EX 1523 if (hw->flags & SKY2_HW_AUTO_TX_SUM)
1472 && hw->chip_rev != CHIP_REV_YU_EX_B0)
1473 ctrl |= CALSUM; /* auto checksum */ 1524 ctrl |= CALSUM; /* auto checksum */
1474 else { 1525 else {
1475 const unsigned offset = skb_transport_offset(skb); 1526 const unsigned offset = skb_transport_offset(skb);
@@ -1622,9 +1673,6 @@ static int sky2_down(struct net_device *dev)
1622 if (netif_msg_ifdown(sky2)) 1673 if (netif_msg_ifdown(sky2))
1623 printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); 1674 printk(KERN_INFO PFX "%s: disabling interface\n", dev->name);
1624 1675
1625 if (netif_carrier_ok(dev) && --hw->active == 0)
1626 del_timer(&hw->watchdog_timer);
1627
1628 /* Stop more packets from being queued */ 1676 /* Stop more packets from being queued */
1629 netif_stop_queue(dev); 1677 netif_stop_queue(dev);
1630 1678
@@ -1708,11 +1756,15 @@ static int sky2_down(struct net_device *dev)
1708 1756
1709static u16 sky2_phy_speed(const struct sky2_hw *hw, u16 aux) 1757static u16 sky2_phy_speed(const struct sky2_hw *hw, u16 aux)
1710{ 1758{
1711 if (!sky2_is_copper(hw)) 1759 if (hw->flags & SKY2_HW_FIBRE_PHY)
1712 return SPEED_1000; 1760 return SPEED_1000;
1713 1761
1714 if (hw->chip_id == CHIP_ID_YUKON_FE) 1762 if (!(hw->flags & SKY2_HW_GIGABIT)) {
1715 return (aux & PHY_M_PS_SPEED_100) ? SPEED_100 : SPEED_10; 1763 if (aux & PHY_M_PS_SPEED_100)
1764 return SPEED_100;
1765 else
1766 return SPEED_10;
1767 }
1716 1768
1717 switch (aux & PHY_M_PS_SPEED_MSK) { 1769 switch (aux & PHY_M_PS_SPEED_MSK) {
1718 case PHY_M_PS_SPEED_1000: 1770 case PHY_M_PS_SPEED_1000:
@@ -1745,17 +1797,13 @@ static void sky2_link_up(struct sky2_port *sky2)
1745 1797
1746 netif_carrier_on(sky2->netdev); 1798 netif_carrier_on(sky2->netdev);
1747 1799
1748 if (hw->active++ == 0) 1800 mod_timer(&hw->watchdog_timer, jiffies + 1);
1749 mod_timer(&hw->watchdog_timer, jiffies + 1);
1750
1751 1801
1752 /* Turn on link LED */ 1802 /* Turn on link LED */
1753 sky2_write8(hw, SK_REG(port, LNK_LED_REG), 1803 sky2_write8(hw, SK_REG(port, LNK_LED_REG),
1754 LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); 1804 LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
1755 1805
1756 if (hw->chip_id == CHIP_ID_YUKON_XL 1806 if (hw->flags & SKY2_HW_NEWER_PHY) {
1757 || hw->chip_id == CHIP_ID_YUKON_EC_U
1758 || hw->chip_id == CHIP_ID_YUKON_EX) {
1759 u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); 1807 u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
1760 u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */ 1808 u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */
1761 1809
@@ -1800,11 +1848,6 @@ static void sky2_link_down(struct sky2_port *sky2)
1800 1848
1801 netif_carrier_off(sky2->netdev); 1849 netif_carrier_off(sky2->netdev);
1802 1850
1803 /* Stop watchdog if both ports are not active */
1804 if (--hw->active == 0)
1805 del_timer(&hw->watchdog_timer);
1806
1807
1808 /* Turn on link LED */ 1851 /* Turn on link LED */
1809 sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); 1852 sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
1810 1853
@@ -1847,7 +1890,7 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
1847 /* Since the pause result bits seem to in different positions on 1890 /* Since the pause result bits seem to in different positions on
1848 * different chips. look at registers. 1891 * different chips. look at registers.
1849 */ 1892 */
1850 if (!sky2_is_copper(hw)) { 1893 if (hw->flags & SKY2_HW_FIBRE_PHY) {
1851 /* Shift for bits in fiber PHY */ 1894 /* Shift for bits in fiber PHY */
1852 advert &= ~(ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM); 1895 advert &= ~(ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM);
1853 lpa &= ~(LPA_PAUSE_CAP|LPA_PAUSE_ASYM); 1896 lpa &= ~(LPA_PAUSE_CAP|LPA_PAUSE_ASYM);
@@ -1958,7 +2001,9 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
1958 if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) 2001 if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
1959 return -EINVAL; 2002 return -EINVAL;
1960 2003
1961 if (new_mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_FE) 2004 if (new_mtu > ETH_DATA_LEN &&
2005 (hw->chip_id == CHIP_ID_YUKON_FE ||
2006 hw->chip_id == CHIP_ID_YUKON_FE_P))
1962 return -EINVAL; 2007 return -EINVAL;
1963 2008
1964 if (!netif_running(dev)) { 2009 if (!netif_running(dev)) {
@@ -1975,7 +2020,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
1975 2020
1976 synchronize_irq(hw->pdev->irq); 2021 synchronize_irq(hw->pdev->irq);
1977 2022
1978 if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) 2023 if (sky2_read8(hw, B2_E_0) == 0)
1979 sky2_set_tx_stfwd(hw, port); 2024 sky2_set_tx_stfwd(hw, port);
1980 2025
1981 ctl = gma_read16(hw, port, GM_GP_CTRL); 2026 ctl = gma_read16(hw, port, GM_GP_CTRL);
@@ -2103,6 +2148,13 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
2103 struct sky2_port *sky2 = netdev_priv(dev); 2148 struct sky2_port *sky2 = netdev_priv(dev);
2104 struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next; 2149 struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next;
2105 struct sk_buff *skb = NULL; 2150 struct sk_buff *skb = NULL;
2151 u16 count = (status & GMR_FS_LEN) >> 16;
2152
2153#ifdef SKY2_VLAN_TAG_USED
2154 /* Account for vlan tag */
2155 if (sky2->vlgrp && (status & GMR_FS_VLAN))
2156 count -= VLAN_HLEN;
2157#endif
2106 2158
2107 if (unlikely(netif_msg_rx_status(sky2))) 2159 if (unlikely(netif_msg_rx_status(sky2)))
2108 printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n", 2160 printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n",
@@ -2111,15 +2163,29 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
2111 sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending; 2163 sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;
2112 prefetch(sky2->rx_ring + sky2->rx_next); 2164 prefetch(sky2->rx_ring + sky2->rx_next);
2113 2165
2166 if (length < ETH_ZLEN || length > sky2->rx_data_size)
2167 goto len_error;
2168
2169 /* This chip has hardware problems that generates bogus status.
2170 * So do only marginal checking and expect higher level protocols
2171 * to handle crap frames.
2172 */
2173 if (sky2->hw->chip_id == CHIP_ID_YUKON_FE_P &&
2174 sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0 &&
2175 length != count)
2176 goto okay;
2177
2114 if (status & GMR_FS_ANY_ERR) 2178 if (status & GMR_FS_ANY_ERR)
2115 goto error; 2179 goto error;
2116 2180
2117 if (!(status & GMR_FS_RX_OK)) 2181 if (!(status & GMR_FS_RX_OK))
2118 goto resubmit; 2182 goto resubmit;
2119 2183
2120 if (status >> 16 != length) 2184 /* if length reported by DMA does not match PHY, packet was truncated */
2121 goto len_mismatch; 2185 if (length != count)
2186 goto len_error;
2122 2187
2188okay:
2123 if (length < copybreak) 2189 if (length < copybreak)
2124 skb = receive_copy(sky2, re, length); 2190 skb = receive_copy(sky2, re, length);
2125 else 2191 else
@@ -2129,10 +2195,14 @@ resubmit:
2129 2195
2130 return skb; 2196 return skb;
2131 2197
2132len_mismatch: 2198len_error:
2133 /* Truncation of overlength packets 2199 /* Truncation of overlength packets
2134 causes PHY length to not match MAC length */ 2200 causes PHY length to not match MAC length */
2135 ++sky2->net_stats.rx_length_errors; 2201 ++sky2->net_stats.rx_length_errors;
2202 if (netif_msg_rx_err(sky2) && net_ratelimit())
2203 pr_info(PFX "%s: rx length error: status %#x length %d\n",
2204 dev->name, status, length);
2205 goto resubmit;
2136 2206
2137error: 2207error:
2138 ++sky2->net_stats.rx_errors; 2208 ++sky2->net_stats.rx_errors;
@@ -2202,7 +2272,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
2202 } 2272 }
2203 2273
2204 /* This chip reports checksum status differently */ 2274 /* This chip reports checksum status differently */
2205 if (hw->chip_id == CHIP_ID_YUKON_EX) { 2275 if (hw->flags & SKY2_HW_NEW_LE) {
2206 if (sky2->rx_csum && 2276 if (sky2->rx_csum &&
2207 (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) && 2277 (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) &&
2208 (le->css & CSS_TCPUDPCSOK)) 2278 (le->css & CSS_TCPUDPCSOK))
@@ -2243,8 +2313,14 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
2243 if (!sky2->rx_csum) 2313 if (!sky2->rx_csum)
2244 break; 2314 break;
2245 2315
2246 if (hw->chip_id == CHIP_ID_YUKON_EX) 2316 /* If this happens then driver assuming wrong format */
2317 if (unlikely(hw->flags & SKY2_HW_NEW_LE)) {
2318 if (net_ratelimit())
2319 printk(KERN_NOTICE "%s: unexpected"
2320 " checksum status\n",
2321 dev->name);
2247 break; 2322 break;
2323 }
2248 2324
2249 /* Both checksum counters are programmed to start at 2325 /* Both checksum counters are programmed to start at
2250 * the same offset, so unless there is a problem they 2326 * the same offset, so unless there is a problem they
@@ -2436,20 +2512,72 @@ static void sky2_le_error(struct sky2_hw *hw, unsigned port,
2436 sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK); 2512 sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK);
2437} 2513}
2438 2514
2439/* Check for lost IRQ once a second */ 2515static int sky2_rx_hung(struct net_device *dev)
2516{
2517 struct sky2_port *sky2 = netdev_priv(dev);
2518 struct sky2_hw *hw = sky2->hw;
2519 unsigned port = sky2->port;
2520 unsigned rxq = rxqaddr[port];
2521 u32 mac_rp = sky2_read32(hw, SK_REG(port, RX_GMF_RP));
2522 u8 mac_lev = sky2_read8(hw, SK_REG(port, RX_GMF_RLEV));
2523 u8 fifo_rp = sky2_read8(hw, Q_ADDR(rxq, Q_RP));
2524 u8 fifo_lev = sky2_read8(hw, Q_ADDR(rxq, Q_RL));
2525
2526 /* If idle and MAC or PCI is stuck */
2527 if (sky2->check.last == dev->last_rx &&
2528 ((mac_rp == sky2->check.mac_rp &&
2529 mac_lev != 0 && mac_lev >= sky2->check.mac_lev) ||
2530 /* Check if the PCI RX hang */
2531 (fifo_rp == sky2->check.fifo_rp &&
2532 fifo_lev != 0 && fifo_lev >= sky2->check.fifo_lev))) {
2533 printk(KERN_DEBUG PFX "%s: hung mac %d:%d fifo %d (%d:%d)\n",
2534 dev->name, mac_lev, mac_rp, fifo_lev, fifo_rp,
2535 sky2_read8(hw, Q_ADDR(rxq, Q_WP)));
2536 return 1;
2537 } else {
2538 sky2->check.last = dev->last_rx;
2539 sky2->check.mac_rp = mac_rp;
2540 sky2->check.mac_lev = mac_lev;
2541 sky2->check.fifo_rp = fifo_rp;
2542 sky2->check.fifo_lev = fifo_lev;
2543 return 0;
2544 }
2545}
2546
2440static void sky2_watchdog(unsigned long arg) 2547static void sky2_watchdog(unsigned long arg)
2441{ 2548{
2442 struct sky2_hw *hw = (struct sky2_hw *) arg; 2549 struct sky2_hw *hw = (struct sky2_hw *) arg;
2550 struct net_device *dev;
2443 2551
2552 /* Check for lost IRQ once a second */
2444 if (sky2_read32(hw, B0_ISRC)) { 2553 if (sky2_read32(hw, B0_ISRC)) {
2445 struct net_device *dev = hw->dev[0]; 2554 dev = hw->dev[0];
2446
2447 if (__netif_rx_schedule_prep(dev)) 2555 if (__netif_rx_schedule_prep(dev))
2448 __netif_rx_schedule(dev); 2556 __netif_rx_schedule(dev);
2557 } else {
2558 int i, active = 0;
2559
2560 for (i = 0; i < hw->ports; i++) {
2561 dev = hw->dev[i];
2562 if (!netif_running(dev))
2563 continue;
2564 ++active;
2565
2566 /* For chips with Rx FIFO, check if stuck */
2567 if ((hw->flags & SKY2_HW_FIFO_HANG_CHECK) &&
2568 sky2_rx_hung(dev)) {
2569 pr_info(PFX "%s: receiver hang detected\n",
2570 dev->name);
2571 schedule_work(&hw->restart_work);
2572 return;
2573 }
2574 }
2575
2576 if (active == 0)
2577 return;
2449 } 2578 }
2450 2579
2451 if (hw->active > 0) 2580 mod_timer(&hw->watchdog_timer, round_jiffies(jiffies + HZ));
2452 mod_timer(&hw->watchdog_timer, round_jiffies(jiffies + HZ));
2453} 2581}
2454 2582
2455/* Hardware/software error handling */ 2583/* Hardware/software error handling */
@@ -2546,17 +2674,25 @@ static void sky2_netpoll(struct net_device *dev)
2546#endif 2674#endif
2547 2675
2548/* Chip internal frequency for clock calculations */ 2676/* Chip internal frequency for clock calculations */
2549static inline u32 sky2_mhz(const struct sky2_hw *hw) 2677static u32 sky2_mhz(const struct sky2_hw *hw)
2550{ 2678{
2551 switch (hw->chip_id) { 2679 switch (hw->chip_id) {
2552 case CHIP_ID_YUKON_EC: 2680 case CHIP_ID_YUKON_EC:
2553 case CHIP_ID_YUKON_EC_U: 2681 case CHIP_ID_YUKON_EC_U:
2554 case CHIP_ID_YUKON_EX: 2682 case CHIP_ID_YUKON_EX:
2555 return 125; /* 125 Mhz */ 2683 return 125;
2684
2556 case CHIP_ID_YUKON_FE: 2685 case CHIP_ID_YUKON_FE:
2557 return 100; /* 100 Mhz */ 2686 return 100;
2558 default: /* YUKON_XL */ 2687
2559 return 156; /* 156 Mhz */ 2688 case CHIP_ID_YUKON_FE_P:
2689 return 50;
2690
2691 case CHIP_ID_YUKON_XL:
2692 return 156;
2693
2694 default:
2695 BUG();
2560 } 2696 }
2561} 2697}
2562 2698
@@ -2581,23 +2717,63 @@ static int __devinit sky2_init(struct sky2_hw *hw)
2581 sky2_write8(hw, B0_CTST, CS_RST_CLR); 2717 sky2_write8(hw, B0_CTST, CS_RST_CLR);
2582 2718
2583 hw->chip_id = sky2_read8(hw, B2_CHIP_ID); 2719 hw->chip_id = sky2_read8(hw, B2_CHIP_ID);
2584 if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) { 2720 hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4;
2721
2722 switch(hw->chip_id) {
2723 case CHIP_ID_YUKON_XL:
2724 hw->flags = SKY2_HW_GIGABIT
2725 | SKY2_HW_NEWER_PHY;
2726 if (hw->chip_rev < 3)
2727 hw->flags |= SKY2_HW_FIFO_HANG_CHECK;
2728
2729 break;
2730
2731 case CHIP_ID_YUKON_EC_U:
2732 hw->flags = SKY2_HW_GIGABIT
2733 | SKY2_HW_NEWER_PHY
2734 | SKY2_HW_ADV_POWER_CTL;
2735 break;
2736
2737 case CHIP_ID_YUKON_EX:
2738 hw->flags = SKY2_HW_GIGABIT
2739 | SKY2_HW_NEWER_PHY
2740 | SKY2_HW_NEW_LE
2741 | SKY2_HW_ADV_POWER_CTL;
2742
2743 /* New transmit checksum */
2744 if (hw->chip_rev != CHIP_REV_YU_EX_B0)
2745 hw->flags |= SKY2_HW_AUTO_TX_SUM;
2746 break;
2747
2748 case CHIP_ID_YUKON_EC:
2749 /* This rev is really old, and requires untested workarounds */
2750 if (hw->chip_rev == CHIP_REV_YU_EC_A1) {
2751 dev_err(&hw->pdev->dev, "unsupported revision Yukon-EC rev A1\n");
2752 return -EOPNOTSUPP;
2753 }
2754 hw->flags = SKY2_HW_GIGABIT | SKY2_HW_FIFO_HANG_CHECK;
2755 break;
2756
2757 case CHIP_ID_YUKON_FE:
2758 break;
2759
2760 case CHIP_ID_YUKON_FE_P:
2761 hw->flags = SKY2_HW_NEWER_PHY
2762 | SKY2_HW_NEW_LE
2763 | SKY2_HW_AUTO_TX_SUM
2764 | SKY2_HW_ADV_POWER_CTL;
2765 break;
2766 default:
2585 dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n", 2767 dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n",
2586 hw->chip_id); 2768 hw->chip_id);
2587 return -EOPNOTSUPP; 2769 return -EOPNOTSUPP;
2588 } 2770 }
2589 2771
2590 hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; 2772 hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
2773 if (hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P')
2774 hw->flags |= SKY2_HW_FIBRE_PHY;
2591 2775
2592 /* This rev is really old, and requires untested workarounds */
2593 if (hw->chip_id == CHIP_ID_YUKON_EC && hw->chip_rev == CHIP_REV_YU_EC_A1) {
2594 dev_err(&hw->pdev->dev, "unsupported revision Yukon-%s (0x%x) rev %d\n",
2595 yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL],
2596 hw->chip_id, hw->chip_rev);
2597 return -EOPNOTSUPP;
2598 }
2599 2776
2600 hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
2601 hw->ports = 1; 2777 hw->ports = 1;
2602 t8 = sky2_read8(hw, B2_Y2_HW_RES); 2778 t8 = sky2_read8(hw, B2_Y2_HW_RES);
2603 if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) { 2779 if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) {
@@ -2791,7 +2967,9 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
2791 2967
2792 sky2->wol = wol->wolopts; 2968 sky2->wol = wol->wolopts;
2793 2969
2794 if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) 2970 if (hw->chip_id == CHIP_ID_YUKON_EC_U ||
2971 hw->chip_id == CHIP_ID_YUKON_EX ||
2972 hw->chip_id == CHIP_ID_YUKON_FE_P)
2795 sky2_write32(hw, B0_CTST, sky2->wol 2973 sky2_write32(hw, B0_CTST, sky2->wol
2796 ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF); 2974 ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF);
2797 2975
@@ -2809,7 +2987,7 @@ static u32 sky2_supported_modes(const struct sky2_hw *hw)
2809 | SUPPORTED_100baseT_Full 2987 | SUPPORTED_100baseT_Full
2810 | SUPPORTED_Autoneg | SUPPORTED_TP; 2988 | SUPPORTED_Autoneg | SUPPORTED_TP;
2811 2989
2812 if (hw->chip_id != CHIP_ID_YUKON_FE) 2990 if (hw->flags & SKY2_HW_GIGABIT)
2813 modes |= SUPPORTED_1000baseT_Half 2991 modes |= SUPPORTED_1000baseT_Half
2814 | SUPPORTED_1000baseT_Full; 2992 | SUPPORTED_1000baseT_Full;
2815 return modes; 2993 return modes;
@@ -2829,13 +3007,6 @@ static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
2829 ecmd->supported = sky2_supported_modes(hw); 3007 ecmd->supported = sky2_supported_modes(hw);
2830 ecmd->phy_address = PHY_ADDR_MARV; 3008 ecmd->phy_address = PHY_ADDR_MARV;
2831 if (sky2_is_copper(hw)) { 3009 if (sky2_is_copper(hw)) {
2832 ecmd->supported = SUPPORTED_10baseT_Half
2833 | SUPPORTED_10baseT_Full
2834 | SUPPORTED_100baseT_Half
2835 | SUPPORTED_100baseT_Full
2836 | SUPPORTED_1000baseT_Half
2837 | SUPPORTED_1000baseT_Full
2838 | SUPPORTED_Autoneg | SUPPORTED_TP;
2839 ecmd->port = PORT_TP; 3010 ecmd->port = PORT_TP;
2840 ecmd->speed = sky2->speed; 3011 ecmd->speed = sky2->speed;
2841 } else { 3012 } else {
@@ -3814,8 +3985,12 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
3814 dev->features |= NETIF_F_HIGHDMA; 3985 dev->features |= NETIF_F_HIGHDMA;
3815 3986
3816#ifdef SKY2_VLAN_TAG_USED 3987#ifdef SKY2_VLAN_TAG_USED
3817 dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; 3988 /* The workaround for FE+ status conflicts with VLAN tag detection. */
3818 dev->vlan_rx_register = sky2_vlan_rx_register; 3989 if (!(sky2->hw->chip_id == CHIP_ID_YUKON_FE_P &&
3990 sky2->hw->chip_rev == CHIP_REV_YU_FE2_A0)) {
3991 dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
3992 dev->vlan_rx_register = sky2_vlan_rx_register;
3993 }
3819#endif 3994#endif
3820 3995
3821 /* read the mac address */ 3996 /* read the mac address */
@@ -3846,7 +4021,7 @@ static irqreturn_t __devinit sky2_test_intr(int irq, void *dev_id)
3846 return IRQ_NONE; 4021 return IRQ_NONE;
3847 4022
3848 if (status & Y2_IS_IRQ_SW) { 4023 if (status & Y2_IS_IRQ_SW) {
3849 hw->msi = 1; 4024 hw->flags |= SKY2_HW_USE_MSI;
3850 wake_up(&hw->msi_wait); 4025 wake_up(&hw->msi_wait);
3851 sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ); 4026 sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ);
3852 } 4027 }
@@ -3874,9 +4049,9 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw)
3874 sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ); 4049 sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ);
3875 sky2_read8(hw, B0_CTST); 4050 sky2_read8(hw, B0_CTST);
3876 4051
3877 wait_event_timeout(hw->msi_wait, hw->msi, HZ/10); 4052 wait_event_timeout(hw->msi_wait, (hw->flags & SKY2_HW_USE_MSI), HZ/10);
3878 4053
3879 if (!hw->msi) { 4054 if (!(hw->flags & SKY2_HW_USE_MSI)) {
3880 /* MSI test failed, go back to INTx mode */ 4055 /* MSI test failed, go back to INTx mode */
3881 dev_info(&pdev->dev, "No interrupt generated using MSI, " 4056 dev_info(&pdev->dev, "No interrupt generated using MSI, "
3882 "switching to INTx mode.\n"); 4057 "switching to INTx mode.\n");
@@ -4009,7 +4184,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
4009 goto err_out_free_netdev; 4184 goto err_out_free_netdev;
4010 } 4185 }
4011 4186
4012 err = request_irq(pdev->irq, sky2_intr, hw->msi ? 0 : IRQF_SHARED, 4187 err = request_irq(pdev->irq, sky2_intr,
4188 (hw->flags & SKY2_HW_USE_MSI) ? 0 : IRQF_SHARED,
4013 dev->name, hw); 4189 dev->name, hw);
4014 if (err) { 4190 if (err) {
4015 dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq); 4191 dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);
@@ -4042,7 +4218,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
4042 return 0; 4218 return 0;
4043 4219
4044err_out_unregister: 4220err_out_unregister:
4045 if (hw->msi) 4221 if (hw->flags & SKY2_HW_USE_MSI)
4046 pci_disable_msi(pdev); 4222 pci_disable_msi(pdev);
4047 unregister_netdev(dev); 4223 unregister_netdev(dev);
4048err_out_free_netdev: 4224err_out_free_netdev:
@@ -4091,7 +4267,7 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
4091 sky2_read8(hw, B0_CTST); 4267 sky2_read8(hw, B0_CTST);
4092 4268
4093 free_irq(pdev->irq, hw); 4269 free_irq(pdev->irq, hw);
4094 if (hw->msi) 4270 if (hw->flags & SKY2_HW_USE_MSI)
4095 pci_disable_msi(pdev); 4271 pci_disable_msi(pdev);
4096 pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma); 4272 pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma);
4097 pci_release_regions(pdev); 4273 pci_release_regions(pdev);
@@ -4159,7 +4335,9 @@ static int sky2_resume(struct pci_dev *pdev)
4159 pci_enable_wake(pdev, PCI_D0, 0); 4335 pci_enable_wake(pdev, PCI_D0, 0);
4160 4336
4161 /* Re-enable all clocks */ 4337 /* Re-enable all clocks */
4162 if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U) 4338 if (hw->chip_id == CHIP_ID_YUKON_EX ||
4339 hw->chip_id == CHIP_ID_YUKON_EC_U ||
4340 hw->chip_id == CHIP_ID_YUKON_FE_P)
4163 sky2_pci_write32(hw, PCI_DEV_REG3, 0); 4341 sky2_pci_write32(hw, PCI_DEV_REG3, 0);
4164 4342
4165 sky2_reset(hw); 4343 sky2_reset(hw);