Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (21 commits) mac80211: check interface is down before type change cfg80211: fix NULL ptr deref libertas if_usb: Fix crash on 64-bit machines mac80211: fix reason code output endianness mac80211: fix addba timer ath9k: fix misplaced semicolon on rate control b43: Fix DMA TX bounce buffer copying mac80211: fix BSS leak rt73usb.c : more ids ipw2200: fix oops on missing firmware gre: Fix dev_addr clobbering for gretap sky2: set carrier off in probe net: fix sk_forward_alloc corruption pcnet_cs: add cis of PreMax PE-200 ethernet pcmcia card r8169: Fix card drop incoming VLAN tagged MTU byte large jumbo frames ibmtr: possible Read buffer overflow? net: Fix RPF to work with policy routing net: fix kmemcheck annotations e1000e: rework disable K1 at 1000Mbps for 82577/82578 e1000e: config PHY via software after resets ...
This commit is contained in:
@@ -1427,19 +1427,31 @@ static int e100_phy_init(struct nic *nic)
|
||||
} else
|
||||
DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id);
|
||||
|
||||
/* Isolate all the PHY ids */
|
||||
for (addr = 0; addr < 32; addr++)
|
||||
mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
|
||||
/* Select the discovered PHY */
|
||||
bmcr &= ~BMCR_ISOLATE;
|
||||
mdio_write(netdev, nic->mii.phy_id, MII_BMCR, bmcr);
|
||||
|
||||
/* Get phy ID */
|
||||
id_lo = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID1);
|
||||
id_hi = mdio_read(netdev, nic->mii.phy_id, MII_PHYSID2);
|
||||
nic->phy = (u32)id_hi << 16 | (u32)id_lo;
|
||||
DPRINTK(HW, DEBUG, "phy ID = 0x%08X\n", nic->phy);
|
||||
|
||||
/* Select the phy and isolate the rest */
|
||||
for (addr = 0; addr < 32; addr++) {
|
||||
if (addr != nic->mii.phy_id) {
|
||||
mdio_write(netdev, addr, MII_BMCR, BMCR_ISOLATE);
|
||||
} else if (nic->phy != phy_82552_v) {
|
||||
bmcr = mdio_read(netdev, addr, MII_BMCR);
|
||||
mdio_write(netdev, addr, MII_BMCR,
|
||||
bmcr & ~BMCR_ISOLATE);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Workaround for 82552:
|
||||
* Clear the ISOLATE bit on selected phy_id last (mirrored on all
|
||||
* other phy_id's) using bmcr value from addr discovery loop above.
|
||||
*/
|
||||
if (nic->phy == phy_82552_v)
|
||||
mdio_write(netdev, nic->mii.phy_id, MII_BMCR,
|
||||
bmcr & ~BMCR_ISOLATE);
|
||||
|
||||
/* Handle National tx phys */
|
||||
#define NCS_PHY_MODEL_MASK 0xFFF0FFFF
|
||||
if ((nic->phy & NCS_PHY_MODEL_MASK) == phy_nsc_tx) {
|
||||
|
@@ -76,6 +76,7 @@
|
||||
/* Extended Device Control */
|
||||
#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */
|
||||
#define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */
|
||||
#define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */
|
||||
#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */
|
||||
#define E1000_CTRL_EXT_DMA_DYN_CLK_EN 0x00080000 /* DMA Dynamic Clock Gating */
|
||||
#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
|
||||
@@ -347,6 +348,7 @@
|
||||
/* Extended Configuration Control and Size */
|
||||
#define E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP 0x00000020
|
||||
#define E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE 0x00000001
|
||||
#define E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE 0x00000008
|
||||
#define E1000_EXTCNF_CTRL_SWFLAG 0x00000020
|
||||
#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK 0x00FF0000
|
||||
#define E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT 16
|
||||
|
@@ -141,6 +141,20 @@ struct e1000_info;
|
||||
#define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */
|
||||
#define HV_TNCRS_LOWER PHY_REG(778, 30)
|
||||
|
||||
/* BM PHY Copper Specific Status */
|
||||
#define BM_CS_STATUS 17
|
||||
#define BM_CS_STATUS_LINK_UP 0x0400
|
||||
#define BM_CS_STATUS_RESOLVED 0x0800
|
||||
#define BM_CS_STATUS_SPEED_MASK 0xC000
|
||||
#define BM_CS_STATUS_SPEED_1000 0x8000
|
||||
|
||||
/* 82577 Mobile Phy Status Register */
|
||||
#define HV_M_STATUS 26
|
||||
#define HV_M_STATUS_AUTONEG_COMPLETE 0x1000
|
||||
#define HV_M_STATUS_SPEED_MASK 0x0300
|
||||
#define HV_M_STATUS_SPEED_1000 0x0200
|
||||
#define HV_M_STATUS_LINK_UP 0x0040
|
||||
|
||||
enum e1000_boards {
|
||||
board_82571,
|
||||
board_82572,
|
||||
|
@@ -903,6 +903,7 @@ struct e1000_shadow_ram {
|
||||
struct e1000_dev_spec_ich8lan {
|
||||
bool kmrn_lock_loss_workaround_enabled;
|
||||
struct e1000_shadow_ram shadow_ram[E1000_ICH8_SHADOW_RAM_WORDS];
|
||||
bool nvm_k1_enabled;
|
||||
};
|
||||
|
||||
struct e1000_hw {
|
||||
|
@@ -124,11 +124,25 @@
|
||||
|
||||
#define SW_FLAG_TIMEOUT 1000 /* SW Semaphore flag timeout in milliseconds */
|
||||
|
||||
/* SMBus Address Phy Register */
|
||||
#define HV_SMB_ADDR PHY_REG(768, 26)
|
||||
#define HV_SMB_ADDR_PEC_EN 0x0200
|
||||
#define HV_SMB_ADDR_VALID 0x0080
|
||||
|
||||
/* Strapping Option Register - RO */
|
||||
#define E1000_STRAP 0x0000C
|
||||
#define E1000_STRAP_SMBUS_ADDRESS_MASK 0x00FE0000
|
||||
#define E1000_STRAP_SMBUS_ADDRESS_SHIFT 17
|
||||
|
||||
/* OEM Bits Phy Register */
|
||||
#define HV_OEM_BITS PHY_REG(768, 25)
|
||||
#define HV_OEM_BITS_LPLU 0x0004 /* Low Power Link Up */
|
||||
#define HV_OEM_BITS_GBE_DIS 0x0040 /* Gigabit Disable */
|
||||
#define HV_OEM_BITS_RESTART_AN 0x0400 /* Restart Auto-negotiation */
|
||||
|
||||
#define E1000_NVM_K1_CONFIG 0x1B /* NVM K1 Config Word */
|
||||
#define E1000_NVM_K1_ENABLE 0x1 /* NVM Enable K1 bit */
|
||||
|
||||
/* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
|
||||
/* Offset 04h HSFSTS */
|
||||
union ich8_hws_flash_status {
|
||||
@@ -208,6 +222,9 @@ static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw);
|
||||
static s32 e1000_led_on_pchlan(struct e1000_hw *hw);
|
||||
static s32 e1000_led_off_pchlan(struct e1000_hw *hw);
|
||||
static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active);
|
||||
static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw);
|
||||
static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link);
|
||||
static s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable);
|
||||
|
||||
static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
|
||||
{
|
||||
@@ -483,14 +500,6 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hw->mac.type == e1000_pchlan) {
|
||||
ret_val = e1000e_write_kmrn_reg(hw,
|
||||
E1000_KMRNCTRLSTA_K1_CONFIG,
|
||||
E1000_KMRNCTRLSTA_K1_ENABLE);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* First we want to see if the MII Status Register reports
|
||||
* link. If so, then we want to get the current speed/duplex
|
||||
@@ -500,6 +509,12 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
if (hw->mac.type == e1000_pchlan) {
|
||||
ret_val = e1000_k1_gig_workaround_hv(hw, link);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!link)
|
||||
goto out; /* No link detected */
|
||||
|
||||
@@ -793,6 +808,326 @@ static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* SW should configure the LCD from the NVM extended configuration region
|
||||
* as a workaround for certain parts.
|
||||
**/
|
||||
static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask;
|
||||
s32 ret_val;
|
||||
u16 word_addr, reg_data, reg_addr, phy_page = 0;
|
||||
|
||||
ret_val = hw->phy.ops.acquire_phy(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/*
|
||||
* Initialize the PHY from the NVM on ICH platforms. This
|
||||
* is needed due to an issue where the NVM configuration is
|
||||
* not properly autoloaded after power transitions.
|
||||
* Therefore, after each PHY reset, we will load the
|
||||
* configuration data out of the NVM manually.
|
||||
*/
|
||||
if ((hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) ||
|
||||
(hw->mac.type == e1000_pchlan)) {
|
||||
struct e1000_adapter *adapter = hw->adapter;
|
||||
|
||||
/* Check if SW needs to configure the PHY */
|
||||
if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) ||
|
||||
(adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M) ||
|
||||
(hw->mac.type == e1000_pchlan))
|
||||
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M;
|
||||
else
|
||||
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG;
|
||||
|
||||
data = er32(FEXTNVM);
|
||||
if (!(data & sw_cfg_mask))
|
||||
goto out;
|
||||
|
||||
/* Wait for basic configuration completes before proceeding */
|
||||
e1000_lan_init_done_ich8lan(hw);
|
||||
|
||||
/*
|
||||
* Make sure HW does not configure LCD from PHY
|
||||
* extended configuration before SW configuration
|
||||
*/
|
||||
data = er32(EXTCNF_CTRL);
|
||||
if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE)
|
||||
goto out;
|
||||
|
||||
cnf_size = er32(EXTCNF_SIZE);
|
||||
cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK;
|
||||
cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT;
|
||||
if (!cnf_size)
|
||||
goto out;
|
||||
|
||||
cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK;
|
||||
cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT;
|
||||
|
||||
if (!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) &&
|
||||
(hw->mac.type == e1000_pchlan)) {
|
||||
/*
|
||||
* HW configures the SMBus address and LEDs when the
|
||||
* OEM and LCD Write Enable bits are set in the NVM.
|
||||
* When both NVM bits are cleared, SW will configure
|
||||
* them instead.
|
||||
*/
|
||||
data = er32(STRAP);
|
||||
data &= E1000_STRAP_SMBUS_ADDRESS_MASK;
|
||||
reg_data = data >> E1000_STRAP_SMBUS_ADDRESS_SHIFT;
|
||||
reg_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID;
|
||||
ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR,
|
||||
reg_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
data = er32(LEDCTL);
|
||||
ret_val = e1000_write_phy_reg_hv_locked(hw,
|
||||
HV_LED_CONFIG,
|
||||
(u16)data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
}
|
||||
/* Configure LCD from extended configuration region. */
|
||||
|
||||
/* cnf_base_addr is in DWORD */
|
||||
word_addr = (u16)(cnf_base_addr << 1);
|
||||
|
||||
for (i = 0; i < cnf_size; i++) {
|
||||
ret_val = e1000_read_nvm(hw, (word_addr + i * 2), 1,
|
||||
®_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
ret_val = e1000_read_nvm(hw, (word_addr + i * 2 + 1),
|
||||
1, ®_addr);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Save off the PHY page for future writes. */
|
||||
if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) {
|
||||
phy_page = reg_data;
|
||||
continue;
|
||||
}
|
||||
|
||||
reg_addr &= PHY_REG_MASK;
|
||||
reg_addr |= phy_page;
|
||||
|
||||
ret_val = phy->ops.write_phy_reg_locked(hw,
|
||||
(u32)reg_addr,
|
||||
reg_data);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
hw->phy.ops.release_phy(hw);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_k1_gig_workaround_hv - K1 Si workaround
|
||||
* @hw: pointer to the HW structure
|
||||
* @link: link up bool flag
|
||||
*
|
||||
* If K1 is enabled for 1Gbps, the MAC might stall when transitioning
|
||||
* from a lower speed. This workaround disables K1 whenever link is at 1Gig
|
||||
* If link is down, the function will restore the default K1 setting located
|
||||
* in the NVM.
|
||||
**/
|
||||
static s32 e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link)
|
||||
{
|
||||
s32 ret_val = 0;
|
||||
u16 status_reg = 0;
|
||||
bool k1_enable = hw->dev_spec.ich8lan.nvm_k1_enabled;
|
||||
|
||||
if (hw->mac.type != e1000_pchlan)
|
||||
goto out;
|
||||
|
||||
/* Wrap the whole flow with the sw flag */
|
||||
ret_val = hw->phy.ops.acquire_phy(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Disable K1 when link is 1Gbps, otherwise use the NVM setting */
|
||||
if (link) {
|
||||
if (hw->phy.type == e1000_phy_82578) {
|
||||
ret_val = hw->phy.ops.read_phy_reg_locked(hw,
|
||||
BM_CS_STATUS,
|
||||
&status_reg);
|
||||
if (ret_val)
|
||||
goto release;
|
||||
|
||||
status_reg &= BM_CS_STATUS_LINK_UP |
|
||||
BM_CS_STATUS_RESOLVED |
|
||||
BM_CS_STATUS_SPEED_MASK;
|
||||
|
||||
if (status_reg == (BM_CS_STATUS_LINK_UP |
|
||||
BM_CS_STATUS_RESOLVED |
|
||||
BM_CS_STATUS_SPEED_1000))
|
||||
k1_enable = false;
|
||||
}
|
||||
|
||||
if (hw->phy.type == e1000_phy_82577) {
|
||||
ret_val = hw->phy.ops.read_phy_reg_locked(hw,
|
||||
HV_M_STATUS,
|
||||
&status_reg);
|
||||
if (ret_val)
|
||||
goto release;
|
||||
|
||||
status_reg &= HV_M_STATUS_LINK_UP |
|
||||
HV_M_STATUS_AUTONEG_COMPLETE |
|
||||
HV_M_STATUS_SPEED_MASK;
|
||||
|
||||
if (status_reg == (HV_M_STATUS_LINK_UP |
|
||||
HV_M_STATUS_AUTONEG_COMPLETE |
|
||||
HV_M_STATUS_SPEED_1000))
|
||||
k1_enable = false;
|
||||
}
|
||||
|
||||
/* Link stall fix for link up */
|
||||
ret_val = hw->phy.ops.write_phy_reg_locked(hw, PHY_REG(770, 19),
|
||||
0x0100);
|
||||
if (ret_val)
|
||||
goto release;
|
||||
|
||||
} else {
|
||||
/* Link stall fix for link down */
|
||||
ret_val = hw->phy.ops.write_phy_reg_locked(hw, PHY_REG(770, 19),
|
||||
0x4100);
|
||||
if (ret_val)
|
||||
goto release;
|
||||
}
|
||||
|
||||
ret_val = e1000_configure_k1_ich8lan(hw, k1_enable);
|
||||
|
||||
release:
|
||||
hw->phy.ops.release_phy(hw);
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_configure_k1_ich8lan - Configure K1 power state
|
||||
* @hw: pointer to the HW structure
|
||||
* @enable: K1 state to configure
|
||||
*
|
||||
* Configure the K1 power state based on the provided parameter.
|
||||
* Assumes semaphore already acquired.
|
||||
*
|
||||
* Success returns 0, Failure returns -E1000_ERR_PHY (-2)
|
||||
**/
|
||||
static s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable)
|
||||
{
|
||||
s32 ret_val = 0;
|
||||
u32 ctrl_reg = 0;
|
||||
u32 ctrl_ext = 0;
|
||||
u32 reg = 0;
|
||||
u16 kmrn_reg = 0;
|
||||
|
||||
ret_val = e1000e_read_kmrn_reg_locked(hw,
|
||||
E1000_KMRNCTRLSTA_K1_CONFIG,
|
||||
&kmrn_reg);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
if (k1_enable)
|
||||
kmrn_reg |= E1000_KMRNCTRLSTA_K1_ENABLE;
|
||||
else
|
||||
kmrn_reg &= ~E1000_KMRNCTRLSTA_K1_ENABLE;
|
||||
|
||||
ret_val = e1000e_write_kmrn_reg_locked(hw,
|
||||
E1000_KMRNCTRLSTA_K1_CONFIG,
|
||||
kmrn_reg);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
udelay(20);
|
||||
ctrl_ext = er32(CTRL_EXT);
|
||||
ctrl_reg = er32(CTRL);
|
||||
|
||||
reg = ctrl_reg & ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
|
||||
reg |= E1000_CTRL_FRCSPD;
|
||||
ew32(CTRL, reg);
|
||||
|
||||
ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_SPD_BYPS);
|
||||
udelay(20);
|
||||
ew32(CTRL, ctrl_reg);
|
||||
ew32(CTRL_EXT, ctrl_ext);
|
||||
udelay(20);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_oem_bits_config_ich8lan - SW-based LCD Configuration
|
||||
* @hw: pointer to the HW structure
|
||||
* @d0_state: boolean if entering d0 or d3 device state
|
||||
*
|
||||
* SW will configure Gbe Disable and LPLU based on the NVM. The four bits are
|
||||
* collectively called OEM bits. The OEM Write Enable bit and SW Config bit
|
||||
* in NVM determines whether HW should configure LPLU and Gbe Disable.
|
||||
**/
|
||||
static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state)
|
||||
{
|
||||
s32 ret_val = 0;
|
||||
u32 mac_reg;
|
||||
u16 oem_reg;
|
||||
|
||||
if (hw->mac.type != e1000_pchlan)
|
||||
return ret_val;
|
||||
|
||||
ret_val = hw->phy.ops.acquire_phy(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
mac_reg = er32(EXTCNF_CTRL);
|
||||
if (mac_reg & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE)
|
||||
goto out;
|
||||
|
||||
mac_reg = er32(FEXTNVM);
|
||||
if (!(mac_reg & E1000_FEXTNVM_SW_CONFIG_ICH8M))
|
||||
goto out;
|
||||
|
||||
mac_reg = er32(PHY_CTRL);
|
||||
|
||||
ret_val = hw->phy.ops.read_phy_reg_locked(hw, HV_OEM_BITS, &oem_reg);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
oem_reg &= ~(HV_OEM_BITS_GBE_DIS | HV_OEM_BITS_LPLU);
|
||||
|
||||
if (d0_state) {
|
||||
if (mac_reg & E1000_PHY_CTRL_GBE_DISABLE)
|
||||
oem_reg |= HV_OEM_BITS_GBE_DIS;
|
||||
|
||||
if (mac_reg & E1000_PHY_CTRL_D0A_LPLU)
|
||||
oem_reg |= HV_OEM_BITS_LPLU;
|
||||
} else {
|
||||
if (mac_reg & E1000_PHY_CTRL_NOND0A_GBE_DISABLE)
|
||||
oem_reg |= HV_OEM_BITS_GBE_DIS;
|
||||
|
||||
if (mac_reg & E1000_PHY_CTRL_NOND0A_LPLU)
|
||||
oem_reg |= HV_OEM_BITS_LPLU;
|
||||
}
|
||||
/* Restart auto-neg to activate the bits */
|
||||
oem_reg |= HV_OEM_BITS_RESTART_AN;
|
||||
ret_val = hw->phy.ops.write_phy_reg_locked(hw, HV_OEM_BITS, oem_reg);
|
||||
|
||||
out:
|
||||
hw->phy.ops.release_phy(hw);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be
|
||||
* done after every PHY reset.
|
||||
@@ -833,10 +1168,20 @@ static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
|
||||
ret_val = hw->phy.ops.acquire_phy(hw);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
hw->phy.addr = 1;
|
||||
e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0);
|
||||
ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
hw->phy.ops.release_phy(hw);
|
||||
|
||||
/*
|
||||
* Configure the K1 Si workaround during phy reset assuming there is
|
||||
* link so that it disables K1 if link is in 1Gbps.
|
||||
*/
|
||||
ret_val = e1000_k1_gig_workaround_hv(hw, true);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
@@ -882,11 +1227,8 @@ static void e1000_lan_init_done_ich8lan(struct e1000_hw *hw)
|
||||
**/
|
||||
static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_phy_info *phy = &hw->phy;
|
||||
u32 i;
|
||||
u32 data, cnf_size, cnf_base_addr, sw_cfg_mask;
|
||||
s32 ret_val;
|
||||
u16 reg, word_addr, reg_data, reg_addr, phy_page = 0;
|
||||
s32 ret_val = 0;
|
||||
u16 reg;
|
||||
|
||||
ret_val = e1000e_phy_hw_reset_generic(hw);
|
||||
if (ret_val)
|
||||
@@ -905,81 +1247,16 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
|
||||
if (hw->mac.type == e1000_pchlan)
|
||||
e1e_rphy(hw, BM_WUC, ®);
|
||||
|
||||
/*
|
||||
* Initialize the PHY from the NVM on ICH platforms. This
|
||||
* is needed due to an issue where the NVM configuration is
|
||||
* not properly autoloaded after power transitions.
|
||||
* Therefore, after each PHY reset, we will load the
|
||||
* configuration data out of the NVM manually.
|
||||
*/
|
||||
if (hw->mac.type == e1000_ich8lan && phy->type == e1000_phy_igp_3) {
|
||||
struct e1000_adapter *adapter = hw->adapter;
|
||||
/* Configure the LCD with the extended configuration region in NVM */
|
||||
ret_val = e1000_sw_lcd_config_ich8lan(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
/* Check if SW needs configure the PHY */
|
||||
if ((adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M_AMT) ||
|
||||
(adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_M))
|
||||
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG_ICH8M;
|
||||
else
|
||||
sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG;
|
||||
|
||||
data = er32(FEXTNVM);
|
||||
if (!(data & sw_cfg_mask))
|
||||
return 0;
|
||||
|
||||
/* Wait for basic configuration completes before proceeding */
|
||||
e1000_lan_init_done_ich8lan(hw);
|
||||
|
||||
/*
|
||||
* Make sure HW does not configure LCD from PHY
|
||||
* extended configuration before SW configuration
|
||||
*/
|
||||
data = er32(EXTCNF_CTRL);
|
||||
if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE)
|
||||
return 0;
|
||||
|
||||
cnf_size = er32(EXTCNF_SIZE);
|
||||
cnf_size &= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_MASK;
|
||||
cnf_size >>= E1000_EXTCNF_SIZE_EXT_PCIE_LENGTH_SHIFT;
|
||||
if (!cnf_size)
|
||||
return 0;
|
||||
|
||||
cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK;
|
||||
cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT;
|
||||
|
||||
/* Configure LCD from extended configuration region. */
|
||||
|
||||
/* cnf_base_addr is in DWORD */
|
||||
word_addr = (u16)(cnf_base_addr << 1);
|
||||
|
||||
for (i = 0; i < cnf_size; i++) {
|
||||
ret_val = e1000_read_nvm(hw,
|
||||
(word_addr + i * 2),
|
||||
1,
|
||||
®_data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
ret_val = e1000_read_nvm(hw,
|
||||
(word_addr + i * 2 + 1),
|
||||
1,
|
||||
®_addr);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
/* Save off the PHY page for future writes. */
|
||||
if (reg_addr == IGP01E1000_PHY_PAGE_SELECT) {
|
||||
phy_page = reg_data;
|
||||
continue;
|
||||
}
|
||||
|
||||
reg_addr |= phy_page;
|
||||
|
||||
ret_val = e1e_wphy(hw, (u32)reg_addr, reg_data);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
}
|
||||
/* Configure the LCD with the OEM bits in NVM */
|
||||
if (hw->mac.type == e1000_pchlan)
|
||||
ret_val = e1000_oem_bits_config_ich8lan(hw, true);
|
||||
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2306,6 +2583,7 @@ static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw)
|
||||
**/
|
||||
static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
|
||||
{
|
||||
struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;
|
||||
u16 reg;
|
||||
u32 ctrl, icr, kab;
|
||||
s32 ret_val;
|
||||
@@ -2341,6 +2619,18 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
|
||||
ew32(PBS, E1000_PBS_16K);
|
||||
}
|
||||
|
||||
if (hw->mac.type == e1000_pchlan) {
|
||||
/* Save the NVM K1 bit setting*/
|
||||
ret_val = e1000_read_nvm(hw, E1000_NVM_K1_CONFIG, 1, ®);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
if (reg & E1000_NVM_K1_ENABLE)
|
||||
dev_spec->nvm_k1_enabled = true;
|
||||
else
|
||||
dev_spec->nvm_k1_enabled = false;
|
||||
}
|
||||
|
||||
ctrl = er32(CTRL);
|
||||
|
||||
if (!e1000_check_reset_block(hw)) {
|
||||
@@ -2386,6 +2676,15 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
|
||||
if (hw->mac.type == e1000_pchlan)
|
||||
e1e_rphy(hw, BM_WUC, ®);
|
||||
|
||||
ret_val = e1000_sw_lcd_config_ich8lan(hw);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
|
||||
if (hw->mac.type == e1000_pchlan) {
|
||||
ret_val = e1000_oem_bits_config_ich8lan(hw, true);
|
||||
if (ret_val)
|
||||
goto out;
|
||||
}
|
||||
/*
|
||||
* For PCH, this write will make sure that any noise
|
||||
* will be detected as a CRC error and be dropped rather than show up
|
||||
@@ -2404,6 +2703,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
|
||||
if (hw->mac.type == e1000_pchlan)
|
||||
ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
|
||||
|
||||
out:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
@@ -2708,14 +3008,6 @@ static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed,
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
|
||||
if ((hw->mac.type == e1000_pchlan) && (*speed == SPEED_1000)) {
|
||||
ret_val = e1000e_write_kmrn_reg(hw,
|
||||
E1000_KMRNCTRLSTA_K1_CONFIG,
|
||||
E1000_KMRNCTRLSTA_K1_DISABLE);
|
||||
if (ret_val)
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
if ((hw->mac.type == e1000_ich8lan) &&
|
||||
(hw->phy.type == e1000_phy_igp_3) &&
|
||||
(*speed == SPEED_1000)) {
|
||||
|
@@ -95,13 +95,6 @@ static const u16 e1000_igp_2_cable_length_table[] =
|
||||
/* BM PHY Copper Specific Control 1 */
|
||||
#define BM_CS_CTRL1 16
|
||||
|
||||
/* BM PHY Copper Specific Status */
|
||||
#define BM_CS_STATUS 17
|
||||
#define BM_CS_STATUS_LINK_UP 0x0400
|
||||
#define BM_CS_STATUS_RESOLVED 0x0800
|
||||
#define BM_CS_STATUS_SPEED_MASK 0xC000
|
||||
#define BM_CS_STATUS_SPEED_1000 0x8000
|
||||
|
||||
#define HV_MUX_DATA_CTRL PHY_REG(776, 16)
|
||||
#define HV_MUX_DATA_CTRL_GEN_TO_MAC 0x0400
|
||||
#define HV_MUX_DATA_CTRL_FORCE_SPEED 0x0004
|
||||
@@ -563,7 +556,7 @@ s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_read_kmrn_reg_locked - Read kumeran register
|
||||
* e1000e_read_kmrn_reg_locked - Read kumeran register
|
||||
* @hw: pointer to the HW structure
|
||||
* @offset: register offset to be read
|
||||
* @data: pointer to the read data
|
||||
@@ -572,7 +565,7 @@ s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data)
|
||||
* information retrieved is stored in data.
|
||||
* Assumes semaphore already acquired.
|
||||
**/
|
||||
s32 e1000_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data)
|
||||
s32 e1000e_read_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 *data)
|
||||
{
|
||||
return __e1000_read_kmrn_reg(hw, offset, data, true);
|
||||
}
|
||||
@@ -631,7 +624,7 @@ s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data)
|
||||
}
|
||||
|
||||
/**
|
||||
* e1000_write_kmrn_reg_locked - Write kumeran register
|
||||
* e1000e_write_kmrn_reg_locked - Write kumeran register
|
||||
* @hw: pointer to the HW structure
|
||||
* @offset: register offset to write to
|
||||
* @data: data to write at register offset
|
||||
@@ -639,7 +632,7 @@ s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data)
|
||||
* Write the data to PHY register at the offset using the kumeran interface.
|
||||
* Assumes semaphore already acquired.
|
||||
**/
|
||||
s32 e1000_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data)
|
||||
s32 e1000e_write_kmrn_reg_locked(struct e1000_hw *hw, u32 offset, u16 data)
|
||||
{
|
||||
return __e1000_write_kmrn_reg(hw, offset, data, true);
|
||||
}
|
||||
|
@@ -1760,7 +1760,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
|
||||
PCMCIA_DEVICE_CIS_MANF_CARD(0xc00f, 0x0002, "cis/LA-PCM.cis"),
|
||||
PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "PE520.cis"),
|
||||
PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"),
|
||||
PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "PE-200.cis"),
|
||||
PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"),
|
||||
PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "cis/tamarack.cis"),
|
||||
PCMCIA_DEVICE_PROD_ID12("Ethernet", "CF Size PC Card", 0x00b2e941, 0x43ac239b),
|
||||
PCMCIA_DEVICE_PROD_ID123("Fast Ethernet", "CF Size PC Card", "1.0",
|
||||
|
@@ -3379,7 +3379,7 @@ static u16 rtl_rw_cpluscmd(void __iomem *ioaddr)
|
||||
static void rtl_set_rx_max_size(void __iomem *ioaddr, unsigned int rx_buf_sz)
|
||||
{
|
||||
/* Low hurts. Let's disable the filtering. */
|
||||
RTL_W16(RxMaxSize, rx_buf_sz);
|
||||
RTL_W16(RxMaxSize, rx_buf_sz + 1);
|
||||
}
|
||||
|
||||
static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
|
||||
|
@@ -4538,6 +4538,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
|
||||
goto err_out_free_netdev;
|
||||
}
|
||||
|
||||
netif_carrier_off(dev);
|
||||
|
||||
netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT);
|
||||
|
||||
err = request_irq(pdev->irq, sky2_intr,
|
||||
|
@@ -1144,9 +1144,16 @@ static void dir_open_adapter (struct net_device *dev)
|
||||
} else {
|
||||
char **prphase = printphase;
|
||||
char **prerror = printerror;
|
||||
int pnr = err / 16 - 1;
|
||||
int enr = err % 16 - 1;
|
||||
DPRINTK("TR Adapter misc open failure, error code = ");
|
||||
printk("0x%x, Phase: %s, Error: %s\n",
|
||||
err, prphase[err/16 -1], prerror[err%16 -1]);
|
||||
if (pnr < 0 || pnr >= ARRAY_SIZE(printphase) ||
|
||||
enr < 0 ||
|
||||
enr >= ARRAY_SIZE(printerror))
|
||||
printk("0x%x, invalid Phase/Error.", err);
|
||||
else
|
||||
printk("0x%x, Phase: %s, Error: %s\n", err,
|
||||
prphase[pnr], prerror[enr]);
|
||||
printk(" retrying after %ds delay...\n",
|
||||
TR_RETRY_INTERVAL/HZ);
|
||||
}
|
||||
|
@@ -679,7 +679,7 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc,
|
||||
return rate;
|
||||
|
||||
if (rate_table->info[rate].valid_single_stream &&
|
||||
!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG));
|
||||
!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG))
|
||||
return rate;
|
||||
|
||||
/* This should not happen */
|
||||
|
@@ -1157,8 +1157,9 @@ struct b43_dmaring *parse_cookie(struct b43_wldev *dev, u16 cookie, int *slot)
|
||||
}
|
||||
|
||||
static int dma_tx_fragment(struct b43_dmaring *ring,
|
||||
struct sk_buff *skb)
|
||||
struct sk_buff **in_skb)
|
||||
{
|
||||
struct sk_buff *skb = *in_skb;
|
||||
const struct b43_dma_ops *ops = ring->ops;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
u8 *header;
|
||||
@@ -1224,8 +1225,14 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
|
||||
}
|
||||
|
||||
memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len);
|
||||
memcpy(bounce_skb->cb, skb->cb, sizeof(skb->cb));
|
||||
bounce_skb->dev = skb->dev;
|
||||
skb_set_queue_mapping(bounce_skb, skb_get_queue_mapping(skb));
|
||||
info = IEEE80211_SKB_CB(bounce_skb);
|
||||
|
||||
dev_kfree_skb_any(skb);
|
||||
skb = bounce_skb;
|
||||
*in_skb = bounce_skb;
|
||||
meta->skb = skb;
|
||||
meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
|
||||
if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) {
|
||||
@@ -1355,7 +1362,11 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
|
||||
* static, so we don't need to store it per frame. */
|
||||
ring->queue_prio = skb_get_queue_mapping(skb);
|
||||
|
||||
err = dma_tx_fragment(ring, skb);
|
||||
/* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing
|
||||
* into the skb data or cb now. */
|
||||
hdr = NULL;
|
||||
info = NULL;
|
||||
err = dma_tx_fragment(ring, &skb);
|
||||
if (unlikely(err == -ENOKEY)) {
|
||||
/* Drop this packet, as we don't have the encryption key
|
||||
* anymore and must not transmit it unencrypted. */
|
||||
|
@@ -6325,8 +6325,10 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
|
||||
|
||||
fail:
|
||||
if (dev) {
|
||||
if (registered)
|
||||
if (registered) {
|
||||
unregister_ieee80211(priv->ieee);
|
||||
unregister_netdev(dev);
|
||||
}
|
||||
|
||||
ipw2100_hw_stop_adapter(priv);
|
||||
|
||||
@@ -6383,6 +6385,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
|
||||
/* Unregister the device first - this results in close()
|
||||
* being called if the device is open. If we free storage
|
||||
* first, then close() will crash. */
|
||||
unregister_ieee80211(priv->ieee);
|
||||
unregister_netdev(dev);
|
||||
|
||||
/* ipw2100_down will ensure that there is no more pending work
|
||||
|
@@ -11822,6 +11822,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
|
||||
if (err) {
|
||||
IPW_ERROR("Failed to register promiscuous network "
|
||||
"device (error %d).\n", err);
|
||||
unregister_ieee80211(priv->ieee);
|
||||
unregister_netdev(priv->net_dev);
|
||||
goto out_remove_sysfs;
|
||||
}
|
||||
@@ -11872,6 +11873,7 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev)
|
||||
|
||||
mutex_unlock(&priv->mutex);
|
||||
|
||||
unregister_ieee80211(priv->ieee);
|
||||
unregister_netdev(priv->net_dev);
|
||||
|
||||
if (priv->rxq) {
|
||||
|
@@ -1020,6 +1020,7 @@ static inline int libipw_is_cck_rate(u8 rate)
|
||||
/* ieee80211.c */
|
||||
extern void free_ieee80211(struct net_device *dev, int monitor);
|
||||
extern struct net_device *alloc_ieee80211(int sizeof_priv, int monitor);
|
||||
extern void unregister_ieee80211(struct libipw_device *ieee);
|
||||
extern int libipw_change_mtu(struct net_device *dev, int new_mtu);
|
||||
|
||||
extern void libipw_networks_age(struct libipw_device *ieee,
|
||||
|
@@ -235,16 +235,19 @@ void free_ieee80211(struct net_device *dev, int monitor)
|
||||
libipw_networks_free(ieee);
|
||||
|
||||
/* free cfg80211 resources */
|
||||
if (!monitor) {
|
||||
wiphy_unregister(ieee->wdev.wiphy);
|
||||
kfree(ieee->a_band.channels);
|
||||
kfree(ieee->bg_band.channels);
|
||||
if (!monitor)
|
||||
wiphy_free(ieee->wdev.wiphy);
|
||||
}
|
||||
|
||||
free_netdev(dev);
|
||||
}
|
||||
|
||||
void unregister_ieee80211(struct libipw_device *ieee)
|
||||
{
|
||||
wiphy_unregister(ieee->wdev.wiphy);
|
||||
kfree(ieee->a_band.channels);
|
||||
kfree(ieee->bg_band.channels);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LIBIPW_DEBUG
|
||||
|
||||
static int debug = 0;
|
||||
@@ -330,3 +333,4 @@ module_init(libipw_init);
|
||||
|
||||
EXPORT_SYMBOL(alloc_ieee80211);
|
||||
EXPORT_SYMBOL(free_ieee80211);
|
||||
EXPORT_SYMBOL(unregister_ieee80211);
|
||||
|
@@ -508,7 +508,7 @@ static int __if_usb_submit_rx_urb(struct if_usb_card *cardp,
|
||||
/* Fill the receive configuration URB and initialise the Rx call back */
|
||||
usb_fill_bulk_urb(cardp->rx_urb, cardp->udev,
|
||||
usb_rcvbulkpipe(cardp->udev, cardp->ep_in),
|
||||
(void *) (skb->tail + (size_t) IPFIELD_ALIGN_OFFSET),
|
||||
skb->data + IPFIELD_ALIGN_OFFSET,
|
||||
MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn,
|
||||
cardp);
|
||||
|
||||
|
@@ -2389,10 +2389,13 @@ static struct usb_device_id rt73usb_device_table[] = {
|
||||
{ USB_DEVICE(0x13b1, 0x0023), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
{ USB_DEVICE(0x13b1, 0x0028), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
/* MSI */
|
||||
{ USB_DEVICE(0x0db0, 0x4600), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
{ USB_DEVICE(0x0db0, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
{ USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
{ USB_DEVICE(0x0db0, 0xa861), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
{ USB_DEVICE(0x0db0, 0xa874), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
/* Ovislink */
|
||||
{ USB_DEVICE(0x1b75, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
/* Ralink */
|
||||
{ USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
{ USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
@@ -2420,6 +2423,8 @@ static struct usb_device_id rt73usb_device_table[] = {
|
||||
/* Planex */
|
||||
{ USB_DEVICE(0x2019, 0xab01), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
{ USB_DEVICE(0x2019, 0xab50), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
/* WideTell */
|
||||
{ USB_DEVICE(0x7167, 0x3840), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
/* Zcom */
|
||||
{ USB_DEVICE(0x0cde, 0x001c), USB_DEVICE_DATA(&rt73usb_ops) },
|
||||
/* ZyXEL */
|
||||
|
Fai riferimento in un nuovo problema
Block a user