diff options
author | Jie Yang <Jie.Yang@atheros.com> | 2010-06-01 03:28:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-01 03:28:12 -0400 |
commit | 8f574b35f22fbb9b5e5f1d11ad6b55b6f35f4533 (patch) | |
tree | 3baea347e8214e9e573436b32a92f37f1c7d1195 /drivers/net | |
parent | aac4dddc358acfd9d98b20024a42c34dfab31c39 (diff) |
atl1c: Add AR8151 v2 support and change L0s/L1 routine
Add AR8151 v2.0 Gigabit 1000 support
Change jumbo frame size to 6K
Update L0s/L1 rountine
when link speed is 100M or 1G, set L1 link timer to 4 for l1d_2 and l2c_b2
set L1 link timer to 7 for l2c_b, set L1 link timer to 0xF for others.
Update atl1c_suspend routine
just refactory the function, add atl1c_phy_power_saving routine,
when Wake On Lan enable, this func will be called to save power,
it will reautoneg PHY to 10/100M speed depend on the link
partners link capability.
Update atl1c_configure_des_ring
do not use l2c_b default SRAM configuration.
Signed-off-by: Jie Yang <Jie.Yang@atheros.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/atl1c/atl1c.h | 9 | ||||
-rw-r--r-- | drivers/net/atl1c/atl1c_hw.c | 107 | ||||
-rw-r--r-- | drivers/net/atl1c/atl1c_hw.h | 49 | ||||
-rw-r--r-- | drivers/net/atl1c/atl1c_main.c | 348 |
4 files changed, 345 insertions, 168 deletions
diff --git a/drivers/net/atl1c/atl1c.h b/drivers/net/atl1c/atl1c.h index 84ae905bf732..52abbbdf8a08 100644 --- a/drivers/net/atl1c/atl1c.h +++ b/drivers/net/atl1c/atl1c.h | |||
@@ -73,7 +73,8 @@ | |||
73 | #define FULL_DUPLEX 2 | 73 | #define FULL_DUPLEX 2 |
74 | 74 | ||
75 | #define AT_RX_BUF_SIZE (ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN) | 75 | #define AT_RX_BUF_SIZE (ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN) |
76 | #define MAX_JUMBO_FRAME_SIZE (9*1024) | 76 | #define MAX_JUMBO_FRAME_SIZE (6*1024) |
77 | #define MAX_TSO_FRAME_SIZE (7*1024) | ||
77 | #define MAX_TX_OFFLOAD_THRESH (9*1024) | 78 | #define MAX_TX_OFFLOAD_THRESH (9*1024) |
78 | 79 | ||
79 | #define AT_MAX_RECEIVE_QUEUE 4 | 80 | #define AT_MAX_RECEIVE_QUEUE 4 |
@@ -87,10 +88,11 @@ | |||
87 | #define AT_MAX_INT_WORK 5 | 88 | #define AT_MAX_INT_WORK 5 |
88 | #define AT_TWSI_EEPROM_TIMEOUT 100 | 89 | #define AT_TWSI_EEPROM_TIMEOUT 100 |
89 | #define AT_HW_MAX_IDLE_DELAY 10 | 90 | #define AT_HW_MAX_IDLE_DELAY 10 |
90 | #define AT_SUSPEND_LINK_TIMEOUT 28 | 91 | #define AT_SUSPEND_LINK_TIMEOUT 100 |
91 | 92 | ||
92 | #define AT_ASPM_L0S_TIMER 6 | 93 | #define AT_ASPM_L0S_TIMER 6 |
93 | #define AT_ASPM_L1_TIMER 12 | 94 | #define AT_ASPM_L1_TIMER 12 |
95 | #define AT_LCKDET_TIMER 12 | ||
94 | 96 | ||
95 | #define ATL1C_PCIE_L0S_L1_DISABLE 0x01 | 97 | #define ATL1C_PCIE_L0S_L1_DISABLE 0x01 |
96 | #define ATL1C_PCIE_PHY_RESET 0x02 | 98 | #define ATL1C_PCIE_PHY_RESET 0x02 |
@@ -316,6 +318,7 @@ enum atl1c_nic_type { | |||
316 | athr_l2c_b, | 318 | athr_l2c_b, |
317 | athr_l2c_b2, | 319 | athr_l2c_b2, |
318 | athr_l1d, | 320 | athr_l1d, |
321 | athr_l1d_2, | ||
319 | }; | 322 | }; |
320 | 323 | ||
321 | enum atl1c_trans_queue { | 324 | enum atl1c_trans_queue { |
@@ -392,6 +395,8 @@ struct atl1c_hw { | |||
392 | u16 subsystem_id; | 395 | u16 subsystem_id; |
393 | u16 subsystem_vendor_id; | 396 | u16 subsystem_vendor_id; |
394 | u8 revision_id; | 397 | u8 revision_id; |
398 | u16 phy_id1; | ||
399 | u16 phy_id2; | ||
395 | 400 | ||
396 | u32 intr_mask; | 401 | u32 intr_mask; |
397 | u8 dmaw_dly_cnt; | 402 | u8 dmaw_dly_cnt; |
diff --git a/drivers/net/atl1c/atl1c_hw.c b/drivers/net/atl1c/atl1c_hw.c index f1389d664a21..d8501f060957 100644 --- a/drivers/net/atl1c/atl1c_hw.c +++ b/drivers/net/atl1c/atl1c_hw.c | |||
@@ -37,6 +37,9 @@ int atl1c_check_eeprom_exist(struct atl1c_hw *hw) | |||
37 | if (data & TWSI_DEBUG_DEV_EXIST) | 37 | if (data & TWSI_DEBUG_DEV_EXIST) |
38 | return 1; | 38 | return 1; |
39 | 39 | ||
40 | AT_READ_REG(hw, REG_MASTER_CTRL, &data); | ||
41 | if (data & MASTER_CTRL_OTP_SEL) | ||
42 | return 1; | ||
40 | return 0; | 43 | return 0; |
41 | } | 44 | } |
42 | 45 | ||
@@ -69,6 +72,8 @@ static int atl1c_get_permanent_address(struct atl1c_hw *hw) | |||
69 | u32 i; | 72 | u32 i; |
70 | u32 otp_ctrl_data; | 73 | u32 otp_ctrl_data; |
71 | u32 twsi_ctrl_data; | 74 | u32 twsi_ctrl_data; |
75 | u32 ltssm_ctrl_data; | ||
76 | u32 wol_data; | ||
72 | u8 eth_addr[ETH_ALEN]; | 77 | u8 eth_addr[ETH_ALEN]; |
73 | u16 phy_data; | 78 | u16 phy_data; |
74 | bool raise_vol = false; | 79 | bool raise_vol = false; |
@@ -104,6 +109,15 @@ static int atl1c_get_permanent_address(struct atl1c_hw *hw) | |||
104 | udelay(20); | 109 | udelay(20); |
105 | raise_vol = true; | 110 | raise_vol = true; |
106 | } | 111 | } |
112 | /* close open bit of ReadOnly*/ | ||
113 | AT_READ_REG(hw, REG_LTSSM_ID_CTRL, <ssm_ctrl_data); | ||
114 | ltssm_ctrl_data &= ~LTSSM_ID_EN_WRO; | ||
115 | AT_WRITE_REG(hw, REG_LTSSM_ID_CTRL, ltssm_ctrl_data); | ||
116 | |||
117 | /* clear any WOL settings */ | ||
118 | AT_WRITE_REG(hw, REG_WOL_CTRL, 0); | ||
119 | AT_READ_REG(hw, REG_WOL_CTRL, &wol_data); | ||
120 | |||
107 | 121 | ||
108 | AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data); | 122 | AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data); |
109 | twsi_ctrl_data |= TWSI_CTRL_SW_LDSTART; | 123 | twsi_ctrl_data |= TWSI_CTRL_SW_LDSTART; |
@@ -119,17 +133,15 @@ static int atl1c_get_permanent_address(struct atl1c_hw *hw) | |||
119 | } | 133 | } |
120 | /* Disable OTP_CLK */ | 134 | /* Disable OTP_CLK */ |
121 | if ((hw->nic_type == athr_l1c || hw->nic_type == athr_l2c)) { | 135 | if ((hw->nic_type == athr_l1c || hw->nic_type == athr_l2c)) { |
122 | if (otp_ctrl_data & OTP_CTRL_CLK_EN) { | 136 | otp_ctrl_data &= ~OTP_CTRL_CLK_EN; |
123 | otp_ctrl_data &= ~OTP_CTRL_CLK_EN; | 137 | AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data); |
124 | AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data); | 138 | msleep(1); |
125 | AT_WRITE_FLUSH(hw); | ||
126 | msleep(1); | ||
127 | } | ||
128 | } | 139 | } |
129 | if (raise_vol) { | 140 | if (raise_vol) { |
130 | if (hw->nic_type == athr_l2c_b || | 141 | if (hw->nic_type == athr_l2c_b || |
131 | hw->nic_type == athr_l2c_b2 || | 142 | hw->nic_type == athr_l2c_b2 || |
132 | hw->nic_type == athr_l1d) { | 143 | hw->nic_type == athr_l1d || |
144 | hw->nic_type == athr_l1d_2) { | ||
133 | atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x00); | 145 | atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x00); |
134 | if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data)) | 146 | if (atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data)) |
135 | goto out; | 147 | goto out; |
@@ -456,14 +468,22 @@ int atl1c_phy_reset(struct atl1c_hw *hw) | |||
456 | 468 | ||
457 | if (hw->nic_type == athr_l2c_b || | 469 | if (hw->nic_type == athr_l2c_b || |
458 | hw->nic_type == athr_l2c_b2 || | 470 | hw->nic_type == athr_l2c_b2 || |
459 | hw->nic_type == athr_l1d) { | 471 | hw->nic_type == athr_l1d || |
472 | hw->nic_type == athr_l1d_2) { | ||
460 | atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B); | 473 | atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x3B); |
461 | atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data); | 474 | atl1c_read_phy_reg(hw, MII_DBG_DATA, &phy_data); |
462 | atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data & 0xFFF7); | 475 | atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data & 0xFFF7); |
463 | msleep(20); | 476 | msleep(20); |
464 | } | 477 | } |
465 | 478 | if (hw->nic_type == athr_l1d) { | |
466 | /*Enable PHY LinkChange Interrupt */ | 479 | atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x29); |
480 | atl1c_write_phy_reg(hw, MII_DBG_DATA, 0x929D); | ||
481 | } | ||
482 | if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c_b2 | ||
483 | || hw->nic_type == athr_l2c || hw->nic_type == athr_l2c) { | ||
484 | atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x29); | ||
485 | atl1c_write_phy_reg(hw, MII_DBG_DATA, 0xB6DD); | ||
486 | } | ||
467 | err = atl1c_write_phy_reg(hw, MII_IER, mii_ier_data); | 487 | err = atl1c_write_phy_reg(hw, MII_IER, mii_ier_data); |
468 | if (err) { | 488 | if (err) { |
469 | if (netif_msg_hw(adapter)) | 489 | if (netif_msg_hw(adapter)) |
@@ -482,12 +502,10 @@ int atl1c_phy_init(struct atl1c_hw *hw) | |||
482 | struct pci_dev *pdev = adapter->pdev; | 502 | struct pci_dev *pdev = adapter->pdev; |
483 | int ret_val; | 503 | int ret_val; |
484 | u16 mii_bmcr_data = BMCR_RESET; | 504 | u16 mii_bmcr_data = BMCR_RESET; |
485 | u16 phy_id1, phy_id2; | ||
486 | 505 | ||
487 | if ((atl1c_read_phy_reg(hw, MII_PHYSID1, &phy_id1) != 0) || | 506 | if ((atl1c_read_phy_reg(hw, MII_PHYSID1, &hw->phy_id1) != 0) || |
488 | (atl1c_read_phy_reg(hw, MII_PHYSID2, &phy_id2) != 0)) { | 507 | (atl1c_read_phy_reg(hw, MII_PHYSID2, &hw->phy_id2) != 0)) { |
489 | if (netif_msg_link(adapter)) | 508 | dev_err(&pdev->dev, "Error get phy ID\n"); |
490 | dev_err(&pdev->dev, "Error get phy ID\n"); | ||
491 | return -1; | 509 | return -1; |
492 | } | 510 | } |
493 | switch (hw->media_type) { | 511 | switch (hw->media_type) { |
@@ -572,6 +590,65 @@ int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex) | |||
572 | return 0; | 590 | return 0; |
573 | } | 591 | } |
574 | 592 | ||
593 | int atl1c_phy_power_saving(struct atl1c_hw *hw) | ||
594 | { | ||
595 | struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter; | ||
596 | struct pci_dev *pdev = adapter->pdev; | ||
597 | int ret = 0; | ||
598 | u16 autoneg_advertised = ADVERTISED_10baseT_Half; | ||
599 | u16 save_autoneg_advertised; | ||
600 | u16 phy_data; | ||
601 | u16 mii_lpa_data; | ||
602 | u16 speed = SPEED_0; | ||
603 | u16 duplex = FULL_DUPLEX; | ||
604 | int i; | ||
605 | |||
606 | atl1c_read_phy_reg(hw, MII_BMSR, &phy_data); | ||
607 | atl1c_read_phy_reg(hw, MII_BMSR, &phy_data); | ||
608 | if (phy_data & BMSR_LSTATUS) { | ||
609 | atl1c_read_phy_reg(hw, MII_LPA, &mii_lpa_data); | ||
610 | if (mii_lpa_data & LPA_10FULL) | ||
611 | autoneg_advertised = ADVERTISED_10baseT_Full; | ||
612 | else if (mii_lpa_data & LPA_10HALF) | ||
613 | autoneg_advertised = ADVERTISED_10baseT_Half; | ||
614 | else if (mii_lpa_data & LPA_100HALF) | ||
615 | autoneg_advertised = ADVERTISED_100baseT_Half; | ||
616 | else if (mii_lpa_data & LPA_100FULL) | ||
617 | autoneg_advertised = ADVERTISED_100baseT_Full; | ||
618 | |||
619 | save_autoneg_advertised = hw->autoneg_advertised; | ||
620 | hw->phy_configured = false; | ||
621 | hw->autoneg_advertised = autoneg_advertised; | ||
622 | if (atl1c_restart_autoneg(hw) != 0) { | ||
623 | dev_dbg(&pdev->dev, "phy autoneg failed\n"); | ||
624 | ret = -1; | ||
625 | } | ||
626 | hw->autoneg_advertised = save_autoneg_advertised; | ||
627 | |||
628 | if (mii_lpa_data) { | ||
629 | for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) { | ||
630 | mdelay(100); | ||
631 | atl1c_read_phy_reg(hw, MII_BMSR, &phy_data); | ||
632 | atl1c_read_phy_reg(hw, MII_BMSR, &phy_data); | ||
633 | if (phy_data & BMSR_LSTATUS) { | ||
634 | if (atl1c_get_speed_and_duplex(hw, &speed, | ||
635 | &duplex) != 0) | ||
636 | dev_dbg(&pdev->dev, | ||
637 | "get speed and duplex failed\n"); | ||
638 | break; | ||
639 | } | ||
640 | } | ||
641 | } | ||
642 | } else { | ||
643 | speed = SPEED_10; | ||
644 | duplex = HALF_DUPLEX; | ||
645 | } | ||
646 | adapter->link_speed = speed; | ||
647 | adapter->link_duplex = duplex; | ||
648 | |||
649 | return ret; | ||
650 | } | ||
651 | |||
575 | int atl1c_restart_autoneg(struct atl1c_hw *hw) | 652 | int atl1c_restart_autoneg(struct atl1c_hw *hw) |
576 | { | 653 | { |
577 | int err = 0; | 654 | int err = 0; |
diff --git a/drivers/net/atl1c/atl1c_hw.h b/drivers/net/atl1c/atl1c_hw.h index 1eeb3ed9f0cb..3dd675979aa1 100644 --- a/drivers/net/atl1c/atl1c_hw.h +++ b/drivers/net/atl1c/atl1c_hw.h | |||
@@ -42,7 +42,7 @@ bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value); | |||
42 | int atl1c_phy_init(struct atl1c_hw *hw); | 42 | int atl1c_phy_init(struct atl1c_hw *hw); |
43 | int atl1c_check_eeprom_exist(struct atl1c_hw *hw); | 43 | int atl1c_check_eeprom_exist(struct atl1c_hw *hw); |
44 | int atl1c_restart_autoneg(struct atl1c_hw *hw); | 44 | int atl1c_restart_autoneg(struct atl1c_hw *hw); |
45 | 45 | int atl1c_phy_power_saving(struct atl1c_hw *hw); | |
46 | /* register definition */ | 46 | /* register definition */ |
47 | #define REG_DEVICE_CAP 0x5C | 47 | #define REG_DEVICE_CAP 0x5C |
48 | #define DEVICE_CAP_MAX_PAYLOAD_MASK 0x7 | 48 | #define DEVICE_CAP_MAX_PAYLOAD_MASK 0x7 |
@@ -120,6 +120,12 @@ int atl1c_restart_autoneg(struct atl1c_hw *hw); | |||
120 | #define REG_PCIE_PHYMISC 0x1000 | 120 | #define REG_PCIE_PHYMISC 0x1000 |
121 | #define PCIE_PHYMISC_FORCE_RCV_DET 0x4 | 121 | #define PCIE_PHYMISC_FORCE_RCV_DET 0x4 |
122 | 122 | ||
123 | #define REG_PCIE_PHYMISC2 0x1004 | ||
124 | #define PCIE_PHYMISC2_SERDES_CDR_MASK 0x3 | ||
125 | #define PCIE_PHYMISC2_SERDES_CDR_SHIFT 16 | ||
126 | #define PCIE_PHYMISC2_SERDES_TH_MASK 0x3 | ||
127 | #define PCIE_PHYMISC2_SERDES_TH_SHIFT 18 | ||
128 | |||
123 | #define REG_TWSI_DEBUG 0x1108 | 129 | #define REG_TWSI_DEBUG 0x1108 |
124 | #define TWSI_DEBUG_DEV_EXIST 0x20000000 | 130 | #define TWSI_DEBUG_DEV_EXIST 0x20000000 |
125 | 131 | ||
@@ -150,24 +156,28 @@ int atl1c_restart_autoneg(struct atl1c_hw *hw); | |||
150 | #define PM_CTRL_ASPM_L0S_EN 0x00001000 | 156 | #define PM_CTRL_ASPM_L0S_EN 0x00001000 |
151 | #define PM_CTRL_CLK_SWH_L1 0x00002000 | 157 | #define PM_CTRL_CLK_SWH_L1 0x00002000 |
152 | #define PM_CTRL_CLK_PWM_VER1_1 0x00004000 | 158 | #define PM_CTRL_CLK_PWM_VER1_1 0x00004000 |
153 | #define PM_CTRL_PCIE_RECV 0x00008000 | 159 | #define PM_CTRL_RCVR_WT_TIMER 0x00008000 |
154 | #define PM_CTRL_L1_ENTRY_TIMER_MASK 0xF | 160 | #define PM_CTRL_L1_ENTRY_TIMER_MASK 0xF |
155 | #define PM_CTRL_L1_ENTRY_TIMER_SHIFT 16 | 161 | #define PM_CTRL_L1_ENTRY_TIMER_SHIFT 16 |
156 | #define PM_CTRL_PM_REQ_TIMER_MASK 0xF | 162 | #define PM_CTRL_PM_REQ_TIMER_MASK 0xF |
157 | #define PM_CTRL_PM_REQ_TIMER_SHIFT 20 | 163 | #define PM_CTRL_PM_REQ_TIMER_SHIFT 20 |
158 | #define PM_CTRL_LCKDET_TIMER_MASK 0x3F | 164 | #define PM_CTRL_LCKDET_TIMER_MASK 0xF |
159 | #define PM_CTRL_LCKDET_TIMER_SHIFT 24 | 165 | #define PM_CTRL_LCKDET_TIMER_SHIFT 24 |
160 | #define PM_CTRL_EN_BUFS_RX_L0S 0x10000000 | 166 | #define PM_CTRL_EN_BUFS_RX_L0S 0x10000000 |
161 | #define PM_CTRL_SA_DLY_EN 0x20000000 | 167 | #define PM_CTRL_SA_DLY_EN 0x20000000 |
162 | #define PM_CTRL_MAC_ASPM_CHK 0x40000000 | 168 | #define PM_CTRL_MAC_ASPM_CHK 0x40000000 |
163 | #define PM_CTRL_HOTRST 0x80000000 | 169 | #define PM_CTRL_HOTRST 0x80000000 |
164 | 170 | ||
171 | #define REG_LTSSM_ID_CTRL 0x12FC | ||
172 | #define LTSSM_ID_EN_WRO 0x1000 | ||
165 | /* Selene Master Control Register */ | 173 | /* Selene Master Control Register */ |
166 | #define REG_MASTER_CTRL 0x1400 | 174 | #define REG_MASTER_CTRL 0x1400 |
167 | #define MASTER_CTRL_SOFT_RST 0x1 | 175 | #define MASTER_CTRL_SOFT_RST 0x1 |
168 | #define MASTER_CTRL_TEST_MODE_MASK 0x3 | 176 | #define MASTER_CTRL_TEST_MODE_MASK 0x3 |
169 | #define MASTER_CTRL_TEST_MODE_SHIFT 2 | 177 | #define MASTER_CTRL_TEST_MODE_SHIFT 2 |
170 | #define MASTER_CTRL_BERT_START 0x10 | 178 | #define MASTER_CTRL_BERT_START 0x10 |
179 | #define MASTER_CTRL_OOB_DIS_OFF 0x40 | ||
180 | #define MASTER_CTRL_SA_TIMER_EN 0x80 | ||
171 | #define MASTER_CTRL_MTIMER_EN 0x100 | 181 | #define MASTER_CTRL_MTIMER_EN 0x100 |
172 | #define MASTER_CTRL_MANUAL_INT 0x200 | 182 | #define MASTER_CTRL_MANUAL_INT 0x200 |
173 | #define MASTER_CTRL_TX_ITIMER_EN 0x400 | 183 | #define MASTER_CTRL_TX_ITIMER_EN 0x400 |
@@ -220,6 +230,12 @@ int atl1c_restart_autoneg(struct atl1c_hw *hw); | |||
220 | GPHY_CTRL_PWDOWN_HW |\ | 230 | GPHY_CTRL_PWDOWN_HW |\ |
221 | GPHY_CTRL_PHY_IDDQ) | 231 | GPHY_CTRL_PHY_IDDQ) |
222 | 232 | ||
233 | #define GPHY_CTRL_POWER_SAVING ( \ | ||
234 | GPHY_CTRL_SEL_ANA_RST |\ | ||
235 | GPHY_CTRL_HIB_EN |\ | ||
236 | GPHY_CTRL_HIB_PULSE |\ | ||
237 | GPHY_CTRL_PWDOWN_HW |\ | ||
238 | GPHY_CTRL_PHY_IDDQ) | ||
223 | /* Block IDLE Status Register */ | 239 | /* Block IDLE Status Register */ |
224 | #define REG_IDLE_STATUS 0x1410 | 240 | #define REG_IDLE_STATUS 0x1410 |
225 | #define IDLE_STATUS_MASK 0x00FF | 241 | #define IDLE_STATUS_MASK 0x00FF |
@@ -287,6 +303,14 @@ int atl1c_restart_autoneg(struct atl1c_hw *hw); | |||
287 | #define SERDES_LOCK_DETECT 0x1 /* SerDes lock detected. This signal | 303 | #define SERDES_LOCK_DETECT 0x1 /* SerDes lock detected. This signal |
288 | * comes from Analog SerDes */ | 304 | * comes from Analog SerDes */ |
289 | #define SERDES_LOCK_DETECT_EN 0x2 /* 1: Enable SerDes Lock detect function */ | 305 | #define SERDES_LOCK_DETECT_EN 0x2 /* 1: Enable SerDes Lock detect function */ |
306 | #define SERDES_LOCK_STS_SELFB_PLL_SHIFT 0xE | ||
307 | #define SERDES_LOCK_STS_SELFB_PLL_MASK 0x3 | ||
308 | #define SERDES_OVCLK_18_25 0x0 | ||
309 | #define SERDES_OVCLK_12_18 0x1 | ||
310 | #define SERDES_OVCLK_0_4 0x2 | ||
311 | #define SERDES_OVCLK_4_12 0x3 | ||
312 | #define SERDES_MAC_CLK_SLOWDOWN 0x20000 | ||
313 | #define SERDES_PYH_CLK_SLOWDOWN 0x40000 | ||
290 | 314 | ||
291 | /* MAC Control Register */ | 315 | /* MAC Control Register */ |
292 | #define REG_MAC_CTRL 0x1480 | 316 | #define REG_MAC_CTRL 0x1480 |
@@ -693,6 +717,21 @@ int atl1c_restart_autoneg(struct atl1c_hw *hw); | |||
693 | #define REG_MAC_TX_STATUS_BIN 0x1760 | 717 | #define REG_MAC_TX_STATUS_BIN 0x1760 |
694 | #define REG_MAC_TX_STATUS_END 0x17c0 | 718 | #define REG_MAC_TX_STATUS_END 0x17c0 |
695 | 719 | ||
720 | #define REG_CLK_GATING_CTRL 0x1814 | ||
721 | #define CLK_GATING_DMAW_EN 0x0001 | ||
722 | #define CLK_GATING_DMAR_EN 0x0002 | ||
723 | #define CLK_GATING_TXQ_EN 0x0004 | ||
724 | #define CLK_GATING_RXQ_EN 0x0008 | ||
725 | #define CLK_GATING_TXMAC_EN 0x0010 | ||
726 | #define CLK_GATING_RXMAC_EN 0x0020 | ||
727 | |||
728 | #define CLK_GATING_EN_ALL (CLK_GATING_DMAW_EN |\ | ||
729 | CLK_GATING_DMAR_EN |\ | ||
730 | CLK_GATING_TXQ_EN |\ | ||
731 | CLK_GATING_RXQ_EN |\ | ||
732 | CLK_GATING_TXMAC_EN|\ | ||
733 | CLK_GATING_RXMAC_EN) | ||
734 | |||
696 | /* DEBUG ADDR */ | 735 | /* DEBUG ADDR */ |
697 | #define REG_DEBUG_DATA0 0x1900 | 736 | #define REG_DEBUG_DATA0 0x1900 |
698 | #define REG_DEBUG_DATA1 0x1904 | 737 | #define REG_DEBUG_DATA1 0x1904 |
@@ -734,6 +773,10 @@ int atl1c_restart_autoneg(struct atl1c_hw *hw); | |||
734 | 773 | ||
735 | #define MII_PHYSID1 0x02 | 774 | #define MII_PHYSID1 0x02 |
736 | #define MII_PHYSID2 0x03 | 775 | #define MII_PHYSID2 0x03 |
776 | #define L1D_MPW_PHYID1 0xD01C /* V7 */ | ||
777 | #define L1D_MPW_PHYID2 0xD01D /* V1-V6 */ | ||
778 | #define L1D_MPW_PHYID3 0xD01E /* V8 */ | ||
779 | |||
737 | 780 | ||
738 | /* Autoneg Advertisement Register */ | 781 | /* Autoneg Advertisement Register */ |
739 | #define MII_ADVERTISE 0x04 | 782 | #define MII_ADVERTISE 0x04 |
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 1c3c046d5f34..c7b8ef507ebd 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | #include "atl1c.h" | 22 | #include "atl1c.h" |
23 | 23 | ||
24 | #define ATL1C_DRV_VERSION "1.0.0.2-NAPI" | 24 | #define ATL1C_DRV_VERSION "1.0.1.0-NAPI" |
25 | char atl1c_driver_name[] = "atl1c"; | 25 | char atl1c_driver_name[] = "atl1c"; |
26 | char atl1c_driver_version[] = ATL1C_DRV_VERSION; | 26 | char atl1c_driver_version[] = ATL1C_DRV_VERSION; |
27 | #define PCI_DEVICE_ID_ATTANSIC_L2C 0x1062 | 27 | #define PCI_DEVICE_ID_ATTANSIC_L2C 0x1062 |
@@ -29,7 +29,7 @@ char atl1c_driver_version[] = ATL1C_DRV_VERSION; | |||
29 | #define PCI_DEVICE_ID_ATHEROS_L2C_B 0x2060 /* AR8152 v1.1 Fast 10/100 */ | 29 | #define PCI_DEVICE_ID_ATHEROS_L2C_B 0x2060 /* AR8152 v1.1 Fast 10/100 */ |
30 | #define PCI_DEVICE_ID_ATHEROS_L2C_B2 0x2062 /* AR8152 v2.0 Fast 10/100 */ | 30 | #define PCI_DEVICE_ID_ATHEROS_L2C_B2 0x2062 /* AR8152 v2.0 Fast 10/100 */ |
31 | #define PCI_DEVICE_ID_ATHEROS_L1D 0x1073 /* AR8151 v1.0 Gigabit 1000 */ | 31 | #define PCI_DEVICE_ID_ATHEROS_L1D 0x1073 /* AR8151 v1.0 Gigabit 1000 */ |
32 | 32 | #define PCI_DEVICE_ID_ATHEROS_L1D_2_0 0x1083 /* AR8151 v2.0 Gigabit 1000 */ | |
33 | #define L2CB_V10 0xc0 | 33 | #define L2CB_V10 0xc0 |
34 | #define L2CB_V11 0xc1 | 34 | #define L2CB_V11 0xc1 |
35 | 35 | ||
@@ -97,7 +97,28 @@ static const u16 atl1c_rrd_addr_lo_regs[AT_MAX_RECEIVE_QUEUE] = | |||
97 | 97 | ||
98 | static const u32 atl1c_default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | | 98 | static const u32 atl1c_default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | |
99 | NETIF_MSG_LINK | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP; | 99 | NETIF_MSG_LINK | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP; |
100 | static void atl1c_pcie_patch(struct atl1c_hw *hw) | ||
101 | { | ||
102 | u32 data; | ||
100 | 103 | ||
104 | AT_READ_REG(hw, REG_PCIE_PHYMISC, &data); | ||
105 | data |= PCIE_PHYMISC_FORCE_RCV_DET; | ||
106 | AT_WRITE_REG(hw, REG_PCIE_PHYMISC, data); | ||
107 | |||
108 | if (hw->nic_type == athr_l2c_b && hw->revision_id == L2CB_V10) { | ||
109 | AT_READ_REG(hw, REG_PCIE_PHYMISC2, &data); | ||
110 | |||
111 | data &= ~(PCIE_PHYMISC2_SERDES_CDR_MASK << | ||
112 | PCIE_PHYMISC2_SERDES_CDR_SHIFT); | ||
113 | data |= 3 << PCIE_PHYMISC2_SERDES_CDR_SHIFT; | ||
114 | data &= ~(PCIE_PHYMISC2_SERDES_TH_MASK << | ||
115 | PCIE_PHYMISC2_SERDES_TH_SHIFT); | ||
116 | data |= 3 << PCIE_PHYMISC2_SERDES_TH_SHIFT; | ||
117 | AT_WRITE_REG(hw, REG_PCIE_PHYMISC2, data); | ||
118 | } | ||
119 | } | ||
120 | |||
121 | /* FIXME: no need any more ? */ | ||
101 | /* | 122 | /* |
102 | * atl1c_init_pcie - init PCIE module | 123 | * atl1c_init_pcie - init PCIE module |
103 | */ | 124 | */ |
@@ -127,6 +148,11 @@ static void atl1c_reset_pcie(struct atl1c_hw *hw, u32 flag) | |||
127 | data &= ~PCIE_UC_SERVRITY_FCP; | 148 | data &= ~PCIE_UC_SERVRITY_FCP; |
128 | AT_WRITE_REG(hw, REG_PCIE_UC_SEVERITY, data); | 149 | AT_WRITE_REG(hw, REG_PCIE_UC_SEVERITY, data); |
129 | 150 | ||
151 | AT_READ_REG(hw, REG_LTSSM_ID_CTRL, &data); | ||
152 | data &= ~LTSSM_ID_EN_WRO; | ||
153 | AT_WRITE_REG(hw, REG_LTSSM_ID_CTRL, data); | ||
154 | |||
155 | atl1c_pcie_patch(hw); | ||
130 | if (flag & ATL1C_PCIE_L0S_L1_DISABLE) | 156 | if (flag & ATL1C_PCIE_L0S_L1_DISABLE) |
131 | atl1c_disable_l0s_l1(hw); | 157 | atl1c_disable_l0s_l1(hw); |
132 | if (flag & ATL1C_PCIE_PHY_RESET) | 158 | if (flag & ATL1C_PCIE_PHY_RESET) |
@@ -135,7 +161,7 @@ static void atl1c_reset_pcie(struct atl1c_hw *hw, u32 flag) | |||
135 | AT_WRITE_REG(hw, REG_GPHY_CTRL, | 161 | AT_WRITE_REG(hw, REG_GPHY_CTRL, |
136 | GPHY_CTRL_DEFAULT | GPHY_CTRL_EXT_RESET); | 162 | GPHY_CTRL_DEFAULT | GPHY_CTRL_EXT_RESET); |
137 | 163 | ||
138 | msleep(1); | 164 | msleep(5); |
139 | } | 165 | } |
140 | 166 | ||
141 | /* | 167 | /* |
@@ -159,6 +185,7 @@ static inline void atl1c_irq_disable(struct atl1c_adapter *adapter) | |||
159 | { | 185 | { |
160 | atomic_inc(&adapter->irq_sem); | 186 | atomic_inc(&adapter->irq_sem); |
161 | AT_WRITE_REG(&adapter->hw, REG_IMR, 0); | 187 | AT_WRITE_REG(&adapter->hw, REG_IMR, 0); |
188 | AT_WRITE_REG(&adapter->hw, REG_ISR, ISR_DIS_INT); | ||
162 | AT_WRITE_FLUSH(&adapter->hw); | 189 | AT_WRITE_FLUSH(&adapter->hw); |
163 | synchronize_irq(adapter->pdev->irq); | 190 | synchronize_irq(adapter->pdev->irq); |
164 | } | 191 | } |
@@ -231,15 +258,15 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter) | |||
231 | 258 | ||
232 | if ((phy_data & BMSR_LSTATUS) == 0) { | 259 | if ((phy_data & BMSR_LSTATUS) == 0) { |
233 | /* link down */ | 260 | /* link down */ |
234 | if (netif_carrier_ok(netdev)) { | 261 | hw->hibernate = true; |
235 | hw->hibernate = true; | 262 | if (atl1c_stop_mac(hw) != 0) |
236 | if (atl1c_stop_mac(hw) != 0) | 263 | if (netif_msg_hw(adapter)) |
237 | if (netif_msg_hw(adapter)) | 264 | dev_warn(&pdev->dev, "stop mac failed\n"); |
238 | dev_warn(&pdev->dev, | 265 | atl1c_set_aspm(hw, false); |
239 | "stop mac failed\n"); | ||
240 | atl1c_set_aspm(hw, false); | ||
241 | } | ||
242 | netif_carrier_off(netdev); | 266 | netif_carrier_off(netdev); |
267 | netif_stop_queue(netdev); | ||
268 | atl1c_phy_reset(hw); | ||
269 | atl1c_phy_init(&adapter->hw); | ||
243 | } else { | 270 | } else { |
244 | /* Link Up */ | 271 | /* Link Up */ |
245 | hw->hibernate = false; | 272 | hw->hibernate = false; |
@@ -308,6 +335,7 @@ static void atl1c_common_task(struct work_struct *work) | |||
308 | netdev = adapter->netdev; | 335 | netdev = adapter->netdev; |
309 | 336 | ||
310 | if (adapter->work_event & ATL1C_WORK_EVENT_RESET) { | 337 | if (adapter->work_event & ATL1C_WORK_EVENT_RESET) { |
338 | adapter->work_event &= ~ATL1C_WORK_EVENT_RESET; | ||
311 | netif_device_detach(netdev); | 339 | netif_device_detach(netdev); |
312 | atl1c_down(adapter); | 340 | atl1c_down(adapter); |
313 | atl1c_up(adapter); | 341 | atl1c_up(adapter); |
@@ -315,8 +343,11 @@ static void atl1c_common_task(struct work_struct *work) | |||
315 | return; | 343 | return; |
316 | } | 344 | } |
317 | 345 | ||
318 | if (adapter->work_event & ATL1C_WORK_EVENT_LINK_CHANGE) | 346 | if (adapter->work_event & ATL1C_WORK_EVENT_LINK_CHANGE) { |
347 | adapter->work_event &= ~ATL1C_WORK_EVENT_LINK_CHANGE; | ||
319 | atl1c_check_link_status(adapter); | 348 | atl1c_check_link_status(adapter); |
349 | } | ||
350 | return; | ||
320 | } | 351 | } |
321 | 352 | ||
322 | 353 | ||
@@ -476,6 +507,13 @@ static int atl1c_change_mtu(struct net_device *netdev, int new_mtu) | |||
476 | netdev->mtu = new_mtu; | 507 | netdev->mtu = new_mtu; |
477 | adapter->hw.max_frame_size = new_mtu; | 508 | adapter->hw.max_frame_size = new_mtu; |
478 | atl1c_set_rxbufsize(adapter, netdev); | 509 | atl1c_set_rxbufsize(adapter, netdev); |
510 | if (new_mtu > MAX_TSO_FRAME_SIZE) { | ||
511 | adapter->netdev->features &= ~NETIF_F_TSO; | ||
512 | adapter->netdev->features &= ~NETIF_F_TSO6; | ||
513 | } else { | ||
514 | adapter->netdev->features |= NETIF_F_TSO; | ||
515 | adapter->netdev->features |= NETIF_F_TSO6; | ||
516 | } | ||
479 | atl1c_down(adapter); | 517 | atl1c_down(adapter); |
480 | atl1c_up(adapter); | 518 | atl1c_up(adapter); |
481 | clear_bit(__AT_RESETTING, &adapter->flags); | 519 | clear_bit(__AT_RESETTING, &adapter->flags); |
@@ -613,6 +651,9 @@ static void atl1c_set_mac_type(struct atl1c_hw *hw) | |||
613 | case PCI_DEVICE_ID_ATHEROS_L1D: | 651 | case PCI_DEVICE_ID_ATHEROS_L1D: |
614 | hw->nic_type = athr_l1d; | 652 | hw->nic_type = athr_l1d; |
615 | break; | 653 | break; |
654 | case PCI_DEVICE_ID_ATHEROS_L1D_2_0: | ||
655 | hw->nic_type = athr_l1d_2; | ||
656 | break; | ||
616 | default: | 657 | default: |
617 | break; | 658 | break; |
618 | } | 659 | } |
@@ -627,9 +668,7 @@ static int atl1c_setup_mac_funcs(struct atl1c_hw *hw) | |||
627 | AT_READ_REG(hw, REG_PHY_STATUS, &phy_status_data); | 668 | AT_READ_REG(hw, REG_PHY_STATUS, &phy_status_data); |
628 | AT_READ_REG(hw, REG_LINK_CTRL, &link_ctrl_data); | 669 | AT_READ_REG(hw, REG_LINK_CTRL, &link_ctrl_data); |
629 | 670 | ||
630 | hw->ctrl_flags = ATL1C_INTR_CLEAR_ON_READ | | 671 | hw->ctrl_flags = ATL1C_INTR_MODRT_ENABLE | |
631 | ATL1C_INTR_MODRT_ENABLE | | ||
632 | ATL1C_RX_IPV6_CHKSUM | | ||
633 | ATL1C_TXQ_MODE_ENHANCE; | 672 | ATL1C_TXQ_MODE_ENHANCE; |
634 | if (link_ctrl_data & LINK_CTRL_L0S_EN) | 673 | if (link_ctrl_data & LINK_CTRL_L0S_EN) |
635 | hw->ctrl_flags |= ATL1C_ASPM_L0S_SUPPORT; | 674 | hw->ctrl_flags |= ATL1C_ASPM_L0S_SUPPORT; |
@@ -637,12 +676,12 @@ static int atl1c_setup_mac_funcs(struct atl1c_hw *hw) | |||
637 | hw->ctrl_flags |= ATL1C_ASPM_L1_SUPPORT; | 676 | hw->ctrl_flags |= ATL1C_ASPM_L1_SUPPORT; |
638 | if (link_ctrl_data & LINK_CTRL_EXT_SYNC) | 677 | if (link_ctrl_data & LINK_CTRL_EXT_SYNC) |
639 | hw->ctrl_flags |= ATL1C_LINK_EXT_SYNC; | 678 | hw->ctrl_flags |= ATL1C_LINK_EXT_SYNC; |
679 | hw->ctrl_flags |= ATL1C_ASPM_CTRL_MON; | ||
640 | 680 | ||
641 | if (hw->nic_type == athr_l1c || | 681 | if (hw->nic_type == athr_l1c || |
642 | hw->nic_type == athr_l1d) { | 682 | hw->nic_type == athr_l1d || |
643 | hw->ctrl_flags |= ATL1C_ASPM_CTRL_MON; | 683 | hw->nic_type == athr_l1d_2) |
644 | hw->link_cap_flags |= ATL1C_LINK_CAP_1000M; | 684 | hw->link_cap_flags |= ATL1C_LINK_CAP_1000M; |
645 | } | ||
646 | return 0; | 685 | return 0; |
647 | } | 686 | } |
648 | /* | 687 | /* |
@@ -657,6 +696,8 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter) | |||
657 | { | 696 | { |
658 | struct atl1c_hw *hw = &adapter->hw; | 697 | struct atl1c_hw *hw = &adapter->hw; |
659 | struct pci_dev *pdev = adapter->pdev; | 698 | struct pci_dev *pdev = adapter->pdev; |
699 | u32 revision; | ||
700 | |||
660 | 701 | ||
661 | adapter->wol = 0; | 702 | adapter->wol = 0; |
662 | adapter->link_speed = SPEED_0; | 703 | adapter->link_speed = SPEED_0; |
@@ -669,7 +710,8 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter) | |||
669 | hw->device_id = pdev->device; | 710 | hw->device_id = pdev->device; |
670 | hw->subsystem_vendor_id = pdev->subsystem_vendor; | 711 | hw->subsystem_vendor_id = pdev->subsystem_vendor; |
671 | hw->subsystem_id = pdev->subsystem_device; | 712 | hw->subsystem_id = pdev->subsystem_device; |
672 | 713 | AT_READ_REG(hw, PCI_CLASS_REVISION, &revision); | |
714 | hw->revision_id = revision & 0xFF; | ||
673 | /* before link up, we assume hibernate is true */ | 715 | /* before link up, we assume hibernate is true */ |
674 | hw->hibernate = true; | 716 | hw->hibernate = true; |
675 | hw->media_type = MEDIA_TYPE_AUTO_SENSOR; | 717 | hw->media_type = MEDIA_TYPE_AUTO_SENSOR; |
@@ -974,6 +1016,7 @@ static void atl1c_configure_des_ring(struct atl1c_adapter *adapter) | |||
974 | struct atl1c_cmb *cmb = (struct atl1c_cmb *) &adapter->cmb; | 1016 | struct atl1c_cmb *cmb = (struct atl1c_cmb *) &adapter->cmb; |
975 | struct atl1c_smb *smb = (struct atl1c_smb *) &adapter->smb; | 1017 | struct atl1c_smb *smb = (struct atl1c_smb *) &adapter->smb; |
976 | int i; | 1018 | int i; |
1019 | u32 data; | ||
977 | 1020 | ||
978 | /* TPD */ | 1021 | /* TPD */ |
979 | AT_WRITE_REG(hw, REG_TX_BASE_ADDR_HI, | 1022 | AT_WRITE_REG(hw, REG_TX_BASE_ADDR_HI, |
@@ -1017,6 +1060,23 @@ static void atl1c_configure_des_ring(struct atl1c_adapter *adapter) | |||
1017 | (u32)((smb->dma & AT_DMA_HI_ADDR_MASK) >> 32)); | 1060 | (u32)((smb->dma & AT_DMA_HI_ADDR_MASK) >> 32)); |
1018 | AT_WRITE_REG(hw, REG_SMB_BASE_ADDR_LO, | 1061 | AT_WRITE_REG(hw, REG_SMB_BASE_ADDR_LO, |
1019 | (u32)(smb->dma & AT_DMA_LO_ADDR_MASK)); | 1062 | (u32)(smb->dma & AT_DMA_LO_ADDR_MASK)); |
1063 | if (hw->nic_type == athr_l2c_b) { | ||
1064 | AT_WRITE_REG(hw, REG_SRAM_RXF_LEN, 0x02a0L); | ||
1065 | AT_WRITE_REG(hw, REG_SRAM_TXF_LEN, 0x0100L); | ||
1066 | AT_WRITE_REG(hw, REG_SRAM_RXF_ADDR, 0x029f0000L); | ||
1067 | AT_WRITE_REG(hw, REG_SRAM_RFD0_INFO, 0x02bf02a0L); | ||
1068 | AT_WRITE_REG(hw, REG_SRAM_TXF_ADDR, 0x03bf02c0L); | ||
1069 | AT_WRITE_REG(hw, REG_SRAM_TRD_ADDR, 0x03df03c0L); | ||
1070 | AT_WRITE_REG(hw, REG_TXF_WATER_MARK, 0); /* TX watermark, to enter l1 state.*/ | ||
1071 | AT_WRITE_REG(hw, REG_RXD_DMA_CTRL, 0); /* RXD threshold.*/ | ||
1072 | } | ||
1073 | if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l1d_2) { | ||
1074 | /* Power Saving for L2c_B */ | ||
1075 | AT_READ_REG(hw, REG_SERDES_LOCK, &data); | ||
1076 | data |= SERDES_MAC_CLK_SLOWDOWN; | ||
1077 | data |= SERDES_PYH_CLK_SLOWDOWN; | ||
1078 | AT_WRITE_REG(hw, REG_SERDES_LOCK, data); | ||
1079 | } | ||
1020 | /* Load all of base address above */ | 1080 | /* Load all of base address above */ |
1021 | AT_WRITE_REG(hw, REG_LOAD_PTR, 1); | 1081 | AT_WRITE_REG(hw, REG_LOAD_PTR, 1); |
1022 | } | 1082 | } |
@@ -1029,6 +1089,7 @@ static void atl1c_configure_tx(struct atl1c_adapter *adapter) | |||
1029 | u16 tx_offload_thresh; | 1089 | u16 tx_offload_thresh; |
1030 | u32 txq_ctrl_data; | 1090 | u32 txq_ctrl_data; |
1031 | u32 extra_size = 0; /* Jumbo frame threshold in QWORD unit */ | 1091 | u32 extra_size = 0; /* Jumbo frame threshold in QWORD unit */ |
1092 | u32 max_pay_load_data; | ||
1032 | 1093 | ||
1033 | extra_size = ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN; | 1094 | extra_size = ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN; |
1034 | tx_offload_thresh = MAX_TX_OFFLOAD_THRESH; | 1095 | tx_offload_thresh = MAX_TX_OFFLOAD_THRESH; |
@@ -1046,8 +1107,11 @@ static void atl1c_configure_tx(struct atl1c_adapter *adapter) | |||
1046 | TXQ_NUM_TPD_BURST_SHIFT; | 1107 | TXQ_NUM_TPD_BURST_SHIFT; |
1047 | if (hw->ctrl_flags & ATL1C_TXQ_MODE_ENHANCE) | 1108 | if (hw->ctrl_flags & ATL1C_TXQ_MODE_ENHANCE) |
1048 | txq_ctrl_data |= TXQ_CTRL_ENH_MODE; | 1109 | txq_ctrl_data |= TXQ_CTRL_ENH_MODE; |
1049 | txq_ctrl_data |= (atl1c_pay_load_size[hw->dmar_block] & | 1110 | max_pay_load_data = (atl1c_pay_load_size[hw->dmar_block] & |
1050 | TXQ_TXF_BURST_NUM_MASK) << TXQ_TXF_BURST_NUM_SHIFT; | 1111 | TXQ_TXF_BURST_NUM_MASK) << TXQ_TXF_BURST_NUM_SHIFT; |
1112 | if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2) | ||
1113 | max_pay_load_data >>= 1; | ||
1114 | txq_ctrl_data |= max_pay_load_data; | ||
1051 | 1115 | ||
1052 | AT_WRITE_REG(hw, REG_TXQ_CTRL, txq_ctrl_data); | 1116 | AT_WRITE_REG(hw, REG_TXQ_CTRL, txq_ctrl_data); |
1053 | } | 1117 | } |
@@ -1078,7 +1142,7 @@ static void atl1c_configure_rx(struct atl1c_adapter *adapter) | |||
1078 | rxq_ctrl_data |= (hw->rss_hash_bits & RSS_HASH_BITS_MASK) << | 1142 | rxq_ctrl_data |= (hw->rss_hash_bits & RSS_HASH_BITS_MASK) << |
1079 | RSS_HASH_BITS_SHIFT; | 1143 | RSS_HASH_BITS_SHIFT; |
1080 | if (hw->ctrl_flags & ATL1C_ASPM_CTRL_MON) | 1144 | if (hw->ctrl_flags & ATL1C_ASPM_CTRL_MON) |
1081 | rxq_ctrl_data |= (ASPM_THRUPUT_LIMIT_100M & | 1145 | rxq_ctrl_data |= (ASPM_THRUPUT_LIMIT_1M & |
1082 | ASPM_THRUPUT_LIMIT_MASK) << ASPM_THRUPUT_LIMIT_SHIFT; | 1146 | ASPM_THRUPUT_LIMIT_MASK) << ASPM_THRUPUT_LIMIT_SHIFT; |
1083 | 1147 | ||
1084 | AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq_ctrl_data); | 1148 | AT_WRITE_REG(hw, REG_RXQ_CTRL, rxq_ctrl_data); |
@@ -1198,21 +1262,23 @@ static int atl1c_reset_mac(struct atl1c_hw *hw) | |||
1198 | { | 1262 | { |
1199 | struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter; | 1263 | struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter; |
1200 | struct pci_dev *pdev = adapter->pdev; | 1264 | struct pci_dev *pdev = adapter->pdev; |
1201 | int ret; | 1265 | u32 master_ctrl_data = 0; |
1202 | 1266 | ||
1203 | AT_WRITE_REG(hw, REG_IMR, 0); | 1267 | AT_WRITE_REG(hw, REG_IMR, 0); |
1204 | AT_WRITE_REG(hw, REG_ISR, ISR_DIS_INT); | 1268 | AT_WRITE_REG(hw, REG_ISR, ISR_DIS_INT); |
1205 | 1269 | ||
1206 | ret = atl1c_stop_mac(hw); | 1270 | atl1c_stop_mac(hw); |
1207 | if (ret) | ||
1208 | return ret; | ||
1209 | /* | 1271 | /* |
1210 | * Issue Soft Reset to the MAC. This will reset the chip's | 1272 | * Issue Soft Reset to the MAC. This will reset the chip's |
1211 | * transmit, receive, DMA. It will not effect | 1273 | * transmit, receive, DMA. It will not effect |
1212 | * the current PCI configuration. The global reset bit is self- | 1274 | * the current PCI configuration. The global reset bit is self- |
1213 | * clearing, and should clear within a microsecond. | 1275 | * clearing, and should clear within a microsecond. |
1214 | */ | 1276 | */ |
1215 | AT_WRITE_REGW(hw, REG_MASTER_CTRL, MASTER_CTRL_SOFT_RST); | 1277 | AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl_data); |
1278 | master_ctrl_data |= MASTER_CTRL_OOB_DIS_OFF; | ||
1279 | AT_WRITE_REGW(hw, REG_MASTER_CTRL, ((master_ctrl_data | MASTER_CTRL_SOFT_RST) | ||
1280 | & 0xFFFF)); | ||
1281 | |||
1216 | AT_WRITE_FLUSH(hw); | 1282 | AT_WRITE_FLUSH(hw); |
1217 | msleep(10); | 1283 | msleep(10); |
1218 | /* Wait at least 10ms for All module to be Idle */ | 1284 | /* Wait at least 10ms for All module to be Idle */ |
@@ -1253,42 +1319,39 @@ static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup) | |||
1253 | { | 1319 | { |
1254 | u32 pm_ctrl_data; | 1320 | u32 pm_ctrl_data; |
1255 | u32 link_ctrl_data; | 1321 | u32 link_ctrl_data; |
1322 | u32 link_l1_timer = 0xF; | ||
1256 | 1323 | ||
1257 | AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data); | 1324 | AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data); |
1258 | AT_READ_REG(hw, REG_LINK_CTRL, &link_ctrl_data); | 1325 | AT_READ_REG(hw, REG_LINK_CTRL, &link_ctrl_data); |
1259 | pm_ctrl_data &= ~PM_CTRL_SERDES_PD_EX_L1; | ||
1260 | 1326 | ||
1327 | pm_ctrl_data &= ~PM_CTRL_SERDES_PD_EX_L1; | ||
1261 | pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK << | 1328 | pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK << |
1262 | PM_CTRL_L1_ENTRY_TIMER_SHIFT); | 1329 | PM_CTRL_L1_ENTRY_TIMER_SHIFT); |
1263 | pm_ctrl_data &= ~(PM_CTRL_LCKDET_TIMER_MASK << | 1330 | pm_ctrl_data &= ~(PM_CTRL_LCKDET_TIMER_MASK << |
1264 | PM_CTRL_LCKDET_TIMER_SHIFT); | 1331 | PM_CTRL_LCKDET_TIMER_SHIFT); |
1265 | 1332 | pm_ctrl_data |= AT_LCKDET_TIMER << PM_CTRL_LCKDET_TIMER_SHIFT; | |
1266 | pm_ctrl_data |= PM_CTRL_MAC_ASPM_CHK; | ||
1267 | pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN; | ||
1268 | pm_ctrl_data |= PM_CTRL_RBER_EN; | ||
1269 | pm_ctrl_data |= PM_CTRL_SDES_EN; | ||
1270 | 1333 | ||
1271 | if (hw->nic_type == athr_l2c_b || | 1334 | if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l1d || |
1272 | hw->nic_type == athr_l1d || | 1335 | hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) { |
1273 | hw->nic_type == athr_l2c_b2) { | ||
1274 | link_ctrl_data &= ~LINK_CTRL_EXT_SYNC; | 1336 | link_ctrl_data &= ~LINK_CTRL_EXT_SYNC; |
1275 | if (!(hw->ctrl_flags & ATL1C_APS_MODE_ENABLE)) { | 1337 | if (!(hw->ctrl_flags & ATL1C_APS_MODE_ENABLE)) { |
1276 | if (hw->nic_type == athr_l2c_b && | 1338 | if (hw->nic_type == athr_l2c_b && hw->revision_id == L2CB_V10) |
1277 | hw->revision_id == L2CB_V10) | ||
1278 | link_ctrl_data |= LINK_CTRL_EXT_SYNC; | 1339 | link_ctrl_data |= LINK_CTRL_EXT_SYNC; |
1279 | } | 1340 | } |
1280 | 1341 | ||
1281 | AT_WRITE_REG(hw, REG_LINK_CTRL, link_ctrl_data); | 1342 | AT_WRITE_REG(hw, REG_LINK_CTRL, link_ctrl_data); |
1282 | 1343 | ||
1283 | pm_ctrl_data |= PM_CTRL_PCIE_RECV; | 1344 | pm_ctrl_data |= PM_CTRL_RCVR_WT_TIMER; |
1284 | pm_ctrl_data |= AT_ASPM_L1_TIMER << PM_CTRL_PM_REQ_TIMER_SHIFT; | 1345 | pm_ctrl_data &= ~(PM_CTRL_PM_REQ_TIMER_MASK << |
1285 | pm_ctrl_data &= ~PM_CTRL_EN_BUFS_RX_L0S; | 1346 | PM_CTRL_PM_REQ_TIMER_SHIFT); |
1347 | pm_ctrl_data |= AT_ASPM_L1_TIMER << | ||
1348 | PM_CTRL_PM_REQ_TIMER_SHIFT; | ||
1286 | pm_ctrl_data &= ~PM_CTRL_SA_DLY_EN; | 1349 | pm_ctrl_data &= ~PM_CTRL_SA_DLY_EN; |
1287 | pm_ctrl_data &= ~PM_CTRL_HOTRST; | 1350 | pm_ctrl_data &= ~PM_CTRL_HOTRST; |
1288 | pm_ctrl_data |= 1 << PM_CTRL_L1_ENTRY_TIMER_SHIFT; | 1351 | pm_ctrl_data |= 1 << PM_CTRL_L1_ENTRY_TIMER_SHIFT; |
1289 | pm_ctrl_data |= PM_CTRL_SERDES_PD_EX_L1; | 1352 | pm_ctrl_data |= PM_CTRL_SERDES_PD_EX_L1; |
1290 | } | 1353 | } |
1291 | 1354 | pm_ctrl_data |= PM_CTRL_MAC_ASPM_CHK; | |
1292 | if (linkup) { | 1355 | if (linkup) { |
1293 | pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN; | 1356 | pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN; |
1294 | pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN; | 1357 | pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN; |
@@ -1297,27 +1360,26 @@ static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup) | |||
1297 | if (hw->ctrl_flags & ATL1C_ASPM_L0S_SUPPORT) | 1360 | if (hw->ctrl_flags & ATL1C_ASPM_L0S_SUPPORT) |
1298 | pm_ctrl_data |= PM_CTRL_ASPM_L0S_EN; | 1361 | pm_ctrl_data |= PM_CTRL_ASPM_L0S_EN; |
1299 | 1362 | ||
1300 | if (hw->nic_type == athr_l2c_b || | 1363 | if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l1d || |
1301 | hw->nic_type == athr_l1d || | 1364 | hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) { |
1302 | hw->nic_type == athr_l2c_b2) { | ||
1303 | if (hw->nic_type == athr_l2c_b) | 1365 | if (hw->nic_type == athr_l2c_b) |
1304 | if (!(hw->ctrl_flags & ATL1C_APS_MODE_ENABLE)) | 1366 | if (!(hw->ctrl_flags & ATL1C_APS_MODE_ENABLE)) |
1305 | pm_ctrl_data &= PM_CTRL_ASPM_L0S_EN; | 1367 | pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN; |
1306 | pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN; | 1368 | pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN; |
1307 | pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN; | 1369 | pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN; |
1308 | pm_ctrl_data &= ~PM_CTRL_SERDES_BUDS_RX_L1_EN; | 1370 | pm_ctrl_data &= ~PM_CTRL_SERDES_BUDS_RX_L1_EN; |
1309 | pm_ctrl_data |= PM_CTRL_CLK_SWH_L1; | 1371 | pm_ctrl_data |= PM_CTRL_CLK_SWH_L1; |
1310 | if (hw->adapter->link_speed == SPEED_100 || | 1372 | if (hw->adapter->link_speed == SPEED_100 || |
1311 | hw->adapter->link_speed == SPEED_1000) { | 1373 | hw->adapter->link_speed == SPEED_1000) { |
1312 | pm_ctrl_data &= | 1374 | pm_ctrl_data &= ~(PM_CTRL_L1_ENTRY_TIMER_MASK << |
1313 | ~(PM_CTRL_L1_ENTRY_TIMER_MASK << | 1375 | PM_CTRL_L1_ENTRY_TIMER_SHIFT); |
1314 | PM_CTRL_L1_ENTRY_TIMER_SHIFT); | 1376 | if (hw->nic_type == athr_l2c_b) |
1315 | if (hw->nic_type == athr_l1d) | 1377 | link_l1_timer = 7; |
1316 | pm_ctrl_data |= 0xF << | 1378 | else if (hw->nic_type == athr_l2c_b2 || |
1317 | PM_CTRL_L1_ENTRY_TIMER_SHIFT; | 1379 | hw->nic_type == athr_l1d_2) |
1318 | else | 1380 | link_l1_timer = 4; |
1319 | pm_ctrl_data |= 7 << | 1381 | pm_ctrl_data |= link_l1_timer << |
1320 | PM_CTRL_L1_ENTRY_TIMER_SHIFT; | 1382 | PM_CTRL_L1_ENTRY_TIMER_SHIFT; |
1321 | } | 1383 | } |
1322 | } else { | 1384 | } else { |
1323 | pm_ctrl_data |= PM_CTRL_SERDES_L1_EN; | 1385 | pm_ctrl_data |= PM_CTRL_SERDES_L1_EN; |
@@ -1326,24 +1388,12 @@ static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup) | |||
1326 | pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1; | 1388 | pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1; |
1327 | pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN; | 1389 | pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN; |
1328 | pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN; | 1390 | pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN; |
1329 | } | ||
1330 | atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0x29); | ||
1331 | if (hw->adapter->link_speed == SPEED_10) | ||
1332 | if (hw->nic_type == athr_l1d) | ||
1333 | atl1c_write_phy_reg(hw, MII_DBG_ADDR, 0xB69D); | ||
1334 | else | ||
1335 | atl1c_write_phy_reg(hw, MII_DBG_DATA, 0xB6DD); | ||
1336 | else if (hw->adapter->link_speed == SPEED_100) | ||
1337 | atl1c_write_phy_reg(hw, MII_DBG_DATA, 0xB2DD); | ||
1338 | else | ||
1339 | atl1c_write_phy_reg(hw, MII_DBG_DATA, 0x96DD); | ||
1340 | 1391 | ||
1392 | } | ||
1341 | } else { | 1393 | } else { |
1342 | pm_ctrl_data &= ~PM_CTRL_SERDES_BUDS_RX_L1_EN; | ||
1343 | pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN; | 1394 | pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN; |
1344 | pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN; | 1395 | pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN; |
1345 | pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN; | 1396 | pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN; |
1346 | |||
1347 | pm_ctrl_data |= PM_CTRL_CLK_SWH_L1; | 1397 | pm_ctrl_data |= PM_CTRL_CLK_SWH_L1; |
1348 | 1398 | ||
1349 | if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT) | 1399 | if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT) |
@@ -1351,8 +1401,9 @@ static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup) | |||
1351 | else | 1401 | else |
1352 | pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN; | 1402 | pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN; |
1353 | } | 1403 | } |
1354 | |||
1355 | AT_WRITE_REG(hw, REG_PM_CTRL, pm_ctrl_data); | 1404 | AT_WRITE_REG(hw, REG_PM_CTRL, pm_ctrl_data); |
1405 | |||
1406 | return; | ||
1356 | } | 1407 | } |
1357 | 1408 | ||
1358 | static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter) | 1409 | static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter) |
@@ -1391,7 +1442,8 @@ static void atl1c_setup_mac_ctrl(struct atl1c_adapter *adapter) | |||
1391 | mac_ctrl_data |= MAC_CTRL_MC_ALL_EN; | 1442 | mac_ctrl_data |= MAC_CTRL_MC_ALL_EN; |
1392 | 1443 | ||
1393 | mac_ctrl_data |= MAC_CTRL_SINGLE_PAUSE_EN; | 1444 | mac_ctrl_data |= MAC_CTRL_SINGLE_PAUSE_EN; |
1394 | if (hw->nic_type == athr_l1d || hw->nic_type == athr_l2c_b2) { | 1445 | if (hw->nic_type == athr_l1d || hw->nic_type == athr_l2c_b2 || |
1446 | hw->nic_type == athr_l1d_2) { | ||
1395 | mac_ctrl_data |= MAC_CTRL_SPEED_MODE_SW; | 1447 | mac_ctrl_data |= MAC_CTRL_SPEED_MODE_SW; |
1396 | mac_ctrl_data |= MAC_CTRL_HASH_ALG_CRC32; | 1448 | mac_ctrl_data |= MAC_CTRL_HASH_ALG_CRC32; |
1397 | } | 1449 | } |
@@ -1409,6 +1461,7 @@ static int atl1c_configure(struct atl1c_adapter *adapter) | |||
1409 | struct atl1c_hw *hw = &adapter->hw; | 1461 | struct atl1c_hw *hw = &adapter->hw; |
1410 | u32 master_ctrl_data = 0; | 1462 | u32 master_ctrl_data = 0; |
1411 | u32 intr_modrt_data; | 1463 | u32 intr_modrt_data; |
1464 | u32 data; | ||
1412 | 1465 | ||
1413 | /* clear interrupt status */ | 1466 | /* clear interrupt status */ |
1414 | AT_WRITE_REG(hw, REG_ISR, 0xFFFFFFFF); | 1467 | AT_WRITE_REG(hw, REG_ISR, 0xFFFFFFFF); |
@@ -1418,6 +1471,15 @@ static int atl1c_configure(struct atl1c_adapter *adapter) | |||
1418 | * HW will enable self to assert interrupt event to system after | 1471 | * HW will enable self to assert interrupt event to system after |
1419 | * waiting x-time for software to notify it accept interrupt. | 1472 | * waiting x-time for software to notify it accept interrupt. |
1420 | */ | 1473 | */ |
1474 | |||
1475 | data = CLK_GATING_EN_ALL; | ||
1476 | if (hw->ctrl_flags & ATL1C_CLK_GATING_EN) { | ||
1477 | if (hw->nic_type == athr_l2c_b) | ||
1478 | data &= ~CLK_GATING_RXMAC_EN; | ||
1479 | } else | ||
1480 | data = 0; | ||
1481 | AT_WRITE_REG(hw, REG_CLK_GATING_CTRL, data); | ||
1482 | |||
1421 | AT_WRITE_REG(hw, REG_INT_RETRIG_TIMER, | 1483 | AT_WRITE_REG(hw, REG_INT_RETRIG_TIMER, |
1422 | hw->ict & INT_RETRIG_TIMER_MASK); | 1484 | hw->ict & INT_RETRIG_TIMER_MASK); |
1423 | 1485 | ||
@@ -1436,6 +1498,7 @@ static int atl1c_configure(struct atl1c_adapter *adapter) | |||
1436 | if (hw->ctrl_flags & ATL1C_INTR_CLEAR_ON_READ) | 1498 | if (hw->ctrl_flags & ATL1C_INTR_CLEAR_ON_READ) |
1437 | master_ctrl_data |= MASTER_CTRL_INT_RDCLR; | 1499 | master_ctrl_data |= MASTER_CTRL_INT_RDCLR; |
1438 | 1500 | ||
1501 | master_ctrl_data |= MASTER_CTRL_SA_TIMER_EN; | ||
1439 | AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data); | 1502 | AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data); |
1440 | 1503 | ||
1441 | if (hw->ctrl_flags & ATL1C_CMB_ENABLE) { | 1504 | if (hw->ctrl_flags & ATL1C_CMB_ENABLE) { |
@@ -1624,11 +1687,9 @@ static irqreturn_t atl1c_intr(int irq, void *data) | |||
1624 | "atl1c hardware error (status = 0x%x)\n", | 1687 | "atl1c hardware error (status = 0x%x)\n", |
1625 | status & ISR_ERROR); | 1688 | status & ISR_ERROR); |
1626 | /* reset MAC */ | 1689 | /* reset MAC */ |
1627 | hw->intr_mask &= ~ISR_ERROR; | ||
1628 | AT_WRITE_REG(hw, REG_IMR, hw->intr_mask); | ||
1629 | adapter->work_event |= ATL1C_WORK_EVENT_RESET; | 1690 | adapter->work_event |= ATL1C_WORK_EVENT_RESET; |
1630 | schedule_work(&adapter->common_task); | 1691 | schedule_work(&adapter->common_task); |
1631 | break; | 1692 | return IRQ_HANDLED; |
1632 | } | 1693 | } |
1633 | 1694 | ||
1634 | if (status & ISR_OVER) | 1695 | if (status & ISR_OVER) |
@@ -2303,7 +2364,6 @@ void atl1c_down(struct atl1c_adapter *adapter) | |||
2303 | napi_disable(&adapter->napi); | 2364 | napi_disable(&adapter->napi); |
2304 | atl1c_irq_disable(adapter); | 2365 | atl1c_irq_disable(adapter); |
2305 | atl1c_free_irq(adapter); | 2366 | atl1c_free_irq(adapter); |
2306 | AT_WRITE_REG(&adapter->hw, REG_ISR, ISR_DIS_INT); | ||
2307 | /* reset MAC to disable all RX/TX */ | 2367 | /* reset MAC to disable all RX/TX */ |
2308 | atl1c_reset_mac(&adapter->hw); | 2368 | atl1c_reset_mac(&adapter->hw); |
2309 | msleep(1); | 2369 | msleep(1); |
@@ -2387,79 +2447,68 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2387 | struct net_device *netdev = pci_get_drvdata(pdev); | 2447 | struct net_device *netdev = pci_get_drvdata(pdev); |
2388 | struct atl1c_adapter *adapter = netdev_priv(netdev); | 2448 | struct atl1c_adapter *adapter = netdev_priv(netdev); |
2389 | struct atl1c_hw *hw = &adapter->hw; | 2449 | struct atl1c_hw *hw = &adapter->hw; |
2390 | u32 ctrl; | 2450 | u32 mac_ctrl_data = 0; |
2391 | u32 mac_ctrl_data; | 2451 | u32 master_ctrl_data = 0; |
2392 | u32 master_ctrl_data; | ||
2393 | u32 wol_ctrl_data = 0; | 2452 | u32 wol_ctrl_data = 0; |
2394 | u16 mii_bmsr_data; | 2453 | u16 mii_intr_status_data = 0; |
2395 | u16 save_autoneg_advertised; | ||
2396 | u16 mii_intr_status_data; | ||
2397 | u32 wufc = adapter->wol; | 2454 | u32 wufc = adapter->wol; |
2398 | u32 i; | ||
2399 | int retval = 0; | 2455 | int retval = 0; |
2400 | 2456 | ||
2457 | atl1c_disable_l0s_l1(hw); | ||
2401 | if (netif_running(netdev)) { | 2458 | if (netif_running(netdev)) { |
2402 | WARN_ON(test_bit(__AT_RESETTING, &adapter->flags)); | 2459 | WARN_ON(test_bit(__AT_RESETTING, &adapter->flags)); |
2403 | atl1c_down(adapter); | 2460 | atl1c_down(adapter); |
2404 | } | 2461 | } |
2405 | netif_device_detach(netdev); | 2462 | netif_device_detach(netdev); |
2406 | atl1c_disable_l0s_l1(hw); | ||
2407 | retval = pci_save_state(pdev); | 2463 | retval = pci_save_state(pdev); |
2408 | if (retval) | 2464 | if (retval) |
2409 | return retval; | 2465 | return retval; |
2466 | |||
2467 | if (wufc) | ||
2468 | if (atl1c_phy_power_saving(hw) != 0) | ||
2469 | dev_dbg(&pdev->dev, "phy power saving failed"); | ||
2470 | |||
2471 | AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl_data); | ||
2472 | AT_READ_REG(hw, REG_MAC_CTRL, &mac_ctrl_data); | ||
2473 | |||
2474 | master_ctrl_data &= ~MASTER_CTRL_CLK_SEL_DIS; | ||
2475 | mac_ctrl_data &= ~(MAC_CTRL_PRMLEN_MASK << MAC_CTRL_PRMLEN_SHIFT); | ||
2476 | mac_ctrl_data |= (((u32)adapter->hw.preamble_len & | ||
2477 | MAC_CTRL_PRMLEN_MASK) << | ||
2478 | MAC_CTRL_PRMLEN_SHIFT); | ||
2479 | mac_ctrl_data &= ~(MAC_CTRL_SPEED_MASK << MAC_CTRL_SPEED_SHIFT); | ||
2480 | mac_ctrl_data &= ~MAC_CTRL_DUPLX; | ||
2481 | |||
2410 | if (wufc) { | 2482 | if (wufc) { |
2411 | AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl_data); | 2483 | mac_ctrl_data |= MAC_CTRL_RX_EN; |
2412 | master_ctrl_data &= ~MASTER_CTRL_CLK_SEL_DIS; | 2484 | if (adapter->link_speed == SPEED_1000 || |
2413 | 2485 | adapter->link_speed == SPEED_0) { | |
2414 | /* get link status */ | 2486 | mac_ctrl_data |= atl1c_mac_speed_1000 << |
2415 | atl1c_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data); | 2487 | MAC_CTRL_SPEED_SHIFT; |
2416 | atl1c_read_phy_reg(hw, MII_BMSR, (u16 *)&mii_bmsr_data); | 2488 | mac_ctrl_data |= MAC_CTRL_DUPLX; |
2417 | save_autoneg_advertised = hw->autoneg_advertised; | 2489 | } else |
2418 | hw->autoneg_advertised = ADVERTISED_10baseT_Half; | 2490 | mac_ctrl_data |= atl1c_mac_speed_10_100 << |
2419 | if (atl1c_restart_autoneg(hw) != 0) | 2491 | MAC_CTRL_SPEED_SHIFT; |
2420 | if (netif_msg_link(adapter)) | 2492 | |
2421 | dev_warn(&pdev->dev, "phy autoneg failed\n"); | 2493 | if (adapter->link_duplex == DUPLEX_FULL) |
2422 | hw->phy_configured = false; /* re-init PHY when resume */ | 2494 | mac_ctrl_data |= MAC_CTRL_DUPLX; |
2423 | hw->autoneg_advertised = save_autoneg_advertised; | 2495 | |
2424 | /* turn on magic packet wol */ | 2496 | /* turn on magic packet wol */ |
2425 | if (wufc & AT_WUFC_MAG) | 2497 | if (wufc & AT_WUFC_MAG) |
2426 | wol_ctrl_data = WOL_MAGIC_EN | WOL_MAGIC_PME_EN; | 2498 | wol_ctrl_data |= WOL_MAGIC_EN | WOL_MAGIC_PME_EN; |
2427 | 2499 | ||
2428 | if (wufc & AT_WUFC_LNKC) { | 2500 | if (wufc & AT_WUFC_LNKC) { |
2429 | for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) { | ||
2430 | msleep(100); | ||
2431 | atl1c_read_phy_reg(hw, MII_BMSR, | ||
2432 | (u16 *)&mii_bmsr_data); | ||
2433 | if (mii_bmsr_data & BMSR_LSTATUS) | ||
2434 | break; | ||
2435 | } | ||
2436 | if ((mii_bmsr_data & BMSR_LSTATUS) == 0) | ||
2437 | if (netif_msg_link(adapter)) | ||
2438 | dev_warn(&pdev->dev, | ||
2439 | "%s: Link may change" | ||
2440 | "when suspend\n", | ||
2441 | atl1c_driver_name); | ||
2442 | wol_ctrl_data |= WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN; | 2501 | wol_ctrl_data |= WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN; |
2443 | /* only link up can wake up */ | 2502 | /* only link up can wake up */ |
2444 | if (atl1c_write_phy_reg(hw, MII_IER, IER_LINK_UP) != 0) { | 2503 | if (atl1c_write_phy_reg(hw, MII_IER, IER_LINK_UP) != 0) { |
2445 | if (netif_msg_link(adapter)) | 2504 | dev_dbg(&pdev->dev, "%s: read write phy " |
2446 | dev_err(&pdev->dev, | 2505 | "register failed.\n", |
2447 | "%s: read write phy " | 2506 | atl1c_driver_name); |
2448 | "register failed.\n", | ||
2449 | atl1c_driver_name); | ||
2450 | goto wol_dis; | ||
2451 | } | 2507 | } |
2452 | } | 2508 | } |
2453 | /* clear phy interrupt */ | 2509 | /* clear phy interrupt */ |
2454 | atl1c_read_phy_reg(hw, MII_ISR, &mii_intr_status_data); | 2510 | atl1c_read_phy_reg(hw, MII_ISR, &mii_intr_status_data); |
2455 | /* Config MAC Ctrl register */ | 2511 | /* Config MAC Ctrl register */ |
2456 | mac_ctrl_data = MAC_CTRL_RX_EN; | ||
2457 | /* set to 10/100M halt duplex */ | ||
2458 | mac_ctrl_data |= atl1c_mac_speed_10_100 << MAC_CTRL_SPEED_SHIFT; | ||
2459 | mac_ctrl_data |= (((u32)adapter->hw.preamble_len & | ||
2460 | MAC_CTRL_PRMLEN_MASK) << | ||
2461 | MAC_CTRL_PRMLEN_SHIFT); | ||
2462 | |||
2463 | if (adapter->vlgrp) | 2512 | if (adapter->vlgrp) |
2464 | mac_ctrl_data |= MAC_CTRL_RMV_VLAN; | 2513 | mac_ctrl_data |= MAC_CTRL_RMV_VLAN; |
2465 | 2514 | ||
@@ -2467,37 +2516,30 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2467 | if (wufc & AT_WUFC_MAG) | 2516 | if (wufc & AT_WUFC_MAG) |
2468 | mac_ctrl_data |= MAC_CTRL_BC_EN; | 2517 | mac_ctrl_data |= MAC_CTRL_BC_EN; |
2469 | 2518 | ||
2470 | if (netif_msg_hw(adapter)) | 2519 | dev_dbg(&pdev->dev, |
2471 | dev_dbg(&pdev->dev, | 2520 | "%s: suspend MAC=0x%x\n", |
2472 | "%s: suspend MAC=0x%x\n", | 2521 | atl1c_driver_name, mac_ctrl_data); |
2473 | atl1c_driver_name, mac_ctrl_data); | ||
2474 | AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data); | 2522 | AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data); |
2475 | AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data); | 2523 | AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data); |
2476 | AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data); | 2524 | AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data); |
2477 | 2525 | ||
2478 | /* pcie patch */ | 2526 | /* pcie patch */ |
2479 | AT_READ_REG(hw, REG_PCIE_PHYMISC, &ctrl); | 2527 | device_set_wakeup_enable(&pdev->dev, 1); |
2480 | ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; | ||
2481 | AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl); | ||
2482 | 2528 | ||
2483 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); | 2529 | AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT | |
2484 | goto suspend_exit; | 2530 | GPHY_CTRL_EXT_RESET); |
2531 | pci_prepare_to_sleep(pdev); | ||
2532 | } else { | ||
2533 | AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_POWER_SAVING); | ||
2534 | master_ctrl_data |= MASTER_CTRL_CLK_SEL_DIS; | ||
2535 | mac_ctrl_data |= atl1c_mac_speed_10_100 << MAC_CTRL_SPEED_SHIFT; | ||
2536 | mac_ctrl_data |= MAC_CTRL_DUPLX; | ||
2537 | AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl_data); | ||
2538 | AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data); | ||
2539 | AT_WRITE_REG(hw, REG_WOL_CTRL, 0); | ||
2540 | hw->phy_configured = false; /* re-init PHY when resume */ | ||
2541 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | ||
2485 | } | 2542 | } |
2486 | wol_dis: | ||
2487 | |||
2488 | /* WOL disabled */ | ||
2489 | AT_WRITE_REG(hw, REG_WOL_CTRL, 0); | ||
2490 | |||
2491 | /* pcie patch */ | ||
2492 | AT_READ_REG(hw, REG_PCIE_PHYMISC, &ctrl); | ||
2493 | ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; | ||
2494 | AT_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl); | ||
2495 | |||
2496 | atl1c_phy_disable(hw); | ||
2497 | hw->phy_configured = false; /* re-init PHY when resume */ | ||
2498 | |||
2499 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | ||
2500 | suspend_exit: | ||
2501 | 2543 | ||
2502 | pci_disable_device(pdev); | 2544 | pci_disable_device(pdev); |
2503 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | 2545 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); |
@@ -2516,9 +2558,19 @@ static int atl1c_resume(struct pci_dev *pdev) | |||
2516 | pci_enable_wake(pdev, PCI_D3cold, 0); | 2558 | pci_enable_wake(pdev, PCI_D3cold, 0); |
2517 | 2559 | ||
2518 | AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0); | 2560 | AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0); |
2561 | atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE | | ||
2562 | ATL1C_PCIE_PHY_RESET); | ||
2519 | 2563 | ||
2520 | atl1c_phy_reset(&adapter->hw); | 2564 | atl1c_phy_reset(&adapter->hw); |
2521 | atl1c_reset_mac(&adapter->hw); | 2565 | atl1c_reset_mac(&adapter->hw); |
2566 | atl1c_phy_init(&adapter->hw); | ||
2567 | |||
2568 | #if 0 | ||
2569 | AT_READ_REG(&adapter->hw, REG_PM_CTRLSTAT, &pm_data); | ||
2570 | pm_data &= ~PM_CTRLSTAT_PME_EN; | ||
2571 | AT_WRITE_REG(&adapter->hw, REG_PM_CTRLSTAT, pm_data); | ||
2572 | #endif | ||
2573 | |||
2522 | netif_device_attach(netdev); | 2574 | netif_device_attach(netdev); |
2523 | if (netif_running(netdev)) | 2575 | if (netif_running(netdev)) |
2524 | atl1c_up(adapter); | 2576 | atl1c_up(adapter); |