diff options
| -rw-r--r-- | drivers/net/myri10ge/myri10ge.c | 3 | ||||
| -rw-r--r-- | drivers/net/phy/phy.c | 1 | ||||
| -rw-r--r-- | drivers/net/sky2.c | 368 | ||||
| -rw-r--r-- | drivers/net/sky2.h | 41 |
4 files changed, 292 insertions, 121 deletions
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 1c42266bf889..556962f9612d 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
| @@ -3094,9 +3094,12 @@ static void myri10ge_remove(struct pci_dev *pdev) | |||
| 3094 | } | 3094 | } |
| 3095 | 3095 | ||
| 3096 | #define PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E 0x0008 | 3096 | #define PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E 0x0008 |
| 3097 | #define PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E_9 0x0009 | ||
| 3097 | 3098 | ||
| 3098 | static struct pci_device_id myri10ge_pci_tbl[] = { | 3099 | static struct pci_device_id myri10ge_pci_tbl[] = { |
| 3099 | {PCI_DEVICE(PCI_VENDOR_ID_MYRICOM, PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E)}, | 3100 | {PCI_DEVICE(PCI_VENDOR_ID_MYRICOM, PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E)}, |
| 3101 | {PCI_DEVICE | ||
| 3102 | (PCI_VENDOR_ID_MYRICOM, PCI_DEVICE_ID_MYRICOM_MYRI10GE_Z8E_9)}, | ||
| 3100 | {0}, | 3103 | {0}, |
| 3101 | }; | 3104 | }; |
| 3102 | 3105 | ||
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 0cc4369cacba..cb230f44d6fc 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
| @@ -409,6 +409,7 @@ int phy_mii_ioctl(struct phy_device *phydev, | |||
| 409 | 409 | ||
| 410 | return 0; | 410 | return 0; |
| 411 | } | 411 | } |
| 412 | EXPORT_SYMBOL(phy_mii_ioctl); | ||
| 412 | 413 | ||
| 413 | /** | 414 | /** |
| 414 | * phy_start_aneg - start auto-negotiation for this PHY device | 415 | * phy_start_aneg - start auto-negotiation for this PHY device |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 5d812de65d90..eaffe551d1d8 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 | ||
| 152 | static void sky2_set_multicast(struct net_device *dev); | 156 | static 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,7 +335,7 @@ 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; |
| 340 | } else { | 341 | } else { |
| @@ -346,9 +347,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
| 346 | 347 | ||
| 347 | /* downshift on PHY 88E1112 and 88E1149 is changed */ | 348 | /* downshift on PHY 88E1112 and 88E1149 is changed */ |
| 348 | if (sky2->autoneg == AUTONEG_ENABLE | 349 | if (sky2->autoneg == AUTONEG_ENABLE |
| 349 | && (hw->chip_id == CHIP_ID_YUKON_XL | 350 | && (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 */ | 351 | /* set downshift counter to 3x and enable downshift */ |
| 353 | ctrl &= ~PHY_M_PC_DSC_MSK; | 352 | ctrl &= ~PHY_M_PC_DSC_MSK; |
| 354 | ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; | 353 | ctrl |= PHY_M_PC_DSC(2) | PHY_M_PC_DOWN_S_ENA; |
| @@ -364,7 +363,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
| 364 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); | 363 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); |
| 365 | 364 | ||
| 366 | /* special setup for PHY 88E1112 Fiber */ | 365 | /* special setup for PHY 88E1112 Fiber */ |
| 367 | if (hw->chip_id == CHIP_ID_YUKON_XL && !sky2_is_copper(hw)) { | 366 | 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); | 367 | pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); |
| 369 | 368 | ||
| 370 | /* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */ | 369 | /* Fiber: select 1000BASE-X only mode MAC Specific Ctrl Reg. */ |
| @@ -455,7 +454,7 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
| 455 | 454 | ||
| 456 | gma_write16(hw, port, GM_GP_CTRL, reg); | 455 | gma_write16(hw, port, GM_GP_CTRL, reg); |
| 457 | 456 | ||
| 458 | if (hw->chip_id != CHIP_ID_YUKON_FE) | 457 | if (hw->flags & SKY2_HW_GIGABIT) |
| 459 | gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000); | 458 | gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000); |
| 460 | 459 | ||
| 461 | gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); | 460 | gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); |
| @@ -479,6 +478,23 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
| 479 | gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl); | 478 | gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl); |
| 480 | break; | 479 | break; |
| 481 | 480 | ||
| 481 | case CHIP_ID_YUKON_FE_P: | ||
| 482 | /* Enable Link Partner Next Page */ | ||
| 483 | ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL); | ||
| 484 | ctrl |= PHY_M_PC_ENA_LIP_NP; | ||
| 485 | |||
| 486 | /* disable Energy Detect and enable scrambler */ | ||
| 487 | ctrl &= ~(PHY_M_PC_ENA_ENE_DT | PHY_M_PC_DIS_SCRAMB); | ||
| 488 | gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl); | ||
| 489 | |||
| 490 | /* set LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED */ | ||
| 491 | ctrl = PHY_M_FELP_LED2_CTRL(LED_PAR_CTRL_ACT_BL) | | ||
| 492 | PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_LINK) | | ||
| 493 | PHY_M_FELP_LED0_CTRL(LED_PAR_CTRL_SPEED); | ||
| 494 | |||
| 495 | gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl); | ||
| 496 | break; | ||
| 497 | |||
| 482 | case CHIP_ID_YUKON_XL: | 498 | case CHIP_ID_YUKON_XL: |
| 483 | pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); | 499 | pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); |
| 484 | 500 | ||
| @@ -548,7 +564,13 @@ static void sky2_phy_init(struct sky2_hw *hw, unsigned port) | |||
| 548 | 564 | ||
| 549 | /* set page register to 0 */ | 565 | /* set page register to 0 */ |
| 550 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0); | 566 | gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0); |
| 567 | } else if (hw->chip_id == CHIP_ID_YUKON_FE_P && | ||
| 568 | hw->chip_rev == CHIP_REV_YU_FE2_A0) { | ||
| 569 | /* apply workaround for integrated resistors calibration */ | ||
| 570 | gm_phy_write(hw, port, PHY_MARV_PAGE_ADDR, 17); | ||
| 571 | gm_phy_write(hw, port, PHY_MARV_PAGE_DATA, 0x3f60); | ||
| 551 | } else if (hw->chip_id != CHIP_ID_YUKON_EX) { | 572 | } else if (hw->chip_id != CHIP_ID_YUKON_EX) { |
| 573 | /* no effect on Yukon-XL */ | ||
| 552 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); | 574 | gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); |
| 553 | 575 | ||
| 554 | if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { | 576 | if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) { |
| @@ -669,25 +691,25 @@ static void sky2_wol_init(struct sky2_port *sky2) | |||
| 669 | 691 | ||
| 670 | static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port) | 692 | static void sky2_set_tx_stfwd(struct sky2_hw *hw, unsigned port) |
| 671 | { | 693 | { |
| 672 | if (hw->chip_id == CHIP_ID_YUKON_EX && hw->chip_rev != CHIP_REV_YU_EX_A0) { | 694 | struct net_device *dev = hw->dev[port]; |
| 695 | |||
| 696 | if (dev->mtu <= ETH_DATA_LEN) | ||
| 673 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | 697 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), |
| 674 | TX_STFW_ENA | | 698 | 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 | 699 | ||
| 682 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | 700 | else if (hw->chip_id != CHIP_ID_YUKON_EC_U) |
| 683 | TX_JUMBO_ENA | TX_STFW_DIS); | 701 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), |
| 702 | TX_STFW_ENA | TX_JUMBO_ENA); | ||
| 703 | else { | ||
| 704 | /* set Tx GMAC FIFO Almost Empty Threshold */ | ||
| 705 | sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR), | ||
| 706 | (ECU_JUMBO_WM << 16) | ECU_AE_THR); | ||
| 684 | 707 | ||
| 685 | /* Can't do offload because of lack of store/forward */ | 708 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), |
| 686 | hw->dev[port]->features &= ~(NETIF_F_TSO | NETIF_F_SG | 709 | TX_JUMBO_ENA | TX_STFW_DIS); |
| 687 | | NETIF_F_ALL_CSUM); | 710 | |
| 688 | } else | 711 | /* Can't do offload because of lack of store/forward */ |
| 689 | sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), | 712 | dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | NETIF_F_ALL_CSUM); |
| 690 | TX_JUMBO_DIS | TX_STFW_ENA); | ||
| 691 | } | 713 | } |
| 692 | } | 714 | } |
| 693 | 715 | ||
| @@ -773,7 +795,8 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) | |||
| 773 | /* Configure Rx MAC FIFO */ | 795 | /* Configure Rx MAC FIFO */ |
| 774 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); | 796 | sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); |
| 775 | rx_reg = GMF_OPER_ON | GMF_RX_F_FL_ON; | 797 | rx_reg = GMF_OPER_ON | GMF_RX_F_FL_ON; |
| 776 | if (hw->chip_id == CHIP_ID_YUKON_EX) | 798 | if (hw->chip_id == CHIP_ID_YUKON_EX || |
| 799 | hw->chip_id == CHIP_ID_YUKON_FE_P) | ||
| 777 | rx_reg |= GMF_RX_OVER_ON; | 800 | rx_reg |= GMF_RX_OVER_ON; |
| 778 | 801 | ||
| 779 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), rx_reg); | 802 | sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T), rx_reg); |
| @@ -782,13 +805,18 @@ 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); | 805 | sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR); |
| 783 | 806 | ||
| 784 | /* Set threshold to 0xa (64 bytes) + 1 to workaround pause bug */ | 807 | /* 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); | 808 | reg = RX_GMF_FL_THR_DEF + 1; |
| 809 | /* Another magic mystery workaround from sk98lin */ | ||
| 810 | if (hw->chip_id == CHIP_ID_YUKON_FE_P && | ||
| 811 | hw->chip_rev == CHIP_REV_YU_FE2_A0) | ||
| 812 | reg = 0x178; | ||
| 813 | sky2_write16(hw, SK_REG(port, RX_GMF_FL_THR), reg); | ||
| 786 | 814 | ||
| 787 | /* Configure Tx MAC FIFO */ | 815 | /* Configure Tx MAC FIFO */ |
| 788 | sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); | 816 | 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); | 817 | sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); |
| 790 | 818 | ||
| 791 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { | 819 | if (!(hw->flags & SKY2_HW_RAMBUFFER)) { |
| 792 | sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8); | 820 | 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); | 821 | sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8); |
| 794 | 822 | ||
| @@ -967,19 +995,15 @@ static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re) | |||
| 967 | */ | 995 | */ |
| 968 | static void rx_set_checksum(struct sky2_port *sky2) | 996 | static void rx_set_checksum(struct sky2_port *sky2) |
| 969 | { | 997 | { |
| 970 | struct sky2_rx_le *le; | 998 | struct sky2_rx_le *le = sky2_next_rx(sky2); |
| 971 | 999 | ||
| 972 | if (sky2->hw->chip_id != CHIP_ID_YUKON_EX) { | 1000 | le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN); |
| 973 | le = sky2_next_rx(sky2); | 1001 | le->ctrl = 0; |
| 974 | le->addr = cpu_to_le32((ETH_HLEN << 16) | ETH_HLEN); | 1002 | le->opcode = OP_TCPSTART | HW_OWNER; |
| 975 | le->ctrl = 0; | ||
| 976 | le->opcode = OP_TCPSTART | HW_OWNER; | ||
| 977 | |||
| 978 | sky2_write32(sky2->hw, | ||
| 979 | Q_ADDR(rxqaddr[sky2->port], Q_CSR), | ||
| 980 | sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); | ||
| 981 | } | ||
| 982 | 1003 | ||
| 1004 | sky2_write32(sky2->hw, | ||
| 1005 | Q_ADDR(rxqaddr[sky2->port], Q_CSR), | ||
| 1006 | sky2->rx_csum ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM); | ||
| 983 | } | 1007 | } |
| 984 | 1008 | ||
| 985 | /* | 1009 | /* |
| @@ -1175,7 +1199,8 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
| 1175 | 1199 | ||
| 1176 | sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); | 1200 | sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); |
| 1177 | 1201 | ||
| 1178 | rx_set_checksum(sky2); | 1202 | if (!(hw->flags & SKY2_HW_NEW_LE)) |
| 1203 | rx_set_checksum(sky2); | ||
| 1179 | 1204 | ||
| 1180 | /* Space needed for frame data + headers rounded up */ | 1205 | /* Space needed for frame data + headers rounded up */ |
| 1181 | size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8); | 1206 | size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8); |
| @@ -1246,7 +1271,7 @@ static int sky2_up(struct net_device *dev) | |||
| 1246 | struct sky2_port *sky2 = netdev_priv(dev); | 1271 | struct sky2_port *sky2 = netdev_priv(dev); |
| 1247 | struct sky2_hw *hw = sky2->hw; | 1272 | struct sky2_hw *hw = sky2->hw; |
| 1248 | unsigned port = sky2->port; | 1273 | unsigned port = sky2->port; |
| 1249 | u32 ramsize, imask; | 1274 | u32 imask; |
| 1250 | int cap, err = -ENOMEM; | 1275 | int cap, err = -ENOMEM; |
| 1251 | struct net_device *otherdev = hw->dev[sky2->port^1]; | 1276 | struct net_device *otherdev = hw->dev[sky2->port^1]; |
| 1252 | 1277 | ||
| @@ -1301,13 +1326,13 @@ static int sky2_up(struct net_device *dev) | |||
| 1301 | 1326 | ||
| 1302 | sky2_mac_init(hw, port); | 1327 | sky2_mac_init(hw, port); |
| 1303 | 1328 | ||
| 1304 | /* Register is number of 4K blocks on internal RAM buffer. */ | 1329 | if (hw->flags & SKY2_HW_RAMBUFFER) { |
| 1305 | ramsize = sky2_read8(hw, B2_E_0) * 4; | 1330 | /* Register is number of 4K blocks on internal RAM buffer. */ |
| 1306 | printk(KERN_INFO PFX "%s: ram buffer %dK\n", dev->name, ramsize); | 1331 | u32 ramsize = sky2_read8(hw, B2_E_0) * 4; |
| 1307 | |||
| 1308 | if (ramsize > 0) { | ||
| 1309 | u32 rxspace; | 1332 | u32 rxspace; |
| 1310 | 1333 | ||
| 1334 | printk(KERN_DEBUG PFX "%s: ram buffer %dK\n", dev->name, ramsize); | ||
| 1335 | |||
| 1311 | if (ramsize < 16) | 1336 | if (ramsize < 16) |
| 1312 | rxspace = ramsize / 2; | 1337 | rxspace = ramsize / 2; |
| 1313 | else | 1338 | else |
| @@ -1436,13 +1461,15 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
| 1436 | /* Check for TCP Segmentation Offload */ | 1461 | /* Check for TCP Segmentation Offload */ |
| 1437 | mss = skb_shinfo(skb)->gso_size; | 1462 | mss = skb_shinfo(skb)->gso_size; |
| 1438 | if (mss != 0) { | 1463 | if (mss != 0) { |
| 1439 | if (hw->chip_id != CHIP_ID_YUKON_EX) | 1464 | |
| 1465 | if (!(hw->flags & SKY2_HW_NEW_LE)) | ||
| 1440 | mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb); | 1466 | mss += ETH_HLEN + ip_hdrlen(skb) + tcp_hdrlen(skb); |
| 1441 | 1467 | ||
| 1442 | if (mss != sky2->tx_last_mss) { | 1468 | if (mss != sky2->tx_last_mss) { |
| 1443 | le = get_tx_le(sky2); | 1469 | le = get_tx_le(sky2); |
| 1444 | le->addr = cpu_to_le32(mss); | 1470 | le->addr = cpu_to_le32(mss); |
| 1445 | if (hw->chip_id == CHIP_ID_YUKON_EX) | 1471 | |
| 1472 | if (hw->flags & SKY2_HW_NEW_LE) | ||
| 1446 | le->opcode = OP_MSS | HW_OWNER; | 1473 | le->opcode = OP_MSS | HW_OWNER; |
| 1447 | else | 1474 | else |
| 1448 | le->opcode = OP_LRGLEN | HW_OWNER; | 1475 | le->opcode = OP_LRGLEN | HW_OWNER; |
| @@ -1468,8 +1495,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
| 1468 | /* Handle TCP checksum offload */ | 1495 | /* Handle TCP checksum offload */ |
| 1469 | if (skb->ip_summed == CHECKSUM_PARTIAL) { | 1496 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
| 1470 | /* On Yukon EX (some versions) encoding change. */ | 1497 | /* On Yukon EX (some versions) encoding change. */ |
| 1471 | if (hw->chip_id == CHIP_ID_YUKON_EX | 1498 | if (hw->flags & SKY2_HW_AUTO_TX_SUM) |
| 1472 | && hw->chip_rev != CHIP_REV_YU_EX_B0) | ||
| 1473 | ctrl |= CALSUM; /* auto checksum */ | 1499 | ctrl |= CALSUM; /* auto checksum */ |
| 1474 | else { | 1500 | else { |
| 1475 | const unsigned offset = skb_transport_offset(skb); | 1501 | const unsigned offset = skb_transport_offset(skb); |
| @@ -1622,9 +1648,6 @@ static int sky2_down(struct net_device *dev) | |||
| 1622 | if (netif_msg_ifdown(sky2)) | 1648 | if (netif_msg_ifdown(sky2)) |
| 1623 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); | 1649 | printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); |
| 1624 | 1650 | ||
| 1625 | if (netif_carrier_ok(dev) && --hw->active == 0) | ||
| 1626 | del_timer(&hw->watchdog_timer); | ||
| 1627 | |||
| 1628 | /* Stop more packets from being queued */ | 1651 | /* Stop more packets from being queued */ |
| 1629 | netif_stop_queue(dev); | 1652 | netif_stop_queue(dev); |
| 1630 | 1653 | ||
| @@ -1708,11 +1731,15 @@ static int sky2_down(struct net_device *dev) | |||
| 1708 | 1731 | ||
| 1709 | static u16 sky2_phy_speed(const struct sky2_hw *hw, u16 aux) | 1732 | static u16 sky2_phy_speed(const struct sky2_hw *hw, u16 aux) |
| 1710 | { | 1733 | { |
| 1711 | if (!sky2_is_copper(hw)) | 1734 | if (hw->flags & SKY2_HW_FIBRE_PHY) |
| 1712 | return SPEED_1000; | 1735 | return SPEED_1000; |
| 1713 | 1736 | ||
| 1714 | if (hw->chip_id == CHIP_ID_YUKON_FE) | 1737 | if (!(hw->flags & SKY2_HW_GIGABIT)) { |
| 1715 | return (aux & PHY_M_PS_SPEED_100) ? SPEED_100 : SPEED_10; | 1738 | if (aux & PHY_M_PS_SPEED_100) |
| 1739 | return SPEED_100; | ||
| 1740 | else | ||
| 1741 | return SPEED_10; | ||
| 1742 | } | ||
| 1716 | 1743 | ||
| 1717 | switch (aux & PHY_M_PS_SPEED_MSK) { | 1744 | switch (aux & PHY_M_PS_SPEED_MSK) { |
| 1718 | case PHY_M_PS_SPEED_1000: | 1745 | case PHY_M_PS_SPEED_1000: |
| @@ -1745,17 +1772,13 @@ static void sky2_link_up(struct sky2_port *sky2) | |||
| 1745 | 1772 | ||
| 1746 | netif_carrier_on(sky2->netdev); | 1773 | netif_carrier_on(sky2->netdev); |
| 1747 | 1774 | ||
| 1748 | if (hw->active++ == 0) | 1775 | mod_timer(&hw->watchdog_timer, jiffies + 1); |
| 1749 | mod_timer(&hw->watchdog_timer, jiffies + 1); | ||
| 1750 | |||
| 1751 | 1776 | ||
| 1752 | /* Turn on link LED */ | 1777 | /* Turn on link LED */ |
| 1753 | sky2_write8(hw, SK_REG(port, LNK_LED_REG), | 1778 | sky2_write8(hw, SK_REG(port, LNK_LED_REG), |
| 1754 | LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); | 1779 | LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); |
| 1755 | 1780 | ||
| 1756 | if (hw->chip_id == CHIP_ID_YUKON_XL | 1781 | 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); | 1782 | u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR); |
| 1760 | u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */ | 1783 | u16 led = PHY_M_LEDC_LOS_CTRL(1); /* link active */ |
| 1761 | 1784 | ||
| @@ -1800,11 +1823,6 @@ static void sky2_link_down(struct sky2_port *sky2) | |||
| 1800 | 1823 | ||
| 1801 | netif_carrier_off(sky2->netdev); | 1824 | netif_carrier_off(sky2->netdev); |
| 1802 | 1825 | ||
| 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 */ | 1826 | /* Turn on link LED */ |
| 1809 | sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); | 1827 | sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); |
| 1810 | 1828 | ||
| @@ -1847,7 +1865,7 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux) | |||
| 1847 | /* Since the pause result bits seem to in different positions on | 1865 | /* Since the pause result bits seem to in different positions on |
| 1848 | * different chips. look at registers. | 1866 | * different chips. look at registers. |
| 1849 | */ | 1867 | */ |
| 1850 | if (!sky2_is_copper(hw)) { | 1868 | if (hw->flags & SKY2_HW_FIBRE_PHY) { |
| 1851 | /* Shift for bits in fiber PHY */ | 1869 | /* Shift for bits in fiber PHY */ |
| 1852 | advert &= ~(ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM); | 1870 | advert &= ~(ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM); |
| 1853 | lpa &= ~(LPA_PAUSE_CAP|LPA_PAUSE_ASYM); | 1871 | lpa &= ~(LPA_PAUSE_CAP|LPA_PAUSE_ASYM); |
| @@ -1958,7 +1976,9 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
| 1958 | if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) | 1976 | if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) |
| 1959 | return -EINVAL; | 1977 | return -EINVAL; |
| 1960 | 1978 | ||
| 1961 | if (new_mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_FE) | 1979 | if (new_mtu > ETH_DATA_LEN && |
| 1980 | (hw->chip_id == CHIP_ID_YUKON_FE || | ||
| 1981 | hw->chip_id == CHIP_ID_YUKON_FE_P)) | ||
| 1962 | return -EINVAL; | 1982 | return -EINVAL; |
| 1963 | 1983 | ||
| 1964 | if (!netif_running(dev)) { | 1984 | if (!netif_running(dev)) { |
| @@ -1975,7 +1995,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
| 1975 | 1995 | ||
| 1976 | synchronize_irq(hw->pdev->irq); | 1996 | synchronize_irq(hw->pdev->irq); |
| 1977 | 1997 | ||
| 1978 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) | 1998 | if (!(hw->flags & SKY2_HW_RAMBUFFER)) |
| 1979 | sky2_set_tx_stfwd(hw, port); | 1999 | sky2_set_tx_stfwd(hw, port); |
| 1980 | 2000 | ||
| 1981 | ctl = gma_read16(hw, port, GM_GP_CTRL); | 2001 | ctl = gma_read16(hw, port, GM_GP_CTRL); |
| @@ -2103,6 +2123,13 @@ static struct sk_buff *sky2_receive(struct net_device *dev, | |||
| 2103 | struct sky2_port *sky2 = netdev_priv(dev); | 2123 | struct sky2_port *sky2 = netdev_priv(dev); |
| 2104 | struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next; | 2124 | struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next; |
| 2105 | struct sk_buff *skb = NULL; | 2125 | struct sk_buff *skb = NULL; |
| 2126 | u16 count = (status & GMR_FS_LEN) >> 16; | ||
| 2127 | |||
| 2128 | #ifdef SKY2_VLAN_TAG_USED | ||
| 2129 | /* Account for vlan tag */ | ||
| 2130 | if (sky2->vlgrp && (status & GMR_FS_VLAN)) | ||
| 2131 | count -= VLAN_HLEN; | ||
| 2132 | #endif | ||
| 2106 | 2133 | ||
| 2107 | if (unlikely(netif_msg_rx_status(sky2))) | 2134 | if (unlikely(netif_msg_rx_status(sky2))) |
| 2108 | printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n", | 2135 | printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n", |
| @@ -2117,7 +2144,8 @@ static struct sk_buff *sky2_receive(struct net_device *dev, | |||
| 2117 | if (!(status & GMR_FS_RX_OK)) | 2144 | if (!(status & GMR_FS_RX_OK)) |
| 2118 | goto resubmit; | 2145 | goto resubmit; |
| 2119 | 2146 | ||
| 2120 | if (status >> 16 != length) | 2147 | /* if length reported by DMA does not match PHY, packet was truncated */ |
| 2148 | if (length != count) | ||
| 2121 | goto len_mismatch; | 2149 | goto len_mismatch; |
| 2122 | 2150 | ||
| 2123 | if (length < copybreak) | 2151 | if (length < copybreak) |
| @@ -2133,6 +2161,10 @@ len_mismatch: | |||
| 2133 | /* Truncation of overlength packets | 2161 | /* Truncation of overlength packets |
| 2134 | causes PHY length to not match MAC length */ | 2162 | causes PHY length to not match MAC length */ |
| 2135 | ++sky2->net_stats.rx_length_errors; | 2163 | ++sky2->net_stats.rx_length_errors; |
| 2164 | if (netif_msg_rx_err(sky2) && net_ratelimit()) | ||
| 2165 | pr_info(PFX "%s: rx length mismatch: length %d status %#x\n", | ||
| 2166 | dev->name, length, status); | ||
| 2167 | goto resubmit; | ||
| 2136 | 2168 | ||
| 2137 | error: | 2169 | error: |
| 2138 | ++sky2->net_stats.rx_errors; | 2170 | ++sky2->net_stats.rx_errors; |
| @@ -2202,7 +2234,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
| 2202 | } | 2234 | } |
| 2203 | 2235 | ||
| 2204 | /* This chip reports checksum status differently */ | 2236 | /* This chip reports checksum status differently */ |
| 2205 | if (hw->chip_id == CHIP_ID_YUKON_EX) { | 2237 | if (hw->flags & SKY2_HW_NEW_LE) { |
| 2206 | if (sky2->rx_csum && | 2238 | if (sky2->rx_csum && |
| 2207 | (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) && | 2239 | (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) && |
| 2208 | (le->css & CSS_TCPUDPCSOK)) | 2240 | (le->css & CSS_TCPUDPCSOK)) |
| @@ -2243,8 +2275,14 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do) | |||
| 2243 | if (!sky2->rx_csum) | 2275 | if (!sky2->rx_csum) |
| 2244 | break; | 2276 | break; |
| 2245 | 2277 | ||
| 2246 | if (hw->chip_id == CHIP_ID_YUKON_EX) | 2278 | /* If this happens then driver assuming wrong format */ |
| 2279 | if (unlikely(hw->flags & SKY2_HW_NEW_LE)) { | ||
| 2280 | if (net_ratelimit()) | ||
| 2281 | printk(KERN_NOTICE "%s: unexpected" | ||
| 2282 | " checksum status\n", | ||
| 2283 | dev->name); | ||
| 2247 | break; | 2284 | break; |
| 2285 | } | ||
| 2248 | 2286 | ||
| 2249 | /* Both checksum counters are programmed to start at | 2287 | /* Both checksum counters are programmed to start at |
| 2250 | * the same offset, so unless there is a problem they | 2288 | * the same offset, so unless there is a problem they |
| @@ -2436,20 +2474,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); | 2474 | sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK); |
| 2437 | } | 2475 | } |
| 2438 | 2476 | ||
| 2439 | /* Check for lost IRQ once a second */ | 2477 | static int sky2_rx_hung(struct net_device *dev) |
| 2478 | { | ||
| 2479 | struct sky2_port *sky2 = netdev_priv(dev); | ||
| 2480 | struct sky2_hw *hw = sky2->hw; | ||
| 2481 | unsigned port = sky2->port; | ||
| 2482 | unsigned rxq = rxqaddr[port]; | ||
| 2483 | u32 mac_rp = sky2_read32(hw, SK_REG(port, RX_GMF_RP)); | ||
| 2484 | u8 mac_lev = sky2_read8(hw, SK_REG(port, RX_GMF_RLEV)); | ||
| 2485 | u8 fifo_rp = sky2_read8(hw, Q_ADDR(rxq, Q_RP)); | ||
| 2486 | u8 fifo_lev = sky2_read8(hw, Q_ADDR(rxq, Q_RL)); | ||
| 2487 | |||
| 2488 | /* If idle and MAC or PCI is stuck */ | ||
| 2489 | if (sky2->check.last == dev->last_rx && | ||
| 2490 | ((mac_rp == sky2->check.mac_rp && | ||
| 2491 | mac_lev != 0 && mac_lev >= sky2->check.mac_lev) || | ||
| 2492 | /* Check if the PCI RX hang */ | ||
| 2493 | (fifo_rp == sky2->check.fifo_rp && | ||
| 2494 | fifo_lev != 0 && fifo_lev >= sky2->check.fifo_lev))) { | ||
| 2495 | printk(KERN_DEBUG PFX "%s: hung mac %d:%d fifo %d (%d:%d)\n", | ||
| 2496 | dev->name, mac_lev, mac_rp, fifo_lev, fifo_rp, | ||
| 2497 | sky2_read8(hw, Q_ADDR(rxq, Q_WP))); | ||
| 2498 | return 1; | ||
| 2499 | } else { | ||
| 2500 | sky2->check.last = dev->last_rx; | ||
| 2501 | sky2->check.mac_rp = mac_rp; | ||
| 2502 | sky2->check.mac_lev = mac_lev; | ||
| 2503 | sky2->check.fifo_rp = fifo_rp; | ||
| 2504 | sky2->check.fifo_lev = fifo_lev; | ||
| 2505 | return 0; | ||
| 2506 | } | ||
| 2507 | } | ||
| 2508 | |||
| 2440 | static void sky2_watchdog(unsigned long arg) | 2509 | static void sky2_watchdog(unsigned long arg) |
| 2441 | { | 2510 | { |
| 2442 | struct sky2_hw *hw = (struct sky2_hw *) arg; | 2511 | struct sky2_hw *hw = (struct sky2_hw *) arg; |
| 2512 | struct net_device *dev; | ||
| 2443 | 2513 | ||
| 2514 | /* Check for lost IRQ once a second */ | ||
| 2444 | if (sky2_read32(hw, B0_ISRC)) { | 2515 | if (sky2_read32(hw, B0_ISRC)) { |
| 2445 | struct net_device *dev = hw->dev[0]; | 2516 | dev = hw->dev[0]; |
| 2446 | |||
| 2447 | if (__netif_rx_schedule_prep(dev)) | 2517 | if (__netif_rx_schedule_prep(dev)) |
| 2448 | __netif_rx_schedule(dev); | 2518 | __netif_rx_schedule(dev); |
| 2519 | } else { | ||
| 2520 | int i, active = 0; | ||
| 2521 | |||
| 2522 | for (i = 0; i < hw->ports; i++) { | ||
| 2523 | dev = hw->dev[i]; | ||
| 2524 | if (!netif_running(dev)) | ||
| 2525 | continue; | ||
| 2526 | ++active; | ||
| 2527 | |||
| 2528 | /* For chips with Rx FIFO, check if stuck */ | ||
| 2529 | if ((hw->flags & SKY2_HW_RAMBUFFER) && | ||
| 2530 | sky2_rx_hung(dev)) { | ||
| 2531 | pr_info(PFX "%s: receiver hang detected\n", | ||
| 2532 | dev->name); | ||
| 2533 | schedule_work(&hw->restart_work); | ||
| 2534 | return; | ||
| 2535 | } | ||
| 2536 | } | ||
| 2537 | |||
| 2538 | if (active == 0) | ||
| 2539 | return; | ||
| 2449 | } | 2540 | } |
| 2450 | 2541 | ||
| 2451 | if (hw->active > 0) | 2542 | mod_timer(&hw->watchdog_timer, round_jiffies(jiffies + HZ)); |
| 2452 | mod_timer(&hw->watchdog_timer, round_jiffies(jiffies + HZ)); | ||
| 2453 | } | 2543 | } |
| 2454 | 2544 | ||
| 2455 | /* Hardware/software error handling */ | 2545 | /* Hardware/software error handling */ |
| @@ -2546,17 +2636,25 @@ static void sky2_netpoll(struct net_device *dev) | |||
| 2546 | #endif | 2636 | #endif |
| 2547 | 2637 | ||
| 2548 | /* Chip internal frequency for clock calculations */ | 2638 | /* Chip internal frequency for clock calculations */ |
| 2549 | static inline u32 sky2_mhz(const struct sky2_hw *hw) | 2639 | static u32 sky2_mhz(const struct sky2_hw *hw) |
| 2550 | { | 2640 | { |
| 2551 | switch (hw->chip_id) { | 2641 | switch (hw->chip_id) { |
| 2552 | case CHIP_ID_YUKON_EC: | 2642 | case CHIP_ID_YUKON_EC: |
| 2553 | case CHIP_ID_YUKON_EC_U: | 2643 | case CHIP_ID_YUKON_EC_U: |
| 2554 | case CHIP_ID_YUKON_EX: | 2644 | case CHIP_ID_YUKON_EX: |
| 2555 | return 125; /* 125 Mhz */ | 2645 | return 125; |
| 2646 | |||
| 2556 | case CHIP_ID_YUKON_FE: | 2647 | case CHIP_ID_YUKON_FE: |
| 2557 | return 100; /* 100 Mhz */ | 2648 | return 100; |
| 2558 | default: /* YUKON_XL */ | 2649 | |
| 2559 | return 156; /* 156 Mhz */ | 2650 | case CHIP_ID_YUKON_FE_P: |
| 2651 | return 50; | ||
| 2652 | |||
| 2653 | case CHIP_ID_YUKON_XL: | ||
| 2654 | return 156; | ||
| 2655 | |||
| 2656 | default: | ||
| 2657 | BUG(); | ||
| 2560 | } | 2658 | } |
| 2561 | } | 2659 | } |
| 2562 | 2660 | ||
| @@ -2581,23 +2679,62 @@ static int __devinit sky2_init(struct sky2_hw *hw) | |||
| 2581 | sky2_write8(hw, B0_CTST, CS_RST_CLR); | 2679 | sky2_write8(hw, B0_CTST, CS_RST_CLR); |
| 2582 | 2680 | ||
| 2583 | hw->chip_id = sky2_read8(hw, B2_CHIP_ID); | 2681 | 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) { | 2682 | hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; |
| 2683 | |||
| 2684 | switch(hw->chip_id) { | ||
| 2685 | case CHIP_ID_YUKON_XL: | ||
| 2686 | hw->flags = SKY2_HW_GIGABIT | ||
| 2687 | | SKY2_HW_NEWER_PHY | ||
| 2688 | | SKY2_HW_RAMBUFFER; | ||
| 2689 | break; | ||
| 2690 | |||
| 2691 | case CHIP_ID_YUKON_EC_U: | ||
| 2692 | hw->flags = SKY2_HW_GIGABIT | ||
| 2693 | | SKY2_HW_NEWER_PHY | ||
| 2694 | | SKY2_HW_ADV_POWER_CTL; | ||
| 2695 | break; | ||
| 2696 | |||
| 2697 | case CHIP_ID_YUKON_EX: | ||
| 2698 | hw->flags = SKY2_HW_GIGABIT | ||
| 2699 | | SKY2_HW_NEWER_PHY | ||
| 2700 | | SKY2_HW_NEW_LE | ||
| 2701 | | SKY2_HW_ADV_POWER_CTL; | ||
| 2702 | |||
| 2703 | /* New transmit checksum */ | ||
| 2704 | if (hw->chip_rev != CHIP_REV_YU_EX_B0) | ||
| 2705 | hw->flags |= SKY2_HW_AUTO_TX_SUM; | ||
| 2706 | break; | ||
| 2707 | |||
| 2708 | case CHIP_ID_YUKON_EC: | ||
| 2709 | /* This rev is really old, and requires untested workarounds */ | ||
| 2710 | if (hw->chip_rev == CHIP_REV_YU_EC_A1) { | ||
| 2711 | dev_err(&hw->pdev->dev, "unsupported revision Yukon-EC rev A1\n"); | ||
| 2712 | return -EOPNOTSUPP; | ||
| 2713 | } | ||
| 2714 | hw->flags = SKY2_HW_GIGABIT | SKY2_HW_RAMBUFFER; | ||
| 2715 | break; | ||
| 2716 | |||
| 2717 | case CHIP_ID_YUKON_FE: | ||
| 2718 | hw->flags = SKY2_HW_RAMBUFFER; | ||
| 2719 | break; | ||
| 2720 | |||
| 2721 | case CHIP_ID_YUKON_FE_P: | ||
| 2722 | hw->flags = SKY2_HW_NEWER_PHY | ||
| 2723 | | SKY2_HW_NEW_LE | ||
| 2724 | | SKY2_HW_AUTO_TX_SUM | ||
| 2725 | | SKY2_HW_ADV_POWER_CTL; | ||
| 2726 | break; | ||
| 2727 | default: | ||
| 2585 | dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n", | 2728 | dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n", |
| 2586 | hw->chip_id); | 2729 | hw->chip_id); |
| 2587 | return -EOPNOTSUPP; | 2730 | return -EOPNOTSUPP; |
| 2588 | } | 2731 | } |
| 2589 | 2732 | ||
| 2590 | hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4; | 2733 | hw->pmd_type = sky2_read8(hw, B2_PMD_TYP); |
| 2734 | if (hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P') | ||
| 2735 | hw->flags |= SKY2_HW_FIBRE_PHY; | ||
| 2591 | 2736 | ||
| 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 | 2737 | ||
| 2600 | hw->pmd_type = sky2_read8(hw, B2_PMD_TYP); | ||
| 2601 | hw->ports = 1; | 2738 | hw->ports = 1; |
| 2602 | t8 = sky2_read8(hw, B2_Y2_HW_RES); | 2739 | t8 = sky2_read8(hw, B2_Y2_HW_RES); |
| 2603 | if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) { | 2740 | if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) { |
| @@ -2791,7 +2928,9 @@ static int sky2_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | |||
| 2791 | 2928 | ||
| 2792 | sky2->wol = wol->wolopts; | 2929 | sky2->wol = wol->wolopts; |
| 2793 | 2930 | ||
| 2794 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) | 2931 | if (hw->chip_id == CHIP_ID_YUKON_EC_U || |
| 2932 | hw->chip_id == CHIP_ID_YUKON_EX || | ||
| 2933 | hw->chip_id == CHIP_ID_YUKON_FE_P) | ||
| 2795 | sky2_write32(hw, B0_CTST, sky2->wol | 2934 | sky2_write32(hw, B0_CTST, sky2->wol |
| 2796 | ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF); | 2935 | ? Y2_HW_WOL_ON : Y2_HW_WOL_OFF); |
| 2797 | 2936 | ||
| @@ -2809,7 +2948,7 @@ static u32 sky2_supported_modes(const struct sky2_hw *hw) | |||
| 2809 | | SUPPORTED_100baseT_Full | 2948 | | SUPPORTED_100baseT_Full |
| 2810 | | SUPPORTED_Autoneg | SUPPORTED_TP; | 2949 | | SUPPORTED_Autoneg | SUPPORTED_TP; |
| 2811 | 2950 | ||
| 2812 | if (hw->chip_id != CHIP_ID_YUKON_FE) | 2951 | if (hw->flags & SKY2_HW_GIGABIT) |
| 2813 | modes |= SUPPORTED_1000baseT_Half | 2952 | modes |= SUPPORTED_1000baseT_Half |
| 2814 | | SUPPORTED_1000baseT_Full; | 2953 | | SUPPORTED_1000baseT_Full; |
| 2815 | return modes; | 2954 | return modes; |
| @@ -2829,13 +2968,6 @@ static int sky2_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
| 2829 | ecmd->supported = sky2_supported_modes(hw); | 2968 | ecmd->supported = sky2_supported_modes(hw); |
| 2830 | ecmd->phy_address = PHY_ADDR_MARV; | 2969 | ecmd->phy_address = PHY_ADDR_MARV; |
| 2831 | if (sky2_is_copper(hw)) { | 2970 | 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; | 2971 | ecmd->port = PORT_TP; |
| 2840 | ecmd->speed = sky2->speed; | 2972 | ecmd->speed = sky2->speed; |
| 2841 | } else { | 2973 | } else { |
| @@ -3791,6 +3923,13 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, | |||
| 3791 | sky2->hw = hw; | 3923 | sky2->hw = hw; |
| 3792 | sky2->msg_enable = netif_msg_init(debug, default_msg); | 3924 | sky2->msg_enable = netif_msg_init(debug, default_msg); |
| 3793 | 3925 | ||
| 3926 | /* This chip has hardware problems that generates | ||
| 3927 | * bogus PHY receive status so by default shut up the message. | ||
| 3928 | */ | ||
| 3929 | if (hw->chip_id == CHIP_ID_YUKON_FE_P && | ||
| 3930 | hw->chip_rev == CHIP_REV_YU_FE2_A0) | ||
| 3931 | sky2->msg_enable &= ~NETIF_MSG_RX_ERR; | ||
| 3932 | |||
| 3794 | /* Auto speed and flow control */ | 3933 | /* Auto speed and flow control */ |
| 3795 | sky2->autoneg = AUTONEG_ENABLE; | 3934 | sky2->autoneg = AUTONEG_ENABLE; |
| 3796 | sky2->flow_mode = FC_BOTH; | 3935 | sky2->flow_mode = FC_BOTH; |
| @@ -3846,7 +3985,7 @@ static irqreturn_t __devinit sky2_test_intr(int irq, void *dev_id) | |||
| 3846 | return IRQ_NONE; | 3985 | return IRQ_NONE; |
| 3847 | 3986 | ||
| 3848 | if (status & Y2_IS_IRQ_SW) { | 3987 | if (status & Y2_IS_IRQ_SW) { |
| 3849 | hw->msi = 1; | 3988 | hw->flags |= SKY2_HW_USE_MSI; |
| 3850 | wake_up(&hw->msi_wait); | 3989 | wake_up(&hw->msi_wait); |
| 3851 | sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ); | 3990 | sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ); |
| 3852 | } | 3991 | } |
| @@ -3874,9 +4013,9 @@ static int __devinit sky2_test_msi(struct sky2_hw *hw) | |||
| 3874 | sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ); | 4013 | sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ); |
| 3875 | sky2_read8(hw, B0_CTST); | 4014 | sky2_read8(hw, B0_CTST); |
| 3876 | 4015 | ||
| 3877 | wait_event_timeout(hw->msi_wait, hw->msi, HZ/10); | 4016 | wait_event_timeout(hw->msi_wait, (hw->flags & SKY2_HW_USE_MSI), HZ/10); |
| 3878 | 4017 | ||
| 3879 | if (!hw->msi) { | 4018 | if (!(hw->flags & SKY2_HW_USE_MSI)) { |
| 3880 | /* MSI test failed, go back to INTx mode */ | 4019 | /* MSI test failed, go back to INTx mode */ |
| 3881 | dev_info(&pdev->dev, "No interrupt generated using MSI, " | 4020 | dev_info(&pdev->dev, "No interrupt generated using MSI, " |
| 3882 | "switching to INTx mode.\n"); | 4021 | "switching to INTx mode.\n"); |
| @@ -4009,7 +4148,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
| 4009 | goto err_out_free_netdev; | 4148 | goto err_out_free_netdev; |
| 4010 | } | 4149 | } |
| 4011 | 4150 | ||
| 4012 | err = request_irq(pdev->irq, sky2_intr, hw->msi ? 0 : IRQF_SHARED, | 4151 | err = request_irq(pdev->irq, sky2_intr, |
| 4152 | (hw->flags & SKY2_HW_USE_MSI) ? 0 : IRQF_SHARED, | ||
| 4013 | dev->name, hw); | 4153 | dev->name, hw); |
| 4014 | if (err) { | 4154 | if (err) { |
| 4015 | dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq); | 4155 | dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq); |
| @@ -4042,7 +4182,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
| 4042 | return 0; | 4182 | return 0; |
| 4043 | 4183 | ||
| 4044 | err_out_unregister: | 4184 | err_out_unregister: |
| 4045 | if (hw->msi) | 4185 | if (hw->flags & SKY2_HW_USE_MSI) |
| 4046 | pci_disable_msi(pdev); | 4186 | pci_disable_msi(pdev); |
| 4047 | unregister_netdev(dev); | 4187 | unregister_netdev(dev); |
| 4048 | err_out_free_netdev: | 4188 | err_out_free_netdev: |
| @@ -4091,7 +4231,7 @@ static void __devexit sky2_remove(struct pci_dev *pdev) | |||
| 4091 | sky2_read8(hw, B0_CTST); | 4231 | sky2_read8(hw, B0_CTST); |
| 4092 | 4232 | ||
| 4093 | free_irq(pdev->irq, hw); | 4233 | free_irq(pdev->irq, hw); |
| 4094 | if (hw->msi) | 4234 | if (hw->flags & SKY2_HW_USE_MSI) |
| 4095 | pci_disable_msi(pdev); | 4235 | pci_disable_msi(pdev); |
| 4096 | pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma); | 4236 | pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma); |
| 4097 | pci_release_regions(pdev); | 4237 | pci_release_regions(pdev); |
| @@ -4159,7 +4299,9 @@ static int sky2_resume(struct pci_dev *pdev) | |||
| 4159 | pci_enable_wake(pdev, PCI_D0, 0); | 4299 | pci_enable_wake(pdev, PCI_D0, 0); |
| 4160 | 4300 | ||
| 4161 | /* Re-enable all clocks */ | 4301 | /* Re-enable all clocks */ |
| 4162 | if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U) | 4302 | if (hw->chip_id == CHIP_ID_YUKON_EX || |
| 4303 | hw->chip_id == CHIP_ID_YUKON_EC_U || | ||
| 4304 | hw->chip_id == CHIP_ID_YUKON_FE_P) | ||
| 4163 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); | 4305 | sky2_pci_write32(hw, PCI_DEV_REG3, 0); |
| 4164 | 4306 | ||
| 4165 | sky2_reset(hw); | 4307 | sky2_reset(hw); |
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 72e12b7cfa40..69cd98400fe6 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
| @@ -470,18 +470,24 @@ enum { | |||
| 470 | CHIP_ID_YUKON_EX = 0xb5, /* Chip ID for YUKON-2 Extreme */ | 470 | CHIP_ID_YUKON_EX = 0xb5, /* Chip ID for YUKON-2 Extreme */ |
| 471 | CHIP_ID_YUKON_EC = 0xb6, /* Chip ID for YUKON-2 EC */ | 471 | CHIP_ID_YUKON_EC = 0xb6, /* Chip ID for YUKON-2 EC */ |
| 472 | CHIP_ID_YUKON_FE = 0xb7, /* Chip ID for YUKON-2 FE */ | 472 | CHIP_ID_YUKON_FE = 0xb7, /* Chip ID for YUKON-2 FE */ |
| 473 | 473 | CHIP_ID_YUKON_FE_P = 0xb8, /* Chip ID for YUKON-2 FE+ */ | |
| 474 | }; | ||
| 475 | enum yukon_ec_rev { | ||
| 474 | CHIP_REV_YU_EC_A1 = 0, /* Chip Rev. for Yukon-EC A1/A0 */ | 476 | CHIP_REV_YU_EC_A1 = 0, /* Chip Rev. for Yukon-EC A1/A0 */ |
| 475 | CHIP_REV_YU_EC_A2 = 1, /* Chip Rev. for Yukon-EC A2 */ | 477 | CHIP_REV_YU_EC_A2 = 1, /* Chip Rev. for Yukon-EC A2 */ |
| 476 | CHIP_REV_YU_EC_A3 = 2, /* Chip Rev. for Yukon-EC A3 */ | 478 | CHIP_REV_YU_EC_A3 = 2, /* Chip Rev. for Yukon-EC A3 */ |
| 477 | 479 | }; | |
| 480 | enum yukon_ec_u_rev { | ||
| 478 | CHIP_REV_YU_EC_U_A0 = 1, | 481 | CHIP_REV_YU_EC_U_A0 = 1, |
| 479 | CHIP_REV_YU_EC_U_A1 = 2, | 482 | CHIP_REV_YU_EC_U_A1 = 2, |
| 480 | CHIP_REV_YU_EC_U_B0 = 3, | 483 | CHIP_REV_YU_EC_U_B0 = 3, |
| 481 | 484 | }; | |
| 485 | enum yukon_fe_rev { | ||
| 482 | CHIP_REV_YU_FE_A1 = 1, | 486 | CHIP_REV_YU_FE_A1 = 1, |
| 483 | CHIP_REV_YU_FE_A2 = 2, | 487 | CHIP_REV_YU_FE_A2 = 2, |
| 484 | 488 | }; | |
| 489 | enum yukon_fe_p_rev { | ||
| 490 | CHIP_REV_YU_FE2_A0 = 0, | ||
| 485 | }; | 491 | }; |
| 486 | enum yukon_ex_rev { | 492 | enum yukon_ex_rev { |
| 487 | CHIP_REV_YU_EX_A0 = 1, | 493 | CHIP_REV_YU_EX_A0 = 1, |
| @@ -1668,7 +1674,7 @@ enum { | |||
| 1668 | 1674 | ||
| 1669 | /* Receive Frame Status Encoding */ | 1675 | /* Receive Frame Status Encoding */ |
| 1670 | enum { | 1676 | enum { |
| 1671 | GMR_FS_LEN = 0xffff<<16, /* Bit 31..16: Rx Frame Length */ | 1677 | GMR_FS_LEN = 0x7fff<<16, /* Bit 30..16: Rx Frame Length */ |
| 1672 | GMR_FS_VLAN = 1<<13, /* VLAN Packet */ | 1678 | GMR_FS_VLAN = 1<<13, /* VLAN Packet */ |
| 1673 | GMR_FS_JABBER = 1<<12, /* Jabber Packet */ | 1679 | GMR_FS_JABBER = 1<<12, /* Jabber Packet */ |
| 1674 | GMR_FS_UN_SIZE = 1<<11, /* Undersize Packet */ | 1680 | GMR_FS_UN_SIZE = 1<<11, /* Undersize Packet */ |
| @@ -1729,6 +1735,10 @@ enum { | |||
| 1729 | GMF_RX_CTRL_DEF = GMF_OPER_ON | GMF_RX_F_FL_ON, | 1735 | GMF_RX_CTRL_DEF = GMF_OPER_ON | GMF_RX_F_FL_ON, |
| 1730 | }; | 1736 | }; |
| 1731 | 1737 | ||
| 1738 | /* TX_GMF_EA 32 bit Tx GMAC FIFO End Address */ | ||
| 1739 | enum { | ||
| 1740 | TX_DYN_WM_ENA = 3, /* Yukon-FE+ specific */ | ||
| 1741 | }; | ||
| 1732 | 1742 | ||
| 1733 | /* TX_GMF_CTRL_T 32 bit Tx GMAC FIFO Control/Test */ | 1743 | /* TX_GMF_CTRL_T 32 bit Tx GMAC FIFO Control/Test */ |
| 1734 | enum { | 1744 | enum { |
| @@ -2017,6 +2027,14 @@ struct sky2_port { | |||
| 2017 | u16 rx_tag; | 2027 | u16 rx_tag; |
| 2018 | struct vlan_group *vlgrp; | 2028 | struct vlan_group *vlgrp; |
| 2019 | #endif | 2029 | #endif |
| 2030 | struct { | ||
| 2031 | unsigned long last; | ||
| 2032 | u32 mac_rp; | ||
| 2033 | u8 mac_lev; | ||
| 2034 | u8 fifo_rp; | ||
| 2035 | u8 fifo_lev; | ||
| 2036 | } check; | ||
| 2037 | |||
| 2020 | 2038 | ||
| 2021 | dma_addr_t rx_le_map; | 2039 | dma_addr_t rx_le_map; |
| 2022 | dma_addr_t tx_le_map; | 2040 | dma_addr_t tx_le_map; |
| @@ -2040,12 +2058,20 @@ struct sky2_hw { | |||
| 2040 | void __iomem *regs; | 2058 | void __iomem *regs; |
| 2041 | struct pci_dev *pdev; | 2059 | struct pci_dev *pdev; |
| 2042 | struct net_device *dev[2]; | 2060 | struct net_device *dev[2]; |
| 2061 | unsigned long flags; | ||
| 2062 | #define SKY2_HW_USE_MSI 0x00000001 | ||
| 2063 | #define SKY2_HW_FIBRE_PHY 0x00000002 | ||
| 2064 | #define SKY2_HW_GIGABIT 0x00000004 | ||
| 2065 | #define SKY2_HW_NEWER_PHY 0x00000008 | ||
| 2066 | #define SKY2_HW_RAMBUFFER 0x00000010 /* chip has RAM FIFO */ | ||
| 2067 | #define SKY2_HW_NEW_LE 0x00000020 /* new LSOv2 format */ | ||
| 2068 | #define SKY2_HW_AUTO_TX_SUM 0x00000040 /* new IP decode for Tx */ | ||
| 2069 | #define SKY2_HW_ADV_POWER_CTL 0x00000080 /* additional PHY power regs */ | ||
| 2043 | 2070 | ||
| 2044 | u8 chip_id; | 2071 | u8 chip_id; |
| 2045 | u8 chip_rev; | 2072 | u8 chip_rev; |
| 2046 | u8 pmd_type; | 2073 | u8 pmd_type; |
| 2047 | u8 ports; | 2074 | u8 ports; |
| 2048 | u8 active; | ||
| 2049 | 2075 | ||
| 2050 | struct sky2_status_le *st_le; | 2076 | struct sky2_status_le *st_le; |
| 2051 | u32 st_idx; | 2077 | u32 st_idx; |
| @@ -2053,13 +2079,12 @@ struct sky2_hw { | |||
| 2053 | 2079 | ||
| 2054 | struct timer_list watchdog_timer; | 2080 | struct timer_list watchdog_timer; |
| 2055 | struct work_struct restart_work; | 2081 | struct work_struct restart_work; |
| 2056 | int msi; | ||
| 2057 | wait_queue_head_t msi_wait; | 2082 | wait_queue_head_t msi_wait; |
| 2058 | }; | 2083 | }; |
| 2059 | 2084 | ||
| 2060 | static inline int sky2_is_copper(const struct sky2_hw *hw) | 2085 | static inline int sky2_is_copper(const struct sky2_hw *hw) |
| 2061 | { | 2086 | { |
| 2062 | return !(hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P'); | 2087 | return !(hw->flags & SKY2_HW_FIBRE_PHY); |
| 2063 | } | 2088 | } |
| 2064 | 2089 | ||
| 2065 | /* Register accessor for memory mapped device */ | 2090 | /* Register accessor for memory mapped device */ |
