cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

atl1c_hw.c (23373B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright(c) 2007 Atheros Corporation. All rights reserved.
      4 *
      5 * Derived from Intel e1000 driver
      6 * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
      7 */
      8#include <linux/pci.h>
      9#include <linux/delay.h>
     10#include <linux/mii.h>
     11#include <linux/crc32.h>
     12
     13#include "atl1c.h"
     14
     15/*
     16 * check_eeprom_exist
     17 * return 1 if eeprom exist
     18 */
     19int atl1c_check_eeprom_exist(struct atl1c_hw *hw)
     20{
     21	u32 data;
     22
     23	AT_READ_REG(hw, REG_TWSI_DEBUG, &data);
     24	if (data & TWSI_DEBUG_DEV_EXIST)
     25		return 1;
     26
     27	AT_READ_REG(hw, REG_MASTER_CTRL, &data);
     28	if (data & MASTER_CTRL_OTP_SEL)
     29		return 1;
     30	return 0;
     31}
     32
     33void atl1c_hw_set_mac_addr(struct atl1c_hw *hw, u8 *mac_addr)
     34{
     35	u32 value;
     36	/*
     37	 * 00-0B-6A-F6-00-DC
     38	 * 0:  6AF600DC 1: 000B
     39	 * low dword
     40	 */
     41	value = mac_addr[2] << 24 |
     42		mac_addr[3] << 16 |
     43		mac_addr[4] << 8  |
     44		mac_addr[5];
     45	AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value);
     46	/* hight dword */
     47	value = mac_addr[0] << 8 |
     48		mac_addr[1];
     49	AT_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value);
     50}
     51
     52/* read mac address from hardware register */
     53static bool atl1c_read_current_addr(struct atl1c_hw *hw, u8 *eth_addr)
     54{
     55	u32 addr[2];
     56
     57	AT_READ_REG(hw, REG_MAC_STA_ADDR, &addr[0]);
     58	AT_READ_REG(hw, REG_MAC_STA_ADDR + 4, &addr[1]);
     59
     60	*(u32 *) &eth_addr[2] = htonl(addr[0]);
     61	*(u16 *) &eth_addr[0] = htons((u16)addr[1]);
     62
     63	return is_valid_ether_addr(eth_addr);
     64}
     65
     66/*
     67 * atl1c_get_permanent_address
     68 * return 0 if get valid mac address,
     69 */
     70static int atl1c_get_permanent_address(struct atl1c_hw *hw)
     71{
     72	u32 i;
     73	u32 otp_ctrl_data;
     74	u32 twsi_ctrl_data;
     75	u16 phy_data;
     76	bool raise_vol = false;
     77
     78	/* MAC-address from BIOS is the 1st priority */
     79	if (atl1c_read_current_addr(hw, hw->perm_mac_addr))
     80		return 0;
     81
     82	/* init */
     83	AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
     84	if (atl1c_check_eeprom_exist(hw)) {
     85		if (hw->nic_type == athr_l1c || hw->nic_type == athr_l2c) {
     86			/* Enable OTP CLK */
     87			if (!(otp_ctrl_data & OTP_CTRL_CLK_EN)) {
     88				otp_ctrl_data |= OTP_CTRL_CLK_EN;
     89				AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
     90				AT_WRITE_FLUSH(hw);
     91				msleep(1);
     92			}
     93		}
     94		/* raise voltage temporally for l2cb */
     95		if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2) {
     96			atl1c_read_phy_dbg(hw, MIIDBG_ANACTRL, &phy_data);
     97			phy_data &= ~ANACTRL_HB_EN;
     98			atl1c_write_phy_dbg(hw, MIIDBG_ANACTRL, phy_data);
     99			atl1c_read_phy_dbg(hw, MIIDBG_VOLT_CTRL, &phy_data);
    100			phy_data |= VOLT_CTRL_SWLOWEST;
    101			atl1c_write_phy_dbg(hw, MIIDBG_VOLT_CTRL, phy_data);
    102			udelay(20);
    103			raise_vol = true;
    104		}
    105
    106		AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
    107		twsi_ctrl_data |= TWSI_CTRL_SW_LDSTART;
    108		AT_WRITE_REG(hw, REG_TWSI_CTRL, twsi_ctrl_data);
    109		for (i = 0; i < AT_TWSI_EEPROM_TIMEOUT; i++) {
    110			msleep(10);
    111			AT_READ_REG(hw, REG_TWSI_CTRL, &twsi_ctrl_data);
    112			if ((twsi_ctrl_data & TWSI_CTRL_SW_LDSTART) == 0)
    113				break;
    114		}
    115		if (i >= AT_TWSI_EEPROM_TIMEOUT)
    116			return -1;
    117	}
    118	/* Disable OTP_CLK */
    119	if ((hw->nic_type == athr_l1c || hw->nic_type == athr_l2c)) {
    120		otp_ctrl_data &= ~OTP_CTRL_CLK_EN;
    121		AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
    122		msleep(1);
    123	}
    124	if (raise_vol) {
    125		atl1c_read_phy_dbg(hw, MIIDBG_ANACTRL, &phy_data);
    126		phy_data |= ANACTRL_HB_EN;
    127		atl1c_write_phy_dbg(hw, MIIDBG_ANACTRL, phy_data);
    128		atl1c_read_phy_dbg(hw, MIIDBG_VOLT_CTRL, &phy_data);
    129		phy_data &= ~VOLT_CTRL_SWLOWEST;
    130		atl1c_write_phy_dbg(hw, MIIDBG_VOLT_CTRL, phy_data);
    131		udelay(20);
    132	}
    133
    134	if (atl1c_read_current_addr(hw, hw->perm_mac_addr))
    135		return 0;
    136
    137	return -1;
    138}
    139
    140bool atl1c_read_eeprom(struct atl1c_hw *hw, u32 offset, u32 *p_value)
    141{
    142	int i;
    143	bool ret = false;
    144	u32 otp_ctrl_data;
    145	u32 control;
    146	u32 data;
    147
    148	if (offset & 3)
    149		return ret; /* address do not align */
    150
    151	AT_READ_REG(hw, REG_OTP_CTRL, &otp_ctrl_data);
    152	if (!(otp_ctrl_data & OTP_CTRL_CLK_EN))
    153		AT_WRITE_REG(hw, REG_OTP_CTRL,
    154				(otp_ctrl_data | OTP_CTRL_CLK_EN));
    155
    156	AT_WRITE_REG(hw, REG_EEPROM_DATA_LO, 0);
    157	control = (offset & EEPROM_CTRL_ADDR_MASK) << EEPROM_CTRL_ADDR_SHIFT;
    158	AT_WRITE_REG(hw, REG_EEPROM_CTRL, control);
    159
    160	for (i = 0; i < 10; i++) {
    161		udelay(100);
    162		AT_READ_REG(hw, REG_EEPROM_CTRL, &control);
    163		if (control & EEPROM_CTRL_RW)
    164			break;
    165	}
    166	if (control & EEPROM_CTRL_RW) {
    167		AT_READ_REG(hw, REG_EEPROM_CTRL, &data);
    168		AT_READ_REG(hw, REG_EEPROM_DATA_LO, p_value);
    169		data = data & 0xFFFF;
    170		*p_value = swab32((data << 16) | (*p_value >> 16));
    171		ret = true;
    172	}
    173	if (!(otp_ctrl_data & OTP_CTRL_CLK_EN))
    174		AT_WRITE_REG(hw, REG_OTP_CTRL, otp_ctrl_data);
    175
    176	return ret;
    177}
    178/*
    179 * Reads the adapter's MAC address from the EEPROM
    180 *
    181 * hw - Struct containing variables accessed by shared code
    182 */
    183int atl1c_read_mac_addr(struct atl1c_hw *hw)
    184{
    185	int err = 0;
    186
    187	err = atl1c_get_permanent_address(hw);
    188	if (err)
    189		eth_random_addr(hw->perm_mac_addr);
    190
    191	memcpy(hw->mac_addr, hw->perm_mac_addr, sizeof(hw->perm_mac_addr));
    192	return err;
    193}
    194
    195/*
    196 * atl1c_hash_mc_addr
    197 *  purpose
    198 *      set hash value for a multicast address
    199 *      hash calcu processing :
    200 *          1. calcu 32bit CRC for multicast address
    201 *          2. reverse crc with MSB to LSB
    202 */
    203u32 atl1c_hash_mc_addr(struct atl1c_hw *hw, u8 *mc_addr)
    204{
    205	u32 crc32;
    206	u32 value = 0;
    207	int i;
    208
    209	crc32 = ether_crc_le(6, mc_addr);
    210	for (i = 0; i < 32; i++)
    211		value |= (((crc32 >> i) & 1) << (31 - i));
    212
    213	return value;
    214}
    215
    216/*
    217 * Sets the bit in the multicast table corresponding to the hash value.
    218 * hw - Struct containing variables accessed by shared code
    219 * hash_value - Multicast address hash value
    220 */
    221void atl1c_hash_set(struct atl1c_hw *hw, u32 hash_value)
    222{
    223	u32 hash_bit, hash_reg;
    224	u32 mta;
    225
    226	/*
    227	 * The HASH Table  is a register array of 2 32-bit registers.
    228	 * It is treated like an array of 64 bits.  We want to set
    229	 * bit BitArray[hash_value]. So we figure out what register
    230	 * the bit is in, read it, OR in the new bit, then write
    231	 * back the new value.  The register is determined by the
    232	 * upper bit of the hash value and the bit within that
    233	 * register are determined by the lower 5 bits of the value.
    234	 */
    235	hash_reg = (hash_value >> 31) & 0x1;
    236	hash_bit = (hash_value >> 26) & 0x1F;
    237
    238	mta = AT_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg);
    239
    240	mta |= (1 << hash_bit);
    241
    242	AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta);
    243}
    244
    245/*
    246 * wait mdio module be idle
    247 * return true: idle
    248 *        false: still busy
    249 */
    250bool atl1c_wait_mdio_idle(struct atl1c_hw *hw)
    251{
    252	u32 val;
    253	int i;
    254
    255	for (i = 0; i < MDIO_MAX_AC_TO; i++) {
    256		AT_READ_REG(hw, REG_MDIO_CTRL, &val);
    257		if (!(val & (MDIO_CTRL_BUSY | MDIO_CTRL_START)))
    258			break;
    259		udelay(10);
    260	}
    261
    262	return i != MDIO_MAX_AC_TO;
    263}
    264
    265void atl1c_stop_phy_polling(struct atl1c_hw *hw)
    266{
    267	if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
    268		return;
    269
    270	AT_WRITE_REG(hw, REG_MDIO_CTRL, 0);
    271	atl1c_wait_mdio_idle(hw);
    272}
    273
    274void atl1c_start_phy_polling(struct atl1c_hw *hw, u16 clk_sel)
    275{
    276	u32 val;
    277
    278	if (!(hw->ctrl_flags & ATL1C_FPGA_VERSION))
    279		return;
    280
    281	val = MDIO_CTRL_SPRES_PRMBL |
    282		FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
    283		FIELDX(MDIO_CTRL_REG, 1) |
    284		MDIO_CTRL_START |
    285		MDIO_CTRL_OP_READ;
    286	AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
    287	atl1c_wait_mdio_idle(hw);
    288	val |= MDIO_CTRL_AP_EN;
    289	val &= ~MDIO_CTRL_START;
    290	AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
    291	udelay(30);
    292}
    293
    294
    295/*
    296 * atl1c_read_phy_core
    297 * core function to read register in PHY via MDIO control register.
    298 * ext: extension register (see IEEE 802.3)
    299 * dev: device address (see IEEE 802.3 DEVAD, PRTAD is fixed to 0)
    300 * reg: reg to read
    301 */
    302int atl1c_read_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
    303			u16 reg, u16 *phy_data)
    304{
    305	u32 val;
    306	u16 clk_sel = MDIO_CTRL_CLK_25_4;
    307
    308	atl1c_stop_phy_polling(hw);
    309
    310	*phy_data = 0;
    311
    312	/* only l2c_b2 & l1d_2 could use slow clock */
    313	if ((hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) &&
    314		hw->hibernate)
    315		clk_sel = MDIO_CTRL_CLK_25_128;
    316	if (ext) {
    317		val = FIELDX(MDIO_EXTN_DEVAD, dev) | FIELDX(MDIO_EXTN_REG, reg);
    318		AT_WRITE_REG(hw, REG_MDIO_EXTN, val);
    319		val = MDIO_CTRL_SPRES_PRMBL |
    320			FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
    321			MDIO_CTRL_START |
    322			MDIO_CTRL_MODE_EXT |
    323			MDIO_CTRL_OP_READ;
    324	} else {
    325		val = MDIO_CTRL_SPRES_PRMBL |
    326			FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
    327			FIELDX(MDIO_CTRL_REG, reg) |
    328			MDIO_CTRL_START |
    329			MDIO_CTRL_OP_READ;
    330	}
    331	AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
    332
    333	if (!atl1c_wait_mdio_idle(hw))
    334		return -1;
    335
    336	AT_READ_REG(hw, REG_MDIO_CTRL, &val);
    337	*phy_data = (u16)FIELD_GETX(val, MDIO_CTRL_DATA);
    338
    339	atl1c_start_phy_polling(hw, clk_sel);
    340
    341	return 0;
    342}
    343
    344/*
    345 * atl1c_write_phy_core
    346 * core function to write to register in PHY via MDIO control register.
    347 * ext: extension register (see IEEE 802.3)
    348 * dev: device address (see IEEE 802.3 DEVAD, PRTAD is fixed to 0)
    349 * reg: reg to write
    350 */
    351int atl1c_write_phy_core(struct atl1c_hw *hw, bool ext, u8 dev,
    352			u16 reg, u16 phy_data)
    353{
    354	u32 val;
    355	u16 clk_sel = MDIO_CTRL_CLK_25_4;
    356
    357	atl1c_stop_phy_polling(hw);
    358
    359
    360	/* only l2c_b2 & l1d_2 could use slow clock */
    361	if ((hw->nic_type == athr_l2c_b2 || hw->nic_type == athr_l1d_2) &&
    362		hw->hibernate)
    363		clk_sel = MDIO_CTRL_CLK_25_128;
    364
    365	if (ext) {
    366		val = FIELDX(MDIO_EXTN_DEVAD, dev) | FIELDX(MDIO_EXTN_REG, reg);
    367		AT_WRITE_REG(hw, REG_MDIO_EXTN, val);
    368		val = MDIO_CTRL_SPRES_PRMBL |
    369			FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
    370			FIELDX(MDIO_CTRL_DATA, phy_data) |
    371			MDIO_CTRL_START |
    372			MDIO_CTRL_MODE_EXT;
    373	} else {
    374		val = MDIO_CTRL_SPRES_PRMBL |
    375			FIELDX(MDIO_CTRL_CLK_SEL, clk_sel) |
    376			FIELDX(MDIO_CTRL_DATA, phy_data) |
    377			FIELDX(MDIO_CTRL_REG, reg) |
    378			MDIO_CTRL_START;
    379	}
    380	AT_WRITE_REG(hw, REG_MDIO_CTRL, val);
    381
    382	if (!atl1c_wait_mdio_idle(hw))
    383		return -1;
    384
    385	atl1c_start_phy_polling(hw, clk_sel);
    386
    387	return 0;
    388}
    389
    390/*
    391 * Reads the value from a PHY register
    392 * hw - Struct containing variables accessed by shared code
    393 * reg_addr - address of the PHY register to read
    394 */
    395int atl1c_read_phy_reg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data)
    396{
    397	return atl1c_read_phy_core(hw, false, 0, reg_addr, phy_data);
    398}
    399
    400/*
    401 * Writes a value to a PHY register
    402 * hw - Struct containing variables accessed by shared code
    403 * reg_addr - address of the PHY register to write
    404 * data - data to write to the PHY
    405 */
    406int atl1c_write_phy_reg(struct atl1c_hw *hw, u32 reg_addr, u16 phy_data)
    407{
    408	return atl1c_write_phy_core(hw, false, 0, reg_addr, phy_data);
    409}
    410
    411/* read from PHY extension register */
    412int atl1c_read_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
    413			u16 reg_addr, u16 *phy_data)
    414{
    415	return atl1c_read_phy_core(hw, true, dev_addr, reg_addr, phy_data);
    416}
    417
    418/* write to PHY extension register */
    419int atl1c_write_phy_ext(struct atl1c_hw *hw, u8 dev_addr,
    420			u16 reg_addr, u16 phy_data)
    421{
    422	return atl1c_write_phy_core(hw, true, dev_addr, reg_addr, phy_data);
    423}
    424
    425int atl1c_read_phy_dbg(struct atl1c_hw *hw, u16 reg_addr, u16 *phy_data)
    426{
    427	int err;
    428
    429	err = atl1c_write_phy_reg(hw, MII_DBG_ADDR, reg_addr);
    430	if (unlikely(err))
    431		return err;
    432	else
    433		err = atl1c_read_phy_reg(hw, MII_DBG_DATA, phy_data);
    434
    435	return err;
    436}
    437
    438int atl1c_write_phy_dbg(struct atl1c_hw *hw, u16 reg_addr, u16 phy_data)
    439{
    440	int err;
    441
    442	err = atl1c_write_phy_reg(hw, MII_DBG_ADDR, reg_addr);
    443	if (unlikely(err))
    444		return err;
    445	else
    446		err = atl1c_write_phy_reg(hw, MII_DBG_DATA, phy_data);
    447
    448	return err;
    449}
    450
    451/*
    452 * Configures PHY autoneg and flow control advertisement settings
    453 *
    454 * hw - Struct containing variables accessed by shared code
    455 */
    456static int atl1c_phy_setup_adv(struct atl1c_hw *hw)
    457{
    458	u16 mii_adv_data = ADVERTISE_DEFAULT_CAP & ~ADVERTISE_ALL;
    459	u16 mii_giga_ctrl_data = GIGA_CR_1000T_DEFAULT_CAP &
    460				~GIGA_CR_1000T_SPEED_MASK;
    461
    462	if (hw->autoneg_advertised & ADVERTISED_10baseT_Half)
    463		mii_adv_data |= ADVERTISE_10HALF;
    464	if (hw->autoneg_advertised & ADVERTISED_10baseT_Full)
    465		mii_adv_data |= ADVERTISE_10FULL;
    466	if (hw->autoneg_advertised & ADVERTISED_100baseT_Half)
    467		mii_adv_data |= ADVERTISE_100HALF;
    468	if (hw->autoneg_advertised & ADVERTISED_100baseT_Full)
    469		mii_adv_data |= ADVERTISE_100FULL;
    470
    471	if (hw->autoneg_advertised & ADVERTISED_Autoneg)
    472		mii_adv_data |= ADVERTISE_10HALF  | ADVERTISE_10FULL |
    473				ADVERTISE_100HALF | ADVERTISE_100FULL;
    474
    475	if (hw->link_cap_flags & ATL1C_LINK_CAP_1000M) {
    476		if (hw->autoneg_advertised & ADVERTISED_1000baseT_Half)
    477			mii_giga_ctrl_data |= ADVERTISE_1000HALF;
    478		if (hw->autoneg_advertised & ADVERTISED_1000baseT_Full)
    479			mii_giga_ctrl_data |= ADVERTISE_1000FULL;
    480		if (hw->autoneg_advertised & ADVERTISED_Autoneg)
    481			mii_giga_ctrl_data |= ADVERTISE_1000HALF |
    482					ADVERTISE_1000FULL;
    483	}
    484
    485	if (atl1c_write_phy_reg(hw, MII_ADVERTISE, mii_adv_data) != 0 ||
    486	    atl1c_write_phy_reg(hw, MII_CTRL1000, mii_giga_ctrl_data) != 0)
    487		return -1;
    488	return 0;
    489}
    490
    491void atl1c_phy_disable(struct atl1c_hw *hw)
    492{
    493	atl1c_power_saving(hw, 0);
    494}
    495
    496
    497int atl1c_phy_reset(struct atl1c_hw *hw)
    498{
    499	struct atl1c_adapter *adapter = hw->adapter;
    500	struct pci_dev *pdev = adapter->pdev;
    501	u16 phy_data;
    502	u32 phy_ctrl_data, lpi_ctrl;
    503	int err;
    504
    505	/* reset PHY core */
    506	AT_READ_REG(hw, REG_GPHY_CTRL, &phy_ctrl_data);
    507	phy_ctrl_data &= ~(GPHY_CTRL_EXT_RESET | GPHY_CTRL_PHY_IDDQ |
    508		GPHY_CTRL_GATE_25M_EN | GPHY_CTRL_PWDOWN_HW | GPHY_CTRL_CLS);
    509	phy_ctrl_data |= GPHY_CTRL_SEL_ANA_RST;
    510	if (!(hw->ctrl_flags & ATL1C_HIB_DISABLE))
    511		phy_ctrl_data |= (GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE);
    512	else
    513		phy_ctrl_data &= ~(GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE);
    514	AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data);
    515	AT_WRITE_FLUSH(hw);
    516	udelay(10);
    517	AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl_data | GPHY_CTRL_EXT_RESET);
    518	AT_WRITE_FLUSH(hw);
    519	udelay(10 * GPHY_CTRL_EXT_RST_TO);	/* delay 800us */
    520
    521	/* switch clock */
    522	if (hw->nic_type == athr_l2c_b) {
    523		atl1c_read_phy_dbg(hw, MIIDBG_CFGLPSPD, &phy_data);
    524		atl1c_write_phy_dbg(hw, MIIDBG_CFGLPSPD,
    525			phy_data & ~CFGLPSPD_RSTCNT_CLK125SW);
    526	}
    527
    528	/* tx-half amplitude issue fix */
    529	if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2) {
    530		atl1c_read_phy_dbg(hw, MIIDBG_CABLE1TH_DET, &phy_data);
    531		phy_data |= CABLE1TH_DET_EN;
    532		atl1c_write_phy_dbg(hw, MIIDBG_CABLE1TH_DET, phy_data);
    533	}
    534
    535	/* clear bit3 of dbgport 3B to lower voltage */
    536	if (!(hw->ctrl_flags & ATL1C_HIB_DISABLE)) {
    537		if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2) {
    538			atl1c_read_phy_dbg(hw, MIIDBG_VOLT_CTRL, &phy_data);
    539			phy_data &= ~VOLT_CTRL_SWLOWEST;
    540			atl1c_write_phy_dbg(hw, MIIDBG_VOLT_CTRL, phy_data);
    541		}
    542		/* power saving config */
    543		phy_data =
    544			hw->nic_type == athr_l1d || hw->nic_type == athr_l1d_2 ?
    545			L1D_LEGCYPS_DEF : L1C_LEGCYPS_DEF;
    546		atl1c_write_phy_dbg(hw, MIIDBG_LEGCYPS, phy_data);
    547		/* hib */
    548		atl1c_write_phy_dbg(hw, MIIDBG_SYSMODCTRL,
    549			SYSMODCTRL_IECHOADJ_DEF);
    550	} else {
    551		/* disable pws */
    552		atl1c_read_phy_dbg(hw, MIIDBG_LEGCYPS, &phy_data);
    553		atl1c_write_phy_dbg(hw, MIIDBG_LEGCYPS,
    554			phy_data & ~LEGCYPS_EN);
    555		/* disable hibernate */
    556		atl1c_read_phy_dbg(hw, MIIDBG_HIBNEG, &phy_data);
    557		atl1c_write_phy_dbg(hw, MIIDBG_HIBNEG,
    558			phy_data & HIBNEG_PSHIB_EN);
    559	}
    560	/* disable AZ(EEE) by default */
    561	if (hw->nic_type == athr_l1d || hw->nic_type == athr_l1d_2 ||
    562	    hw->nic_type == athr_l2c_b2) {
    563		AT_READ_REG(hw, REG_LPI_CTRL, &lpi_ctrl);
    564		AT_WRITE_REG(hw, REG_LPI_CTRL, lpi_ctrl & ~LPI_CTRL_EN);
    565		atl1c_write_phy_ext(hw, MIIEXT_ANEG, MIIEXT_LOCAL_EEEADV, 0);
    566		atl1c_write_phy_ext(hw, MIIEXT_PCS, MIIEXT_CLDCTRL3,
    567			L2CB_CLDCTRL3);
    568	}
    569
    570	/* other debug port to set */
    571	atl1c_write_phy_dbg(hw, MIIDBG_ANACTRL, ANACTRL_DEF);
    572	atl1c_write_phy_dbg(hw, MIIDBG_SRDSYSMOD, SRDSYSMOD_DEF);
    573	atl1c_write_phy_dbg(hw, MIIDBG_TST10BTCFG, TST10BTCFG_DEF);
    574	/* UNH-IOL test issue, set bit7 */
    575	atl1c_write_phy_dbg(hw, MIIDBG_TST100BTCFG,
    576		TST100BTCFG_DEF | TST100BTCFG_LITCH_EN);
    577
    578	/* set phy interrupt mask */
    579	phy_data = IER_LINK_UP | IER_LINK_DOWN;
    580	err = atl1c_write_phy_reg(hw, MII_IER, phy_data);
    581	if (err) {
    582		if (netif_msg_hw(adapter))
    583			dev_err(&pdev->dev,
    584				"Error enable PHY linkChange Interrupt\n");
    585		return err;
    586	}
    587	return 0;
    588}
    589
    590int atl1c_phy_init(struct atl1c_hw *hw)
    591{
    592	struct atl1c_adapter *adapter = hw->adapter;
    593	struct pci_dev *pdev = adapter->pdev;
    594	int ret_val;
    595	u16 mii_bmcr_data = BMCR_RESET;
    596
    597	if (hw->nic_type == athr_mt) {
    598		hw->phy_configured = true;
    599		return 0;
    600	}
    601
    602	if ((atl1c_read_phy_reg(hw, MII_PHYSID1, &hw->phy_id1) != 0) ||
    603		(atl1c_read_phy_reg(hw, MII_PHYSID2, &hw->phy_id2) != 0)) {
    604		dev_err(&pdev->dev, "Error get phy ID\n");
    605		return -1;
    606	}
    607	switch (hw->media_type) {
    608	case MEDIA_TYPE_AUTO_SENSOR:
    609		ret_val = atl1c_phy_setup_adv(hw);
    610		if (ret_val) {
    611			if (netif_msg_link(adapter))
    612				dev_err(&pdev->dev,
    613					"Error Setting up Auto-Negotiation\n");
    614			return ret_val;
    615		}
    616		mii_bmcr_data |= BMCR_ANENABLE | BMCR_ANRESTART;
    617		break;
    618	case MEDIA_TYPE_100M_FULL:
    619		mii_bmcr_data |= BMCR_SPEED100 | BMCR_FULLDPLX;
    620		break;
    621	case MEDIA_TYPE_100M_HALF:
    622		mii_bmcr_data |= BMCR_SPEED100;
    623		break;
    624	case MEDIA_TYPE_10M_FULL:
    625		mii_bmcr_data |= BMCR_FULLDPLX;
    626		break;
    627	case MEDIA_TYPE_10M_HALF:
    628		break;
    629	default:
    630		if (netif_msg_link(adapter))
    631			dev_err(&pdev->dev, "Wrong Media type %d\n",
    632				hw->media_type);
    633		return -1;
    634	}
    635
    636	ret_val = atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
    637	if (ret_val)
    638		return ret_val;
    639	hw->phy_configured = true;
    640
    641	return 0;
    642}
    643
    644bool atl1c_get_link_status(struct atl1c_hw *hw)
    645{
    646	u16 phy_data;
    647
    648	if (hw->nic_type == athr_mt) {
    649		u32 spd;
    650
    651		AT_READ_REG(hw, REG_MT_SPEED, &spd);
    652		return !!spd;
    653	}
    654
    655	/* MII_BMSR must be read twice */
    656	atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
    657	atl1c_read_phy_reg(hw, MII_BMSR, &phy_data);
    658	return !!(phy_data & BMSR_LSTATUS);
    659}
    660
    661/*
    662 * Detects the current speed and duplex settings of the hardware.
    663 *
    664 * hw - Struct containing variables accessed by shared code
    665 * speed - Speed of the connection
    666 * duplex - Duplex setting of the connection
    667 */
    668int atl1c_get_speed_and_duplex(struct atl1c_hw *hw, u16 *speed, u16 *duplex)
    669{
    670	int err;
    671	u16 phy_data;
    672
    673	if (hw->nic_type == athr_mt) {
    674		u32 spd;
    675
    676		AT_READ_REG(hw, REG_MT_SPEED, &spd);
    677		*speed = spd;
    678		*duplex = FULL_DUPLEX;
    679		return 0;
    680	}
    681
    682	/* Read   PHY Specific Status Register (17) */
    683	err = atl1c_read_phy_reg(hw, MII_GIGA_PSSR, &phy_data);
    684	if (err)
    685		return err;
    686
    687	if (!(phy_data & GIGA_PSSR_SPD_DPLX_RESOLVED))
    688		return -1;
    689
    690	switch (phy_data & GIGA_PSSR_SPEED) {
    691	case GIGA_PSSR_1000MBS:
    692		*speed = SPEED_1000;
    693		break;
    694	case GIGA_PSSR_100MBS:
    695		*speed = SPEED_100;
    696		break;
    697	case  GIGA_PSSR_10MBS:
    698		*speed = SPEED_10;
    699		break;
    700	default:
    701		return -1;
    702	}
    703
    704	if (phy_data & GIGA_PSSR_DPLX)
    705		*duplex = FULL_DUPLEX;
    706	else
    707		*duplex = HALF_DUPLEX;
    708
    709	return 0;
    710}
    711
    712/* select one link mode to get lower power consumption */
    713int atl1c_phy_to_ps_link(struct atl1c_hw *hw)
    714{
    715	struct atl1c_adapter *adapter = hw->adapter;
    716	struct pci_dev *pdev = adapter->pdev;
    717	int ret = 0;
    718	u16 autoneg_advertised = ADVERTISED_10baseT_Half;
    719	u16 save_autoneg_advertised;
    720	u16 mii_lpa_data;
    721	u16 speed = SPEED_0;
    722	u16 duplex = FULL_DUPLEX;
    723	int i;
    724
    725	if (atl1c_get_link_status(hw)) {
    726		atl1c_read_phy_reg(hw, MII_LPA, &mii_lpa_data);
    727		if (mii_lpa_data & LPA_10FULL)
    728			autoneg_advertised = ADVERTISED_10baseT_Full;
    729		else if (mii_lpa_data & LPA_10HALF)
    730			autoneg_advertised = ADVERTISED_10baseT_Half;
    731		else if (mii_lpa_data & LPA_100HALF)
    732			autoneg_advertised = ADVERTISED_100baseT_Half;
    733		else if (mii_lpa_data & LPA_100FULL)
    734			autoneg_advertised = ADVERTISED_100baseT_Full;
    735
    736		save_autoneg_advertised = hw->autoneg_advertised;
    737		hw->phy_configured = false;
    738		hw->autoneg_advertised = autoneg_advertised;
    739		if (atl1c_restart_autoneg(hw) != 0) {
    740			dev_dbg(&pdev->dev, "phy autoneg failed\n");
    741			ret = -1;
    742		}
    743		hw->autoneg_advertised = save_autoneg_advertised;
    744
    745		if (mii_lpa_data) {
    746			for (i = 0; i < AT_SUSPEND_LINK_TIMEOUT; i++) {
    747				mdelay(100);
    748				if (atl1c_get_link_status(hw)) {
    749					if (atl1c_get_speed_and_duplex(hw, &speed,
    750									&duplex) != 0)
    751						dev_dbg(&pdev->dev,
    752							"get speed and duplex failed\n");
    753					break;
    754				}
    755			}
    756		}
    757	} else {
    758		speed = SPEED_10;
    759		duplex = HALF_DUPLEX;
    760	}
    761	adapter->link_speed = speed;
    762	adapter->link_duplex = duplex;
    763
    764	return ret;
    765}
    766
    767int atl1c_restart_autoneg(struct atl1c_hw *hw)
    768{
    769	int err = 0;
    770	u16 mii_bmcr_data = BMCR_RESET;
    771
    772	err = atl1c_phy_setup_adv(hw);
    773	if (err)
    774		return err;
    775	mii_bmcr_data |= BMCR_ANENABLE | BMCR_ANRESTART;
    776
    777	return atl1c_write_phy_reg(hw, MII_BMCR, mii_bmcr_data);
    778}
    779
    780int atl1c_power_saving(struct atl1c_hw *hw, u32 wufc)
    781{
    782	struct atl1c_adapter *adapter = hw->adapter;
    783	struct pci_dev *pdev = adapter->pdev;
    784	u32 master_ctrl, mac_ctrl, phy_ctrl;
    785	u32 wol_ctrl, speed;
    786	u16 phy_data;
    787
    788	wol_ctrl = 0;
    789	speed = adapter->link_speed == SPEED_1000 ?
    790		MAC_CTRL_SPEED_1000 : MAC_CTRL_SPEED_10_100;
    791
    792	AT_READ_REG(hw, REG_MASTER_CTRL, &master_ctrl);
    793	AT_READ_REG(hw, REG_MAC_CTRL, &mac_ctrl);
    794	AT_READ_REG(hw, REG_GPHY_CTRL, &phy_ctrl);
    795
    796	master_ctrl &= ~MASTER_CTRL_CLK_SEL_DIS;
    797	mac_ctrl = FIELD_SETX(mac_ctrl, MAC_CTRL_SPEED, speed);
    798	mac_ctrl &= ~(MAC_CTRL_DUPLX | MAC_CTRL_RX_EN | MAC_CTRL_TX_EN);
    799	if (adapter->link_duplex == FULL_DUPLEX)
    800		mac_ctrl |= MAC_CTRL_DUPLX;
    801	phy_ctrl &= ~(GPHY_CTRL_EXT_RESET | GPHY_CTRL_CLS);
    802	phy_ctrl |= GPHY_CTRL_SEL_ANA_RST | GPHY_CTRL_HIB_PULSE |
    803		GPHY_CTRL_HIB_EN;
    804	if (!wufc) { /* without WoL */
    805		master_ctrl |= MASTER_CTRL_CLK_SEL_DIS;
    806		phy_ctrl |= GPHY_CTRL_PHY_IDDQ | GPHY_CTRL_PWDOWN_HW;
    807		AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl);
    808		AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl);
    809		AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl);
    810		AT_WRITE_REG(hw, REG_WOL_CTRL, 0);
    811		hw->phy_configured = false; /* re-init PHY when resume */
    812		return 0;
    813	}
    814	phy_ctrl |= GPHY_CTRL_EXT_RESET;
    815	if (wufc & AT_WUFC_MAG) {
    816		mac_ctrl |= MAC_CTRL_RX_EN | MAC_CTRL_BC_EN;
    817		wol_ctrl |= WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
    818		if (hw->nic_type == athr_l2c_b && hw->revision_id == L2CB_V11)
    819			wol_ctrl |= WOL_PATTERN_EN | WOL_PATTERN_PME_EN;
    820	}
    821	if (wufc & AT_WUFC_LNKC) {
    822		wol_ctrl |= WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN;
    823		if (atl1c_write_phy_reg(hw, MII_IER, IER_LINK_UP) != 0) {
    824			dev_dbg(&pdev->dev, "%s: write phy MII_IER failed.\n",
    825				atl1c_driver_name);
    826		}
    827	}
    828	/* clear PHY interrupt */
    829	atl1c_read_phy_reg(hw, MII_ISR, &phy_data);
    830
    831	dev_dbg(&pdev->dev, "%s: suspend MAC=%x,MASTER=%x,PHY=0x%x,WOL=%x\n",
    832		atl1c_driver_name, mac_ctrl, master_ctrl, phy_ctrl, wol_ctrl);
    833	AT_WRITE_REG(hw, REG_MASTER_CTRL, master_ctrl);
    834	AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl);
    835	AT_WRITE_REG(hw, REG_GPHY_CTRL, phy_ctrl);
    836	AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl);
    837
    838	return 0;
    839}
    840
    841
    842/* configure phy after Link change Event */
    843void atl1c_post_phy_linkchg(struct atl1c_hw *hw, u16 link_speed)
    844{
    845	u16 phy_val;
    846	bool adj_thresh = false;
    847
    848	if (hw->nic_type == athr_l2c_b || hw->nic_type == athr_l2c_b2 ||
    849	    hw->nic_type == athr_l1d || hw->nic_type == athr_l1d_2)
    850		adj_thresh = true;
    851
    852	if (link_speed != SPEED_0) { /* link up */
    853		/* az with brcm, half-amp */
    854		if (hw->nic_type == athr_l1d_2) {
    855			atl1c_read_phy_ext(hw, MIIEXT_PCS, MIIEXT_CLDCTRL6,
    856				&phy_val);
    857			phy_val = FIELD_GETX(phy_val, CLDCTRL6_CAB_LEN);
    858			phy_val = phy_val > CLDCTRL6_CAB_LEN_SHORT ?
    859				AZ_ANADECT_LONG : AZ_ANADECT_DEF;
    860			atl1c_write_phy_dbg(hw, MIIDBG_AZ_ANADECT, phy_val);
    861		}
    862		/* threshold adjust */
    863		if (adj_thresh && link_speed == SPEED_100 && hw->msi_lnkpatch) {
    864			atl1c_write_phy_dbg(hw, MIIDBG_MSE16DB, L1D_MSE16DB_UP);
    865			atl1c_write_phy_dbg(hw, MIIDBG_SYSMODCTRL,
    866				L1D_SYSMODCTRL_IECHOADJ_DEF);
    867		}
    868	} else { /* link down */
    869		if (adj_thresh && hw->msi_lnkpatch) {
    870			atl1c_write_phy_dbg(hw, MIIDBG_SYSMODCTRL,
    871				SYSMODCTRL_IECHOADJ_DEF);
    872			atl1c_write_phy_dbg(hw, MIIDBG_MSE16DB,
    873				L1D_MSE16DB_DOWN);
    874		}
    875	}
    876}