forked from Minki/linux
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
This commit is contained in:
commit
9316f0e3c6
@ -227,7 +227,17 @@ int __devinit bcma_bus_register(struct bcma_bus *bus)
|
||||
|
||||
void bcma_bus_unregister(struct bcma_bus *bus)
|
||||
{
|
||||
struct bcma_device *cores[3];
|
||||
|
||||
cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
|
||||
cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE);
|
||||
cores[2] = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON);
|
||||
|
||||
bcma_unregister_cores(bus);
|
||||
|
||||
kfree(cores[2]);
|
||||
kfree(cores[1]);
|
||||
kfree(cores[0]);
|
||||
}
|
||||
|
||||
int __init bcma_bus_early_register(struct bcma_bus *bus,
|
||||
|
@ -86,6 +86,7 @@ static struct usb_device_id ath3k_table[] = {
|
||||
|
||||
/* Atheros AR5BBU22 with sflash firmware */
|
||||
{ USB_DEVICE(0x0489, 0xE03C) },
|
||||
{ USB_DEVICE(0x0489, 0xE036) },
|
||||
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
@ -109,6 +110,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
|
||||
|
||||
/* Atheros AR5BBU22 with sflash firmware */
|
||||
{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 },
|
||||
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
@ -52,6 +52,9 @@ static struct usb_device_id btusb_table[] = {
|
||||
/* Generic Bluetooth USB device */
|
||||
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
|
||||
|
||||
/* Apple-specific (Broadcom) devices */
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01) },
|
||||
|
||||
/* Broadcom SoftSailing reporting vendor specific */
|
||||
{ USB_DEVICE(0x0a5c, 0x21e1) },
|
||||
|
||||
@ -94,16 +97,14 @@ static struct usb_device_id btusb_table[] = {
|
||||
|
||||
/* Broadcom BCM20702A0 */
|
||||
{ USB_DEVICE(0x0489, 0xe042) },
|
||||
{ USB_DEVICE(0x0a5c, 0x21e3) },
|
||||
{ USB_DEVICE(0x0a5c, 0x21e6) },
|
||||
{ USB_DEVICE(0x0a5c, 0x21e8) },
|
||||
{ USB_DEVICE(0x0a5c, 0x21f3) },
|
||||
{ USB_DEVICE(0x0a5c, 0x21f4) },
|
||||
{ USB_DEVICE(0x413c, 0x8197) },
|
||||
|
||||
/* Foxconn - Hon Hai */
|
||||
{ USB_DEVICE(0x0489, 0xe033) },
|
||||
|
||||
/*Broadcom devices with vendor specific id */
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) },
|
||||
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
@ -141,6 +142,7 @@ static struct usb_device_id blacklist_table[] = {
|
||||
|
||||
/* Atheros AR5BBU12 with sflash firmware */
|
||||
{ USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe036), .driver_info = BTUSB_ATH3012 },
|
||||
|
||||
/* Broadcom BCM2035 */
|
||||
{ USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU },
|
||||
|
@ -87,7 +87,6 @@ static struct pci_driver airo_driver = {
|
||||
/* Include Wireless Extension definition and check version - Jean II */
|
||||
#include <linux/wireless.h>
|
||||
#define WIRELESS_SPY /* enable iwspy support */
|
||||
#include <net/iw_handler.h> /* New driver API */
|
||||
|
||||
#define CISCO_EXT /* enable Cisco extensions */
|
||||
#ifdef CISCO_EXT
|
||||
@ -5984,13 +5983,11 @@ static int airo_set_wap(struct net_device *dev,
|
||||
Cmd cmd;
|
||||
Resp rsp;
|
||||
APListRid APList_rid;
|
||||
static const u8 any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
static const u8 off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
if (awrq->sa_family != ARPHRD_ETHER)
|
||||
return -EINVAL;
|
||||
else if (!memcmp(any, awrq->sa_data, ETH_ALEN) ||
|
||||
!memcmp(off, awrq->sa_data, ETH_ALEN)) {
|
||||
else if (is_broadcast_ether_addr(awrq->sa_data) ||
|
||||
is_zero_ether_addr(awrq->sa_data)) {
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.cmd=CMD_LOSE_SYNC;
|
||||
if (down_interruptible(&local->sem))
|
||||
|
@ -498,36 +498,6 @@ exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define HEX2STR_BUFFERS 4
|
||||
#define HEX2STR_MAX_LEN 64
|
||||
|
||||
/* Convert binary data into hex string */
|
||||
static char *hex2str(void *buf, size_t len)
|
||||
{
|
||||
static atomic_t a = ATOMIC_INIT(0);
|
||||
static char bufs[HEX2STR_BUFFERS][3 * HEX2STR_MAX_LEN + 1];
|
||||
char *ret = bufs[atomic_inc_return(&a) & (HEX2STR_BUFFERS - 1)];
|
||||
char *obuf = ret;
|
||||
u8 *ibuf = buf;
|
||||
|
||||
if (len > HEX2STR_MAX_LEN)
|
||||
len = HEX2STR_MAX_LEN;
|
||||
|
||||
if (len == 0)
|
||||
goto exit;
|
||||
|
||||
while (len--) {
|
||||
obuf = hex_byte_pack(obuf, *ibuf++);
|
||||
*obuf++ = '-';
|
||||
}
|
||||
obuf--;
|
||||
|
||||
exit:
|
||||
*obuf = '\0';
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* LED trigger */
|
||||
static int tx_activity;
|
||||
static void at76_ledtrig_tx_timerfunc(unsigned long data);
|
||||
@ -1004,9 +974,9 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv)
|
||||
WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
|
||||
|
||||
for (i = 0; i < WEP_KEYS; i++)
|
||||
at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: key %d: %s",
|
||||
at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: key %d: %*phD",
|
||||
wiphy_name(priv->hw->wiphy), i,
|
||||
hex2str(m->wep_default_keyvalue[i], key_len));
|
||||
key_len, m->wep_default_keyvalue[i]);
|
||||
exit:
|
||||
kfree(m);
|
||||
}
|
||||
@ -1031,7 +1001,7 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
|
||||
at76_dbg(DBG_MIB, "%s: MIB MAC_MGMT: beacon_period %d CFP_max_duration "
|
||||
"%d medium_occupancy_limit %d station_id 0x%x ATIM_window %d "
|
||||
"CFP_mode %d privacy_opt_impl %d DTIM_period %d CFP_period %d "
|
||||
"current_bssid %pM current_essid %s current_bss_type %d "
|
||||
"current_bssid %pM current_essid %*phD current_bss_type %d "
|
||||
"pm_mode %d ibss_change %d res %d "
|
||||
"multi_domain_capability_implemented %d "
|
||||
"international_roaming %d country_string %.3s",
|
||||
@ -1041,7 +1011,7 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
|
||||
le16_to_cpu(m->station_id), le16_to_cpu(m->ATIM_window),
|
||||
m->CFP_mode, m->privacy_option_implemented, m->DTIM_period,
|
||||
m->CFP_period, m->current_bssid,
|
||||
hex2str(m->current_essid, IW_ESSID_MAX_SIZE),
|
||||
IW_ESSID_MAX_SIZE, m->current_essid,
|
||||
m->current_bss_type, m->power_mgmt_mode, m->ibss_change,
|
||||
m->res, m->multi_domain_capability_implemented,
|
||||
m->multi_domain_capability_enabled, m->country_string);
|
||||
@ -1069,7 +1039,7 @@ static void at76_dump_mib_mac(struct at76_priv *priv)
|
||||
"cwmin %d cwmax %d short_retry_time %d long_retry_time %d "
|
||||
"scan_type %d scan_channel %d probe_delay %u "
|
||||
"min_channel_time %d max_channel_time %d listen_int %d "
|
||||
"desired_ssid %s desired_bssid %pM desired_bsstype %d",
|
||||
"desired_ssid %*phD desired_bssid %pM desired_bsstype %d",
|
||||
wiphy_name(priv->hw->wiphy),
|
||||
le32_to_cpu(m->max_tx_msdu_lifetime),
|
||||
le32_to_cpu(m->max_rx_lifetime),
|
||||
@ -1080,7 +1050,7 @@ static void at76_dump_mib_mac(struct at76_priv *priv)
|
||||
le16_to_cpu(m->min_channel_time),
|
||||
le16_to_cpu(m->max_channel_time),
|
||||
le16_to_cpu(m->listen_interval),
|
||||
hex2str(m->desired_ssid, IW_ESSID_MAX_SIZE),
|
||||
IW_ESSID_MAX_SIZE, m->desired_ssid,
|
||||
m->desired_bssid, m->desired_bsstype);
|
||||
exit:
|
||||
kfree(m);
|
||||
@ -1160,13 +1130,13 @@ static void at76_dump_mib_mdomain(struct at76_priv *priv)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s",
|
||||
at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %*phD",
|
||||
wiphy_name(priv->hw->wiphy),
|
||||
hex2str(m->channel_list, sizeof(m->channel_list)));
|
||||
(int)sizeof(m->channel_list), m->channel_list);
|
||||
|
||||
at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: tx_powerlevel %s",
|
||||
at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: tx_powerlevel %*phD",
|
||||
wiphy_name(priv->hw->wiphy),
|
||||
hex2str(m->tx_powerlevel, sizeof(m->tx_powerlevel)));
|
||||
(int)sizeof(m->tx_powerlevel), m->tx_powerlevel);
|
||||
exit:
|
||||
kfree(m);
|
||||
}
|
||||
@ -1369,9 +1339,9 @@ static int at76_startup_device(struct at76_priv *priv)
|
||||
int ret;
|
||||
|
||||
at76_dbg(DBG_PARAMS,
|
||||
"%s param: ssid %.*s (%s) mode %s ch %d wep %s key %d "
|
||||
"%s param: ssid %.*s (%*phD) mode %s ch %d wep %s key %d "
|
||||
"keylen %d", wiphy_name(priv->hw->wiphy), priv->essid_size,
|
||||
priv->essid, hex2str(priv->essid, IW_ESSID_MAX_SIZE),
|
||||
priv->essid, IW_ESSID_MAX_SIZE, priv->essid,
|
||||
priv->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra",
|
||||
priv->channel, priv->wep_enabled ? "enabled" : "disabled",
|
||||
priv->wep_key_id, priv->wep_keys_len[priv->wep_key_id]);
|
||||
|
@ -237,7 +237,7 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel,
|
||||
entry_cck->fir_step_level);
|
||||
|
||||
/* Skip MRC CCK for pre AR9003 families */
|
||||
if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9485(ah))
|
||||
if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah))
|
||||
return;
|
||||
|
||||
if (aniState->mrcCCK != entry_cck->mrc_cck_on)
|
||||
|
@ -138,7 +138,8 @@ static const struct ar9300_eeprom ar9300_default = {
|
||||
},
|
||||
.base_ext1 = {
|
||||
.ant_div_control = 0,
|
||||
.future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
.future = {0, 0, 0},
|
||||
.tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
|
||||
},
|
||||
.calFreqPier2G = {
|
||||
FREQ2FBIN(2412, 1),
|
||||
@ -713,7 +714,8 @@ static const struct ar9300_eeprom ar9300_x113 = {
|
||||
},
|
||||
.base_ext1 = {
|
||||
.ant_div_control = 0,
|
||||
.future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
.future = {0, 0, 0},
|
||||
.tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
|
||||
},
|
||||
.calFreqPier2G = {
|
||||
FREQ2FBIN(2412, 1),
|
||||
@ -1289,7 +1291,8 @@ static const struct ar9300_eeprom ar9300_h112 = {
|
||||
},
|
||||
.base_ext1 = {
|
||||
.ant_div_control = 0,
|
||||
.future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
.future = {0, 0, 0},
|
||||
.tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
|
||||
},
|
||||
.calFreqPier2G = {
|
||||
FREQ2FBIN(2412, 1),
|
||||
@ -1865,7 +1868,8 @@ static const struct ar9300_eeprom ar9300_x112 = {
|
||||
},
|
||||
.base_ext1 = {
|
||||
.ant_div_control = 0,
|
||||
.future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
.future = {0, 0, 0},
|
||||
.tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
|
||||
},
|
||||
.calFreqPier2G = {
|
||||
FREQ2FBIN(2412, 1),
|
||||
@ -2440,7 +2444,8 @@ static const struct ar9300_eeprom ar9300_h116 = {
|
||||
},
|
||||
.base_ext1 = {
|
||||
.ant_div_control = 0,
|
||||
.future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
.future = {0, 0, 0},
|
||||
.tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0}
|
||||
},
|
||||
.calFreqPier2G = {
|
||||
FREQ2FBIN(2412, 1),
|
||||
@ -3520,7 +3525,7 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
|
||||
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
|
||||
REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
|
||||
else if (AR_SREV_9462(ah) || AR_SREV_9550(ah))
|
||||
else if (AR_SREV_9462(ah) || AR_SREV_9550(ah) || AR_SREV_9565(ah))
|
||||
REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
|
||||
else {
|
||||
REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
|
||||
@ -3568,7 +3573,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
|
||||
|
||||
u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
|
||||
|
||||
if (AR_SREV_9462(ah)) {
|
||||
if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
|
||||
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
|
||||
AR_SWITCH_TABLE_COM_AR9462_ALL, value);
|
||||
} else if (AR_SREV_9550(ah)) {
|
||||
@ -3612,7 +3617,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
|
||||
}
|
||||
}
|
||||
|
||||
if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
|
||||
if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
|
||||
value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
|
||||
/*
|
||||
* main_lnaconf, alt_lnaconf, main_tb, alt_tb
|
||||
@ -3622,19 +3627,16 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
|
||||
regval &= (~AR_ANT_DIV_CTRL_ALL);
|
||||
regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
|
||||
/* enable_lnadiv */
|
||||
regval &= (~AR_PHY_9485_ANT_DIV_LNADIV);
|
||||
regval |= ((value >> 6) & 0x1) <<
|
||||
AR_PHY_9485_ANT_DIV_LNADIV_S;
|
||||
regval &= (~AR_PHY_ANT_DIV_LNADIV);
|
||||
regval |= ((value >> 6) & 0x1) << AR_PHY_ANT_DIV_LNADIV_S;
|
||||
REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
|
||||
|
||||
/*enable fast_div */
|
||||
regval = REG_READ(ah, AR_PHY_CCK_DETECT);
|
||||
regval &= (~AR_FAST_DIV_ENABLE);
|
||||
regval |= ((value >> 7) & 0x1) <<
|
||||
AR_FAST_DIV_ENABLE_S;
|
||||
regval |= ((value >> 7) & 0x1) << AR_FAST_DIV_ENABLE_S;
|
||||
REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
|
||||
ant_div_ctl1 =
|
||||
ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
|
||||
ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
|
||||
/* check whether antenna diversity is enabled */
|
||||
if ((ant_div_ctl1 >> 0x6) == 0x3) {
|
||||
regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
|
||||
@ -3642,15 +3644,15 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
|
||||
* clear bits 25-30 main_lnaconf, alt_lnaconf,
|
||||
* main_tb, alt_tb
|
||||
*/
|
||||
regval &= (~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF |
|
||||
AR_PHY_9485_ANT_DIV_ALT_LNACONF |
|
||||
AR_PHY_9485_ANT_DIV_ALT_GAINTB |
|
||||
AR_PHY_9485_ANT_DIV_MAIN_GAINTB));
|
||||
regval &= (~(AR_PHY_ANT_DIV_MAIN_LNACONF |
|
||||
AR_PHY_ANT_DIV_ALT_LNACONF |
|
||||
AR_PHY_ANT_DIV_ALT_GAINTB |
|
||||
AR_PHY_ANT_DIV_MAIN_GAINTB));
|
||||
/* by default use LNA1 for the main antenna */
|
||||
regval |= (AR_PHY_9485_ANT_DIV_LNA1 <<
|
||||
AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S);
|
||||
regval |= (AR_PHY_9485_ANT_DIV_LNA2 <<
|
||||
AR_PHY_9485_ANT_DIV_ALT_LNACONF_S);
|
||||
regval |= (AR_PHY_ANT_DIV_LNA1 <<
|
||||
AR_PHY_ANT_DIV_MAIN_LNACONF_S);
|
||||
regval |= (AR_PHY_ANT_DIV_LNA2 <<
|
||||
AR_PHY_ANT_DIV_ALT_LNACONF_S);
|
||||
REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
|
||||
}
|
||||
|
||||
@ -3843,7 +3845,7 @@ void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
|
||||
REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
|
||||
if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
|
||||
return;
|
||||
} else if (AR_SREV_9462(ah)) {
|
||||
} else if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
|
||||
reg_val = le32_to_cpu(pBase->swreg);
|
||||
REG_WRITE(ah, AR_PHY_PMU1, reg_val);
|
||||
} else {
|
||||
@ -3874,7 +3876,7 @@ void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
|
||||
while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
|
||||
AR_PHY_PMU2_PGM))
|
||||
udelay(10);
|
||||
} else if (AR_SREV_9462(ah))
|
||||
} else if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
|
||||
REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
|
||||
else {
|
||||
reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) |
|
||||
@ -3977,6 +3979,62 @@ static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz)
|
||||
bias & 0x3);
|
||||
}
|
||||
|
||||
static int ar9003_hw_get_thermometer(struct ath_hw *ah)
|
||||
{
|
||||
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
|
||||
struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
|
||||
int thermometer = (pBase->miscConfiguration >> 1) & 0x3;
|
||||
|
||||
return --thermometer;
|
||||
}
|
||||
|
||||
static void ar9003_hw_thermometer_apply(struct ath_hw *ah)
|
||||
{
|
||||
int thermometer = ar9003_hw_get_thermometer(ah);
|
||||
u8 therm_on = (thermometer < 0) ? 0 : 1;
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
|
||||
AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
|
||||
if (ah->caps.tx_chainmask & BIT(1))
|
||||
REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
|
||||
AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
|
||||
if (ah->caps.tx_chainmask & BIT(2))
|
||||
REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
|
||||
AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on);
|
||||
|
||||
therm_on = (thermometer < 0) ? 0 : (thermometer == 0);
|
||||
REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4,
|
||||
AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
|
||||
if (ah->caps.tx_chainmask & BIT(1)) {
|
||||
therm_on = (thermometer < 0) ? 0 : (thermometer == 1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4,
|
||||
AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
|
||||
}
|
||||
if (ah->caps.tx_chainmask & BIT(2)) {
|
||||
therm_on = (thermometer < 0) ? 0 : (thermometer == 2);
|
||||
REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4,
|
||||
AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on);
|
||||
}
|
||||
}
|
||||
|
||||
static void ar9003_hw_thermo_cal_apply(struct ath_hw *ah)
|
||||
{
|
||||
u32 data, ko, kg;
|
||||
|
||||
if (!AR_SREV_9462_20(ah))
|
||||
return;
|
||||
ar9300_otp_read_word(ah, 1, &data);
|
||||
ko = data & 0xff;
|
||||
kg = (data >> 8) & 0xff;
|
||||
if (ko || kg) {
|
||||
REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
|
||||
AR_PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET, ko);
|
||||
REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3,
|
||||
AR_PHY_BB_THERM_ADC_3_THERM_ADC_SCALE_GAIN,
|
||||
kg + 256);
|
||||
}
|
||||
}
|
||||
|
||||
static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
@ -3992,6 +4050,8 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
|
||||
ar9003_hw_internal_regulator_apply(ah);
|
||||
ar9003_hw_apply_tuning_caps(ah);
|
||||
ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz);
|
||||
ar9003_hw_thermometer_apply(ah);
|
||||
ar9003_hw_thermo_cal_apply(ah);
|
||||
}
|
||||
|
||||
static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
|
||||
@ -4528,7 +4588,7 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah,
|
||||
{
|
||||
int tempSlope = 0;
|
||||
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
|
||||
int f[3], t[3];
|
||||
int f[8], t[8], i;
|
||||
|
||||
REG_RMW(ah, AR_PHY_TPC_11_B0,
|
||||
(correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
|
||||
@ -4561,7 +4621,14 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah,
|
||||
*/
|
||||
if (frequency < 4000)
|
||||
tempSlope = eep->modalHeader2G.tempSlope;
|
||||
else if (eep->base_ext2.tempSlopeLow != 0) {
|
||||
else if ((eep->baseEepHeader.miscConfiguration & 0x20) != 0) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
t[i] = eep->base_ext1.tempslopextension[i];
|
||||
f[i] = FBIN2FREQ(eep->calFreqPier5G[i], 0);
|
||||
}
|
||||
tempSlope = ar9003_hw_power_interpolate((s32) frequency,
|
||||
f, t, 8);
|
||||
} else if (eep->base_ext2.tempSlopeLow != 0) {
|
||||
t[0] = eep->base_ext2.tempSlopeLow;
|
||||
f[0] = 5180;
|
||||
t[1] = eep->modalHeader5G.tempSlope;
|
||||
|
@ -267,7 +267,8 @@ struct cal_ctl_data_5g {
|
||||
|
||||
struct ar9300_BaseExtension_1 {
|
||||
u8 ant_div_control;
|
||||
u8 future[11];
|
||||
u8 future[3];
|
||||
u8 tempslopextension[8];
|
||||
int8_t quick_drop_low;
|
||||
int8_t quick_drop_high;
|
||||
} __packed;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "ar955x_1p0_initvals.h"
|
||||
#include "ar9580_1p0_initvals.h"
|
||||
#include "ar9462_2p0_initvals.h"
|
||||
#include "ar9565_1p0_initvals.h"
|
||||
|
||||
/* General hardware code for the AR9003 hadware family */
|
||||
|
||||
@ -34,14 +35,12 @@
|
||||
*/
|
||||
static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
{
|
||||
#define PCIE_PLL_ON_CREQ_DIS_L1_2P0 \
|
||||
ar9462_pciephy_pll_on_clkreq_disable_L1_2p0
|
||||
|
||||
#define AR9462_BB_CTX_COEFJ(x) \
|
||||
ar9462_##x##_baseband_core_txfir_coeff_japan_2484
|
||||
|
||||
#define AR9462_BBC_TXIFR_COEFFJ \
|
||||
ar9462_2p0_baseband_core_txfir_coeff_japan_2484
|
||||
|
||||
if (AR_SREV_9330_11(ah)) {
|
||||
/* mac */
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
|
||||
@ -220,10 +219,10 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
|
||||
/* Awake -> Sleep Setting */
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
PCIE_PLL_ON_CREQ_DIS_L1_2P0);
|
||||
ar9462_pciephy_pll_on_clkreq_disable_L1_2p0);
|
||||
/* Sleep -> Awake Setting */
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
|
||||
PCIE_PLL_ON_CREQ_DIS_L1_2P0);
|
||||
ar9462_pciephy_pll_on_clkreq_disable_L1_2p0);
|
||||
|
||||
/* Fast clock modal settings */
|
||||
INIT_INI_ARRAY(&ah->iniModesFastClock,
|
||||
@ -302,6 +301,39 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesFastClock,
|
||||
ar9580_1p0_modes_fast_clock);
|
||||
} else if (AR_SREV_9565(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
|
||||
ar9565_1p0_mac_core);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
|
||||
ar9565_1p0_mac_postamble);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
|
||||
ar9565_1p0_baseband_core);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
|
||||
ar9565_1p0_baseband_postamble);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
|
||||
ar9565_1p0_radio_core);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
|
||||
ar9565_1p0_radio_postamble);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
|
||||
ar9565_1p0_soc_preamble);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
|
||||
ar9565_1p0_soc_postamble);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9565_1p0_Common_rx_gain_table);
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9565_1p0_Modes_lowest_ob_db_tx_gain_table);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
ar9565_1p0_pciephy_pll_on_clkreq_disable_L1);
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
|
||||
ar9565_1p0_pciephy_pll_on_clkreq_disable_L1);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesFastClock,
|
||||
ar9565_1p0_modes_fast_clock);
|
||||
} else {
|
||||
/* mac */
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
|
||||
@ -374,6 +406,9 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah)
|
||||
else if (AR_SREV_9462_20(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9462_modes_low_ob_db_tx_gain_table_2p0);
|
||||
else if (AR_SREV_9565(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9565_1p0_modes_low_ob_db_tx_gain_table);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9300Modes_lowest_ob_db_tx_gain_table_2p2);
|
||||
@ -402,6 +437,9 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah)
|
||||
else if (AR_SREV_9462_20(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9462_modes_high_ob_db_tx_gain_table_2p0);
|
||||
else if (AR_SREV_9565(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9565_1p0_modes_high_ob_db_tx_gain_table);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9300Modes_high_ob_db_tx_gain_table_2p2);
|
||||
@ -424,6 +462,9 @@ static void ar9003_tx_gain_table_mode2(struct ath_hw *ah)
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9580_1p0_low_ob_db_tx_gain_table);
|
||||
else if (AR_SREV_9565(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9565_1p0_modes_low_ob_db_tx_gain_table);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9300Modes_low_ob_db_tx_gain_table_2p2);
|
||||
@ -446,6 +487,9 @@ static void ar9003_tx_gain_table_mode3(struct ath_hw *ah)
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9580_1p0_high_power_tx_gain_table);
|
||||
else if (AR_SREV_9565(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9565_1p0_modes_high_power_tx_gain_table);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9300Modes_high_power_tx_gain_table_2p2);
|
||||
@ -538,6 +582,9 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
|
||||
} else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9580_1p0_wo_xlna_rx_gain_table);
|
||||
else if (AR_SREV_9565(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9565_1p0_common_wo_xlna_rx_gain_table);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9300Common_wo_xlna_rx_gain_table_2p2);
|
||||
|
@ -31,7 +31,7 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
|
||||
u32 val, ctl12, ctl17;
|
||||
u8 desc_len;
|
||||
|
||||
desc_len = (AR_SREV_9462(ah) ? 0x18 : 0x17);
|
||||
desc_len = ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x18 : 0x17);
|
||||
|
||||
val = (ATHEROS_VENDOR_ID << AR_DescId_S) |
|
||||
(1 << AR_TxRxDesc_S) |
|
||||
@ -531,7 +531,7 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
|
||||
rxs->rs_status |= ATH9K_RXERR_PHY;
|
||||
rxs->rs_phyerr = phyerr;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (rxsp->status11 & AR_KeyMiss)
|
||||
|
@ -714,6 +714,7 @@ bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL(ar9003_mci_start_reset);
|
||||
|
||||
int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
struct ath9k_hw_cal_data *caldata)
|
||||
@ -1201,12 +1202,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type)
|
||||
|
||||
ar9003_mci_2g5g_switch(ah, false);
|
||||
break;
|
||||
case MCI_STATE_SET_BT_CAL_START:
|
||||
mci->bt_state = MCI_BT_CAL_START;
|
||||
break;
|
||||
case MCI_STATE_SET_BT_CAL:
|
||||
mci->bt_state = MCI_BT_CAL;
|
||||
break;
|
||||
case MCI_STATE_RESET_REQ_WAKE:
|
||||
ar9003_mci_reset_req_wakeup(ah);
|
||||
mci->update_2g5g = true;
|
||||
@ -1327,6 +1322,10 @@ u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more)
|
||||
|
||||
if (first) {
|
||||
gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
|
||||
|
||||
if (gpm_ptr >= mci->gpm_len)
|
||||
gpm_ptr = 0;
|
||||
|
||||
mci->gpm_idx = gpm_ptr;
|
||||
return gpm_ptr;
|
||||
}
|
||||
@ -1371,6 +1370,10 @@ u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more)
|
||||
more_gpm = MCI_GPM_NOMORE;
|
||||
|
||||
temp_index = mci->gpm_idx;
|
||||
|
||||
if (temp_index >= mci->gpm_len)
|
||||
temp_index = 0;
|
||||
|
||||
mci->gpm_idx++;
|
||||
|
||||
if (mci->gpm_idx >= mci->gpm_len)
|
||||
|
@ -190,8 +190,6 @@ enum mci_bt_state {
|
||||
enum mci_state_type {
|
||||
MCI_STATE_ENABLE,
|
||||
MCI_STATE_SET_BT_AWAKE,
|
||||
MCI_STATE_SET_BT_CAL_START,
|
||||
MCI_STATE_SET_BT_CAL,
|
||||
MCI_STATE_LAST_SCHD_MSG_OFFSET,
|
||||
MCI_STATE_REMOTE_SLEEP,
|
||||
MCI_STATE_RESET_REQ_WAKE,
|
||||
|
@ -142,6 +142,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
|
||||
};
|
||||
int training_power;
|
||||
int i, val;
|
||||
u32 am2pm_mask = ah->paprd_ratemask;
|
||||
|
||||
if (IS_CHAN_2GHZ(ah->curchan))
|
||||
training_power = ar9003_get_training_power_2g(ah);
|
||||
@ -158,10 +159,13 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
|
||||
}
|
||||
ah->paprd_training_power = training_power;
|
||||
|
||||
if (AR_SREV_9330(ah))
|
||||
am2pm_mask = 0;
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK,
|
||||
ah->paprd_ratemask);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK,
|
||||
ah->paprd_ratemask);
|
||||
am2pm_mask);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK,
|
||||
ah->paprd_ratemask_ht40);
|
||||
|
||||
@ -782,6 +786,102 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)
|
||||
}
|
||||
EXPORT_SYMBOL(ar9003_paprd_setup_gain_table);
|
||||
|
||||
static bool ar9003_paprd_retrain_pa_in(struct ath_hw *ah,
|
||||
struct ath9k_hw_cal_data *caldata,
|
||||
int chain)
|
||||
{
|
||||
u32 *pa_in = caldata->pa_table[chain];
|
||||
int capdiv_offset, quick_drop_offset;
|
||||
int capdiv2g, quick_drop;
|
||||
int count = 0;
|
||||
int i;
|
||||
|
||||
if (!AR_SREV_9485(ah) && !AR_SREV_9330(ah))
|
||||
return false;
|
||||
|
||||
capdiv2g = REG_READ_FIELD(ah, AR_PHY_65NM_CH0_TXRF3,
|
||||
AR_PHY_65NM_CH0_TXRF3_CAPDIV2G);
|
||||
|
||||
quick_drop = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
|
||||
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP);
|
||||
|
||||
if (quick_drop)
|
||||
quick_drop -= 0x40;
|
||||
|
||||
for (i = 0; i < NUM_BIN + 1; i++) {
|
||||
if (pa_in[i] == 1400)
|
||||
count++;
|
||||
}
|
||||
|
||||
if (AR_SREV_9485(ah)) {
|
||||
if (pa_in[23] < 800) {
|
||||
capdiv_offset = (int)((1000 - pa_in[23] + 75) / 150);
|
||||
capdiv2g += capdiv_offset;
|
||||
if (capdiv2g > 7) {
|
||||
capdiv2g = 7;
|
||||
if (pa_in[23] < 600) {
|
||||
quick_drop++;
|
||||
if (quick_drop > 0)
|
||||
quick_drop = 0;
|
||||
}
|
||||
}
|
||||
} else if (pa_in[23] == 1400) {
|
||||
quick_drop_offset = min_t(int, count / 3, 2);
|
||||
quick_drop += quick_drop_offset;
|
||||
capdiv2g += quick_drop_offset / 2;
|
||||
|
||||
if (capdiv2g > 7)
|
||||
capdiv2g = 7;
|
||||
|
||||
if (quick_drop > 0) {
|
||||
quick_drop = 0;
|
||||
capdiv2g -= quick_drop_offset;
|
||||
if (capdiv2g < 0)
|
||||
capdiv2g = 0;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else if (AR_SREV_9330(ah)) {
|
||||
if (pa_in[23] < 1000) {
|
||||
capdiv_offset = (1000 - pa_in[23]) / 100;
|
||||
capdiv2g += capdiv_offset;
|
||||
if (capdiv_offset > 3) {
|
||||
capdiv_offset = 1;
|
||||
quick_drop--;
|
||||
}
|
||||
|
||||
capdiv2g += capdiv_offset;
|
||||
if (capdiv2g > 6)
|
||||
capdiv2g = 6;
|
||||
if (quick_drop < -4)
|
||||
quick_drop = -4;
|
||||
} else if (pa_in[23] == 1400) {
|
||||
if (count > 3) {
|
||||
quick_drop++;
|
||||
capdiv2g -= count / 4;
|
||||
if (quick_drop > -2)
|
||||
quick_drop = -2;
|
||||
} else {
|
||||
capdiv2g--;
|
||||
}
|
||||
|
||||
if (capdiv2g < 0)
|
||||
capdiv2g = 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_TXRF3,
|
||||
AR_PHY_65NM_CH0_TXRF3_CAPDIV2G, capdiv2g);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
|
||||
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
|
||||
quick_drop);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int ar9003_paprd_create_curve(struct ath_hw *ah,
|
||||
struct ath9k_hw_cal_data *caldata, int chain)
|
||||
{
|
||||
@ -817,6 +917,9 @@ int ar9003_paprd_create_curve(struct ath_hw *ah,
|
||||
if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain))
|
||||
status = -2;
|
||||
|
||||
if (ar9003_paprd_retrain_pa_in(ah, caldata, chain))
|
||||
status = -EINPROGRESS;
|
||||
|
||||
REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
|
||||
AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
|
||||
|
||||
|
@ -88,7 +88,7 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
channelSel = (freq * 4) / div;
|
||||
chan_frac = (((freq * 4) % div) * 0x20000) / div;
|
||||
channelSel = (channelSel << 17) | chan_frac;
|
||||
} else if (AR_SREV_9485(ah)) {
|
||||
} else if (AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
|
||||
u32 chan_frac;
|
||||
|
||||
/*
|
||||
@ -206,6 +206,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
|
||||
for (i = 0; i < max_spur_cnts; i++) {
|
||||
if (AR_SREV_9462(ah) && (i == 0 || i == 3))
|
||||
continue;
|
||||
|
||||
negative = 0;
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah) ||
|
||||
AR_SREV_9550(ah))
|
||||
@ -301,7 +302,9 @@ static void ar9003_hw_spur_ofdm(struct ath_hw *ah,
|
||||
int freq_offset,
|
||||
int spur_freq_sd,
|
||||
int spur_delta_phase,
|
||||
int spur_subchannel_sd)
|
||||
int spur_subchannel_sd,
|
||||
int range,
|
||||
int synth_freq)
|
||||
{
|
||||
int mask_index = 0;
|
||||
|
||||
@ -316,8 +319,11 @@ static void ar9003_hw_spur_ofdm(struct ath_hw *ah,
|
||||
AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, spur_subchannel_sd);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING11,
|
||||
AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0x1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING11,
|
||||
AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0x1);
|
||||
|
||||
if (!(AR_SREV_9565(ah) && range == 10 && synth_freq == 2437))
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING11,
|
||||
AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0x1);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_TIMING4,
|
||||
AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0x1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
|
||||
@ -358,9 +364,44 @@ static void ar9003_hw_spur_ofdm(struct ath_hw *ah,
|
||||
AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0xff);
|
||||
}
|
||||
|
||||
static void ar9003_hw_spur_ofdm_9565(struct ath_hw *ah,
|
||||
int freq_offset)
|
||||
{
|
||||
int mask_index = 0;
|
||||
|
||||
mask_index = (freq_offset << 4) / 5;
|
||||
if (mask_index < 0)
|
||||
mask_index = mask_index - 1;
|
||||
|
||||
mask_index = mask_index & 0x7f;
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
|
||||
AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_B,
|
||||
mask_index);
|
||||
|
||||
/* A == B */
|
||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_B,
|
||||
AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A,
|
||||
mask_index);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
|
||||
AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_B,
|
||||
mask_index);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
|
||||
AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_B, 0xe);
|
||||
REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
|
||||
AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_B, 0xe);
|
||||
|
||||
/* A == B */
|
||||
REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_B,
|
||||
AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0xa0);
|
||||
}
|
||||
|
||||
static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
int freq_offset)
|
||||
int freq_offset,
|
||||
int range,
|
||||
int synth_freq)
|
||||
{
|
||||
int spur_freq_sd = 0;
|
||||
int spur_subchannel_sd = 0;
|
||||
@ -402,7 +443,8 @@ static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah,
|
||||
freq_offset,
|
||||
spur_freq_sd,
|
||||
spur_delta_phase,
|
||||
spur_subchannel_sd);
|
||||
spur_subchannel_sd,
|
||||
range, synth_freq);
|
||||
}
|
||||
|
||||
/* Spur mitigation for OFDM */
|
||||
@ -447,7 +489,17 @@ static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah,
|
||||
freq_offset = ath9k_hw_fbin2freq(spurChansPtr[i], mode);
|
||||
freq_offset -= synth_freq;
|
||||
if (abs(freq_offset) < range) {
|
||||
ar9003_hw_spur_ofdm_work(ah, chan, freq_offset);
|
||||
ar9003_hw_spur_ofdm_work(ah, chan, freq_offset,
|
||||
range, synth_freq);
|
||||
|
||||
if (AR_SREV_9565(ah) && (i < 4)) {
|
||||
freq_offset = ath9k_hw_fbin2freq(spurChansPtr[i + 1],
|
||||
mode);
|
||||
freq_offset -= synth_freq;
|
||||
if (abs(freq_offset) < range)
|
||||
ar9003_hw_spur_ofdm_9565(ah, freq_offset);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -456,7 +508,8 @@ static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah,
|
||||
static void ar9003_hw_spur_mitigate(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
ar9003_hw_spur_mitigate_mrc_cck(ah, chan);
|
||||
if (!AR_SREV_9565(ah))
|
||||
ar9003_hw_spur_mitigate_mrc_cck(ah, chan);
|
||||
ar9003_hw_spur_mitigate_ofdm(ah, chan);
|
||||
}
|
||||
|
||||
@ -736,7 +789,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
|
||||
if (chan->channel == 2484)
|
||||
ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1);
|
||||
|
||||
if (AR_SREV_9462(ah))
|
||||
if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
|
||||
REG_WRITE(ah, AR_GLB_SWREG_DISCONT_MODE,
|
||||
AR_GLB_SWREG_DISCONT_EN_BT_WLAN);
|
||||
|
||||
@ -746,9 +799,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
|
||||
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
|
||||
ath9k_hw_apply_txpower(ah, chan, false);
|
||||
|
||||
if (AR_SREV_9462(ah)) {
|
||||
if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
|
||||
if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0,
|
||||
AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL))
|
||||
AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL))
|
||||
ah->enabled_cals |= TX_IQ_CAL;
|
||||
else
|
||||
ah->enabled_cals &= ~TX_IQ_CAL;
|
||||
@ -1111,7 +1164,7 @@ static void ar9003_hw_set_nf_limits(struct ath_hw *ah)
|
||||
if (AR_SREV_9330(ah))
|
||||
ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9330_2GHZ;
|
||||
|
||||
if (AR_SREV_9462(ah)) {
|
||||
if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
|
||||
ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9462_2GHZ;
|
||||
ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9462_2GHZ;
|
||||
ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9462_5GHZ;
|
||||
@ -1223,17 +1276,17 @@ static void ar9003_hw_set_radar_conf(struct ath_hw *ah)
|
||||
}
|
||||
|
||||
static void ar9003_hw_antdiv_comb_conf_get(struct ath_hw *ah,
|
||||
struct ath_hw_antcomb_conf *antconf)
|
||||
struct ath_hw_antcomb_conf *antconf)
|
||||
{
|
||||
u32 regval;
|
||||
|
||||
regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
|
||||
antconf->main_lna_conf = (regval & AR_PHY_9485_ANT_DIV_MAIN_LNACONF) >>
|
||||
AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S;
|
||||
antconf->alt_lna_conf = (regval & AR_PHY_9485_ANT_DIV_ALT_LNACONF) >>
|
||||
AR_PHY_9485_ANT_DIV_ALT_LNACONF_S;
|
||||
antconf->fast_div_bias = (regval & AR_PHY_9485_ANT_FAST_DIV_BIAS) >>
|
||||
AR_PHY_9485_ANT_FAST_DIV_BIAS_S;
|
||||
antconf->main_lna_conf = (regval & AR_PHY_ANT_DIV_MAIN_LNACONF) >>
|
||||
AR_PHY_ANT_DIV_MAIN_LNACONF_S;
|
||||
antconf->alt_lna_conf = (regval & AR_PHY_ANT_DIV_ALT_LNACONF) >>
|
||||
AR_PHY_ANT_DIV_ALT_LNACONF_S;
|
||||
antconf->fast_div_bias = (regval & AR_PHY_ANT_FAST_DIV_BIAS) >>
|
||||
AR_PHY_ANT_FAST_DIV_BIAS_S;
|
||||
|
||||
if (AR_SREV_9330_11(ah)) {
|
||||
antconf->lna1_lna2_delta = -9;
|
||||
@ -1253,22 +1306,21 @@ static void ar9003_hw_antdiv_comb_conf_set(struct ath_hw *ah,
|
||||
u32 regval;
|
||||
|
||||
regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
|
||||
regval &= ~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF |
|
||||
AR_PHY_9485_ANT_DIV_ALT_LNACONF |
|
||||
AR_PHY_9485_ANT_FAST_DIV_BIAS |
|
||||
AR_PHY_9485_ANT_DIV_MAIN_GAINTB |
|
||||
AR_PHY_9485_ANT_DIV_ALT_GAINTB);
|
||||
regval |= ((antconf->main_lna_conf <<
|
||||
AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S)
|
||||
& AR_PHY_9485_ANT_DIV_MAIN_LNACONF);
|
||||
regval |= ((antconf->alt_lna_conf << AR_PHY_9485_ANT_DIV_ALT_LNACONF_S)
|
||||
& AR_PHY_9485_ANT_DIV_ALT_LNACONF);
|
||||
regval |= ((antconf->fast_div_bias << AR_PHY_9485_ANT_FAST_DIV_BIAS_S)
|
||||
& AR_PHY_9485_ANT_FAST_DIV_BIAS);
|
||||
regval |= ((antconf->main_gaintb << AR_PHY_9485_ANT_DIV_MAIN_GAINTB_S)
|
||||
& AR_PHY_9485_ANT_DIV_MAIN_GAINTB);
|
||||
regval |= ((antconf->alt_gaintb << AR_PHY_9485_ANT_DIV_ALT_GAINTB_S)
|
||||
& AR_PHY_9485_ANT_DIV_ALT_GAINTB);
|
||||
regval &= ~(AR_PHY_ANT_DIV_MAIN_LNACONF |
|
||||
AR_PHY_ANT_DIV_ALT_LNACONF |
|
||||
AR_PHY_ANT_FAST_DIV_BIAS |
|
||||
AR_PHY_ANT_DIV_MAIN_GAINTB |
|
||||
AR_PHY_ANT_DIV_ALT_GAINTB);
|
||||
regval |= ((antconf->main_lna_conf << AR_PHY_ANT_DIV_MAIN_LNACONF_S)
|
||||
& AR_PHY_ANT_DIV_MAIN_LNACONF);
|
||||
regval |= ((antconf->alt_lna_conf << AR_PHY_ANT_DIV_ALT_LNACONF_S)
|
||||
& AR_PHY_ANT_DIV_ALT_LNACONF);
|
||||
regval |= ((antconf->fast_div_bias << AR_PHY_ANT_FAST_DIV_BIAS_S)
|
||||
& AR_PHY_ANT_FAST_DIV_BIAS);
|
||||
regval |= ((antconf->main_gaintb << AR_PHY_ANT_DIV_MAIN_GAINTB_S)
|
||||
& AR_PHY_ANT_DIV_MAIN_GAINTB);
|
||||
regval |= ((antconf->alt_gaintb << AR_PHY_ANT_DIV_ALT_GAINTB_S)
|
||||
& AR_PHY_ANT_DIV_ALT_GAINTB);
|
||||
|
||||
REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
|
||||
}
|
||||
@ -1312,10 +1364,10 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah,
|
||||
ar9003_hw_prog_ini(ah, &ah->iniMac[ATH_INI_POST], modesIndex);
|
||||
ar9003_hw_prog_ini(ah, &ah->iniBB[ATH_INI_POST], modesIndex);
|
||||
ar9003_hw_prog_ini(ah, &ah->iniRadio[ATH_INI_POST], modesIndex);
|
||||
|
||||
if (AR_SREV_9462_20(ah))
|
||||
ar9003_hw_prog_ini(ah,
|
||||
&ah->ini_radio_post_sys2ant,
|
||||
modesIndex);
|
||||
ar9003_hw_prog_ini(ah, &ah->ini_radio_post_sys2ant,
|
||||
modesIndex);
|
||||
|
||||
REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
|
||||
|
||||
@ -1326,6 +1378,9 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah,
|
||||
if (IS_CHAN_A_FAST_CLOCK(ah, chan))
|
||||
REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex, regWrites);
|
||||
|
||||
if (AR_SREV_9565(ah))
|
||||
REG_WRITE_ARRAY(&ah->iniModesFastClock, 1, regWrites);
|
||||
|
||||
REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites);
|
||||
|
||||
ah->modes_index = modesIndex;
|
||||
|
@ -223,15 +223,24 @@
|
||||
#define AR_PHY_ML_CNTL_2 (AR_MRC_BASE + 0x1c)
|
||||
#define AR_PHY_TST_ADC (AR_MRC_BASE + 0x20)
|
||||
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A 0x00000FE0
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A 0x00000FE0
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_S 5
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A 0x1F
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A_S 0
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A 0x1F
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A_S 0
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_B 0x00FE0000
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_B_S 17
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_B 0x0001F000
|
||||
#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_B_S 12
|
||||
|
||||
#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A 0x00000FE0
|
||||
#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_S 5
|
||||
#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A 0x1F
|
||||
#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A_S 0
|
||||
#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_B 0x00FE0000
|
||||
#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_B_S 17
|
||||
#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_B 0x0001F000
|
||||
#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_B_S 12
|
||||
|
||||
|
||||
/*
|
||||
* MRC Feild Definitions
|
||||
@ -271,23 +280,23 @@
|
||||
#define AR_ANT_DIV_ENABLE_S 24
|
||||
|
||||
|
||||
#define AR_PHY_9485_ANT_FAST_DIV_BIAS 0x00007e00
|
||||
#define AR_PHY_9485_ANT_FAST_DIV_BIAS_S 9
|
||||
#define AR_PHY_9485_ANT_DIV_LNADIV 0x01000000
|
||||
#define AR_PHY_9485_ANT_DIV_LNADIV_S 24
|
||||
#define AR_PHY_9485_ANT_DIV_ALT_LNACONF 0x06000000
|
||||
#define AR_PHY_9485_ANT_DIV_ALT_LNACONF_S 25
|
||||
#define AR_PHY_9485_ANT_DIV_MAIN_LNACONF 0x18000000
|
||||
#define AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S 27
|
||||
#define AR_PHY_9485_ANT_DIV_ALT_GAINTB 0x20000000
|
||||
#define AR_PHY_9485_ANT_DIV_ALT_GAINTB_S 29
|
||||
#define AR_PHY_9485_ANT_DIV_MAIN_GAINTB 0x40000000
|
||||
#define AR_PHY_9485_ANT_DIV_MAIN_GAINTB_S 30
|
||||
#define AR_PHY_ANT_FAST_DIV_BIAS 0x00007e00
|
||||
#define AR_PHY_ANT_FAST_DIV_BIAS_S 9
|
||||
#define AR_PHY_ANT_DIV_LNADIV 0x01000000
|
||||
#define AR_PHY_ANT_DIV_LNADIV_S 24
|
||||
#define AR_PHY_ANT_DIV_ALT_LNACONF 0x06000000
|
||||
#define AR_PHY_ANT_DIV_ALT_LNACONF_S 25
|
||||
#define AR_PHY_ANT_DIV_MAIN_LNACONF 0x18000000
|
||||
#define AR_PHY_ANT_DIV_MAIN_LNACONF_S 27
|
||||
#define AR_PHY_ANT_DIV_ALT_GAINTB 0x20000000
|
||||
#define AR_PHY_ANT_DIV_ALT_GAINTB_S 29
|
||||
#define AR_PHY_ANT_DIV_MAIN_GAINTB 0x40000000
|
||||
#define AR_PHY_ANT_DIV_MAIN_GAINTB_S 30
|
||||
|
||||
#define AR_PHY_9485_ANT_DIV_LNA1_MINUS_LNA2 0x0
|
||||
#define AR_PHY_9485_ANT_DIV_LNA2 0x1
|
||||
#define AR_PHY_9485_ANT_DIV_LNA1 0x2
|
||||
#define AR_PHY_9485_ANT_DIV_LNA1_PLUS_LNA2 0x3
|
||||
#define AR_PHY_ANT_DIV_LNA1_MINUS_LNA2 0x0
|
||||
#define AR_PHY_ANT_DIV_LNA2 0x1
|
||||
#define AR_PHY_ANT_DIV_LNA1 0x2
|
||||
#define AR_PHY_ANT_DIV_LNA1_PLUS_LNA2 0x3
|
||||
|
||||
#define AR_PHY_EXTCHN_PWRTHR1 (AR_AGC_BASE + 0x2c)
|
||||
#define AR_PHY_EXT_CHN_WIN (AR_AGC_BASE + 0x30)
|
||||
@ -609,6 +618,12 @@
|
||||
#define AR_PHY_BB_THERM_ADC_1_INIT_THERM 0x000000ff
|
||||
#define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S 0
|
||||
|
||||
#define AR_PHY_BB_THERM_ADC_3 (AR_SM_BASE + 0x250)
|
||||
#define AR_PHY_BB_THERM_ADC_3_THERM_ADC_SCALE_GAIN 0x0001ff00
|
||||
#define AR_PHY_BB_THERM_ADC_3_THERM_ADC_SCALE_GAIN_S 8
|
||||
#define AR_PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET 0x000000ff
|
||||
#define AR_PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET_S 0
|
||||
|
||||
#define AR_PHY_BB_THERM_ADC_4 (AR_SM_BASE + 0x254)
|
||||
#define AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE 0x000000ff
|
||||
#define AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE_S 0
|
||||
@ -625,9 +640,13 @@
|
||||
#define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0)
|
||||
#define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc)
|
||||
|
||||
#define AR_PHY_65NM_CH0_TXRF3 0x16048
|
||||
#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G 0x0000001e
|
||||
#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G_S 1
|
||||
|
||||
#define AR_PHY_65NM_CH0_SYNTH4 0x1608c
|
||||
#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002)
|
||||
#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1)
|
||||
#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x00000001 : 0x00000002)
|
||||
#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0 : 1)
|
||||
#define AR_PHY_65NM_CH0_SYNTH7 0x16098
|
||||
#define AR_PHY_65NM_CH0_BIAS1 0x160c0
|
||||
#define AR_PHY_65NM_CH0_BIAS2 0x160c4
|
||||
@ -637,7 +656,7 @@
|
||||
#define AR_PHY_65NM_CH2_RXTX4 0x1690c
|
||||
|
||||
#define AR_CH0_TOP (AR_SREV_9300(ah) ? 0x16288 : \
|
||||
((AR_SREV_9462(ah) ? 0x1628c : 0x16280)))
|
||||
(((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x1628c : 0x16280)))
|
||||
#define AR_CH0_TOP_XPABIASLVL (AR_SREV_9550(ah) ? 0x3c0 : 0x300)
|
||||
#define AR_CH0_TOP_XPABIASLVL_S (AR_SREV_9550(ah) ? 6 : 8)
|
||||
|
||||
@ -665,7 +684,7 @@
|
||||
#define AR_SWITCH_TABLE_ALL_S (0)
|
||||
|
||||
#define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 :\
|
||||
(AR_SREV_9462(ah) ? 0x16294 : 0x1628c))
|
||||
((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16294 : 0x1628c))
|
||||
|
||||
#define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000
|
||||
#define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
|
||||
@ -687,17 +706,17 @@
|
||||
#define AR_CH0_TOP2_XPABIASLVL_S 12
|
||||
|
||||
#define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : \
|
||||
(AR_SREV_9462(ah) ? 0x16298 : 0x16290))
|
||||
((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16298 : 0x16290))
|
||||
#define AR_CH0_XTAL_CAPINDAC 0x7f000000
|
||||
#define AR_CH0_XTAL_CAPINDAC_S 24
|
||||
#define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000
|
||||
#define AR_CH0_XTAL_CAPOUTDAC_S 17
|
||||
|
||||
#define AR_PHY_PMU1 (AR_SREV_9462(ah) ? 0x16340 : 0x16c40)
|
||||
#define AR_PHY_PMU1 ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16340 : 0x16c40)
|
||||
#define AR_PHY_PMU1_PWD 0x1
|
||||
#define AR_PHY_PMU1_PWD_S 0
|
||||
|
||||
#define AR_PHY_PMU2 (AR_SREV_9462(ah) ? 0x16344 : 0x16c44)
|
||||
#define AR_PHY_PMU2 ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16344 : 0x16c44)
|
||||
#define AR_PHY_PMU2_PGM 0x00200000
|
||||
#define AR_PHY_PMU2_PGM_S 21
|
||||
|
||||
@ -877,6 +896,8 @@
|
||||
|
||||
#define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000
|
||||
#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28
|
||||
#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR 0x20000000
|
||||
#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR_S 29
|
||||
|
||||
#define AR_PHY_65NM_RXTX4_XLNA_BIAS 0xC0000000
|
||||
#define AR_PHY_65NM_RXTX4_XLNA_BIAS_S 30
|
||||
|
@ -58,7 +58,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = {
|
||||
{0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
|
||||
{0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
|
||||
{0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
|
||||
{0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
|
||||
{0x00009e3c, 0xcf946222, 0xcf946222, 0xcfd5c782, 0xcfd5c282},
|
||||
{0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27},
|
||||
{0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
|
||||
{0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
|
||||
|
1233
drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h
Normal file
1233
drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -423,7 +423,6 @@ void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif);
|
||||
void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif);
|
||||
void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif);
|
||||
void ath9k_set_beacon(struct ath_softc *sc);
|
||||
void ath9k_set_beaconing_status(struct ath_softc *sc, bool status);
|
||||
|
||||
/*******************/
|
||||
/* Link Monitoring */
|
||||
@ -473,7 +472,7 @@ struct ath_btcoex {
|
||||
unsigned long op_flags;
|
||||
int bt_stomp_type; /* Types of BT stomping */
|
||||
u32 btcoex_no_stomp; /* in usec */
|
||||
u32 btcoex_period; /* in usec */
|
||||
u32 btcoex_period; /* in msec */
|
||||
u32 btscan_no_stomp; /* in usec */
|
||||
u32 duty_cycle;
|
||||
u32 bt_wait_time;
|
||||
|
@ -373,6 +373,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
|
||||
sc->debug.stats.istats.tsfoor++;
|
||||
if (status & ATH9K_INT_MCI)
|
||||
sc->debug.stats.istats.mci++;
|
||||
if (status & ATH9K_INT_GENTIMER)
|
||||
sc->debug.stats.istats.gen_timer++;
|
||||
}
|
||||
|
||||
static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
|
||||
@ -418,6 +420,7 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
|
||||
PR_IS("DTIM", dtim);
|
||||
PR_IS("TSFOOR", tsfoor);
|
||||
PR_IS("MCI", mci);
|
||||
PR_IS("GENTIMER", gen_timer);
|
||||
PR_IS("TOTAL", total);
|
||||
|
||||
len += snprintf(buf + len, mxlen - len,
|
||||
|
@ -41,7 +41,6 @@ enum ath_reset_type {
|
||||
RESET_TYPE_PLL_HANG,
|
||||
RESET_TYPE_MAC_HANG,
|
||||
RESET_TYPE_BEACON_STUCK,
|
||||
RESET_TYPE_MCI,
|
||||
__RESET_TYPE_MAX
|
||||
};
|
||||
|
||||
@ -74,6 +73,8 @@ enum ath_reset_type {
|
||||
* from a beacon differs from the PCU's internal TSF by more than a
|
||||
* (programmable) threshold
|
||||
* @local_timeout: Internal bus timeout.
|
||||
* @mci: MCI interrupt, specific to MCI based BTCOEX chipsets
|
||||
* @gen_timer: Generic hardware timer interrupt
|
||||
*/
|
||||
struct ath_interrupt_stats {
|
||||
u32 total;
|
||||
@ -100,6 +101,7 @@ struct ath_interrupt_stats {
|
||||
u32 bb_watchdog;
|
||||
u32 tsfoor;
|
||||
u32 mci;
|
||||
u32 gen_timer;
|
||||
|
||||
/* Sync-cause stats */
|
||||
u32 sync_cause_all;
|
||||
|
@ -96,6 +96,7 @@
|
||||
|
||||
#define ATH9K_POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
|
||||
#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
|
||||
#define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x))
|
||||
#define ath9k_hw_use_flash(_ah) (!(_ah->ah_flags & AH_USE_EEPROM))
|
||||
|
||||
#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
|
||||
@ -108,7 +109,7 @@
|
||||
#define EEP_RFSILENT_ENABLED_S 0
|
||||
#define EEP_RFSILENT_POLARITY 0x0002
|
||||
#define EEP_RFSILENT_POLARITY_S 1
|
||||
#define EEP_RFSILENT_GPIO_SEL (AR_SREV_9462(ah) ? 0x00fc : 0x001c)
|
||||
#define EEP_RFSILENT_GPIO_SEL ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x00fc : 0x001c)
|
||||
#define EEP_RFSILENT_GPIO_SEL_S 2
|
||||
|
||||
#define AR5416_OPFLAGS_11A 0x01
|
||||
|
@ -51,7 +51,7 @@ void ath_init_leds(struct ath_softc *sc)
|
||||
sc->sc_ah->led_pin = ATH_LED_PIN_9485;
|
||||
else if (AR_SREV_9300(sc->sc_ah))
|
||||
sc->sc_ah->led_pin = ATH_LED_PIN_9300;
|
||||
else if (AR_SREV_9462(sc->sc_ah))
|
||||
else if (AR_SREV_9462(sc->sc_ah) || AR_SREV_9565(sc->sc_ah))
|
||||
sc->sc_ah->led_pin = ATH_LED_PIN_9462;
|
||||
else
|
||||
sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
|
||||
@ -228,7 +228,12 @@ static void ath_btcoex_period_timer(unsigned long data)
|
||||
ath9k_hw_btcoex_enable(ah);
|
||||
spin_unlock_bh(&btcoex->btcoex_lock);
|
||||
|
||||
if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) {
|
||||
/*
|
||||
* btcoex_period is in msec while (btocex/btscan_)no_stomp are in usec,
|
||||
* ensure that we properly convert btcoex_period to usec
|
||||
* for any comparision with (btcoex/btscan_)no_stomp.
|
||||
*/
|
||||
if (btcoex->btcoex_period * 1000 != btcoex->btcoex_no_stomp) {
|
||||
if (btcoex->hw_timer_enabled)
|
||||
ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
|
||||
|
||||
@ -341,7 +346,8 @@ void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_btcoex *btcoex = &sc->btcoex;
|
||||
|
||||
ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
|
||||
if (btcoex->hw_timer_enabled)
|
||||
ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
|
||||
}
|
||||
|
||||
u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen)
|
||||
|
@ -973,8 +973,8 @@ static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
|
||||
static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
|
||||
{
|
||||
int transfer, err;
|
||||
const void *data = hif_dev->firmware->data;
|
||||
size_t len = hif_dev->firmware->size;
|
||||
const void *data = hif_dev->fw_data;
|
||||
size_t len = hif_dev->fw_size;
|
||||
u32 addr = AR9271_FIRMWARE;
|
||||
u8 *buf = kzalloc(4096, GFP_KERNEL);
|
||||
u32 firm_offset;
|
||||
@ -1017,7 +1017,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
|
||||
return -EIO;
|
||||
|
||||
dev_info(&hif_dev->udev->dev, "ath9k_htc: Transferred FW: %s, size: %ld\n",
|
||||
hif_dev->fw_name, (unsigned long) hif_dev->firmware->size);
|
||||
hif_dev->fw_name, (unsigned long) hif_dev->fw_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1099,11 +1099,11 @@ static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context)
|
||||
|
||||
hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb,
|
||||
&hif_dev->udev->dev);
|
||||
if (hif_dev->htc_handle == NULL) {
|
||||
goto err_fw;
|
||||
}
|
||||
if (hif_dev->htc_handle == NULL)
|
||||
goto err_dev_alloc;
|
||||
|
||||
hif_dev->firmware = fw;
|
||||
hif_dev->fw_data = fw->data;
|
||||
hif_dev->fw_size = fw->size;
|
||||
|
||||
/* Proceed with initialization */
|
||||
|
||||
@ -1121,6 +1121,8 @@ static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context)
|
||||
goto err_htc_hw_init;
|
||||
}
|
||||
|
||||
release_firmware(fw);
|
||||
hif_dev->flags |= HIF_USB_READY;
|
||||
complete(&hif_dev->fw_done);
|
||||
|
||||
return;
|
||||
@ -1129,8 +1131,8 @@ err_htc_hw_init:
|
||||
ath9k_hif_usb_dev_deinit(hif_dev);
|
||||
err_dev_init:
|
||||
ath9k_htc_hw_free(hif_dev->htc_handle);
|
||||
err_dev_alloc:
|
||||
release_firmware(fw);
|
||||
hif_dev->firmware = NULL;
|
||||
err_fw:
|
||||
ath9k_hif_usb_firmware_fail(hif_dev);
|
||||
}
|
||||
@ -1277,11 +1279,10 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface)
|
||||
|
||||
wait_for_completion(&hif_dev->fw_done);
|
||||
|
||||
if (hif_dev->firmware) {
|
||||
if (hif_dev->flags & HIF_USB_READY) {
|
||||
ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged);
|
||||
ath9k_htc_hw_free(hif_dev->htc_handle);
|
||||
ath9k_hif_usb_dev_deinit(hif_dev);
|
||||
release_firmware(hif_dev->firmware);
|
||||
}
|
||||
|
||||
usb_set_intfdata(interface, NULL);
|
||||
@ -1317,13 +1318,23 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface)
|
||||
struct hif_device_usb *hif_dev = usb_get_intfdata(interface);
|
||||
struct htc_target *htc_handle = hif_dev->htc_handle;
|
||||
int ret;
|
||||
const struct firmware *fw;
|
||||
|
||||
ret = ath9k_hif_usb_alloc_urbs(hif_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (hif_dev->firmware) {
|
||||
if (hif_dev->flags & HIF_USB_READY) {
|
||||
/* request cached firmware during suspend/resume cycle */
|
||||
ret = request_firmware(&fw, hif_dev->fw_name,
|
||||
&hif_dev->udev->dev);
|
||||
if (ret)
|
||||
goto fail_resume;
|
||||
|
||||
hif_dev->fw_data = fw->data;
|
||||
hif_dev->fw_size = fw->size;
|
||||
ret = ath9k_hif_usb_download_fw(hif_dev);
|
||||
release_firmware(fw);
|
||||
if (ret)
|
||||
goto fail_resume;
|
||||
} else {
|
||||
|
@ -85,12 +85,14 @@ struct cmd_buf {
|
||||
};
|
||||
|
||||
#define HIF_USB_START BIT(0)
|
||||
#define HIF_USB_READY BIT(1)
|
||||
|
||||
struct hif_device_usb {
|
||||
struct usb_device *udev;
|
||||
struct usb_interface *interface;
|
||||
const struct usb_device_id *usb_device_id;
|
||||
const struct firmware *firmware;
|
||||
const void *fw_data;
|
||||
size_t fw_size;
|
||||
struct completion fw_done;
|
||||
struct htc_target *htc_handle;
|
||||
struct hif_usb_tx tx;
|
||||
|
@ -173,17 +173,26 @@ void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv)
|
||||
|
||||
if (ah->btcoex_hw.enabled &&
|
||||
ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
|
||||
ath9k_hw_btcoex_disable(ah);
|
||||
if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
|
||||
ath_htc_cancel_btcoex_work(priv);
|
||||
ath9k_hw_btcoex_disable(ah);
|
||||
}
|
||||
}
|
||||
|
||||
void ath9k_htc_init_btcoex(struct ath9k_htc_priv *priv, char *product)
|
||||
{
|
||||
struct ath_hw *ah = priv->ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int qnum;
|
||||
|
||||
/*
|
||||
* Check if BTCOEX is globally disabled.
|
||||
*/
|
||||
if (!common->btcoex_enabled) {
|
||||
ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (product && strncmp(product, ATH_HTC_BTCOEX_PRODUCT_ID, 5) == 0) {
|
||||
ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_3WIRE;
|
||||
}
|
||||
|
@ -30,6 +30,10 @@ int htc_modparam_nohwcrypt;
|
||||
module_param_named(nohwcrypt, htc_modparam_nohwcrypt, int, 0444);
|
||||
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
|
||||
|
||||
static int ath9k_htc_btcoex_enable;
|
||||
module_param_named(btcoex_enable, ath9k_htc_btcoex_enable, int, 0444);
|
||||
MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
|
||||
|
||||
#define CHAN2G(_freq, _idx) { \
|
||||
.center_freq = (_freq), \
|
||||
.hw_value = (_idx), \
|
||||
@ -635,6 +639,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
|
||||
common->hw = priv->hw;
|
||||
common->priv = priv;
|
||||
common->debug_mask = ath9k_debug;
|
||||
common->btcoex_enabled = ath9k_htc_btcoex_enable == 1;
|
||||
|
||||
spin_lock_init(&priv->beacon_lock);
|
||||
spin_lock_init(&priv->tx.tx_lock);
|
||||
|
@ -489,24 +489,20 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
|
||||
ista = (struct ath9k_htc_sta *) sta->drv_priv;
|
||||
memcpy(&tsta.macaddr, sta->addr, ETH_ALEN);
|
||||
memcpy(&tsta.bssid, common->curbssid, ETH_ALEN);
|
||||
tsta.is_vif_sta = 0;
|
||||
ista->index = sta_idx;
|
||||
tsta.is_vif_sta = 0;
|
||||
maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
|
||||
sta->ht_cap.ampdu_factor);
|
||||
tsta.maxampdu = cpu_to_be16(maxampdu);
|
||||
} else {
|
||||
memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
|
||||
tsta.is_vif_sta = 1;
|
||||
tsta.maxampdu = cpu_to_be16(0xffff);
|
||||
}
|
||||
|
||||
tsta.sta_index = sta_idx;
|
||||
tsta.vif_index = avp->index;
|
||||
|
||||
if (!sta) {
|
||||
tsta.maxampdu = cpu_to_be16(0xffff);
|
||||
} else {
|
||||
maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
|
||||
sta->ht_cap.ampdu_factor);
|
||||
tsta.maxampdu = cpu_to_be16(maxampdu);
|
||||
}
|
||||
|
||||
WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
|
||||
if (ret) {
|
||||
if (sta)
|
||||
|
@ -355,7 +355,7 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
|
||||
(val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
|
||||
ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
|
||||
|
||||
if (AR_SREV_9462(ah))
|
||||
if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
|
||||
ah->is_pciexpress = true;
|
||||
else
|
||||
ah->is_pciexpress = (val &
|
||||
@ -463,9 +463,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
|
||||
ah->config.spurchans[i][1] = AR_NO_SPUR;
|
||||
}
|
||||
|
||||
/* PAPRD needs some more work to be enabled */
|
||||
ah->config.paprd_disable = 1;
|
||||
|
||||
ah->config.rx_intr_mitigation = true;
|
||||
ah->config.pcieSerDesWrite = true;
|
||||
|
||||
@ -605,6 +602,11 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
||||
if (AR_SREV_9462(ah))
|
||||
ah->WARegVal &= ~AR_WA_D3_L1_DISABLE;
|
||||
|
||||
if (AR_SREV_9565(ah)) {
|
||||
ah->WARegVal |= AR_WA_BIT22;
|
||||
REG_WRITE(ah, AR_WA, ah->WARegVal);
|
||||
}
|
||||
|
||||
ath9k_hw_init_defaults(ah);
|
||||
ath9k_hw_init_config(ah);
|
||||
|
||||
@ -650,6 +652,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
||||
case AR_SREV_VERSION_9340:
|
||||
case AR_SREV_VERSION_9462:
|
||||
case AR_SREV_VERSION_9550:
|
||||
case AR_SREV_VERSION_9565:
|
||||
break;
|
||||
default:
|
||||
ath_err(common,
|
||||
@ -711,7 +714,7 @@ int ath9k_hw_init(struct ath_hw *ah)
|
||||
int ret;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
/* These are all the AR5008/AR9001/AR9002 hardware family of chipsets */
|
||||
/* These are all the AR5008/AR9001/AR9002/AR9003 hardware family of chipsets */
|
||||
switch (ah->hw_version.devid) {
|
||||
case AR5416_DEVID_PCI:
|
||||
case AR5416_DEVID_PCIE:
|
||||
@ -731,6 +734,7 @@ int ath9k_hw_init(struct ath_hw *ah)
|
||||
case AR9300_DEVID_AR9580:
|
||||
case AR9300_DEVID_AR9462:
|
||||
case AR9485_DEVID_AR1111:
|
||||
case AR9300_DEVID_AR9565:
|
||||
break;
|
||||
default:
|
||||
if (common->bus_ops->ath_bus_type == ATH_USB)
|
||||
@ -803,8 +807,7 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
|
||||
{
|
||||
u32 pll;
|
||||
|
||||
if (AR_SREV_9485(ah)) {
|
||||
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
|
||||
/* program BB PLL ki and kd value, ki=0x4, kd=0x40 */
|
||||
REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
|
||||
AR_CH0_BB_DPLL2_PLL_PWD, 0x1);
|
||||
@ -915,7 +918,8 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
|
||||
}
|
||||
|
||||
pll = ath9k_hw_compute_pll_control(ah, chan);
|
||||
|
||||
if (AR_SREV_9565(ah))
|
||||
pll |= 0x40000;
|
||||
REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
|
||||
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah) ||
|
||||
@ -978,9 +982,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
|
||||
else
|
||||
imr_reg |= AR_IMR_TXOK;
|
||||
|
||||
if (opmode == NL80211_IFTYPE_AP)
|
||||
imr_reg |= AR_IMR_MIB;
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
REG_WRITE(ah, AR_IMR, imr_reg);
|
||||
@ -1778,6 +1779,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
/* Operating channel changed, reset channel calibration data */
|
||||
memset(caldata, 0, sizeof(*caldata));
|
||||
ath9k_init_nfcal_hist_buffer(ah, chan);
|
||||
} else if (caldata) {
|
||||
caldata->paprd_packet_sent = false;
|
||||
}
|
||||
ah->noise = ath9k_hw_getchan_noise(ah, chan);
|
||||
|
||||
@ -2038,7 +2041,7 @@ static void ath9k_set_power_sleep(struct ath_hw *ah)
|
||||
{
|
||||
REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
|
||||
|
||||
if (AR_SREV_9462(ah)) {
|
||||
if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
|
||||
REG_CLR_BIT(ah, AR_TIMER_MODE, 0xff);
|
||||
REG_CLR_BIT(ah, AR_NDP2_TIMER_MODE, 0xff);
|
||||
REG_CLR_BIT(ah, AR_SLP32_INC, 0xfffff);
|
||||
@ -2405,7 +2408,10 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
||||
if (eeval & AR5416_OPFLAGS_11G)
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_2GHZ;
|
||||
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9285(ah) || AR_SREV_9330(ah))
|
||||
if (AR_SREV_9485(ah) ||
|
||||
AR_SREV_9285(ah) ||
|
||||
AR_SREV_9330(ah) ||
|
||||
AR_SREV_9565(ah))
|
||||
chip_chainmask = 1;
|
||||
else if (AR_SREV_9462(ah))
|
||||
chip_chainmask = 3;
|
||||
@ -2493,7 +2499,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
||||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK;
|
||||
if (!AR_SREV_9330(ah) && !AR_SREV_9485(ah))
|
||||
if (!AR_SREV_9330(ah) && !AR_SREV_9485(ah) && !AR_SREV_9565(ah))
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_LDPC;
|
||||
|
||||
pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH;
|
||||
@ -2502,7 +2508,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
||||
pCap->tx_desc_len = sizeof(struct ar9003_txc);
|
||||
pCap->txs_len = sizeof(struct ar9003_txs);
|
||||
if (!ah->config.paprd_disable &&
|
||||
ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
|
||||
ah->eep_ops->get_eeprom(ah, EEP_PAPRD) &&
|
||||
!AR_SREV_9462(ah))
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
|
||||
} else {
|
||||
pCap->tx_desc_len = sizeof(struct ath_desc);
|
||||
@ -2575,14 +2582,12 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
||||
ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
|
||||
}
|
||||
|
||||
if (AR_SREV_9462(ah)) {
|
||||
|
||||
if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
|
||||
if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE))
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_MCI;
|
||||
|
||||
if (AR_SREV_9462_20(ah))
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_RTT;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -2748,7 +2753,7 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
if (AR_SREV_9462(ah))
|
||||
if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
|
||||
bits |= ATH9K_RX_FILTER_CONTROL_WRAPPER;
|
||||
|
||||
REG_WRITE(ah, AR_RX_FILTER, bits);
|
||||
@ -3045,7 +3050,7 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah,
|
||||
REG_SET_BIT(ah, gen_tmr_configuration[timer->index].mode_addr,
|
||||
gen_tmr_configuration[timer->index].mode_mask);
|
||||
|
||||
if (AR_SREV_9462(ah)) {
|
||||
if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
|
||||
/*
|
||||
* Starting from AR9462, each generic timer can select which tsf
|
||||
* to use. But we still follow the old rule, 0 - 7 use tsf and
|
||||
@ -3079,6 +3084,16 @@ void ath9k_hw_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
|
||||
REG_CLR_BIT(ah, gen_tmr_configuration[timer->index].mode_addr,
|
||||
gen_tmr_configuration[timer->index].mode_mask);
|
||||
|
||||
if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
|
||||
/*
|
||||
* Need to switch back to TSF if it was using TSF2.
|
||||
*/
|
||||
if ((timer->index >= AR_GEN_TIMER_BANK_1_LEN)) {
|
||||
REG_CLR_BIT(ah, AR_MAC_PCU_GEN_TIMER_TSF_SEL,
|
||||
(1 << timer->index));
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable both trigger and thresh interrupt masks */
|
||||
REG_CLR_BIT(ah, AR_IMR_S5,
|
||||
(SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) |
|
||||
@ -3160,6 +3175,7 @@ static struct {
|
||||
{ AR_SREV_VERSION_9485, "9485" },
|
||||
{ AR_SREV_VERSION_9462, "9462" },
|
||||
{ AR_SREV_VERSION_9550, "9550" },
|
||||
{ AR_SREV_VERSION_9565, "9565" },
|
||||
};
|
||||
|
||||
/* For devices with external radios */
|
||||
|
@ -50,6 +50,7 @@
|
||||
#define AR9300_DEVID_AR9330 0x0035
|
||||
#define AR9300_DEVID_QCA955X 0x0038
|
||||
#define AR9485_DEVID_AR1111 0x0037
|
||||
#define AR9300_DEVID_AR9565 0x0036
|
||||
|
||||
#define AR5416_AR9100_DEVID 0x000b
|
||||
|
||||
@ -405,6 +406,7 @@ struct ath9k_hw_cal_data {
|
||||
int8_t iCoff;
|
||||
int8_t qCoff;
|
||||
bool rtt_done;
|
||||
bool paprd_packet_sent;
|
||||
bool paprd_done;
|
||||
bool nfcal_pending;
|
||||
bool nfcal_interference;
|
||||
|
@ -258,7 +258,7 @@ static void setup_ht_cap(struct ath_softc *sc,
|
||||
ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
|
||||
ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
|
||||
|
||||
if (AR_SREV_9330(ah) || AR_SREV_9485(ah))
|
||||
if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah))
|
||||
max_streams = 1;
|
||||
else if (AR_SREV_9462(ah))
|
||||
max_streams = 2;
|
||||
|
@ -254,8 +254,9 @@ void ath_paprd_calibrate(struct work_struct *work)
|
||||
int chain_ok = 0;
|
||||
int chain;
|
||||
int len = 1800;
|
||||
int ret;
|
||||
|
||||
if (!caldata)
|
||||
if (!caldata || !caldata->paprd_packet_sent || caldata->paprd_done)
|
||||
return;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
@ -282,13 +283,6 @@ void ath_paprd_calibrate(struct work_struct *work)
|
||||
continue;
|
||||
|
||||
chain_ok = 0;
|
||||
|
||||
ath_dbg(common, CALIBRATE,
|
||||
"Sending PAPRD frame for thermal measurement on chain %d\n",
|
||||
chain);
|
||||
if (!ath_paprd_send_frame(sc, skb, chain))
|
||||
goto fail_paprd;
|
||||
|
||||
ar9003_paprd_setup_gain_table(ah, chain);
|
||||
|
||||
ath_dbg(common, CALIBRATE,
|
||||
@ -302,7 +296,13 @@ void ath_paprd_calibrate(struct work_struct *work)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ar9003_paprd_create_curve(ah, caldata, chain)) {
|
||||
ret = ar9003_paprd_create_curve(ah, caldata, chain);
|
||||
if (ret == -EINPROGRESS) {
|
||||
ath_dbg(common, CALIBRATE,
|
||||
"PAPRD curve on chain %d needs to be re-trained\n",
|
||||
chain);
|
||||
break;
|
||||
} else if (ret) {
|
||||
ath_dbg(common, CALIBRATE,
|
||||
"PAPRD create curve failed on chain %d\n",
|
||||
chain);
|
||||
|
@ -986,47 +986,21 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int ret = 0;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
mutex_lock(&sc->mutex);
|
||||
|
||||
switch (vif->type) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_WDS:
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
break;
|
||||
default:
|
||||
ath_err(common, "Interface type %d not yet supported\n",
|
||||
vif->type);
|
||||
ret = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ath9k_uses_beacons(vif->type)) {
|
||||
if (sc->nbcnvifs >= ATH_BCBUF) {
|
||||
ath_err(common, "Not enough beacon buffers when adding"
|
||||
" new interface of type: %i\n",
|
||||
vif->type);
|
||||
ret = -ENOBUFS;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type);
|
||||
|
||||
sc->nvifs++;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath9k_calculate_summary_state(hw, vif);
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
if (ath9k_uses_beacons(vif->type))
|
||||
ath9k_beacon_assign_slot(sc, vif);
|
||||
|
||||
out:
|
||||
mutex_unlock(&sc->mutex);
|
||||
ath9k_ps_restore(sc);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath9k_change_interface(struct ieee80211_hw *hw,
|
||||
@ -1036,21 +1010,9 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
int ret = 0;
|
||||
|
||||
ath_dbg(common, CONFIG, "Change Interface\n");
|
||||
|
||||
mutex_lock(&sc->mutex);
|
||||
ath9k_ps_wakeup(sc);
|
||||
|
||||
if (ath9k_uses_beacons(new_type) &&
|
||||
!ath9k_uses_beacons(vif->type)) {
|
||||
if (sc->nbcnvifs >= ATH_BCBUF) {
|
||||
ath_err(common, "No beacon slot available\n");
|
||||
ret = -ENOBUFS;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (ath9k_uses_beacons(vif->type))
|
||||
ath9k_beacon_remove_slot(sc, vif);
|
||||
@ -1058,14 +1020,15 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
|
||||
vif->type = new_type;
|
||||
vif->p2p = p2p;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath9k_calculate_summary_state(hw, vif);
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
if (ath9k_uses_beacons(vif->type))
|
||||
ath9k_beacon_assign_slot(sc, vif);
|
||||
|
||||
out:
|
||||
ath9k_ps_restore(sc);
|
||||
mutex_unlock(&sc->mutex);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath9k_remove_interface(struct ieee80211_hw *hw,
|
||||
@ -1076,7 +1039,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
|
||||
|
||||
ath_dbg(common, CONFIG, "Detach Interface\n");
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
mutex_lock(&sc->mutex);
|
||||
|
||||
sc->nvifs--;
|
||||
@ -1084,10 +1046,11 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
|
||||
if (ath9k_uses_beacons(vif->type))
|
||||
ath9k_beacon_remove_slot(sc, vif);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath9k_calculate_summary_state(hw, NULL);
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
mutex_unlock(&sc->mutex);
|
||||
ath9k_ps_restore(sc);
|
||||
}
|
||||
|
||||
static void ath9k_enable_ps(struct ath_softc *sc)
|
||||
@ -2260,7 +2223,7 @@ static int ath9k_suspend(struct ieee80211_hw *hw,
|
||||
mutex_lock(&sc->mutex);
|
||||
|
||||
ath_cancel_work(sc);
|
||||
del_timer_sync(&common->ani.timer);
|
||||
ath_stop_ani(sc);
|
||||
del_timer_sync(&sc->rx_poll_timer);
|
||||
|
||||
if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
|
||||
|
@ -191,6 +191,23 @@ skip_tuning:
|
||||
ath9k_btcoex_timer_resume(sc);
|
||||
}
|
||||
|
||||
static void ath_mci_wait_btcal_done(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
|
||||
/* Stop tx & rx */
|
||||
ieee80211_stop_queues(sc->hw);
|
||||
ath_stoprecv(sc);
|
||||
ath_drain_all_txq(sc, false);
|
||||
|
||||
/* Wait for cal done */
|
||||
ar9003_mci_start_reset(ah, ah->curchan);
|
||||
|
||||
/* Resume tx & rx */
|
||||
ath_startrecv(sc);
|
||||
ieee80211_wake_queues(sc->hw);
|
||||
}
|
||||
|
||||
static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
@ -201,8 +218,8 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload)
|
||||
switch (opcode) {
|
||||
case MCI_GPM_BT_CAL_REQ:
|
||||
if (mci_hw->bt_state == MCI_BT_AWAKE) {
|
||||
ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START);
|
||||
ath9k_queue_reset(sc, RESET_TYPE_MCI);
|
||||
mci_hw->bt_state = MCI_BT_CAL_START;
|
||||
ath_mci_wait_btcal_done(sc);
|
||||
}
|
||||
ath_dbg(common, MCI, "MCI State : %d\n", mci_hw->bt_state);
|
||||
break;
|
||||
|
@ -38,6 +38,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0036) }, /* PCI-E AR9565 */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@ -801,6 +801,8 @@
|
||||
#define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */
|
||||
#define AR_SREV_VERSION_9462 0x280
|
||||
#define AR_SREV_REVISION_9462_20 2
|
||||
#define AR_SREV_VERSION_9565 0x2C0
|
||||
#define AR_SREV_REVISION_9565_10 0
|
||||
#define AR_SREV_VERSION_9550 0x400
|
||||
|
||||
#define AR_SREV_5416(_ah) \
|
||||
@ -909,6 +911,13 @@
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
|
||||
((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_20))
|
||||
|
||||
#define AR_SREV_9565(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565))
|
||||
|
||||
#define AR_SREV_9565_10(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_10))
|
||||
|
||||
#define AR_SREV_9550(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9550))
|
||||
|
||||
|
@ -568,7 +568,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
if (!an->sleeping) {
|
||||
ath_tx_queue_tid(txq, tid);
|
||||
|
||||
if (ts->ts_status & ATH9K_TXERR_FILT)
|
||||
if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY))
|
||||
tid->ac->clear_ps_filter = true;
|
||||
}
|
||||
}
|
||||
@ -2019,6 +2019,9 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
|
||||
|
||||
ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb);
|
||||
|
||||
if (sc->sc_ah->caldata)
|
||||
sc->sc_ah->caldata->paprd_packet_sent = true;
|
||||
|
||||
if (!(tx_flags & ATH_TX_ERROR))
|
||||
/* Frame was ACKed */
|
||||
tx_info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
|
@ -55,6 +55,14 @@ config BRCMFMAC_USB
|
||||
IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
|
||||
use the driver for an USB wireless card.
|
||||
|
||||
config BRCMISCAN
|
||||
bool "Broadcom I-Scan (OBSOLETE)"
|
||||
depends on BRCMFMAC
|
||||
---help---
|
||||
This option enables the I-Scan method. By default fullmac uses the
|
||||
new E-Scan method which uses less memory in firmware and gives no
|
||||
limitation on the number of scan results.
|
||||
|
||||
config BRCMDBG
|
||||
bool "Broadcom driver debug functions"
|
||||
depends on BRCMSMAC || BRCMFMAC
|
||||
|
@ -42,6 +42,7 @@
|
||||
|
||||
#define DMA_ALIGN_MASK 0x03
|
||||
|
||||
#define SDIO_DEVICE_ID_BROADCOM_43241 0x4324
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334
|
||||
@ -51,6 +52,7 @@
|
||||
|
||||
/* devices we support, null terminated */
|
||||
static const struct sdio_device_id brcmf_sdmmc_ids[] = {
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43241)},
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)},
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)},
|
||||
|
@ -130,6 +130,10 @@
|
||||
#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02
|
||||
#define BRCMF_EVENT_MSG_GROUP 0x04
|
||||
|
||||
#define BRCMF_ESCAN_REQ_VERSION 1
|
||||
|
||||
#define WLC_BSS_RSSI_ON_CHANNEL 0x0002
|
||||
|
||||
struct brcmf_event_msg {
|
||||
__be16 version;
|
||||
__be16 flags;
|
||||
@ -140,6 +144,8 @@ struct brcmf_event_msg {
|
||||
__be32 datalen;
|
||||
u8 addr[ETH_ALEN];
|
||||
char ifname[IFNAMSIZ];
|
||||
u8 ifidx;
|
||||
u8 bsscfgidx;
|
||||
} __packed;
|
||||
|
||||
struct brcm_ethhdr {
|
||||
@ -454,6 +460,24 @@ struct brcmf_scan_results_le {
|
||||
__le32 count;
|
||||
};
|
||||
|
||||
struct brcmf_escan_params_le {
|
||||
__le32 version;
|
||||
__le16 action;
|
||||
__le16 sync_id;
|
||||
struct brcmf_scan_params_le params_le;
|
||||
};
|
||||
|
||||
struct brcmf_escan_result_le {
|
||||
__le32 buflen;
|
||||
__le32 version;
|
||||
__le16 sync_id;
|
||||
__le16 bss_count;
|
||||
struct brcmf_bss_info_le bss_info_le;
|
||||
};
|
||||
|
||||
#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(struct brcmf_escan_result_le) - \
|
||||
sizeof(struct brcmf_bss_info_le))
|
||||
|
||||
/* used for association with a specific BSSID and chanspec list */
|
||||
struct brcmf_assoc_params_le {
|
||||
/* 00:00:00:00:00:00: broadcast scan */
|
||||
@ -638,6 +662,7 @@ extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen,
|
||||
extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
|
||||
|
||||
extern s32 brcmf_exec_dcmd(struct net_device *dev, u32 cmd, void *arg, u32 len);
|
||||
extern int brcmf_netlink_dcmd(struct net_device *ndev, struct brcmf_dcmd *dcmd);
|
||||
|
||||
/* Return pointer to interface name */
|
||||
extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
|
||||
|
@ -103,7 +103,7 @@ extern int brcmf_attach(uint bus_hdrlen, struct device *dev);
|
||||
extern void brcmf_detach(struct device *dev);
|
||||
|
||||
/* Indication from bus module to change flow-control state */
|
||||
extern void brcmf_txflowcontrol(struct device *dev, int ifidx, bool on);
|
||||
extern void brcmf_txflowblock(struct device *dev, bool state);
|
||||
|
||||
/* Notify tx completion */
|
||||
extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp,
|
||||
|
@ -205,7 +205,8 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
|
||||
BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, {
|
||||
BRCMF_E_IF, "IF"}, {
|
||||
BRCMF_E_RSSI, "RSSI"}, {
|
||||
BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}
|
||||
BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}, {
|
||||
BRCMF_E_ESCAN_RESULT, "ESCAN_RESULT"}
|
||||
};
|
||||
uint event_type, flags, auth_type, datalen;
|
||||
static u32 seqnum_prev;
|
||||
@ -350,6 +351,11 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name);
|
||||
break;
|
||||
|
||||
case BRCMF_E_ESCAN_RESULT:
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name);
|
||||
datalen = 0;
|
||||
break;
|
||||
|
||||
case BRCMF_E_PFN_NET_FOUND:
|
||||
case BRCMF_E_PFN_NET_LOST:
|
||||
case BRCMF_E_PFN_SCAN_COMPLETE:
|
||||
|
@ -350,19 +350,23 @@ done:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void brcmf_txflowcontrol(struct device *dev, int ifidx, bool state)
|
||||
void brcmf_txflowblock(struct device *dev, bool state)
|
||||
{
|
||||
struct net_device *ndev;
|
||||
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
struct brcmf_pub *drvr = bus_if->drvr;
|
||||
int i;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
ndev = drvr->iflist[ifidx]->ndev;
|
||||
if (state == ON)
|
||||
netif_stop_queue(ndev);
|
||||
else
|
||||
netif_wake_queue(ndev);
|
||||
for (i = 0; i < BRCMF_MAX_IFS; i++)
|
||||
if (drvr->iflist[i]) {
|
||||
ndev = drvr->iflist[i]->ndev;
|
||||
if (state)
|
||||
netif_stop_queue(ndev);
|
||||
else
|
||||
netif_wake_queue(ndev);
|
||||
}
|
||||
}
|
||||
|
||||
static int brcmf_host_event(struct brcmf_pub *drvr, int *ifidx,
|
||||
@ -775,6 +779,14 @@ done:
|
||||
return err;
|
||||
}
|
||||
|
||||
int brcmf_netlink_dcmd(struct net_device *ndev, struct brcmf_dcmd *dcmd)
|
||||
{
|
||||
brcmf_dbg(TRACE, "enter: cmd %x buf %p len %d\n",
|
||||
dcmd->cmd, dcmd->buf, dcmd->len);
|
||||
|
||||
return brcmf_exec_dcmd(ndev, dcmd->cmd, dcmd->buf, dcmd->len);
|
||||
}
|
||||
|
||||
static int brcmf_netdev_stop(struct net_device *ndev)
|
||||
{
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
|
@ -2235,8 +2235,8 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
|
||||
if (bus->sdiodev->bus_if->drvr_up &&
|
||||
(bus->sdiodev->bus_if->state == BRCMF_BUS_DATA) &&
|
||||
bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
|
||||
bus->txoff = OFF;
|
||||
brcmf_txflowcontrol(bus->sdiodev->dev, 0, OFF);
|
||||
bus->txoff = false;
|
||||
brcmf_txflowblock(bus->sdiodev->dev, false);
|
||||
}
|
||||
|
||||
return cnt;
|
||||
@ -2672,8 +2672,8 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
|
||||
spin_unlock_bh(&bus->txqlock);
|
||||
|
||||
if (pktq_len(&bus->txq) >= TXHI) {
|
||||
bus->txoff = ON;
|
||||
brcmf_txflowcontrol(bus->sdiodev->dev, 0, ON);
|
||||
bus->txoff = true;
|
||||
brcmf_txflowblock(bus->sdiodev->dev, true);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -3881,6 +3881,8 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
|
||||
|
||||
static bool brcmf_sdbrcm_chipmatch(u16 chipid)
|
||||
{
|
||||
if (chipid == BCM43241_CHIP_ID)
|
||||
return true;
|
||||
if (chipid == BCM4329_CHIP_ID)
|
||||
return true;
|
||||
if (chipid == BCM4330_CHIP_ID)
|
||||
|
@ -377,6 +377,23 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
|
||||
|
||||
/* Address of cores for new chips should be added here */
|
||||
switch (ci->chip) {
|
||||
case BCM43241_CHIP_ID:
|
||||
ci->c_inf[0].wrapbase = 0x18100000;
|
||||
ci->c_inf[0].cib = 0x2a084411;
|
||||
ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
|
||||
ci->c_inf[1].base = 0x18002000;
|
||||
ci->c_inf[1].wrapbase = 0x18102000;
|
||||
ci->c_inf[1].cib = 0x0e004211;
|
||||
ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
|
||||
ci->c_inf[2].base = 0x18004000;
|
||||
ci->c_inf[2].wrapbase = 0x18104000;
|
||||
ci->c_inf[2].cib = 0x14080401;
|
||||
ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
|
||||
ci->c_inf[3].base = 0x18003000;
|
||||
ci->c_inf[3].wrapbase = 0x18103000;
|
||||
ci->c_inf[3].cib = 0x07004211;
|
||||
ci->ramsize = 0x90000;
|
||||
break;
|
||||
case BCM4329_CHIP_ID:
|
||||
ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
|
||||
ci->c_inf[1].base = BCM4329_CORE_BUS_BASE;
|
||||
|
@ -66,7 +66,9 @@
|
||||
#define BRCMF_USB_CBCTL_READ 1
|
||||
#define BRCMF_USB_MAX_PKT_SIZE 1600
|
||||
|
||||
#define BRCMF_USB_43143_FW_NAME "brcm/brcmfmac43143.bin"
|
||||
#define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin"
|
||||
#define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin"
|
||||
|
||||
enum usbdev_suspend_state {
|
||||
USBOS_SUSPEND_STATE_DEVICE_ACTIVE = 0, /* Device is busy, won't allow
|
||||
@ -78,20 +80,6 @@ enum usbdev_suspend_state {
|
||||
USBOS_SUSPEND_STATE_SUSPENDED /* Device suspended */
|
||||
};
|
||||
|
||||
struct brcmf_usb_probe_info {
|
||||
void *usbdev_info;
|
||||
struct usb_device *usb; /* USB device pointer from OS */
|
||||
uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2;
|
||||
int intr_size; /* Size of interrupt message */
|
||||
int interval; /* Interrupt polling interval */
|
||||
int vid;
|
||||
int pid;
|
||||
enum usb_device_speed device_speed;
|
||||
enum usbdev_suspend_state suspend_state;
|
||||
struct usb_interface *intf;
|
||||
};
|
||||
static struct brcmf_usb_probe_info usbdev_probe_info;
|
||||
|
||||
struct brcmf_usb_image {
|
||||
void *data;
|
||||
u32 len;
|
||||
@ -117,9 +105,8 @@ struct brcmf_usbdev_info {
|
||||
int rx_low_watermark;
|
||||
int tx_low_watermark;
|
||||
int tx_high_watermark;
|
||||
bool txoff;
|
||||
bool rxoff;
|
||||
bool txoverride;
|
||||
int tx_freecount;
|
||||
bool tx_flowblock;
|
||||
|
||||
struct brcmf_usbreq *tx_reqs;
|
||||
struct brcmf_usbreq *rx_reqs;
|
||||
@ -133,7 +120,6 @@ struct brcmf_usbdev_info {
|
||||
|
||||
struct usb_device *usbdev;
|
||||
struct device *dev;
|
||||
enum usb_device_speed device_speed;
|
||||
|
||||
int ctl_in_pipe, ctl_out_pipe;
|
||||
struct urb *ctl_urb; /* URB for control endpoint */
|
||||
@ -153,9 +139,6 @@ struct brcmf_usbdev_info {
|
||||
int intr_size; /* Size of interrupt message */
|
||||
int interval; /* Interrupt polling interval */
|
||||
struct intr_transfer_buf intr; /* Data buffer for interrupt endpoint */
|
||||
|
||||
struct brcmf_usb_probe_info probe_info;
|
||||
|
||||
};
|
||||
|
||||
static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
|
||||
@ -177,14 +160,6 @@ static struct brcmf_usbdev_info *brcmf_usb_get_businfo(struct device *dev)
|
||||
return brcmf_usb_get_buspub(dev)->devinfo;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
brcmf_usb_txflowcontrol(struct brcmf_usbdev_info *devinfo, bool onoff)
|
||||
{
|
||||
dhd_txflowcontrol(devinfo->bus_pub.netdev, 0, onoff);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo,
|
||||
uint *condition, bool *pending)
|
||||
{
|
||||
@ -366,13 +341,13 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len)
|
||||
if (test_and_set_bit(0, &devinfo->ctl_op))
|
||||
return -EIO;
|
||||
|
||||
devinfo->ctl_completed = false;
|
||||
err = brcmf_usb_send_ctl(devinfo, buf, len);
|
||||
if (err) {
|
||||
brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len);
|
||||
return err;
|
||||
}
|
||||
|
||||
devinfo->ctl_completed = false;
|
||||
timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
|
||||
&pending);
|
||||
clear_bit(0, &devinfo->ctl_op);
|
||||
@ -418,7 +393,7 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
|
||||
}
|
||||
|
||||
static struct brcmf_usbreq *brcmf_usb_deq(struct brcmf_usbdev_info *devinfo,
|
||||
struct list_head *q)
|
||||
struct list_head *q, int *counter)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct brcmf_usbreq *req;
|
||||
@ -429,17 +404,22 @@ static struct brcmf_usbreq *brcmf_usb_deq(struct brcmf_usbdev_info *devinfo,
|
||||
}
|
||||
req = list_entry(q->next, struct brcmf_usbreq, list);
|
||||
list_del_init(q->next);
|
||||
if (counter)
|
||||
(*counter)--;
|
||||
spin_unlock_irqrestore(&devinfo->qlock, flags);
|
||||
return req;
|
||||
|
||||
}
|
||||
|
||||
static void brcmf_usb_enq(struct brcmf_usbdev_info *devinfo,
|
||||
struct list_head *q, struct brcmf_usbreq *req)
|
||||
struct list_head *q, struct brcmf_usbreq *req,
|
||||
int *counter)
|
||||
{
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&devinfo->qlock, flags);
|
||||
list_add_tail(&req->list, q);
|
||||
if (counter)
|
||||
(*counter)++;
|
||||
spin_unlock_irqrestore(&devinfo->qlock, flags);
|
||||
}
|
||||
|
||||
@ -519,10 +499,14 @@ static void brcmf_usb_tx_complete(struct urb *urb)
|
||||
else
|
||||
devinfo->bus_pub.bus->dstats.tx_errors++;
|
||||
|
||||
dev_kfree_skb(req->skb);
|
||||
brcmu_pkt_buf_free_skb(req->skb);
|
||||
req->skb = NULL;
|
||||
brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);
|
||||
|
||||
brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount);
|
||||
if (devinfo->tx_freecount > devinfo->tx_high_watermark &&
|
||||
devinfo->tx_flowblock) {
|
||||
brcmf_txflowblock(devinfo->dev, false);
|
||||
devinfo->tx_flowblock = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void brcmf_usb_rx_complete(struct urb *urb)
|
||||
@ -540,8 +524,8 @@ static void brcmf_usb_rx_complete(struct urb *urb)
|
||||
devinfo->bus_pub.bus->dstats.rx_packets++;
|
||||
} else {
|
||||
devinfo->bus_pub.bus->dstats.rx_errors++;
|
||||
dev_kfree_skb(skb);
|
||||
brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -551,12 +535,12 @@ static void brcmf_usb_rx_complete(struct urb *urb)
|
||||
brcmf_dbg(ERROR, "rx protocol error\n");
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
devinfo->bus_pub.bus->dstats.rx_errors++;
|
||||
} else {
|
||||
} else
|
||||
brcmf_rx_packet(devinfo->dev, ifidx, skb);
|
||||
brcmf_usb_rx_refill(devinfo, req);
|
||||
}
|
||||
brcmf_usb_rx_refill(devinfo, req);
|
||||
} else {
|
||||
dev_kfree_skb(skb);
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
|
||||
}
|
||||
return;
|
||||
|
||||
@ -573,7 +557,7 @@ static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
|
||||
|
||||
skb = dev_alloc_skb(devinfo->bus_pub.bus_mtu);
|
||||
if (!skb) {
|
||||
brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
|
||||
brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
|
||||
return;
|
||||
}
|
||||
req->skb = skb;
|
||||
@ -581,16 +565,15 @@ static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
|
||||
usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe,
|
||||
skb->data, skb_tailroom(skb), brcmf_usb_rx_complete,
|
||||
req);
|
||||
req->urb->transfer_flags |= URB_ZERO_PACKET;
|
||||
req->devinfo = devinfo;
|
||||
brcmf_usb_enq(devinfo, &devinfo->rx_postq, req, NULL);
|
||||
|
||||
ret = usb_submit_urb(req->urb, GFP_ATOMIC);
|
||||
if (ret == 0) {
|
||||
brcmf_usb_enq(devinfo, &devinfo->rx_postq, req);
|
||||
} else {
|
||||
dev_kfree_skb(req->skb);
|
||||
if (ret) {
|
||||
brcmf_usb_del_fromq(devinfo, req);
|
||||
brcmu_pkt_buf_free_skb(req->skb);
|
||||
req->skb = NULL;
|
||||
brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
|
||||
brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -603,7 +586,7 @@ static void brcmf_usb_rx_fill_all(struct brcmf_usbdev_info *devinfo)
|
||||
brcmf_dbg(ERROR, "bus is not up\n");
|
||||
return;
|
||||
}
|
||||
while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq)) != NULL)
|
||||
while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq, NULL)) != NULL)
|
||||
brcmf_usb_rx_refill(devinfo, req);
|
||||
}
|
||||
|
||||
@ -681,27 +664,34 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq);
|
||||
req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq,
|
||||
&devinfo->tx_freecount);
|
||||
if (!req) {
|
||||
brcmu_pkt_buf_free_skb(skb);
|
||||
brcmf_dbg(ERROR, "no req to send\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!req->urb) {
|
||||
brcmf_dbg(ERROR, "no urb for req %p\n", req);
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
req->skb = skb;
|
||||
req->devinfo = devinfo;
|
||||
usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe,
|
||||
skb->data, skb->len, brcmf_usb_tx_complete, req);
|
||||
req->urb->transfer_flags |= URB_ZERO_PACKET;
|
||||
brcmf_usb_enq(devinfo, &devinfo->tx_postq, req, NULL);
|
||||
ret = usb_submit_urb(req->urb, GFP_ATOMIC);
|
||||
if (!ret) {
|
||||
brcmf_usb_enq(devinfo, &devinfo->tx_postq, req);
|
||||
} else {
|
||||
if (ret) {
|
||||
brcmf_dbg(ERROR, "brcmf_usb_tx usb_submit_urb FAILED\n");
|
||||
brcmf_usb_del_fromq(devinfo, req);
|
||||
brcmu_pkt_buf_free_skb(req->skb);
|
||||
req->skb = NULL;
|
||||
brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req);
|
||||
brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req,
|
||||
&devinfo->tx_freecount);
|
||||
} else {
|
||||
if (devinfo->tx_freecount < devinfo->tx_low_watermark &&
|
||||
!devinfo->tx_flowblock) {
|
||||
brcmf_txflowblock(dev, true);
|
||||
devinfo->tx_flowblock = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -1112,10 +1102,14 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo)
|
||||
static bool brcmf_usb_chip_support(int chipid, int chiprev)
|
||||
{
|
||||
switch(chipid) {
|
||||
case 43143:
|
||||
return true;
|
||||
case 43235:
|
||||
case 43236:
|
||||
case 43238:
|
||||
return (chiprev == 3);
|
||||
case 43242:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1154,11 +1148,8 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo)
|
||||
}
|
||||
|
||||
|
||||
static void brcmf_usb_detach(const struct brcmf_usbdev *bus_pub)
|
||||
static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo)
|
||||
{
|
||||
struct brcmf_usbdev_info *devinfo =
|
||||
(struct brcmf_usbdev_info *)bus_pub;
|
||||
|
||||
brcmf_dbg(TRACE, "devinfo %p\n", devinfo);
|
||||
|
||||
/* store the image globally */
|
||||
@ -1175,7 +1166,6 @@ static void brcmf_usb_detach(const struct brcmf_usbdev *bus_pub)
|
||||
|
||||
kfree(devinfo->tx_reqs);
|
||||
kfree(devinfo->rx_reqs);
|
||||
kfree(devinfo);
|
||||
}
|
||||
|
||||
#define TRX_MAGIC 0x30524448 /* "HDR0" */
|
||||
@ -1228,7 +1218,22 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
|
||||
if (devinfo->image)
|
||||
return 0;
|
||||
|
||||
fwname = BRCMF_USB_43236_FW_NAME;
|
||||
switch (devinfo->bus_pub.devid) {
|
||||
case 43143:
|
||||
fwname = BRCMF_USB_43143_FW_NAME;
|
||||
break;
|
||||
case 43235:
|
||||
case 43236:
|
||||
case 43238:
|
||||
fwname = BRCMF_USB_43236_FW_NAME;
|
||||
break;
|
||||
case 43242:
|
||||
fwname = BRCMF_USB_43242_FW_NAME;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
err = request_firmware(&fw, fwname, devinfo->dev);
|
||||
if (!fw) {
|
||||
@ -1253,14 +1258,9 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
|
||||
|
||||
|
||||
static
|
||||
struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
|
||||
struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo,
|
||||
int nrxq, int ntxq)
|
||||
{
|
||||
struct brcmf_usbdev_info *devinfo;
|
||||
|
||||
devinfo = kzalloc(sizeof(struct brcmf_usbdev_info), GFP_ATOMIC);
|
||||
if (devinfo == NULL)
|
||||
return NULL;
|
||||
|
||||
devinfo->bus_pub.nrxq = nrxq;
|
||||
devinfo->rx_low_watermark = nrxq / 2;
|
||||
devinfo->bus_pub.devinfo = devinfo;
|
||||
@ -1269,18 +1269,6 @@ struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
|
||||
/* flow control when too many tx urbs posted */
|
||||
devinfo->tx_low_watermark = ntxq / 4;
|
||||
devinfo->tx_high_watermark = devinfo->tx_low_watermark * 3;
|
||||
devinfo->dev = dev;
|
||||
devinfo->usbdev = usbdev_probe_info.usb;
|
||||
devinfo->tx_pipe = usbdev_probe_info.tx_pipe;
|
||||
devinfo->rx_pipe = usbdev_probe_info.rx_pipe;
|
||||
devinfo->rx_pipe2 = usbdev_probe_info.rx_pipe2;
|
||||
devinfo->intr_pipe = usbdev_probe_info.intr_pipe;
|
||||
|
||||
devinfo->interval = usbdev_probe_info.interval;
|
||||
devinfo->intr_size = usbdev_probe_info.intr_size;
|
||||
|
||||
memcpy(&devinfo->probe_info, &usbdev_probe_info,
|
||||
sizeof(struct brcmf_usb_probe_info));
|
||||
devinfo->bus_pub.bus_mtu = BRCMF_USB_MAX_PKT_SIZE;
|
||||
|
||||
/* Initialize other structure content */
|
||||
@ -1295,6 +1283,8 @@ struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
|
||||
INIT_LIST_HEAD(&devinfo->tx_freeq);
|
||||
INIT_LIST_HEAD(&devinfo->tx_postq);
|
||||
|
||||
devinfo->tx_flowblock = false;
|
||||
|
||||
devinfo->rx_reqs = brcmf_usbdev_qinit(&devinfo->rx_freeq, nrxq);
|
||||
if (!devinfo->rx_reqs)
|
||||
goto error;
|
||||
@ -1302,6 +1292,7 @@ struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
|
||||
devinfo->tx_reqs = brcmf_usbdev_qinit(&devinfo->tx_freeq, ntxq);
|
||||
if (!devinfo->tx_reqs)
|
||||
goto error;
|
||||
devinfo->tx_freecount = ntxq;
|
||||
|
||||
devinfo->intr_urb = usb_alloc_urb(0, GFP_ATOMIC);
|
||||
if (!devinfo->intr_urb) {
|
||||
@ -1336,19 +1327,19 @@ struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
|
||||
|
||||
error:
|
||||
brcmf_dbg(ERROR, "failed!\n");
|
||||
brcmf_usb_detach(&devinfo->bus_pub);
|
||||
brcmf_usb_detach(devinfo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int brcmf_usb_probe_cb(struct device *dev, const char *desc,
|
||||
u32 bustype, u32 hdrlen)
|
||||
static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo,
|
||||
const char *desc, u32 bustype, u32 hdrlen)
|
||||
{
|
||||
struct brcmf_bus *bus = NULL;
|
||||
struct brcmf_usbdev *bus_pub = NULL;
|
||||
int ret;
|
||||
struct device *dev = devinfo->dev;
|
||||
|
||||
|
||||
bus_pub = brcmf_usb_attach(BRCMF_USB_NRXQ, BRCMF_USB_NTXQ, dev);
|
||||
bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ);
|
||||
if (!bus_pub) {
|
||||
ret = -ENODEV;
|
||||
goto fail;
|
||||
@ -1387,23 +1378,21 @@ static int brcmf_usb_probe_cb(struct device *dev, const char *desc,
|
||||
return 0;
|
||||
fail:
|
||||
/* Release resources in reverse order */
|
||||
if (bus_pub)
|
||||
brcmf_usb_detach(bus_pub);
|
||||
kfree(bus);
|
||||
brcmf_usb_detach(devinfo);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
brcmf_usb_disconnect_cb(struct brcmf_usbdev *bus_pub)
|
||||
brcmf_usb_disconnect_cb(struct brcmf_usbdev_info *devinfo)
|
||||
{
|
||||
if (!bus_pub)
|
||||
if (!devinfo)
|
||||
return;
|
||||
brcmf_dbg(TRACE, "enter: bus_pub %p\n", bus_pub);
|
||||
|
||||
brcmf_detach(bus_pub->devinfo->dev);
|
||||
kfree(bus_pub->bus);
|
||||
brcmf_usb_detach(bus_pub);
|
||||
brcmf_dbg(TRACE, "enter: bus_pub %p\n", devinfo);
|
||||
|
||||
brcmf_detach(devinfo->dev);
|
||||
kfree(devinfo->bus_pub.bus);
|
||||
brcmf_usb_detach(devinfo);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1415,18 +1404,18 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
struct usb_device *usb = interface_to_usbdev(intf);
|
||||
int num_of_eps;
|
||||
u8 endpoint_num;
|
||||
struct brcmf_usbdev_info *devinfo;
|
||||
|
||||
brcmf_dbg(TRACE, "enter\n");
|
||||
|
||||
usbdev_probe_info.usb = usb;
|
||||
usbdev_probe_info.intf = intf;
|
||||
devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC);
|
||||
if (devinfo == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
if (id != NULL) {
|
||||
usbdev_probe_info.vid = id->idVendor;
|
||||
usbdev_probe_info.pid = id->idProduct;
|
||||
}
|
||||
devinfo->usbdev = usb;
|
||||
devinfo->dev = &usb->dev;
|
||||
|
||||
usb_set_intfdata(intf, &usbdev_probe_info);
|
||||
usb_set_intfdata(intf, devinfo);
|
||||
|
||||
/* Check that the device supports only one configuration */
|
||||
if (usb->descriptor.bNumConfigurations != 1) {
|
||||
@ -1475,11 +1464,11 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
}
|
||||
|
||||
endpoint_num = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
|
||||
usbdev_probe_info.intr_pipe = usb_rcvintpipe(usb, endpoint_num);
|
||||
devinfo->intr_pipe = usb_rcvintpipe(usb, endpoint_num);
|
||||
|
||||
usbdev_probe_info.rx_pipe = 0;
|
||||
usbdev_probe_info.rx_pipe2 = 0;
|
||||
usbdev_probe_info.tx_pipe = 0;
|
||||
devinfo->rx_pipe = 0;
|
||||
devinfo->rx_pipe2 = 0;
|
||||
devinfo->tx_pipe = 0;
|
||||
num_of_eps = IFDESC(usb, BULK_IF).bNumEndpoints - 1;
|
||||
|
||||
/* Check data endpoints and get pipes */
|
||||
@ -1496,35 +1485,33 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
USB_ENDPOINT_NUMBER_MASK;
|
||||
if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
|
||||
== USB_DIR_IN) {
|
||||
if (!usbdev_probe_info.rx_pipe) {
|
||||
usbdev_probe_info.rx_pipe =
|
||||
if (!devinfo->rx_pipe) {
|
||||
devinfo->rx_pipe =
|
||||
usb_rcvbulkpipe(usb, endpoint_num);
|
||||
} else {
|
||||
usbdev_probe_info.rx_pipe2 =
|
||||
devinfo->rx_pipe2 =
|
||||
usb_rcvbulkpipe(usb, endpoint_num);
|
||||
}
|
||||
} else {
|
||||
usbdev_probe_info.tx_pipe =
|
||||
usb_sndbulkpipe(usb, endpoint_num);
|
||||
devinfo->tx_pipe = usb_sndbulkpipe(usb, endpoint_num);
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate interrupt URB and data buffer */
|
||||
/* RNDIS says 8-byte intr, our old drivers used 4-byte */
|
||||
if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16))
|
||||
usbdev_probe_info.intr_size = 8;
|
||||
devinfo->intr_size = 8;
|
||||
else
|
||||
usbdev_probe_info.intr_size = 4;
|
||||
devinfo->intr_size = 4;
|
||||
|
||||
usbdev_probe_info.interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
|
||||
devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
|
||||
|
||||
usbdev_probe_info.device_speed = usb->speed;
|
||||
if (usb->speed == USB_SPEED_HIGH)
|
||||
brcmf_dbg(INFO, "Broadcom high speed USB wireless device detected\n");
|
||||
else
|
||||
brcmf_dbg(INFO, "Broadcom full speed USB wireless device detected\n");
|
||||
|
||||
ret = brcmf_usb_probe_cb(&usb->dev, "", USB_BUS, 0);
|
||||
ret = brcmf_usb_probe_cb(devinfo, "", USB_BUS, 0);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
@ -1533,6 +1520,7 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
|
||||
fail:
|
||||
brcmf_dbg(ERROR, "failed with errno %d\n", ret);
|
||||
kfree(devinfo);
|
||||
usb_set_intfdata(intf, NULL);
|
||||
return ret;
|
||||
|
||||
@ -1541,11 +1529,12 @@ fail:
|
||||
static void
|
||||
brcmf_usb_disconnect(struct usb_interface *intf)
|
||||
{
|
||||
struct usb_device *usb = interface_to_usbdev(intf);
|
||||
struct brcmf_usbdev_info *devinfo;
|
||||
|
||||
brcmf_dbg(TRACE, "enter\n");
|
||||
brcmf_usb_disconnect_cb(brcmf_usb_get_buspub(&usb->dev));
|
||||
usb_set_intfdata(intf, NULL);
|
||||
devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf);
|
||||
brcmf_usb_disconnect_cb(devinfo);
|
||||
kfree(devinfo);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1577,17 +1566,23 @@ static int brcmf_usb_resume(struct usb_interface *intf)
|
||||
}
|
||||
|
||||
#define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c
|
||||
#define BRCMF_USB_DEVICE_ID_43143 0xbd1e
|
||||
#define BRCMF_USB_DEVICE_ID_43236 0xbd17
|
||||
#define BRCMF_USB_DEVICE_ID_43242 0xbd1f
|
||||
#define BRCMF_USB_DEVICE_ID_BCMFW 0x0bdc
|
||||
|
||||
static struct usb_device_id brcmf_usb_devid_table[] = {
|
||||
{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43143) },
|
||||
{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43236) },
|
||||
{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43242) },
|
||||
/* special entry for device with firmware loaded and running */
|
||||
{ USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table);
|
||||
MODULE_FIRMWARE(BRCMF_USB_43143_FW_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME);
|
||||
MODULE_FIRMWARE(BRCMF_USB_43242_FW_NAME);
|
||||
|
||||
/* TODO: suspend and resume entries */
|
||||
static struct usb_driver brcmf_usbdrvr = {
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <linux/ieee80211.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include <net/netlink.h>
|
||||
|
||||
#include <brcmu_utils.h>
|
||||
#include <defs.h>
|
||||
@ -489,8 +490,8 @@ static void brcmf_set_mpc(struct net_device *ndev, int mpc)
|
||||
}
|
||||
}
|
||||
|
||||
static void wl_iscan_prep(struct brcmf_scan_params_le *params_le,
|
||||
struct brcmf_ssid *ssid)
|
||||
static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le,
|
||||
struct brcmf_ssid *ssid)
|
||||
{
|
||||
memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
|
||||
params_le->bss_type = DOT11_BSSTYPE_ANY;
|
||||
@ -544,7 +545,7 @@ brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
|
||||
return -ENOMEM;
|
||||
BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
|
||||
|
||||
wl_iscan_prep(¶ms->params_le, ssid);
|
||||
brcmf_iscan_prep(¶ms->params_le, ssid);
|
||||
|
||||
params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
|
||||
params->action = cpu_to_le16(action);
|
||||
@ -597,9 +598,9 @@ static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
|
||||
}
|
||||
|
||||
static s32
|
||||
__brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
|
||||
struct cfg80211_scan_request *request,
|
||||
struct cfg80211_ssid *this_ssid)
|
||||
brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
|
||||
struct cfg80211_scan_request *request,
|
||||
struct cfg80211_ssid *this_ssid)
|
||||
{
|
||||
struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
|
||||
struct cfg80211_ssid *ssids;
|
||||
@ -690,11 +691,342 @@ scan_out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
|
||||
struct cfg80211_scan_request *request)
|
||||
{
|
||||
u32 n_ssids;
|
||||
u32 n_channels;
|
||||
s32 i;
|
||||
s32 offset;
|
||||
__le16 chanspec;
|
||||
u16 channel;
|
||||
struct ieee80211_channel *req_channel;
|
||||
char *ptr;
|
||||
struct brcmf_ssid ssid;
|
||||
|
||||
memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
|
||||
params_le->bss_type = DOT11_BSSTYPE_ANY;
|
||||
params_le->scan_type = 0;
|
||||
params_le->channel_num = 0;
|
||||
params_le->nprobes = cpu_to_le32(-1);
|
||||
params_le->active_time = cpu_to_le32(-1);
|
||||
params_le->passive_time = cpu_to_le32(-1);
|
||||
params_le->home_time = cpu_to_le32(-1);
|
||||
memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
|
||||
|
||||
/* if request is null exit so it will be all channel broadcast scan */
|
||||
if (!request)
|
||||
return;
|
||||
|
||||
n_ssids = request->n_ssids;
|
||||
n_channels = request->n_channels;
|
||||
/* Copy channel array if applicable */
|
||||
WL_SCAN("### List of channelspecs to scan ### %d\n", n_channels);
|
||||
if (n_channels > 0) {
|
||||
for (i = 0; i < n_channels; i++) {
|
||||
chanspec = 0;
|
||||
req_channel = request->channels[i];
|
||||
channel = ieee80211_frequency_to_channel(
|
||||
req_channel->center_freq);
|
||||
if (req_channel->band == IEEE80211_BAND_2GHZ)
|
||||
chanspec |= WL_CHANSPEC_BAND_2G;
|
||||
else
|
||||
chanspec |= WL_CHANSPEC_BAND_5G;
|
||||
|
||||
if (req_channel->flags & IEEE80211_CHAN_NO_HT40) {
|
||||
chanspec |= WL_CHANSPEC_BW_20;
|
||||
chanspec |= WL_CHANSPEC_CTL_SB_NONE;
|
||||
} else {
|
||||
chanspec |= WL_CHANSPEC_BW_40;
|
||||
if (req_channel->flags &
|
||||
IEEE80211_CHAN_NO_HT40PLUS)
|
||||
chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
|
||||
else
|
||||
chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
|
||||
}
|
||||
|
||||
params_le->channel_list[i] =
|
||||
(channel & WL_CHANSPEC_CHAN_MASK) |
|
||||
chanspec;
|
||||
WL_SCAN("Chan : %d, Channel spec: %x\n",
|
||||
channel, params_le->channel_list[i]);
|
||||
params_le->channel_list[i] =
|
||||
cpu_to_le16(params_le->channel_list[i]);
|
||||
}
|
||||
} else {
|
||||
WL_SCAN("Scanning all channels\n");
|
||||
}
|
||||
/* Copy ssid array if applicable */
|
||||
WL_SCAN("### List of SSIDs to scan ### %d\n", n_ssids);
|
||||
if (n_ssids > 0) {
|
||||
offset = offsetof(struct brcmf_scan_params_le, channel_list) +
|
||||
n_channels * sizeof(u16);
|
||||
offset = roundup(offset, sizeof(u32));
|
||||
ptr = (char *)params_le + offset;
|
||||
for (i = 0; i < n_ssids; i++) {
|
||||
memset(&ssid, 0, sizeof(ssid));
|
||||
ssid.SSID_len = cpu_to_le32(request->ssids[i].ssid_len);
|
||||
memcpy(ssid.SSID, request->ssids[i].ssid,
|
||||
request->ssids[i].ssid_len);
|
||||
if (!ssid.SSID_len)
|
||||
WL_SCAN("%d: Broadcast scan\n", i);
|
||||
else
|
||||
WL_SCAN("%d: scan for %s size =%d\n", i,
|
||||
ssid.SSID, ssid.SSID_len);
|
||||
memcpy(ptr, &ssid, sizeof(ssid));
|
||||
ptr += sizeof(ssid);
|
||||
}
|
||||
} else {
|
||||
WL_SCAN("Broadcast scan %p\n", request->ssids);
|
||||
if ((request->ssids) && request->ssids->ssid_len) {
|
||||
WL_SCAN("SSID %s len=%d\n", params_le->ssid_le.SSID,
|
||||
request->ssids->ssid_len);
|
||||
params_le->ssid_le.SSID_len =
|
||||
cpu_to_le32(request->ssids->ssid_len);
|
||||
memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
|
||||
request->ssids->ssid_len);
|
||||
}
|
||||
}
|
||||
/* Adding mask to channel numbers */
|
||||
params_le->channel_num =
|
||||
cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
|
||||
(n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
|
||||
}
|
||||
|
||||
static s32
|
||||
brcmf_notify_escan_complete(struct brcmf_cfg80211_priv *cfg_priv,
|
||||
struct net_device *ndev,
|
||||
bool aborted, bool fw_abort)
|
||||
{
|
||||
struct brcmf_scan_params_le params_le;
|
||||
struct cfg80211_scan_request *scan_request;
|
||||
s32 err = 0;
|
||||
|
||||
WL_SCAN("Enter\n");
|
||||
|
||||
/* clear scan request, because the FW abort can cause a second call */
|
||||
/* to this functon and might cause a double cfg80211_scan_done */
|
||||
scan_request = cfg_priv->scan_request;
|
||||
cfg_priv->scan_request = NULL;
|
||||
|
||||
if (timer_pending(&cfg_priv->escan_timeout))
|
||||
del_timer_sync(&cfg_priv->escan_timeout);
|
||||
|
||||
if (fw_abort) {
|
||||
/* Do a scan abort to stop the driver's scan engine */
|
||||
WL_SCAN("ABORT scan in firmware\n");
|
||||
memset(¶ms_le, 0, sizeof(params_le));
|
||||
memcpy(params_le.bssid, ether_bcast, ETH_ALEN);
|
||||
params_le.bss_type = DOT11_BSSTYPE_ANY;
|
||||
params_le.scan_type = 0;
|
||||
params_le.channel_num = cpu_to_le32(1);
|
||||
params_le.nprobes = cpu_to_le32(1);
|
||||
params_le.active_time = cpu_to_le32(-1);
|
||||
params_le.passive_time = cpu_to_le32(-1);
|
||||
params_le.home_time = cpu_to_le32(-1);
|
||||
/* Scan is aborted by setting channel_list[0] to -1 */
|
||||
params_le.channel_list[0] = cpu_to_le16(-1);
|
||||
/* E-Scan (or anyother type) can be aborted by SCAN */
|
||||
err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, ¶ms_le,
|
||||
sizeof(params_le));
|
||||
if (err)
|
||||
WL_ERR("Scan abort failed\n");
|
||||
}
|
||||
if (scan_request) {
|
||||
WL_SCAN("ESCAN Completed scan: %s\n",
|
||||
aborted ? "Aborted" : "Done");
|
||||
cfg80211_scan_done(scan_request, aborted);
|
||||
brcmf_set_mpc(ndev, 1);
|
||||
}
|
||||
if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
|
||||
WL_ERR("Scan complete while device not scanning\n");
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static s32
|
||||
brcmf_run_escan(struct brcmf_cfg80211_priv *cfg_priv, struct net_device *ndev,
|
||||
struct cfg80211_scan_request *request, u16 action)
|
||||
{
|
||||
s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
|
||||
offsetof(struct brcmf_escan_params_le, params_le);
|
||||
struct brcmf_escan_params_le *params;
|
||||
s32 err = 0;
|
||||
|
||||
WL_SCAN("E-SCAN START\n");
|
||||
|
||||
if (request != NULL) {
|
||||
/* Allocate space for populating ssids in struct */
|
||||
params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
|
||||
|
||||
/* Allocate space for populating ssids in struct */
|
||||
params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
|
||||
}
|
||||
|
||||
params = kzalloc(params_size, GFP_KERNEL);
|
||||
if (!params) {
|
||||
err = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
|
||||
brcmf_escan_prep(¶ms->params_le, request);
|
||||
params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
|
||||
params->action = cpu_to_le16(action);
|
||||
params->sync_id = cpu_to_le16(0x1234);
|
||||
|
||||
err = brcmf_dev_iovar_setbuf(ndev, "escan", params, params_size,
|
||||
cfg_priv->escan_ioctl_buf, BRCMF_DCMD_MEDLEN);
|
||||
if (err) {
|
||||
if (err == -EBUSY)
|
||||
WL_INFO("system busy : escan canceled\n");
|
||||
else
|
||||
WL_ERR("error (%d)\n", err);
|
||||
}
|
||||
|
||||
kfree(params);
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static s32
|
||||
brcmf_do_escan(struct brcmf_cfg80211_priv *cfg_priv, struct wiphy *wiphy,
|
||||
struct net_device *ndev, struct cfg80211_scan_request *request)
|
||||
{
|
||||
s32 err;
|
||||
__le32 passive_scan;
|
||||
struct brcmf_scan_results *results;
|
||||
|
||||
WL_SCAN("Enter\n");
|
||||
cfg_priv->escan_info.ndev = ndev;
|
||||
cfg_priv->escan_info.wiphy = wiphy;
|
||||
cfg_priv->escan_info.escan_state = WL_ESCAN_STATE_SCANNING;
|
||||
passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
|
||||
err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
|
||||
&passive_scan, sizeof(passive_scan));
|
||||
if (err) {
|
||||
WL_ERR("error (%d)\n", err);
|
||||
return err;
|
||||
}
|
||||
brcmf_set_mpc(ndev, 0);
|
||||
results = (struct brcmf_scan_results *)cfg_priv->escan_info.escan_buf;
|
||||
results->version = 0;
|
||||
results->count = 0;
|
||||
results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
|
||||
|
||||
err = brcmf_run_escan(cfg_priv, ndev, request, WL_ESCAN_ACTION_START);
|
||||
if (err)
|
||||
brcmf_set_mpc(ndev, 1);
|
||||
return err;
|
||||
}
|
||||
|
||||
static s32
|
||||
brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
|
||||
struct cfg80211_scan_request *request,
|
||||
struct cfg80211_ssid *this_ssid)
|
||||
{
|
||||
struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
|
||||
struct cfg80211_ssid *ssids;
|
||||
struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
|
||||
__le32 passive_scan;
|
||||
bool escan_req;
|
||||
bool spec_scan;
|
||||
s32 err;
|
||||
u32 SSID_len;
|
||||
|
||||
WL_SCAN("START ESCAN\n");
|
||||
|
||||
if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
|
||||
WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
|
||||
return -EAGAIN;
|
||||
}
|
||||
if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
|
||||
WL_ERR("Scanning being aborted : status (%lu)\n",
|
||||
cfg_priv->status);
|
||||
return -EAGAIN;
|
||||
}
|
||||
if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
|
||||
WL_ERR("Connecting : status (%lu)\n",
|
||||
cfg_priv->status);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
/* Arm scan timeout timer */
|
||||
mod_timer(&cfg_priv->escan_timeout, jiffies +
|
||||
WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
|
||||
|
||||
escan_req = false;
|
||||
if (request) {
|
||||
/* scan bss */
|
||||
ssids = request->ssids;
|
||||
escan_req = true;
|
||||
} else {
|
||||
/* scan in ibss */
|
||||
/* we don't do escan in ibss */
|
||||
ssids = this_ssid;
|
||||
}
|
||||
|
||||
cfg_priv->scan_request = request;
|
||||
set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
|
||||
if (escan_req) {
|
||||
err = brcmf_do_escan(cfg_priv, wiphy, ndev, request);
|
||||
if (!err)
|
||||
return err;
|
||||
else
|
||||
goto scan_out;
|
||||
} else {
|
||||
WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
|
||||
ssids->ssid, ssids->ssid_len);
|
||||
memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
|
||||
SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
|
||||
sr->ssid_le.SSID_len = cpu_to_le32(0);
|
||||
spec_scan = false;
|
||||
if (SSID_len) {
|
||||
memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
|
||||
sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
|
||||
spec_scan = true;
|
||||
} else
|
||||
WL_SCAN("Broadcast scan\n");
|
||||
|
||||
passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
|
||||
err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
|
||||
&passive_scan, sizeof(passive_scan));
|
||||
if (err) {
|
||||
WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
|
||||
goto scan_out;
|
||||
}
|
||||
brcmf_set_mpc(ndev, 0);
|
||||
err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
|
||||
sizeof(sr->ssid_le));
|
||||
if (err) {
|
||||
if (err == -EBUSY)
|
||||
WL_INFO("BUSY: scan for \"%s\" canceled\n",
|
||||
sr->ssid_le.SSID);
|
||||
else
|
||||
WL_ERR("WLC_SCAN error (%d)\n", err);
|
||||
|
||||
brcmf_set_mpc(ndev, 1);
|
||||
goto scan_out;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
scan_out:
|
||||
clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
|
||||
if (timer_pending(&cfg_priv->escan_timeout))
|
||||
del_timer_sync(&cfg_priv->escan_timeout);
|
||||
cfg_priv->scan_request = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
static s32
|
||||
brcmf_cfg80211_scan(struct wiphy *wiphy,
|
||||
struct cfg80211_scan_request *request)
|
||||
{
|
||||
struct net_device *ndev = request->wdev->netdev;
|
||||
struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
|
||||
s32 err = 0;
|
||||
|
||||
WL_TRACE("Enter\n");
|
||||
@ -702,7 +1034,11 @@ brcmf_cfg80211_scan(struct wiphy *wiphy,
|
||||
if (!check_sys_up(wiphy))
|
||||
return -EIO;
|
||||
|
||||
err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
|
||||
if (cfg_priv->iscan_on)
|
||||
err = brcmf_cfg80211_iscan(wiphy, ndev, request, NULL);
|
||||
else if (cfg_priv->escan_on)
|
||||
err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
|
||||
|
||||
if (err)
|
||||
WL_ERR("scan error (%d)\n", err);
|
||||
|
||||
@ -1876,16 +2212,17 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
|
||||
}
|
||||
|
||||
if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
|
||||
scb_val.val = cpu_to_le32(0);
|
||||
memset(&scb_val, 0, sizeof(scb_val));
|
||||
err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
|
||||
sizeof(struct brcmf_scb_val_le));
|
||||
if (err)
|
||||
if (err) {
|
||||
WL_ERR("Could not get rssi (%d)\n", err);
|
||||
|
||||
rssi = le32_to_cpu(scb_val.val);
|
||||
sinfo->filled |= STATION_INFO_SIGNAL;
|
||||
sinfo->signal = rssi;
|
||||
WL_CONN("RSSI %d dBm\n", rssi);
|
||||
} else {
|
||||
rssi = le32_to_cpu(scb_val.val);
|
||||
sinfo->filled |= STATION_INFO_SIGNAL;
|
||||
sinfo->signal = rssi;
|
||||
WL_CONN("RSSI %d dBm\n", rssi);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
@ -2470,6 +2807,175 @@ static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
|
||||
return err;
|
||||
}
|
||||
|
||||
static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
|
||||
{
|
||||
struct brcmf_cfg80211_priv *cfg_priv =
|
||||
container_of(work, struct brcmf_cfg80211_priv,
|
||||
escan_timeout_work);
|
||||
|
||||
brcmf_notify_escan_complete(cfg_priv,
|
||||
cfg_priv->escan_info.ndev, true, true);
|
||||
}
|
||||
|
||||
static void brcmf_escan_timeout(unsigned long data)
|
||||
{
|
||||
struct brcmf_cfg80211_priv *cfg_priv =
|
||||
(struct brcmf_cfg80211_priv *)data;
|
||||
|
||||
if (cfg_priv->scan_request) {
|
||||
WL_ERR("timer expired\n");
|
||||
if (cfg_priv->escan_on)
|
||||
schedule_work(&cfg_priv->escan_timeout_work);
|
||||
}
|
||||
}
|
||||
|
||||
static s32
|
||||
brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
|
||||
struct brcmf_bss_info_le *bss_info_le)
|
||||
{
|
||||
if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
|
||||
(CHSPEC_BAND(le16_to_cpu(bss_info_le->chanspec)) ==
|
||||
CHSPEC_BAND(le16_to_cpu(bss->chanspec))) &&
|
||||
bss_info_le->SSID_len == bss->SSID_len &&
|
||||
!memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
|
||||
if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
|
||||
(bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
|
||||
/* preserve max RSSI if the measurements are
|
||||
* both on-channel or both off-channel
|
||||
*/
|
||||
if (bss_info_le->RSSI > bss->RSSI)
|
||||
bss->RSSI = bss_info_le->RSSI;
|
||||
} else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
|
||||
(bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
|
||||
/* preserve the on-channel rssi measurement
|
||||
* if the new measurement is off channel
|
||||
*/
|
||||
bss->RSSI = bss_info_le->RSSI;
|
||||
bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static s32
|
||||
brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_priv *cfg_priv,
|
||||
struct net_device *ndev,
|
||||
const struct brcmf_event_msg *e, void *data)
|
||||
{
|
||||
s32 status;
|
||||
s32 err = 0;
|
||||
struct brcmf_escan_result_le *escan_result_le;
|
||||
struct brcmf_bss_info_le *bss_info_le;
|
||||
struct brcmf_bss_info_le *bss = NULL;
|
||||
u32 bi_length;
|
||||
struct brcmf_scan_results *list;
|
||||
u32 i;
|
||||
|
||||
status = be32_to_cpu(e->status);
|
||||
|
||||
if (!ndev || !cfg_priv->escan_on ||
|
||||
!test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
|
||||
WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n",
|
||||
ndev, cfg_priv->escan_on,
|
||||
!test_bit(WL_STATUS_SCANNING, &cfg_priv->status));
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
if (status == BRCMF_E_STATUS_PARTIAL) {
|
||||
WL_SCAN("ESCAN Partial result\n");
|
||||
escan_result_le = (struct brcmf_escan_result_le *) data;
|
||||
if (!escan_result_le) {
|
||||
WL_ERR("Invalid escan result (NULL pointer)\n");
|
||||
goto exit;
|
||||
}
|
||||
if (!cfg_priv->scan_request) {
|
||||
WL_SCAN("result without cfg80211 request\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (le16_to_cpu(escan_result_le->bss_count) != 1) {
|
||||
WL_ERR("Invalid bss_count %d: ignoring\n",
|
||||
escan_result_le->bss_count);
|
||||
goto exit;
|
||||
}
|
||||
bss_info_le = &escan_result_le->bss_info_le;
|
||||
|
||||
bi_length = le32_to_cpu(bss_info_le->length);
|
||||
if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
|
||||
WL_ESCAN_RESULTS_FIXED_SIZE)) {
|
||||
WL_ERR("Invalid bss_info length %d: ignoring\n",
|
||||
bi_length);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!(cfg_to_wiphy(cfg_priv)->interface_modes &
|
||||
BIT(NL80211_IFTYPE_ADHOC))) {
|
||||
if (le16_to_cpu(bss_info_le->capability) &
|
||||
WLAN_CAPABILITY_IBSS) {
|
||||
WL_ERR("Ignoring IBSS result\n");
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
list = (struct brcmf_scan_results *)
|
||||
cfg_priv->escan_info.escan_buf;
|
||||
if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
|
||||
WL_ERR("Buffer is too small: ignoring\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
for (i = 0; i < list->count; i++) {
|
||||
bss = bss ? (struct brcmf_bss_info_le *)
|
||||
((unsigned char *)bss +
|
||||
le32_to_cpu(bss->length)) : list->bss_info_le;
|
||||
if (brcmf_compare_update_same_bss(bss, bss_info_le))
|
||||
goto exit;
|
||||
}
|
||||
memcpy(&(cfg_priv->escan_info.escan_buf[list->buflen]),
|
||||
bss_info_le, bi_length);
|
||||
list->version = le32_to_cpu(bss_info_le->version);
|
||||
list->buflen += bi_length;
|
||||
list->count++;
|
||||
} else {
|
||||
cfg_priv->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
|
||||
if (cfg_priv->scan_request) {
|
||||
cfg_priv->bss_list = (struct brcmf_scan_results *)
|
||||
cfg_priv->escan_info.escan_buf;
|
||||
brcmf_inform_bss(cfg_priv);
|
||||
if (status == BRCMF_E_STATUS_SUCCESS) {
|
||||
WL_SCAN("ESCAN Completed\n");
|
||||
brcmf_notify_escan_complete(cfg_priv, ndev,
|
||||
false, false);
|
||||
} else {
|
||||
WL_ERR("ESCAN Aborted, Event 0x%x\n", status);
|
||||
brcmf_notify_escan_complete(cfg_priv, ndev,
|
||||
true, false);
|
||||
}
|
||||
brcmf_set_mpc(ndev, 1);
|
||||
} else
|
||||
WL_ERR("Unexpected scan result 0x%x\n", status);
|
||||
}
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void brcmf_init_escan(struct brcmf_cfg80211_priv *cfg_priv)
|
||||
{
|
||||
|
||||
if (cfg_priv->escan_on) {
|
||||
cfg_priv->el.handler[BRCMF_E_ESCAN_RESULT] =
|
||||
brcmf_cfg80211_escan_handler;
|
||||
cfg_priv->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
|
||||
/* Init scan_timeout timer */
|
||||
init_timer(&cfg_priv->escan_timeout);
|
||||
cfg_priv->escan_timeout.data = (unsigned long) cfg_priv;
|
||||
cfg_priv->escan_timeout.function = brcmf_escan_timeout;
|
||||
INIT_WORK(&cfg_priv->escan_timeout_work,
|
||||
brcmf_cfg80211_escan_timeout_worker);
|
||||
}
|
||||
}
|
||||
|
||||
static __always_inline void brcmf_delay(u32 ms)
|
||||
{
|
||||
if (ms < 1000 / HZ) {
|
||||
@ -2545,10 +3051,8 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
|
||||
clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
|
||||
|
||||
/* Turn off watchdog timer */
|
||||
if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
|
||||
WL_INFO("Enable MPC\n");
|
||||
if (test_bit(WL_STATUS_READY, &cfg_priv->status))
|
||||
brcmf_set_mpc(ndev, 1);
|
||||
}
|
||||
|
||||
WL_TRACE("Exit\n");
|
||||
|
||||
@ -2723,6 +3227,25 @@ brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
|
||||
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
|
||||
{
|
||||
struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
|
||||
struct net_device *ndev = cfg_priv->wdev->netdev;
|
||||
struct brcmf_dcmd *dcmd = data;
|
||||
struct sk_buff *reply;
|
||||
int ret;
|
||||
|
||||
ret = brcmf_netlink_dcmd(ndev, dcmd);
|
||||
if (ret == 0) {
|
||||
reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
|
||||
nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
|
||||
ret = cfg80211_testmode_reply(reply);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct cfg80211_ops wl_cfg80211_ops = {
|
||||
.change_virtual_intf = brcmf_cfg80211_change_iface,
|
||||
.scan = brcmf_cfg80211_scan,
|
||||
@ -2745,7 +3268,10 @@ static struct cfg80211_ops wl_cfg80211_ops = {
|
||||
.resume = brcmf_cfg80211_resume,
|
||||
.set_pmksa = brcmf_cfg80211_set_pmksa,
|
||||
.del_pmksa = brcmf_cfg80211_del_pmksa,
|
||||
.flush_pmksa = brcmf_cfg80211_flush_pmksa
|
||||
.flush_pmksa = brcmf_cfg80211_flush_pmksa,
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
.testmode_cmd = brcmf_cfg80211_testmode
|
||||
#endif
|
||||
};
|
||||
|
||||
static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
|
||||
@ -3170,10 +3696,8 @@ brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
|
||||
cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
|
||||
|
||||
err = brcmf_inform_bss(cfg_priv);
|
||||
if (err) {
|
||||
if (err)
|
||||
scan_abort = true;
|
||||
goto scan_done_out;
|
||||
}
|
||||
|
||||
scan_done_out:
|
||||
if (cfg_priv->scan_request) {
|
||||
@ -3220,6 +3744,8 @@ static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
|
||||
cfg_priv->profile = NULL;
|
||||
kfree(cfg_priv->scan_req_int);
|
||||
cfg_priv->scan_req_int = NULL;
|
||||
kfree(cfg_priv->escan_ioctl_buf);
|
||||
cfg_priv->escan_ioctl_buf = NULL;
|
||||
kfree(cfg_priv->dcmd_buf);
|
||||
cfg_priv->dcmd_buf = NULL;
|
||||
kfree(cfg_priv->extra_buf);
|
||||
@ -3248,6 +3774,9 @@ static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
|
||||
GFP_KERNEL);
|
||||
if (!cfg_priv->scan_req_int)
|
||||
goto init_priv_mem_out;
|
||||
cfg_priv->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
|
||||
if (!cfg_priv->escan_ioctl_buf)
|
||||
goto init_priv_mem_out;
|
||||
cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
|
||||
if (!cfg_priv->dcmd_buf)
|
||||
goto init_priv_mem_out;
|
||||
@ -3297,18 +3826,28 @@ static struct brcmf_cfg80211_event_q *brcmf_deq_event(
|
||||
|
||||
static s32
|
||||
brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
|
||||
const struct brcmf_event_msg *msg)
|
||||
const struct brcmf_event_msg *msg, void *data)
|
||||
{
|
||||
struct brcmf_cfg80211_event_q *e;
|
||||
s32 err = 0;
|
||||
ulong flags;
|
||||
u32 data_len;
|
||||
u32 total_len;
|
||||
|
||||
e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_ATOMIC);
|
||||
total_len = sizeof(struct brcmf_cfg80211_event_q);
|
||||
if (data)
|
||||
data_len = be32_to_cpu(msg->datalen);
|
||||
else
|
||||
data_len = 0;
|
||||
total_len += data_len;
|
||||
e = kzalloc(total_len, GFP_ATOMIC);
|
||||
if (!e)
|
||||
return -ENOMEM;
|
||||
|
||||
e->etype = event;
|
||||
memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
|
||||
if (data)
|
||||
memcpy(&e->edata, data, data_len);
|
||||
|
||||
spin_lock_irqsave(&cfg_priv->evt_q_lock, flags);
|
||||
list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
|
||||
@ -3374,8 +3913,17 @@ static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
|
||||
|
||||
cfg_priv->scan_request = NULL;
|
||||
cfg_priv->pwr_save = true;
|
||||
#ifdef CONFIG_BRCMISCAN
|
||||
cfg_priv->iscan_on = true; /* iscan on & off switch.
|
||||
we enable iscan per default */
|
||||
cfg_priv->escan_on = false; /* escan on & off switch.
|
||||
we disable escan per default */
|
||||
#else
|
||||
cfg_priv->iscan_on = false; /* iscan on & off switch.
|
||||
we disable iscan per default */
|
||||
cfg_priv->escan_on = true; /* escan on & off switch.
|
||||
we enable escan per default */
|
||||
#endif
|
||||
cfg_priv->roam_on = true; /* roam on & off switch.
|
||||
we enable roam per default */
|
||||
|
||||
@ -3393,6 +3941,7 @@ static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
|
||||
err = brcmf_init_iscan(cfg_priv);
|
||||
if (err)
|
||||
return err;
|
||||
brcmf_init_escan(cfg_priv);
|
||||
brcmf_init_conf(cfg_priv->conf);
|
||||
brcmf_init_prof(cfg_priv->profile);
|
||||
brcmf_link_down(cfg_priv);
|
||||
@ -3477,7 +4026,7 @@ brcmf_cfg80211_event(struct net_device *ndev,
|
||||
u32 event_type = be32_to_cpu(e->event_type);
|
||||
struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
|
||||
|
||||
if (!brcmf_enq_event(cfg_priv, event_type, e))
|
||||
if (!brcmf_enq_event(cfg_priv, event_type, e, data))
|
||||
schedule_work(&cfg_priv->event_work);
|
||||
}
|
||||
|
||||
@ -3551,6 +4100,7 @@ static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
|
||||
setbit(eventmask, BRCMF_E_TXFAIL);
|
||||
setbit(eventmask, BRCMF_E_JOIN_START);
|
||||
setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
|
||||
setbit(eventmask, BRCMF_E_ESCAN_RESULT);
|
||||
|
||||
brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
|
||||
iovbuf, sizeof(iovbuf));
|
||||
|
@ -123,6 +123,13 @@ do { \
|
||||
#define WL_SCAN_UNASSOC_TIME 40
|
||||
#define WL_SCAN_PASSIVE_TIME 120
|
||||
|
||||
#define WL_ESCAN_BUF_SIZE (1024 * 64)
|
||||
#define WL_ESCAN_TIMER_INTERVAL_MS 8000 /* E-Scan timeout */
|
||||
|
||||
#define WL_ESCAN_ACTION_START 1
|
||||
#define WL_ESCAN_ACTION_CONTINUE 2
|
||||
#define WL_ESCAN_ACTION_ABORT 3
|
||||
|
||||
/* dongle status */
|
||||
enum wl_status {
|
||||
WL_STATUS_READY,
|
||||
@ -275,6 +282,19 @@ struct brcmf_cfg80211_pmk_list {
|
||||
struct pmkid foo[MAXPMKID - 1];
|
||||
};
|
||||
|
||||
/* dongle escan state */
|
||||
enum wl_escan_state {
|
||||
WL_ESCAN_STATE_IDLE,
|
||||
WL_ESCAN_STATE_SCANNING
|
||||
};
|
||||
|
||||
struct escan_info {
|
||||
u32 escan_state;
|
||||
u8 escan_buf[WL_ESCAN_BUF_SIZE];
|
||||
struct wiphy *wiphy;
|
||||
struct net_device *ndev;
|
||||
};
|
||||
|
||||
/* dongle private data of cfg80211 interface */
|
||||
struct brcmf_cfg80211_priv {
|
||||
struct wireless_dev *wdev; /* representing wl cfg80211 device */
|
||||
@ -315,6 +335,11 @@ struct brcmf_cfg80211_priv {
|
||||
u8 *dcmd_buf; /* dcmd buffer */
|
||||
u8 *extra_buf; /* maily to grab assoc information */
|
||||
struct dentry *debugfsdir;
|
||||
bool escan_on; /* escan on/off switch */
|
||||
struct escan_info escan_info; /* escan information */
|
||||
struct timer_list escan_timeout; /* Timer for catch scan timeout */
|
||||
struct work_struct escan_timeout_work; /* scan timeout worker */
|
||||
u8 *escan_ioctl_buf;
|
||||
u8 ci[0] __aligned(NETDEV_ALIGN);
|
||||
};
|
||||
|
||||
|
@ -535,9 +535,6 @@ void ai_detach(struct si_pub *sih)
|
||||
{
|
||||
struct si_info *sii;
|
||||
|
||||
struct si_pub *si_local = NULL;
|
||||
memcpy(&si_local, &sih, sizeof(struct si_pub **));
|
||||
|
||||
sii = container_of(sih, struct si_info, pub);
|
||||
|
||||
if (sii == NULL)
|
||||
|
@ -34,6 +34,7 @@
|
||||
#define BCM43235_CHIP_ID 43235
|
||||
#define BCM43236_CHIP_ID 43236
|
||||
#define BCM43238_CHIP_ID 43238
|
||||
#define BCM43241_CHIP_ID 0x4324
|
||||
#define BCM4329_CHIP_ID 0x4329
|
||||
#define BCM4330_CHIP_ID 0x4330
|
||||
#define BCM4331_CHIP_ID 0x4331
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include "hostap_wlan.h"
|
||||
#include "hostap.h"
|
||||
#include "hostap_ap.h"
|
||||
@ -463,8 +464,7 @@ static void handle_info_queue_scanresults(local_info_t *local)
|
||||
prism2_host_roaming(local);
|
||||
|
||||
if (local->host_roaming == 2 && local->iw_mode == IW_MODE_INFRA &&
|
||||
memcmp(local->preferred_ap, "\x00\x00\x00\x00\x00\x00",
|
||||
ETH_ALEN) != 0) {
|
||||
!is_zero_ether_addr(local->preferred_ap)) {
|
||||
/*
|
||||
* Firmware seems to be getting into odd state in host_roaming
|
||||
* mode 2 when hostscan is used without join command, so try
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <net/lib80211.h>
|
||||
|
||||
#include "hostap_wlan.h"
|
||||
@ -3221,8 +3222,7 @@ static int prism2_ioctl_siwencodeext(struct net_device *dev,
|
||||
return -EINVAL;
|
||||
|
||||
addr = ext->addr.sa_data;
|
||||
if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
|
||||
addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
|
||||
if (is_broadcast_ether_addr(addr)) {
|
||||
sta_ptr = NULL;
|
||||
crypt = &local->crypt_info.crypt[i];
|
||||
} else {
|
||||
@ -3394,8 +3394,7 @@ static int prism2_ioctl_giwencodeext(struct net_device *dev,
|
||||
i--;
|
||||
|
||||
addr = ext->addr.sa_data;
|
||||
if (addr[0] == 0xff && addr[1] == 0xff && addr[2] == 0xff &&
|
||||
addr[3] == 0xff && addr[4] == 0xff && addr[5] == 0xff) {
|
||||
if (is_broadcast_ether_addr(addr)) {
|
||||
sta_ptr = NULL;
|
||||
crypt = &local->crypt_info.crypt[i];
|
||||
} else {
|
||||
@ -3458,9 +3457,7 @@ static int prism2_ioctl_set_encryption(local_info_t *local,
|
||||
param->u.crypt.key_len)
|
||||
return -EINVAL;
|
||||
|
||||
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
|
||||
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
|
||||
param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
|
||||
if (is_broadcast_ether_addr(param->sta_addr)) {
|
||||
if (param->u.crypt.idx >= WEP_KEYS)
|
||||
return -EINVAL;
|
||||
sta_ptr = NULL;
|
||||
@ -3593,9 +3590,7 @@ static int prism2_ioctl_get_encryption(local_info_t *local,
|
||||
if (max_key_len < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
|
||||
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
|
||||
param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
|
||||
if (is_broadcast_ether_addr(param->sta_addr)) {
|
||||
sta_ptr = NULL;
|
||||
if (param->u.crypt.idx >= WEP_KEYS)
|
||||
param->u.crypt.idx = local->crypt_info.tx_keyidx;
|
||||
|
@ -1084,7 +1084,7 @@ int prism2_sta_deauth(local_info_t *local, u16 reason)
|
||||
__le16 val = cpu_to_le16(reason);
|
||||
|
||||
if (local->iw_mode != IW_MODE_INFRA ||
|
||||
memcmp(local->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0 ||
|
||||
is_zero_ether_addr(local->bssid) ||
|
||||
memcmp(local->bssid, "\x44\x44\x44\x44\x44\x44", ETH_ALEN) == 0)
|
||||
return 0;
|
||||
|
||||
|
@ -6964,13 +6964,6 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
|
||||
struct ipw2100_priv *priv = libipw_priv(dev);
|
||||
int err = 0;
|
||||
|
||||
static const unsigned char any[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
static const unsigned char off[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
// sanity checks
|
||||
if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
|
||||
return -EINVAL;
|
||||
@ -6981,8 +6974,8 @@ static int ipw2100_wx_set_wap(struct net_device *dev,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
|
||||
!memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
|
||||
if (is_broadcast_ether_addr(wrqu->ap_addr.sa_data) ||
|
||||
is_zero_ether_addr(wrqu->ap_addr.sa_data)) {
|
||||
/* we disable mandatory BSSID association */
|
||||
IPW_DEBUG_WX("exit - disable mandatory BSSID\n");
|
||||
priv->config &= ~CFG_STATIC_BSSID;
|
||||
|
@ -9037,18 +9037,11 @@ static int ipw_wx_set_wap(struct net_device *dev,
|
||||
{
|
||||
struct ipw_priv *priv = libipw_priv(dev);
|
||||
|
||||
static const unsigned char any[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
static const unsigned char off[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
|
||||
return -EINVAL;
|
||||
mutex_lock(&priv->mutex);
|
||||
if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
|
||||
!memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
|
||||
if (is_broadcast_ether_addr(wrqu->ap_addr.sa_data) ||
|
||||
is_zero_ether_addr(wrqu->ap_addr.sa_data)) {
|
||||
/* we disable mandatory BSSID association */
|
||||
IPW_DEBUG_WX("Setting AP BSSID to ANY\n");
|
||||
priv->config &= ~CFG_STATIC_BSSID;
|
||||
|
@ -1055,8 +1055,9 @@ struct iwl_wep_cmd {
|
||||
#define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1)
|
||||
#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2)
|
||||
#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3)
|
||||
#define RX_RES_PHY_FLAGS_ANTENNA_MSK 0xf0
|
||||
#define RX_RES_PHY_FLAGS_ANTENNA_MSK 0x70
|
||||
#define RX_RES_PHY_FLAGS_ANTENNA_POS 4
|
||||
#define RX_RES_PHY_FLAGS_AGG_MSK cpu_to_le16(1 << 7)
|
||||
|
||||
#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8)
|
||||
#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8)
|
||||
|
@ -771,6 +771,7 @@ struct iwl_priv {
|
||||
u8 agg_tids_count;
|
||||
|
||||
struct iwl_rx_phy_res last_phy_res;
|
||||
u32 ampdu_ref;
|
||||
bool last_phy_res_valid;
|
||||
|
||||
/*
|
||||
|
@ -667,6 +667,7 @@ static int iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
|
||||
priv->last_phy_res_valid = true;
|
||||
priv->ampdu_ref++;
|
||||
memcpy(&priv->last_phy_res, pkt->data,
|
||||
sizeof(struct iwl_rx_phy_res));
|
||||
return 0;
|
||||
@ -981,6 +982,16 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv,
|
||||
if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
|
||||
rx_status.flag |= RX_FLAG_SHORTPRE;
|
||||
|
||||
if (phy_res->phy_flags & RX_RES_PHY_FLAGS_AGG_MSK) {
|
||||
/*
|
||||
* We know which subframes of an A-MPDU belong
|
||||
* together since we get a single PHY response
|
||||
* from the firmware for all of them
|
||||
*/
|
||||
rx_status.flag |= RX_FLAG_AMPDU_DETAILS;
|
||||
rx_status.ampdu_reference = priv->ampdu_ref;
|
||||
}
|
||||
|
||||
/* Set up the HT phy flags */
|
||||
if (rate_n_flags & RATE_MCS_HT_MSK)
|
||||
rx_status.flag |= RX_FLAG_HT;
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include <linux/tracepoint.h>
|
||||
#include <linux/device.h>
|
||||
#include "iwl-trans.h"
|
||||
|
||||
|
||||
#if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__)
|
||||
@ -237,27 +238,34 @@ TRACE_EVENT(iwlwifi_dbg,
|
||||
#define TRACE_SYSTEM iwlwifi
|
||||
|
||||
TRACE_EVENT(iwlwifi_dev_hcmd,
|
||||
TP_PROTO(const struct device *dev, u32 flags,
|
||||
const void *hcmd0, size_t len0,
|
||||
const void *hcmd1, size_t len1,
|
||||
const void *hcmd2, size_t len2),
|
||||
TP_ARGS(dev, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2),
|
||||
TP_PROTO(const struct device *dev,
|
||||
struct iwl_host_cmd *cmd, u16 total_size,
|
||||
const void *hdr, size_t hdr_len),
|
||||
TP_ARGS(dev, cmd, total_size, hdr, hdr_len),
|
||||
TP_STRUCT__entry(
|
||||
DEV_ENTRY
|
||||
__dynamic_array(u8, hcmd0, len0)
|
||||
__dynamic_array(u8, hcmd1, len1)
|
||||
__dynamic_array(u8, hcmd2, len2)
|
||||
__dynamic_array(u8, hcmd, total_size)
|
||||
__field(u32, flags)
|
||||
),
|
||||
TP_fast_assign(
|
||||
int i, offset = hdr_len;
|
||||
|
||||
DEV_ASSIGN;
|
||||
memcpy(__get_dynamic_array(hcmd0), hcmd0, len0);
|
||||
memcpy(__get_dynamic_array(hcmd1), hcmd1, len1);
|
||||
memcpy(__get_dynamic_array(hcmd2), hcmd2, len2);
|
||||
__entry->flags = flags;
|
||||
__entry->flags = cmd->flags;
|
||||
memcpy(__get_dynamic_array(hcmd), hdr, hdr_len);
|
||||
|
||||
for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
|
||||
if (!cmd->len[i])
|
||||
continue;
|
||||
if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
|
||||
continue;
|
||||
memcpy((u8 *)__get_dynamic_array(hcmd) + offset,
|
||||
cmd->data[i], cmd->len[i]);
|
||||
offset += cmd->len[i];
|
||||
}
|
||||
),
|
||||
TP_printk("[%s] hcmd %#.2x (%ssync)",
|
||||
__get_str(dev), ((u8 *)__get_dynamic_array(hcmd0))[0],
|
||||
__get_str(dev), ((u8 *)__get_dynamic_array(hcmd))[0],
|
||||
__entry->flags & CMD_ASYNC ? "a" : "")
|
||||
);
|
||||
|
||||
|
@ -85,8 +85,6 @@ struct iwl_eeprom_data {
|
||||
int n_hw_addrs;
|
||||
u8 hw_addr[ETH_ALEN];
|
||||
|
||||
u16 radio_config;
|
||||
|
||||
u8 calib_version;
|
||||
__le16 calib_voltage;
|
||||
|
||||
|
@ -522,11 +522,6 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
|
||||
bool had_nocopy = false;
|
||||
int i;
|
||||
u32 cmd_pos;
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
|
||||
const void *trace_bufs[IWL_MAX_CMD_TFDS + 1] = {};
|
||||
int trace_lens[IWL_MAX_CMD_TFDS + 1] = {};
|
||||
int trace_idx;
|
||||
#endif
|
||||
|
||||
copy_size = sizeof(out_cmd->hdr);
|
||||
cmd_size = sizeof(out_cmd->hdr);
|
||||
@ -628,11 +623,6 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
|
||||
dma_unmap_len_set(out_meta, len, copy_size);
|
||||
|
||||
iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, copy_size, 1);
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
|
||||
trace_bufs[0] = &out_cmd->hdr;
|
||||
trace_lens[0] = copy_size;
|
||||
trace_idx = 1;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
|
||||
if (!cmd->len[i])
|
||||
@ -651,25 +641,14 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
|
||||
|
||||
iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr,
|
||||
cmd->len[i], 0);
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
|
||||
trace_bufs[trace_idx] = cmd->data[i];
|
||||
trace_lens[trace_idx] = cmd->len[i];
|
||||
trace_idx++;
|
||||
#endif
|
||||
}
|
||||
|
||||
out_meta->flags = cmd->flags;
|
||||
|
||||
txq->need_update = 1;
|
||||
|
||||
/* check that tracing gets all possible blocks */
|
||||
BUILD_BUG_ON(IWL_MAX_CMD_TFDS + 1 != 3);
|
||||
#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
|
||||
trace_iwlwifi_dev_hcmd(trans->dev, cmd->flags,
|
||||
trace_bufs[0], trace_lens[0],
|
||||
trace_bufs[1], trace_lens[1],
|
||||
trace_bufs[2], trace_lens[2]);
|
||||
#endif
|
||||
trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size,
|
||||
&out_cmd->hdr, copy_size);
|
||||
|
||||
/* start timer if queue currently empty */
|
||||
if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout)
|
||||
|
@ -1159,6 +1159,22 @@ void lbs_set_mac_control(struct lbs_private *priv)
|
||||
lbs_deb_leave(LBS_DEB_CMD);
|
||||
}
|
||||
|
||||
int lbs_set_mac_control_sync(struct lbs_private *priv)
|
||||
{
|
||||
struct cmd_ds_mac_control cmd;
|
||||
int ret = 0;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CMD);
|
||||
|
||||
cmd.hdr.size = cpu_to_le16(sizeof(cmd));
|
||||
cmd.action = cpu_to_le16(priv->mac_control);
|
||||
cmd.reserved = 0;
|
||||
ret = lbs_cmd_with_response(priv, CMD_MAC_CONTROL, &cmd);
|
||||
|
||||
lbs_deb_leave(LBS_DEB_CMD);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* lbs_allocate_cmd_buffer - allocates the command buffer and links
|
||||
* it to command free queue
|
||||
|
@ -96,6 +96,7 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv);
|
||||
int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on);
|
||||
|
||||
void lbs_set_mac_control(struct lbs_private *priv);
|
||||
int lbs_set_mac_control_sync(struct lbs_private *priv);
|
||||
|
||||
int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
|
||||
s16 *maxlevel);
|
||||
|
@ -1326,6 +1326,11 @@ static int if_sdio_suspend(struct device *dev)
|
||||
|
||||
mmc_pm_flag_t flags = sdio_get_host_pm_caps(func);
|
||||
|
||||
/* If we're powered off anyway, just let the mmc layer remove the
|
||||
* card. */
|
||||
if (!lbs_iface_active(card->priv))
|
||||
return -ENOSYS;
|
||||
|
||||
dev_info(dev, "%s: suspend: PM flags = 0x%x\n",
|
||||
sdio_func_id(func), flags);
|
||||
|
||||
|
@ -682,8 +682,10 @@ static int lbs_setup_firmware(struct lbs_private *priv)
|
||||
|
||||
/* Send cmd to FW to enable 11D function */
|
||||
ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_11D_ENABLE, 1);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
lbs_set_mac_control(priv);
|
||||
ret = lbs_set_mac_control_sync(priv);
|
||||
done:
|
||||
lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
|
||||
return ret;
|
||||
|
@ -175,23 +175,6 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function handles the command response of 11n configuration request.
|
||||
*
|
||||
* Handling includes changing the header fields into CPU format.
|
||||
*/
|
||||
int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp,
|
||||
struct mwifiex_ds_11n_tx_cfg *tx_cfg)
|
||||
{
|
||||
struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg;
|
||||
|
||||
if (tx_cfg) {
|
||||
tx_cfg->tx_htcap = le16_to_cpu(htcfg->ht_tx_cap);
|
||||
tx_cfg->tx_htinfo = le16_to_cpu(htcfg->ht_tx_info);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function prepares command of reconfigure Tx buffer.
|
||||
*
|
||||
@ -257,27 +240,6 @@ int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function handles the command response of AMSDU aggregation
|
||||
* control request.
|
||||
*
|
||||
* Handling includes changing the header fields into CPU format.
|
||||
*/
|
||||
int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp,
|
||||
struct mwifiex_ds_11n_amsdu_aggr_ctrl
|
||||
*amsdu_aggr_ctrl)
|
||||
{
|
||||
struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl =
|
||||
&resp->params.amsdu_aggr_ctrl;
|
||||
|
||||
if (amsdu_aggr_ctrl) {
|
||||
amsdu_aggr_ctrl->enable = le16_to_cpu(amsdu_ctrl->enable);
|
||||
amsdu_aggr_ctrl->curr_buf_size =
|
||||
le16_to_cpu(amsdu_ctrl->curr_buf_size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function prepares 11n configuration command.
|
||||
*
|
||||
|
@ -28,8 +28,6 @@ int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_command *resp);
|
||||
int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_command *resp);
|
||||
int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp,
|
||||
struct mwifiex_ds_11n_tx_cfg *tx_cfg);
|
||||
int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd, u16 cmd_action,
|
||||
struct mwifiex_ds_11n_tx_cfg *txcfg);
|
||||
|
||||
@ -60,9 +58,6 @@ int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv,
|
||||
struct mwifiex_ds_rx_reorder_tbl *buf);
|
||||
int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
|
||||
struct mwifiex_ds_tx_ba_stream_tbl *buf);
|
||||
int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp,
|
||||
struct mwifiex_ds_11n_amsdu_aggr_ctrl
|
||||
*amsdu_aggr_ctrl);
|
||||
int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_command *cmd,
|
||||
int cmd_action, u16 *buf_size);
|
||||
|
@ -37,6 +37,36 @@ static const struct ieee80211_iface_combination mwifiex_iface_comb_ap_sta = {
|
||||
.beacon_int_infra_match = true,
|
||||
};
|
||||
|
||||
static const struct ieee80211_regdomain mwifiex_world_regdom_custom = {
|
||||
.n_reg_rules = 7,
|
||||
.alpha2 = "99",
|
||||
.reg_rules = {
|
||||
/* Channel 1 - 11 */
|
||||
REG_RULE(2412-10, 2462+10, 40, 3, 20, 0),
|
||||
/* Channel 12 - 13 */
|
||||
REG_RULE(2467-10, 2472+10, 20, 3, 20,
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
|
||||
/* Channel 14 */
|
||||
REG_RULE(2484-10, 2484+10, 20, 3, 20,
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS |
|
||||
NL80211_RRF_NO_OFDM),
|
||||
/* Channel 36 - 48 */
|
||||
REG_RULE(5180-10, 5240+10, 40, 3, 20,
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
|
||||
/* Channel 149 - 165 */
|
||||
REG_RULE(5745-10, 5825+10, 40, 3, 20,
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS),
|
||||
/* Channel 52 - 64 */
|
||||
REG_RULE(5260-10, 5320+10, 40, 3, 30,
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS |
|
||||
NL80211_RRF_DFS),
|
||||
/* Channel 100 - 140 */
|
||||
REG_RULE(5500-10, 5700+10, 40, 3, 30,
|
||||
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS |
|
||||
NL80211_RRF_DFS),
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* This function maps the nl802.11 channel type into driver channel type.
|
||||
*
|
||||
@ -969,15 +999,18 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
|
||||
|
||||
bss_cfg->channel =
|
||||
(u8)ieee80211_frequency_to_channel(params->channel->center_freq);
|
||||
bss_cfg->band_cfg = BAND_CONFIG_MANUAL;
|
||||
|
||||
/* Set appropriate bands */
|
||||
if (params->channel->band == IEEE80211_BAND_2GHZ) {
|
||||
bss_cfg->band_cfg = BAND_CONFIG_BG;
|
||||
|
||||
if (params->channel_type == NL80211_CHAN_NO_HT)
|
||||
config_bands = BAND_B | BAND_G;
|
||||
else
|
||||
config_bands = BAND_B | BAND_G | BAND_GN;
|
||||
} else {
|
||||
bss_cfg->band_cfg = BAND_CONFIG_A;
|
||||
|
||||
if (params->channel_type == NL80211_CHAN_NO_HT)
|
||||
config_bands = BAND_A;
|
||||
else
|
||||
@ -988,6 +1021,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
|
||||
~priv->adapter->fw_bands))
|
||||
priv->adapter->config_bands = config_bands;
|
||||
|
||||
mwifiex_set_uap_rates(bss_cfg, params);
|
||||
mwifiex_send_domain_info_cmd_fw(wiphy);
|
||||
|
||||
if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
|
||||
@ -1153,7 +1187,6 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
|
||||
~priv->adapter->fw_bands))
|
||||
priv->adapter->config_bands = config_bands;
|
||||
}
|
||||
mwifiex_send_domain_info_cmd_fw(priv->wdev->wiphy);
|
||||
}
|
||||
|
||||
/* As this is new association, clear locally stored
|
||||
@ -1637,7 +1670,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
|
||||
|
||||
priv->bss_type = MWIFIEX_BSS_TYPE_STA;
|
||||
priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
|
||||
priv->bss_priority = MWIFIEX_BSS_ROLE_STA;
|
||||
priv->bss_priority = 0;
|
||||
priv->bss_role = MWIFIEX_BSS_ROLE_STA;
|
||||
priv->bss_num = 0;
|
||||
|
||||
@ -1660,7 +1693,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
|
||||
|
||||
priv->bss_type = MWIFIEX_BSS_TYPE_UAP;
|
||||
priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
|
||||
priv->bss_priority = MWIFIEX_BSS_ROLE_UAP;
|
||||
priv->bss_priority = 0;
|
||||
priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
|
||||
priv->bss_started = 0;
|
||||
priv->bss_num = 0;
|
||||
@ -1830,7 +1863,10 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
|
||||
memcpy(wiphy->perm_addr, priv->curr_addr, ETH_ALEN);
|
||||
wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
|
||||
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
|
||||
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
|
||||
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
|
||||
WIPHY_FLAG_CUSTOM_REGULATORY;
|
||||
|
||||
wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom);
|
||||
|
||||
wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
|
||||
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2;
|
||||
@ -1859,8 +1895,9 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
|
||||
return ret;
|
||||
}
|
||||
country_code = mwifiex_11d_code_2_region(priv->adapter->region_code);
|
||||
if (country_code && regulatory_hint(wiphy, country_code))
|
||||
dev_err(adapter->dev, "regulatory_hint() failed\n");
|
||||
if (country_code)
|
||||
dev_info(adapter->dev,
|
||||
"ignoring F/W country code %2.2s\n", country_code);
|
||||
|
||||
adapter->wiphy = wiphy;
|
||||
return ret;
|
||||
|
@ -170,7 +170,20 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
|
||||
cmd_code = le16_to_cpu(host_cmd->command);
|
||||
cmd_size = le16_to_cpu(host_cmd->size);
|
||||
|
||||
skb_trim(cmd_node->cmd_skb, cmd_size);
|
||||
/* Adjust skb length */
|
||||
if (cmd_node->cmd_skb->len > cmd_size)
|
||||
/*
|
||||
* cmd_size is less than sizeof(struct host_cmd_ds_command).
|
||||
* Trim off the unused portion.
|
||||
*/
|
||||
skb_trim(cmd_node->cmd_skb, cmd_size);
|
||||
else if (cmd_node->cmd_skb->len < cmd_size)
|
||||
/*
|
||||
* cmd_size is larger than sizeof(struct host_cmd_ds_command)
|
||||
* because we have appended custom IE TLV. Increase skb length
|
||||
* accordingly.
|
||||
*/
|
||||
skb_put(cmd_node->cmd_skb, cmd_size - cmd_node->cmd_skb->len);
|
||||
|
||||
do_gettimeofday(&tstamp);
|
||||
dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d,"
|
||||
|
@ -108,6 +108,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
|
||||
#define MGMT_MASK_BEACON 0x100
|
||||
|
||||
#define TLV_TYPE_UAP_SSID 0x0000
|
||||
#define TLV_TYPE_UAP_RATES 0x0001
|
||||
|
||||
#define PROPRIETARY_TLV_BASE_ID 0x0100
|
||||
#define TLV_TYPE_KEY_MATERIAL (PROPRIETARY_TLV_BASE_ID + 0)
|
||||
@ -309,7 +310,7 @@ enum ENH_PS_MODES {
|
||||
#define HostCmd_SCAN_RADIO_TYPE_A 1
|
||||
|
||||
#define HOST_SLEEP_CFG_CANCEL 0xffffffff
|
||||
#define HOST_SLEEP_CFG_COND_DEF 0x0000000f
|
||||
#define HOST_SLEEP_CFG_COND_DEF 0x00000000
|
||||
#define HOST_SLEEP_CFG_GPIO_DEF 0xff
|
||||
#define HOST_SLEEP_CFG_GAP_DEF 0
|
||||
|
||||
@ -1284,6 +1285,11 @@ struct host_cmd_tlv_ssid {
|
||||
u8 ssid[0];
|
||||
} __packed;
|
||||
|
||||
struct host_cmd_tlv_rates {
|
||||
struct host_cmd_tlv tlv;
|
||||
u8 rates[0];
|
||||
} __packed;
|
||||
|
||||
struct host_cmd_tlv_bcast_ssid {
|
||||
struct host_cmd_tlv tlv;
|
||||
u8 bcast_ctl;
|
||||
|
@ -73,7 +73,6 @@ static void scan_delay_timer_fn(unsigned long data)
|
||||
list_for_each_entry_safe(cmd_node, tmp_node,
|
||||
&adapter->scan_pending_q, list) {
|
||||
list_del(&cmd_node->list);
|
||||
cmd_node->wait_q_enabled = false;
|
||||
mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
|
||||
}
|
||||
spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
|
||||
@ -92,6 +91,11 @@ static void scan_delay_timer_fn(unsigned long data)
|
||||
kfree(priv->user_scan_cfg);
|
||||
priv->user_scan_cfg = NULL;
|
||||
}
|
||||
|
||||
if (priv->scan_pending_on_block) {
|
||||
priv->scan_pending_on_block = false;
|
||||
up(&priv->async_sem);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,11 @@ struct wep_key {
|
||||
|
||||
#define KEY_MGMT_ON_HOST 0x03
|
||||
#define MWIFIEX_AUTH_MODE_AUTO 0xFF
|
||||
#define BAND_CONFIG_MANUAL 0x00
|
||||
#define BAND_CONFIG_BG 0x00
|
||||
#define BAND_CONFIG_A 0x01
|
||||
#define MWIFIEX_SUPPORTED_RATES 14
|
||||
#define MWIFIEX_SUPPORTED_RATES_EXT 32
|
||||
|
||||
struct mwifiex_uap_bss_param {
|
||||
u8 channel;
|
||||
u8 band_cfg;
|
||||
@ -100,6 +104,7 @@ struct mwifiex_uap_bss_param {
|
||||
struct wpa_param wpa_cfg;
|
||||
struct wep_key wep_cfg[NUM_WEP_KEYS];
|
||||
struct ieee80211_ht_cap ht_cap;
|
||||
u8 rates[MWIFIEX_SUPPORTED_RATES];
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -72,7 +72,6 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
|
||||
goto error;
|
||||
|
||||
adapter->priv[i]->adapter = adapter;
|
||||
adapter->priv[i]->bss_priority = i;
|
||||
adapter->priv_num++;
|
||||
}
|
||||
mwifiex_init_lock_list(adapter);
|
||||
|
@ -116,6 +116,7 @@ enum {
|
||||
#define MAX_BITMAP_RATES_SIZE 10
|
||||
|
||||
#define MAX_CHANNEL_BAND_BG 14
|
||||
#define MAX_CHANNEL_BAND_A 165
|
||||
|
||||
#define MAX_FREQUENCY_BAND_BG 2484
|
||||
|
||||
@ -249,10 +250,6 @@ struct ieee_types_header {
|
||||
u8 len;
|
||||
} __packed;
|
||||
|
||||
#define MWIFIEX_SUPPORTED_RATES 14
|
||||
|
||||
#define MWIFIEX_SUPPORTED_RATES_EXT 32
|
||||
|
||||
struct ieee_types_vendor_specific {
|
||||
struct ieee_types_vendor_header vend_hdr;
|
||||
u8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_vendor_header)];
|
||||
@ -487,6 +484,7 @@ struct mwifiex_private {
|
||||
s32 cqm_rssi_thold;
|
||||
u32 cqm_rssi_hyst;
|
||||
u8 subsc_evt_rssi_state;
|
||||
struct mwifiex_ds_misc_subsc_evt async_subsc_evt_storage;
|
||||
struct mwifiex_ie mgmt_ie[MAX_MGMT_IE_INDEX];
|
||||
u16 beacon_idx;
|
||||
u16 proberesp_idx;
|
||||
@ -814,6 +812,7 @@ struct mwifiex_sta_node *
|
||||
mwifiex_get_sta_entry(struct mwifiex_private *priv, u8 *mac);
|
||||
void mwifiex_delete_all_station_list(struct mwifiex_private *priv);
|
||||
void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb);
|
||||
void *mwifiex_process_uap_txpd(struct mwifiex_private *, struct sk_buff *skb);
|
||||
int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta);
|
||||
int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd,
|
||||
struct mwifiex_scan_cmd_config *scan_cfg);
|
||||
@ -872,6 +871,8 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv,
|
||||
void mwifiex_set_ht_params(struct mwifiex_private *priv,
|
||||
struct mwifiex_uap_bss_param *bss_cfg,
|
||||
struct cfg80211_ap_settings *params);
|
||||
void mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg,
|
||||
struct cfg80211_ap_settings *params);
|
||||
|
||||
/*
|
||||
* This function checks if the queuing is RA based or not.
|
||||
|
@ -726,7 +726,6 @@ mwifiex_config_scan(struct mwifiex_private *priv,
|
||||
struct mwifiex_ie_types_num_probes *num_probes_tlv;
|
||||
struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv;
|
||||
struct mwifiex_ie_types_rates_param_set *rates_tlv;
|
||||
const u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
|
||||
u8 *tlv_pos;
|
||||
u32 num_probes;
|
||||
u32 ssid_len;
|
||||
@ -840,8 +839,7 @@ mwifiex_config_scan(struct mwifiex_private *priv,
|
||||
* or BSSID filter applied to the scan results in the firmware.
|
||||
*/
|
||||
if ((i && ssid_filter) ||
|
||||
memcmp(scan_cfg_out->specific_bssid, &zero_mac,
|
||||
sizeof(zero_mac)))
|
||||
!is_zero_ether_addr(scan_cfg_out->specific_bssid))
|
||||
*filtered_scan = true;
|
||||
} else {
|
||||
scan_cfg_out->bss_mode = (u8) adapter->scan_mode;
|
||||
|
@ -551,7 +551,6 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
|
||||
struct host_cmd_tlv_mac_addr *tlv_mac;
|
||||
u16 key_param_len = 0, cmd_size;
|
||||
int ret = 0;
|
||||
const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
cmd->command = cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL);
|
||||
key_material->action = cpu_to_le16(cmd_action);
|
||||
@ -593,7 +592,7 @@ mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
|
||||
/* set 0 when re-key */
|
||||
key_material->key_param_set.key[1] = 0;
|
||||
|
||||
if (0 != memcmp(enc_key->mac_addr, bc_mac, sizeof(bc_mac))) {
|
||||
if (!is_broadcast_ether_addr(enc_key->mac_addr)) {
|
||||
/* WAPI pairwise key: unicast */
|
||||
key_material->key_param_set.key_info |=
|
||||
cpu_to_le16(KEY_UNICAST);
|
||||
|
@ -123,7 +123,8 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv,
|
||||
{
|
||||
struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp =
|
||||
&resp->params.rssi_info_rsp;
|
||||
struct mwifiex_ds_misc_subsc_evt subsc_evt;
|
||||
struct mwifiex_ds_misc_subsc_evt *subsc_evt =
|
||||
&priv->async_subsc_evt_storage;
|
||||
|
||||
priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last);
|
||||
priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last);
|
||||
@ -140,26 +141,27 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv,
|
||||
if (priv->subsc_evt_rssi_state == EVENT_HANDLED)
|
||||
return 0;
|
||||
|
||||
memset(subsc_evt, 0x00, sizeof(struct mwifiex_ds_misc_subsc_evt));
|
||||
|
||||
/* Resubscribe low and high rssi events with new thresholds */
|
||||
memset(&subsc_evt, 0x00, sizeof(struct mwifiex_ds_misc_subsc_evt));
|
||||
subsc_evt.events = BITMASK_BCN_RSSI_LOW | BITMASK_BCN_RSSI_HIGH;
|
||||
subsc_evt.action = HostCmd_ACT_BITWISE_SET;
|
||||
subsc_evt->events = BITMASK_BCN_RSSI_LOW | BITMASK_BCN_RSSI_HIGH;
|
||||
subsc_evt->action = HostCmd_ACT_BITWISE_SET;
|
||||
if (priv->subsc_evt_rssi_state == RSSI_LOW_RECVD) {
|
||||
subsc_evt.bcn_l_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg -
|
||||
subsc_evt->bcn_l_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg -
|
||||
priv->cqm_rssi_hyst);
|
||||
subsc_evt.bcn_h_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold);
|
||||
subsc_evt->bcn_h_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold);
|
||||
} else if (priv->subsc_evt_rssi_state == RSSI_HIGH_RECVD) {
|
||||
subsc_evt.bcn_l_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold);
|
||||
subsc_evt.bcn_h_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg +
|
||||
subsc_evt->bcn_l_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold);
|
||||
subsc_evt->bcn_h_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg +
|
||||
priv->cqm_rssi_hyst);
|
||||
}
|
||||
subsc_evt.bcn_l_rssi_cfg.evt_freq = 1;
|
||||
subsc_evt.bcn_h_rssi_cfg.evt_freq = 1;
|
||||
subsc_evt->bcn_l_rssi_cfg.evt_freq = 1;
|
||||
subsc_evt->bcn_h_rssi_cfg.evt_freq = 1;
|
||||
|
||||
priv->subsc_evt_rssi_state = EVENT_HANDLED;
|
||||
|
||||
mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
|
||||
0, 0, &subsc_evt);
|
||||
0, 0, subsc_evt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -736,7 +738,6 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv,
|
||||
{
|
||||
struct host_cmd_ds_802_11_ibss_status *ibss_coal_resp =
|
||||
&(resp->params.ibss_coalescing);
|
||||
u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
if (le16_to_cpu(ibss_coal_resp->action) == HostCmd_ACT_GEN_SET)
|
||||
return 0;
|
||||
@ -745,7 +746,7 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv,
|
||||
"info: new BSSID %pM\n", ibss_coal_resp->bssid);
|
||||
|
||||
/* If rsp has NULL BSSID, Just return..... No Action */
|
||||
if (!memcmp(ibss_coal_resp->bssid, zero_mac, ETH_ALEN)) {
|
||||
if (is_zero_ether_addr(ibss_coal_resp->bssid)) {
|
||||
dev_warn(priv->adapter->dev, "new BSSID is NULL\n");
|
||||
return 0;
|
||||
}
|
||||
@ -775,8 +776,7 @@ static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv,
|
||||
* This function handles the command response for subscribe event command.
|
||||
*/
|
||||
static int mwifiex_ret_subsc_evt(struct mwifiex_private *priv,
|
||||
struct host_cmd_ds_command *resp,
|
||||
struct mwifiex_ds_misc_subsc_evt *sub_event)
|
||||
struct host_cmd_ds_command *resp)
|
||||
{
|
||||
struct host_cmd_ds_802_11_subsc_evt *cmd_sub_event =
|
||||
&resp->params.subsc_evt;
|
||||
@ -786,10 +786,6 @@ static int mwifiex_ret_subsc_evt(struct mwifiex_private *priv,
|
||||
dev_dbg(priv->adapter->dev, "Bitmap of currently subscribed events: %16x\n",
|
||||
le16_to_cpu(cmd_sub_event->events));
|
||||
|
||||
/*Return the subscribed event info for a Get request*/
|
||||
if (sub_event)
|
||||
sub_event->events = le16_to_cpu(cmd_sub_event->events);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -913,7 +909,6 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
|
||||
le16_to_cpu(resp->params.tx_buf.mp_end_port));
|
||||
break;
|
||||
case HostCmd_CMD_AMSDU_AGGR_CTRL:
|
||||
ret = mwifiex_ret_amsdu_aggr_ctrl(resp, data_buf);
|
||||
break;
|
||||
case HostCmd_CMD_WMM_GET_STATUS:
|
||||
ret = mwifiex_ret_wmm_get_status(priv, resp);
|
||||
@ -932,12 +927,11 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
|
||||
case HostCmd_CMD_SET_BSS_MODE:
|
||||
break;
|
||||
case HostCmd_CMD_11N_CFG:
|
||||
ret = mwifiex_ret_11n_cfg(resp, data_buf);
|
||||
break;
|
||||
case HostCmd_CMD_PCIE_DESC_DETAILS:
|
||||
break;
|
||||
case HostCmd_CMD_802_11_SUBSCRIBE_EVENT:
|
||||
ret = mwifiex_ret_subsc_evt(priv, resp, data_buf);
|
||||
ret = mwifiex_ret_subsc_evt(priv, resp);
|
||||
break;
|
||||
case HostCmd_CMD_UAP_SYS_CONFIG:
|
||||
break;
|
||||
|
@ -192,6 +192,44 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mwifiex_process_country_ie(struct mwifiex_private *priv,
|
||||
struct cfg80211_bss *bss)
|
||||
{
|
||||
u8 *country_ie, country_ie_len;
|
||||
struct mwifiex_802_11d_domain_reg *domain_info =
|
||||
&priv->adapter->domain_reg;
|
||||
|
||||
country_ie = (u8 *)ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
|
||||
|
||||
if (!country_ie)
|
||||
return 0;
|
||||
|
||||
country_ie_len = country_ie[1];
|
||||
if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN)
|
||||
return 0;
|
||||
|
||||
domain_info->country_code[0] = country_ie[2];
|
||||
domain_info->country_code[1] = country_ie[3];
|
||||
domain_info->country_code[2] = ' ';
|
||||
|
||||
country_ie_len -= IEEE80211_COUNTRY_STRING_LEN;
|
||||
|
||||
domain_info->no_of_triplet =
|
||||
country_ie_len / sizeof(struct ieee80211_country_ie_triplet);
|
||||
|
||||
memcpy((u8 *)domain_info->triplet,
|
||||
&country_ie[2] + IEEE80211_COUNTRY_STRING_LEN, country_ie_len);
|
||||
|
||||
if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
|
||||
HostCmd_ACT_GEN_SET, 0, NULL)) {
|
||||
wiphy_err(priv->adapter->wiphy,
|
||||
"11D: setting domain info in FW\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* In Ad-Hoc mode, the IBSS is created if not found in scan list.
|
||||
* In both Ad-Hoc and infra mode, an deauthentication is performed
|
||||
@ -207,6 +245,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
|
||||
priv->scan_block = false;
|
||||
|
||||
if (bss) {
|
||||
mwifiex_process_country_ie(priv, bss);
|
||||
|
||||
/* Allocate and fill new bss descriptor */
|
||||
bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor),
|
||||
GFP_KERNEL);
|
||||
|
@ -75,7 +75,11 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
|
||||
u8 *head_ptr;
|
||||
struct txpd *local_tx_pd = NULL;
|
||||
|
||||
head_ptr = mwifiex_process_sta_txpd(priv, skb);
|
||||
if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
|
||||
head_ptr = mwifiex_process_uap_txpd(priv, skb);
|
||||
else
|
||||
head_ptr = mwifiex_process_sta_txpd(priv, skb);
|
||||
|
||||
if (head_ptr) {
|
||||
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
|
||||
local_tx_pd =
|
||||
|
@ -177,6 +177,25 @@ mwifiex_set_ht_params(struct mwifiex_private *priv,
|
||||
return;
|
||||
}
|
||||
|
||||
/* This function finds supported rates IE from beacon parameter and sets
|
||||
* these rates into bss_config structure.
|
||||
*/
|
||||
void
|
||||
mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg,
|
||||
struct cfg80211_ap_settings *params)
|
||||
{
|
||||
struct ieee_types_header *rate_ie;
|
||||
int var_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
|
||||
const u8 *var_pos = params->beacon.head + var_offset;
|
||||
int len = params->beacon.head_len - var_offset;
|
||||
|
||||
rate_ie = (void *)cfg80211_find_ie(WLAN_EID_SUPP_RATES, var_pos, len);
|
||||
if (rate_ie)
|
||||
memcpy(bss_cfg->rates, rate_ie + 1, rate_ie->len);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* This function initializes some of mwifiex_uap_bss_param variables.
|
||||
* This helps FW in ignoring invalid values. These values may or may not
|
||||
* be get updated to valid ones at later stage.
|
||||
@ -323,8 +342,10 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
|
||||
struct host_cmd_tlv_retry_limit *retry_limit;
|
||||
struct host_cmd_tlv_encrypt_protocol *encrypt_protocol;
|
||||
struct host_cmd_tlv_auth_type *auth_type;
|
||||
struct host_cmd_tlv_rates *tlv_rates;
|
||||
struct mwifiex_ie_types_htcap *htcap;
|
||||
struct mwifiex_uap_bss_param *bss_cfg = cmd_buf;
|
||||
int i;
|
||||
u16 cmd_size = *param_size;
|
||||
|
||||
if (bss_cfg->ssid.ssid_len) {
|
||||
@ -344,7 +365,23 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
|
||||
cmd_size += sizeof(struct host_cmd_tlv_bcast_ssid);
|
||||
tlv += sizeof(struct host_cmd_tlv_bcast_ssid);
|
||||
}
|
||||
if (bss_cfg->channel && bss_cfg->channel <= MAX_CHANNEL_BAND_BG) {
|
||||
if (bss_cfg->rates[0]) {
|
||||
tlv_rates = (struct host_cmd_tlv_rates *)tlv;
|
||||
tlv_rates->tlv.type = cpu_to_le16(TLV_TYPE_UAP_RATES);
|
||||
|
||||
for (i = 0; i < MWIFIEX_SUPPORTED_RATES && bss_cfg->rates[i];
|
||||
i++)
|
||||
tlv_rates->rates[i] = bss_cfg->rates[i];
|
||||
|
||||
tlv_rates->tlv.len = cpu_to_le16(i);
|
||||
cmd_size += sizeof(struct host_cmd_tlv_rates) + i;
|
||||
tlv += sizeof(struct host_cmd_tlv_rates) + i;
|
||||
}
|
||||
if (bss_cfg->channel &&
|
||||
((bss_cfg->band_cfg == BAND_CONFIG_BG &&
|
||||
bss_cfg->channel <= MAX_CHANNEL_BAND_BG) ||
|
||||
(bss_cfg->band_cfg == BAND_CONFIG_A &&
|
||||
bss_cfg->channel <= MAX_CHANNEL_BAND_A))) {
|
||||
chan_band = (struct host_cmd_tlv_channel_band *)tlv;
|
||||
chan_band->tlv.type = cpu_to_le16(TLV_TYPE_CHANNELBANDLIST);
|
||||
chan_band->tlv.len =
|
||||
|
@ -253,3 +253,73 @@ int mwifiex_process_uap_rx_packet(struct mwifiex_adapter *adapter,
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function fills the TxPD for AP tx packets.
|
||||
*
|
||||
* The Tx buffer received by this function should already have the
|
||||
* header space allocated for TxPD.
|
||||
*
|
||||
* This function inserts the TxPD in between interface header and actual
|
||||
* data and adjusts the buffer pointers accordingly.
|
||||
*
|
||||
* The following TxPD fields are set by this function, as required -
|
||||
* - BSS number
|
||||
* - Tx packet length and offset
|
||||
* - Priority
|
||||
* - Packet delay
|
||||
* - Priority specific Tx control
|
||||
* - Flags
|
||||
*/
|
||||
void *mwifiex_process_uap_txpd(struct mwifiex_private *priv,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct mwifiex_adapter *adapter = priv->adapter;
|
||||
struct uap_txpd *txpd;
|
||||
struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
|
||||
int pad, len;
|
||||
|
||||
if (!skb->len) {
|
||||
dev_err(adapter->dev, "Tx: bad packet length: %d\n", skb->len);
|
||||
tx_info->status_code = -1;
|
||||
return skb->data;
|
||||
}
|
||||
|
||||
/* If skb->data is not aligned, add padding */
|
||||
pad = (4 - (((void *)skb->data - NULL) & 0x3)) % 4;
|
||||
|
||||
len = sizeof(*txpd) + pad;
|
||||
|
||||
BUG_ON(skb_headroom(skb) < len + INTF_HEADER_LEN);
|
||||
|
||||
skb_push(skb, len);
|
||||
|
||||
txpd = (struct uap_txpd *)skb->data;
|
||||
memset(txpd, 0, sizeof(*txpd));
|
||||
txpd->bss_num = priv->bss_num;
|
||||
txpd->bss_type = priv->bss_type;
|
||||
txpd->tx_pkt_length = cpu_to_le16((u16)(skb->len - len));
|
||||
|
||||
txpd->priority = (u8)skb->priority;
|
||||
txpd->pkt_delay_2ms = mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
|
||||
|
||||
if (txpd->priority < ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl))
|
||||
/*
|
||||
* Set the priority specific tx_control field, setting of 0 will
|
||||
* cause the default value to be used later in this function.
|
||||
*/
|
||||
txpd->tx_control =
|
||||
cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[txpd->priority]);
|
||||
|
||||
/* Offset of actual data */
|
||||
txpd->tx_pkt_offset = cpu_to_le16(len);
|
||||
|
||||
/* make space for INTF_HEADER_LEN */
|
||||
skb_push(skb, INTF_HEADER_LEN);
|
||||
|
||||
if (!txpd->tx_control)
|
||||
/* TxCtrl set by user or default */
|
||||
txpd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl);
|
||||
|
||||
return skb->data;
|
||||
}
|
||||
|
@ -907,17 +907,16 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
|
||||
if (adapter->bss_prio_tbl[j].bss_prio_cur ==
|
||||
(struct mwifiex_bss_prio_node *)
|
||||
&adapter->bss_prio_tbl[j].bss_prio_head) {
|
||||
bssprio_node =
|
||||
adapter->bss_prio_tbl[j].bss_prio_cur =
|
||||
list_first_entry(&adapter->bss_prio_tbl[j]
|
||||
.bss_prio_head,
|
||||
struct mwifiex_bss_prio_node,
|
||||
list);
|
||||
bssprio_head = bssprio_node;
|
||||
} else {
|
||||
bssprio_node = adapter->bss_prio_tbl[j].bss_prio_cur;
|
||||
bssprio_head = bssprio_node;
|
||||
}
|
||||
|
||||
bssprio_node = adapter->bss_prio_tbl[j].bss_prio_cur;
|
||||
bssprio_head = bssprio_node;
|
||||
|
||||
do {
|
||||
priv_tmp = bssprio_node->priv;
|
||||
hqp = &priv_tmp->wmm.highest_queued_prio;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/wireless.h>
|
||||
#include <linux/ieee80211.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <net/iw_handler.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include <net/cfg80211-wext.h>
|
||||
@ -159,15 +160,13 @@ static int orinoco_ioctl_setwap(struct net_device *dev,
|
||||
struct orinoco_private *priv = ndev_priv(dev);
|
||||
int err = -EINPROGRESS; /* Call commit handler */
|
||||
unsigned long flags;
|
||||
static const u8 off_addr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static const u8 any_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
if (orinoco_lock(priv, &flags) != 0)
|
||||
return -EBUSY;
|
||||
|
||||
/* Enable automatic roaming - no sanity checks are needed */
|
||||
if (memcmp(&ap_addr->sa_data, off_addr, ETH_ALEN) == 0 ||
|
||||
memcmp(&ap_addr->sa_data, any_addr, ETH_ALEN) == 0) {
|
||||
if (is_zero_ether_addr(ap_addr->sa_data) ||
|
||||
is_broadcast_ether_addr(ap_addr->sa_data)) {
|
||||
priv->bssid_fixed = 0;
|
||||
memset(priv->desired_bssid, 0, ETH_ALEN);
|
||||
|
||||
|
@ -139,6 +139,7 @@ static int p54_beacon_format_ie_tim(struct sk_buff *skb)
|
||||
static int p54_beacon_update(struct p54_common *priv,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ieee80211_tx_control control = { };
|
||||
struct sk_buff *beacon;
|
||||
int ret;
|
||||
|
||||
@ -158,7 +159,7 @@ static int p54_beacon_update(struct p54_common *priv,
|
||||
* to cancel the old beacon template by hand, instead the firmware
|
||||
* will release the previous one through the feedback mechanism.
|
||||
*/
|
||||
p54_tx_80211(priv->hw, NULL, beacon);
|
||||
p54_tx_80211(priv->hw, &control, beacon);
|
||||
priv->tsf_high32 = 0;
|
||||
priv->tsf_low32 = 0;
|
||||
|
||||
|
@ -1959,9 +1959,6 @@ static int rndis_scan(struct wiphy *wiphy,
|
||||
*/
|
||||
rndis_check_bssid_list(usbdev, NULL, NULL);
|
||||
|
||||
if (!request)
|
||||
return -EINVAL;
|
||||
|
||||
if (priv->scan_request && priv->scan_request != request)
|
||||
return -EBUSY;
|
||||
|
||||
|
@ -205,7 +205,7 @@ static int rt2400pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
|
||||
u32 reg;
|
||||
|
||||
rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®);
|
||||
return rt2x00_get_field32(reg, GPIOCSR_BIT0);
|
||||
return rt2x00_get_field32(reg, GPIOCSR_VAL0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RT2X00_LIB_LEDS
|
||||
@ -1611,6 +1611,7 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
int retval;
|
||||
u32 reg;
|
||||
|
||||
/*
|
||||
* Allocate eeprom data.
|
||||
@ -1623,6 +1624,14 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/*
|
||||
* Enable rfkill polling by setting GPIO direction of the
|
||||
* rfkill switch GPIO pin correctly.
|
||||
*/
|
||||
rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®);
|
||||
rt2x00_set_field32(®, GPIOCSR_DIR0, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg);
|
||||
|
||||
/*
|
||||
* Initialize hw specifications.
|
||||
*/
|
||||
|
@ -660,16 +660,26 @@
|
||||
|
||||
/*
|
||||
* GPIOCSR: GPIO control register.
|
||||
* GPIOCSR_VALx: Actual GPIO pin x value
|
||||
* GPIOCSR_DIRx: GPIO direction: 0 = output; 1 = input
|
||||
*/
|
||||
#define GPIOCSR 0x0120
|
||||
#define GPIOCSR_BIT0 FIELD32(0x00000001)
|
||||
#define GPIOCSR_BIT1 FIELD32(0x00000002)
|
||||
#define GPIOCSR_BIT2 FIELD32(0x00000004)
|
||||
#define GPIOCSR_BIT3 FIELD32(0x00000008)
|
||||
#define GPIOCSR_BIT4 FIELD32(0x00000010)
|
||||
#define GPIOCSR_BIT5 FIELD32(0x00000020)
|
||||
#define GPIOCSR_BIT6 FIELD32(0x00000040)
|
||||
#define GPIOCSR_BIT7 FIELD32(0x00000080)
|
||||
#define GPIOCSR_VAL0 FIELD32(0x00000001)
|
||||
#define GPIOCSR_VAL1 FIELD32(0x00000002)
|
||||
#define GPIOCSR_VAL2 FIELD32(0x00000004)
|
||||
#define GPIOCSR_VAL3 FIELD32(0x00000008)
|
||||
#define GPIOCSR_VAL4 FIELD32(0x00000010)
|
||||
#define GPIOCSR_VAL5 FIELD32(0x00000020)
|
||||
#define GPIOCSR_VAL6 FIELD32(0x00000040)
|
||||
#define GPIOCSR_VAL7 FIELD32(0x00000080)
|
||||
#define GPIOCSR_DIR0 FIELD32(0x00000100)
|
||||
#define GPIOCSR_DIR1 FIELD32(0x00000200)
|
||||
#define GPIOCSR_DIR2 FIELD32(0x00000400)
|
||||
#define GPIOCSR_DIR3 FIELD32(0x00000800)
|
||||
#define GPIOCSR_DIR4 FIELD32(0x00001000)
|
||||
#define GPIOCSR_DIR5 FIELD32(0x00002000)
|
||||
#define GPIOCSR_DIR6 FIELD32(0x00004000)
|
||||
#define GPIOCSR_DIR7 FIELD32(0x00008000)
|
||||
|
||||
/*
|
||||
* BBPPCSR: BBP Pin control register.
|
||||
|
@ -205,7 +205,7 @@ static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
|
||||
u32 reg;
|
||||
|
||||
rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®);
|
||||
return rt2x00_get_field32(reg, GPIOCSR_BIT0);
|
||||
return rt2x00_get_field32(reg, GPIOCSR_VAL0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RT2X00_LIB_LEDS
|
||||
@ -1929,6 +1929,7 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
int retval;
|
||||
u32 reg;
|
||||
|
||||
/*
|
||||
* Allocate eeprom data.
|
||||
@ -1941,6 +1942,14 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/*
|
||||
* Enable rfkill polling by setting GPIO direction of the
|
||||
* rfkill switch GPIO pin correctly.
|
||||
*/
|
||||
rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®);
|
||||
rt2x00_set_field32(®, GPIOCSR_DIR0, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg);
|
||||
|
||||
/*
|
||||
* Initialize hw specifications.
|
||||
*/
|
||||
|
@ -789,16 +789,18 @@
|
||||
|
||||
/*
|
||||
* GPIOCSR: GPIO control register.
|
||||
* GPIOCSR_VALx: GPIO value
|
||||
* GPIOCSR_DIRx: GPIO direction: 0 = output; 1 = input
|
||||
*/
|
||||
#define GPIOCSR 0x0120
|
||||
#define GPIOCSR_BIT0 FIELD32(0x00000001)
|
||||
#define GPIOCSR_BIT1 FIELD32(0x00000002)
|
||||
#define GPIOCSR_BIT2 FIELD32(0x00000004)
|
||||
#define GPIOCSR_BIT3 FIELD32(0x00000008)
|
||||
#define GPIOCSR_BIT4 FIELD32(0x00000010)
|
||||
#define GPIOCSR_BIT5 FIELD32(0x00000020)
|
||||
#define GPIOCSR_BIT6 FIELD32(0x00000040)
|
||||
#define GPIOCSR_BIT7 FIELD32(0x00000080)
|
||||
#define GPIOCSR_VAL0 FIELD32(0x00000001)
|
||||
#define GPIOCSR_VAL1 FIELD32(0x00000002)
|
||||
#define GPIOCSR_VAL2 FIELD32(0x00000004)
|
||||
#define GPIOCSR_VAL3 FIELD32(0x00000008)
|
||||
#define GPIOCSR_VAL4 FIELD32(0x00000010)
|
||||
#define GPIOCSR_VAL5 FIELD32(0x00000020)
|
||||
#define GPIOCSR_VAL6 FIELD32(0x00000040)
|
||||
#define GPIOCSR_VAL7 FIELD32(0x00000080)
|
||||
#define GPIOCSR_DIR0 FIELD32(0x00000100)
|
||||
#define GPIOCSR_DIR1 FIELD32(0x00000200)
|
||||
#define GPIOCSR_DIR2 FIELD32(0x00000400)
|
||||
|
@ -283,7 +283,7 @@ static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
|
||||
u16 reg;
|
||||
|
||||
rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®);
|
||||
return rt2x00_get_field32(reg, MAC_CSR19_BIT7);
|
||||
return rt2x00_get_field16(reg, MAC_CSR19_VAL7);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RT2X00_LIB_LEDS
|
||||
@ -1768,6 +1768,7 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
int retval;
|
||||
u16 reg;
|
||||
|
||||
/*
|
||||
* Allocate eeprom data.
|
||||
@ -1780,6 +1781,14 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/*
|
||||
* Enable rfkill polling by setting GPIO direction of the
|
||||
* rfkill switch GPIO pin correctly.
|
||||
*/
|
||||
rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®);
|
||||
rt2x00_set_field16(®, MAC_CSR19_DIR0, 0);
|
||||
rt2500usb_register_write(rt2x00dev, MAC_CSR19, reg);
|
||||
|
||||
/*
|
||||
* Initialize hw specifications.
|
||||
*/
|
||||
|
@ -187,16 +187,26 @@
|
||||
|
||||
/*
|
||||
* MAC_CSR19: GPIO control register.
|
||||
* MAC_CSR19_VALx: GPIO value
|
||||
* MAC_CSR19_DIRx: GPIO direction: 0 = input; 1 = output
|
||||
*/
|
||||
#define MAC_CSR19 0x0426
|
||||
#define MAC_CSR19_BIT0 FIELD32(0x0001)
|
||||
#define MAC_CSR19_BIT1 FIELD32(0x0002)
|
||||
#define MAC_CSR19_BIT2 FIELD32(0x0004)
|
||||
#define MAC_CSR19_BIT3 FIELD32(0x0008)
|
||||
#define MAC_CSR19_BIT4 FIELD32(0x0010)
|
||||
#define MAC_CSR19_BIT5 FIELD32(0x0020)
|
||||
#define MAC_CSR19_BIT6 FIELD32(0x0040)
|
||||
#define MAC_CSR19_BIT7 FIELD32(0x0080)
|
||||
#define MAC_CSR19_VAL0 FIELD16(0x0001)
|
||||
#define MAC_CSR19_VAL1 FIELD16(0x0002)
|
||||
#define MAC_CSR19_VAL2 FIELD16(0x0004)
|
||||
#define MAC_CSR19_VAL3 FIELD16(0x0008)
|
||||
#define MAC_CSR19_VAL4 FIELD16(0x0010)
|
||||
#define MAC_CSR19_VAL5 FIELD16(0x0020)
|
||||
#define MAC_CSR19_VAL6 FIELD16(0x0040)
|
||||
#define MAC_CSR19_VAL7 FIELD16(0x0080)
|
||||
#define MAC_CSR19_DIR0 FIELD16(0x0100)
|
||||
#define MAC_CSR19_DIR1 FIELD16(0x0200)
|
||||
#define MAC_CSR19_DIR2 FIELD16(0x0400)
|
||||
#define MAC_CSR19_DIR3 FIELD16(0x0800)
|
||||
#define MAC_CSR19_DIR4 FIELD16(0x1000)
|
||||
#define MAC_CSR19_DIR5 FIELD16(0x2000)
|
||||
#define MAC_CSR19_DIR6 FIELD16(0x4000)
|
||||
#define MAC_CSR19_DIR7 FIELD16(0x8000)
|
||||
|
||||
/*
|
||||
* MAC_CSR20: LED control register.
|
||||
|
@ -439,26 +439,33 @@
|
||||
#define WMM_TXOP1_CFG_AC3TXOP FIELD32(0xffff0000)
|
||||
|
||||
/*
|
||||
* GPIO_CTRL_CFG:
|
||||
* GPIOD: GPIO direction, 0: Output, 1: Input
|
||||
* GPIO_CTRL:
|
||||
* GPIO_CTRL_VALx: GPIO value
|
||||
* GPIO_CTRL_DIRx: GPIO direction: 0 = output; 1 = input
|
||||
*/
|
||||
#define GPIO_CTRL_CFG 0x0228
|
||||
#define GPIO_CTRL_CFG_BIT0 FIELD32(0x00000001)
|
||||
#define GPIO_CTRL_CFG_BIT1 FIELD32(0x00000002)
|
||||
#define GPIO_CTRL_CFG_BIT2 FIELD32(0x00000004)
|
||||
#define GPIO_CTRL_CFG_BIT3 FIELD32(0x00000008)
|
||||
#define GPIO_CTRL_CFG_BIT4 FIELD32(0x00000010)
|
||||
#define GPIO_CTRL_CFG_BIT5 FIELD32(0x00000020)
|
||||
#define GPIO_CTRL_CFG_BIT6 FIELD32(0x00000040)
|
||||
#define GPIO_CTRL_CFG_BIT7 FIELD32(0x00000080)
|
||||
#define GPIO_CTRL_CFG_GPIOD_BIT0 FIELD32(0x00000100)
|
||||
#define GPIO_CTRL_CFG_GPIOD_BIT1 FIELD32(0x00000200)
|
||||
#define GPIO_CTRL_CFG_GPIOD_BIT2 FIELD32(0x00000400)
|
||||
#define GPIO_CTRL_CFG_GPIOD_BIT3 FIELD32(0x00000800)
|
||||
#define GPIO_CTRL_CFG_GPIOD_BIT4 FIELD32(0x00001000)
|
||||
#define GPIO_CTRL_CFG_GPIOD_BIT5 FIELD32(0x00002000)
|
||||
#define GPIO_CTRL_CFG_GPIOD_BIT6 FIELD32(0x00004000)
|
||||
#define GPIO_CTRL_CFG_GPIOD_BIT7 FIELD32(0x00008000)
|
||||
#define GPIO_CTRL 0x0228
|
||||
#define GPIO_CTRL_VAL0 FIELD32(0x00000001)
|
||||
#define GPIO_CTRL_VAL1 FIELD32(0x00000002)
|
||||
#define GPIO_CTRL_VAL2 FIELD32(0x00000004)
|
||||
#define GPIO_CTRL_VAL3 FIELD32(0x00000008)
|
||||
#define GPIO_CTRL_VAL4 FIELD32(0x00000010)
|
||||
#define GPIO_CTRL_VAL5 FIELD32(0x00000020)
|
||||
#define GPIO_CTRL_VAL6 FIELD32(0x00000040)
|
||||
#define GPIO_CTRL_VAL7 FIELD32(0x00000080)
|
||||
#define GPIO_CTRL_DIR0 FIELD32(0x00000100)
|
||||
#define GPIO_CTRL_DIR1 FIELD32(0x00000200)
|
||||
#define GPIO_CTRL_DIR2 FIELD32(0x00000400)
|
||||
#define GPIO_CTRL_DIR3 FIELD32(0x00000800)
|
||||
#define GPIO_CTRL_DIR4 FIELD32(0x00001000)
|
||||
#define GPIO_CTRL_DIR5 FIELD32(0x00002000)
|
||||
#define GPIO_CTRL_DIR6 FIELD32(0x00004000)
|
||||
#define GPIO_CTRL_DIR7 FIELD32(0x00008000)
|
||||
#define GPIO_CTRL_VAL8 FIELD32(0x00010000)
|
||||
#define GPIO_CTRL_VAL9 FIELD32(0x00020000)
|
||||
#define GPIO_CTRL_VAL10 FIELD32(0x00040000)
|
||||
#define GPIO_CTRL_DIR8 FIELD32(0x01000000)
|
||||
#define GPIO_CTRL_DIR9 FIELD32(0x02000000)
|
||||
#define GPIO_CTRL_DIR10 FIELD32(0x04000000)
|
||||
|
||||
/*
|
||||
* MCU_CMD_CFG
|
||||
@ -1935,6 +1942,11 @@ struct mac_iveiv_entry {
|
||||
#define BBP47_TSSI_TSSI_MODE FIELD8(0x18)
|
||||
#define BBP47_TSSI_ADC6 FIELD8(0x80)
|
||||
|
||||
/*
|
||||
* BBP 49
|
||||
*/
|
||||
#define BBP49_UPDATE_FLAG FIELD8(0x01)
|
||||
|
||||
/*
|
||||
* BBP 109
|
||||
*/
|
||||
|
@ -923,8 +923,8 @@ int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®);
|
||||
return rt2x00_get_field32(reg, WLAN_GPIO_IN_BIT0);
|
||||
} else {
|
||||
rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®);
|
||||
return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2);
|
||||
rt2800_register_read(rt2x00dev, GPIO_CTRL, ®);
|
||||
return rt2x00_get_field32(reg, GPIO_CTRL_VAL2);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_rfkill_poll);
|
||||
@ -1570,10 +1570,10 @@ static void rt2800_set_ant_diversity(struct rt2x00_dev *rt2x00dev,
|
||||
rt2800_mcu_request(rt2x00dev, MCU_ANT_SELECT, 0xff,
|
||||
eesk_pin, 0);
|
||||
|
||||
rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT3, 0);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, gpio_bit3);
|
||||
rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
|
||||
rt2800_register_read(rt2x00dev, GPIO_CTRL, ®);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_DIR3, 0);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_VAL3, gpio_bit3);
|
||||
rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
|
||||
}
|
||||
|
||||
void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
|
||||
@ -1615,6 +1615,7 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant)
|
||||
case 1:
|
||||
if (rt2x00_rt(rt2x00dev, RT3070) ||
|
||||
rt2x00_rt(rt2x00dev, RT3090) ||
|
||||
rt2x00_rt(rt2x00dev, RT3352) ||
|
||||
rt2x00_rt(rt2x00dev, RT3390)) {
|
||||
rt2x00_eeprom_read(rt2x00dev,
|
||||
EEPROM_NIC_CONF1, &eeprom);
|
||||
@ -1995,13 +1996,13 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev,
|
||||
rt2800_rfcsr_write(rt2x00dev, 29, 0x9f);
|
||||
}
|
||||
|
||||
rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT7, 0);
|
||||
rt2800_register_read(rt2x00dev, GPIO_CTRL, ®);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_DIR7, 0);
|
||||
if (rf->channel <= 14)
|
||||
rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT7, 1);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_VAL7, 1);
|
||||
else
|
||||
rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT7, 0);
|
||||
rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_VAL7, 0);
|
||||
rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
|
||||
|
||||
rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
|
||||
@ -2053,6 +2054,60 @@ static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev,
|
||||
}
|
||||
}
|
||||
|
||||
static void rt2800_config_channel_rf3322(struct rt2x00_dev *rt2x00dev,
|
||||
struct ieee80211_conf *conf,
|
||||
struct rf_channel *rf,
|
||||
struct channel_info *info)
|
||||
{
|
||||
u8 rfcsr;
|
||||
|
||||
rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3);
|
||||
|
||||
rt2800_rfcsr_write(rt2x00dev, 11, 0x42);
|
||||
rt2800_rfcsr_write(rt2x00dev, 12, 0x1c);
|
||||
rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
|
||||
|
||||
if (info->default_power1 > POWER_BOUND)
|
||||
rt2800_rfcsr_write(rt2x00dev, 47, POWER_BOUND);
|
||||
else
|
||||
rt2800_rfcsr_write(rt2x00dev, 47, info->default_power1);
|
||||
|
||||
if (info->default_power2 > POWER_BOUND)
|
||||
rt2800_rfcsr_write(rt2x00dev, 48, POWER_BOUND);
|
||||
else
|
||||
rt2800_rfcsr_write(rt2x00dev, 48, info->default_power2);
|
||||
|
||||
rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
|
||||
if (rt2x00dev->freq_offset > FREQ_OFFSET_BOUND)
|
||||
rt2x00_set_field8(&rfcsr, RFCSR17_CODE, FREQ_OFFSET_BOUND);
|
||||
else
|
||||
rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
|
||||
|
||||
rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
|
||||
|
||||
rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1);
|
||||
|
||||
if ( rt2x00dev->default_ant.tx_chain_num == 2 )
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1);
|
||||
else
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0);
|
||||
|
||||
if ( rt2x00dev->default_ant.rx_chain_num == 2 )
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1);
|
||||
else
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0);
|
||||
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0);
|
||||
rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0);
|
||||
|
||||
rt2800_rfcsr_write(rt2x00dev, 1, rfcsr);
|
||||
|
||||
rt2800_rfcsr_write(rt2x00dev, 31, 80);
|
||||
}
|
||||
|
||||
static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
|
||||
struct ieee80211_conf *conf,
|
||||
struct rf_channel *rf,
|
||||
@ -2182,6 +2237,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
|
||||
case RF3290:
|
||||
rt2800_config_channel_rf3290(rt2x00dev, conf, rf, info);
|
||||
break;
|
||||
case RF3322:
|
||||
rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info);
|
||||
break;
|
||||
case RF5360:
|
||||
case RF5370:
|
||||
case RF5372:
|
||||
@ -2194,6 +2252,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
|
||||
}
|
||||
|
||||
if (rt2x00_rf(rt2x00dev, RF3290) ||
|
||||
rt2x00_rf(rt2x00dev, RF3322) ||
|
||||
rt2x00_rf(rt2x00dev, RF5360) ||
|
||||
rt2x00_rf(rt2x00dev, RF5370) ||
|
||||
rt2x00_rf(rt2x00dev, RF5372) ||
|
||||
@ -2212,10 +2271,17 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
|
||||
/*
|
||||
* Change BBP settings
|
||||
*/
|
||||
rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
|
||||
rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
|
||||
rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
|
||||
rt2800_bbp_write(rt2x00dev, 86, 0);
|
||||
if (rt2x00_rt(rt2x00dev, RT3352)) {
|
||||
rt2800_bbp_write(rt2x00dev, 27, 0x0);
|
||||
rt2800_bbp_write(rt2x00dev, 62, 0x26 + rt2x00dev->lna_gain);
|
||||
rt2800_bbp_write(rt2x00dev, 27, 0x20);
|
||||
rt2800_bbp_write(rt2x00dev, 62, 0x26 + rt2x00dev->lna_gain);
|
||||
} else {
|
||||
rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
|
||||
rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
|
||||
rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
|
||||
rt2800_bbp_write(rt2x00dev, 86, 0);
|
||||
}
|
||||
|
||||
if (rf->channel <= 14) {
|
||||
if (!rt2x00_rt(rt2x00dev, RT5390) &&
|
||||
@ -2310,6 +2376,15 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
|
||||
rt2800_register_read(rt2x00dev, CH_IDLE_STA, ®);
|
||||
rt2800_register_read(rt2x00dev, CH_BUSY_STA, ®);
|
||||
rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, ®);
|
||||
|
||||
/*
|
||||
* Clear update flag
|
||||
*/
|
||||
if (rt2x00_rt(rt2x00dev, RT3352)) {
|
||||
rt2800_bbp_read(rt2x00dev, 49, &bbp);
|
||||
rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0);
|
||||
rt2800_bbp_write(rt2x00dev, 49, bbp);
|
||||
}
|
||||
}
|
||||
|
||||
static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev)
|
||||
@ -2998,6 +3073,10 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000030);
|
||||
} else if (rt2x00_rt(rt2x00dev, RT3352)) {
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000402);
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
|
||||
} else if (rt2x00_rt(rt2x00dev, RT3572)) {
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
|
||||
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
|
||||
@ -3378,6 +3457,11 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_wait_bbp_ready(rt2x00dev)))
|
||||
return -EACCES;
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3352)) {
|
||||
rt2800_bbp_write(rt2x00dev, 3, 0x00);
|
||||
rt2800_bbp_write(rt2x00dev, 4, 0x50);
|
||||
}
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392)) {
|
||||
@ -3388,15 +3472,20 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
|
||||
if (rt2800_is_305x_soc(rt2x00dev) ||
|
||||
rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT3352) ||
|
||||
rt2x00_rt(rt2x00dev, RT3572) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
rt2800_bbp_write(rt2x00dev, 31, 0x08);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3352))
|
||||
rt2800_bbp_write(rt2x00dev, 47, 0x48);
|
||||
|
||||
rt2800_bbp_write(rt2x00dev, 65, 0x2c);
|
||||
rt2800_bbp_write(rt2x00dev, 66, 0x38);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT3352) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
rt2800_bbp_write(rt2x00dev, 68, 0x0b);
|
||||
@ -3405,6 +3494,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_bbp_write(rt2x00dev, 69, 0x16);
|
||||
rt2800_bbp_write(rt2x00dev, 73, 0x12);
|
||||
} else if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT3352) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392)) {
|
||||
rt2800_bbp_write(rt2x00dev, 69, 0x12);
|
||||
@ -3436,6 +3526,10 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
} else if (rt2800_is_305x_soc(rt2x00dev)) {
|
||||
rt2800_bbp_write(rt2x00dev, 78, 0x0e);
|
||||
rt2800_bbp_write(rt2x00dev, 80, 0x08);
|
||||
} else if (rt2x00_rt(rt2x00dev, RT3352)) {
|
||||
rt2800_bbp_write(rt2x00dev, 78, 0x0e);
|
||||
rt2800_bbp_write(rt2x00dev, 80, 0x08);
|
||||
rt2800_bbp_write(rt2x00dev, 81, 0x37);
|
||||
} else {
|
||||
rt2800_bbp_write(rt2x00dev, 81, 0x37);
|
||||
}
|
||||
@ -3465,18 +3559,21 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_bbp_write(rt2x00dev, 84, 0x99);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT3352) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
rt2800_bbp_write(rt2x00dev, 86, 0x38);
|
||||
else
|
||||
rt2800_bbp_write(rt2x00dev, 86, 0x00);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT5392))
|
||||
if (rt2x00_rt(rt2x00dev, RT3352) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
rt2800_bbp_write(rt2x00dev, 88, 0x90);
|
||||
|
||||
rt2800_bbp_write(rt2x00dev, 91, 0x04);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT3352) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
rt2800_bbp_write(rt2x00dev, 92, 0x02);
|
||||
@ -3493,6 +3590,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) ||
|
||||
rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) ||
|
||||
rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT3352) ||
|
||||
rt2x00_rt(rt2x00dev, RT3572) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392) ||
|
||||
@ -3502,6 +3600,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_bbp_write(rt2x00dev, 103, 0x00);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT3352) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
rt2800_bbp_write(rt2x00dev, 104, 0x92);
|
||||
@ -3510,6 +3609,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_bbp_write(rt2x00dev, 105, 0x01);
|
||||
else if (rt2x00_rt(rt2x00dev, RT3290))
|
||||
rt2800_bbp_write(rt2x00dev, 105, 0x1c);
|
||||
else if (rt2x00_rt(rt2x00dev, RT3352))
|
||||
rt2800_bbp_write(rt2x00dev, 105, 0x34);
|
||||
else if (rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
rt2800_bbp_write(rt2x00dev, 105, 0x3c);
|
||||
@ -3519,11 +3620,16 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390))
|
||||
rt2800_bbp_write(rt2x00dev, 106, 0x03);
|
||||
else if (rt2x00_rt(rt2x00dev, RT3352))
|
||||
rt2800_bbp_write(rt2x00dev, 106, 0x05);
|
||||
else if (rt2x00_rt(rt2x00dev, RT5392))
|
||||
rt2800_bbp_write(rt2x00dev, 106, 0x12);
|
||||
else
|
||||
rt2800_bbp_write(rt2x00dev, 106, 0x35);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3352))
|
||||
rt2800_bbp_write(rt2x00dev, 120, 0x50);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3290) ||
|
||||
rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392))
|
||||
@ -3534,6 +3640,9 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_bbp_write(rt2x00dev, 135, 0xf6);
|
||||
}
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3352))
|
||||
rt2800_bbp_write(rt2x00dev, 137, 0x0f);
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3071) ||
|
||||
rt2x00_rt(rt2x00dev, RT3090) ||
|
||||
rt2x00_rt(rt2x00dev, RT3390) ||
|
||||
@ -3574,6 +3683,28 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_bbp_write(rt2x00dev, 3, value);
|
||||
}
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3352)) {
|
||||
rt2800_bbp_write(rt2x00dev, 163, 0xbd);
|
||||
/* Set ITxBF timeout to 0x9c40=1000msec */
|
||||
rt2800_bbp_write(rt2x00dev, 179, 0x02);
|
||||
rt2800_bbp_write(rt2x00dev, 180, 0x00);
|
||||
rt2800_bbp_write(rt2x00dev, 182, 0x40);
|
||||
rt2800_bbp_write(rt2x00dev, 180, 0x01);
|
||||
rt2800_bbp_write(rt2x00dev, 182, 0x9c);
|
||||
rt2800_bbp_write(rt2x00dev, 179, 0x00);
|
||||
/* Reprogram the inband interface to put right values in RXWI */
|
||||
rt2800_bbp_write(rt2x00dev, 142, 0x04);
|
||||
rt2800_bbp_write(rt2x00dev, 143, 0x3b);
|
||||
rt2800_bbp_write(rt2x00dev, 142, 0x06);
|
||||
rt2800_bbp_write(rt2x00dev, 143, 0xa0);
|
||||
rt2800_bbp_write(rt2x00dev, 142, 0x07);
|
||||
rt2800_bbp_write(rt2x00dev, 143, 0xa1);
|
||||
rt2800_bbp_write(rt2x00dev, 142, 0x08);
|
||||
rt2800_bbp_write(rt2x00dev, 143, 0xa2);
|
||||
|
||||
rt2800_bbp_write(rt2x00dev, 148, 0xc8);
|
||||
}
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT5390) ||
|
||||
rt2x00_rt(rt2x00dev, RT5392)) {
|
||||
int ant, div_mode;
|
||||
@ -3587,16 +3718,16 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
|
||||
if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
|
||||
u32 reg;
|
||||
|
||||
rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT3, 0);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT6, 0);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 0);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 0);
|
||||
rt2800_register_read(rt2x00dev, GPIO_CTRL, ®);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_DIR3, 0);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_DIR6, 0);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_VAL3, 0);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_VAL6, 0);
|
||||
if (ant == 0)
|
||||
rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 1);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_VAL3, 1);
|
||||
else if (ant == 1)
|
||||
rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 1);
|
||||
rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_VAL6, 1);
|
||||
rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
|
||||
}
|
||||
|
||||
/* This chip has hardware antenna diversity*/
|
||||
@ -3707,6 +3838,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
|
||||
!rt2x00_rt(rt2x00dev, RT3071) &&
|
||||
!rt2x00_rt(rt2x00dev, RT3090) &&
|
||||
!rt2x00_rt(rt2x00dev, RT3290) &&
|
||||
!rt2x00_rt(rt2x00dev, RT3352) &&
|
||||
!rt2x00_rt(rt2x00dev, RT3390) &&
|
||||
!rt2x00_rt(rt2x00dev, RT3572) &&
|
||||
!rt2x00_rt(rt2x00dev, RT5390) &&
|
||||
@ -3903,6 +4035,70 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_rfcsr_write(rt2x00dev, 30, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 31, 0x00);
|
||||
return 0;
|
||||
} else if (rt2x00_rt(rt2x00dev, RT3352)) {
|
||||
rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
|
||||
rt2800_rfcsr_write(rt2x00dev, 1, 0x23);
|
||||
rt2800_rfcsr_write(rt2x00dev, 2, 0x50);
|
||||
rt2800_rfcsr_write(rt2x00dev, 3, 0x18);
|
||||
rt2800_rfcsr_write(rt2x00dev, 4, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 5, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 6, 0x33);
|
||||
rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 8, 0xf1);
|
||||
rt2800_rfcsr_write(rt2x00dev, 9, 0x02);
|
||||
rt2800_rfcsr_write(rt2x00dev, 10, 0xd2);
|
||||
rt2800_rfcsr_write(rt2x00dev, 11, 0x42);
|
||||
rt2800_rfcsr_write(rt2x00dev, 12, 0x1c);
|
||||
rt2800_rfcsr_write(rt2x00dev, 13, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 14, 0x5a);
|
||||
rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 16, 0x01);
|
||||
rt2800_rfcsr_write(rt2x00dev, 18, 0x45);
|
||||
rt2800_rfcsr_write(rt2x00dev, 19, 0x02);
|
||||
rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 21, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 22, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 23, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 24, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
|
||||
rt2800_rfcsr_write(rt2x00dev, 26, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 27, 0x03);
|
||||
rt2800_rfcsr_write(rt2x00dev, 28, 0x03);
|
||||
rt2800_rfcsr_write(rt2x00dev, 29, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
|
||||
rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
|
||||
rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
|
||||
rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 34, 0x01);
|
||||
rt2800_rfcsr_write(rt2x00dev, 35, 0x03);
|
||||
rt2800_rfcsr_write(rt2x00dev, 36, 0xbd);
|
||||
rt2800_rfcsr_write(rt2x00dev, 37, 0x3c);
|
||||
rt2800_rfcsr_write(rt2x00dev, 38, 0x5f);
|
||||
rt2800_rfcsr_write(rt2x00dev, 39, 0xc5);
|
||||
rt2800_rfcsr_write(rt2x00dev, 40, 0x33);
|
||||
rt2800_rfcsr_write(rt2x00dev, 41, 0x5b);
|
||||
rt2800_rfcsr_write(rt2x00dev, 42, 0x5b);
|
||||
rt2800_rfcsr_write(rt2x00dev, 43, 0xdb);
|
||||
rt2800_rfcsr_write(rt2x00dev, 44, 0xdb);
|
||||
rt2800_rfcsr_write(rt2x00dev, 45, 0xdb);
|
||||
rt2800_rfcsr_write(rt2x00dev, 46, 0xdd);
|
||||
rt2800_rfcsr_write(rt2x00dev, 47, 0x0d);
|
||||
rt2800_rfcsr_write(rt2x00dev, 48, 0x14);
|
||||
rt2800_rfcsr_write(rt2x00dev, 49, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 50, 0x2d);
|
||||
rt2800_rfcsr_write(rt2x00dev, 51, 0x7f);
|
||||
rt2800_rfcsr_write(rt2x00dev, 52, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 53, 0x52);
|
||||
rt2800_rfcsr_write(rt2x00dev, 54, 0x1b);
|
||||
rt2800_rfcsr_write(rt2x00dev, 55, 0x7f);
|
||||
rt2800_rfcsr_write(rt2x00dev, 56, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 57, 0x52);
|
||||
rt2800_rfcsr_write(rt2x00dev, 58, 0x1b);
|
||||
rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
|
||||
rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
|
||||
} else if (rt2x00_rt(rt2x00dev, RT5390)) {
|
||||
rt2800_rfcsr_write(rt2x00dev, 1, 0x0f);
|
||||
rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
|
||||
@ -4089,6 +4285,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
|
||||
msleep(1);
|
||||
rt2800_register_read(rt2x00dev, LDO_CFG0, ®);
|
||||
rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0);
|
||||
rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1);
|
||||
rt2800_register_write(rt2x00dev, LDO_CFG0, reg);
|
||||
}
|
||||
@ -4103,6 +4300,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
|
||||
rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
|
||||
} else if (rt2x00_rt(rt2x00dev, RT3071) ||
|
||||
rt2x00_rt(rt2x00dev, RT3090) ||
|
||||
rt2x00_rt(rt2x00dev, RT3352) ||
|
||||
rt2x00_rt(rt2x00dev, RT3390) ||
|
||||
rt2x00_rt(rt2x00dev, RT3572)) {
|
||||
drv_data->calibration_bw20 =
|
||||
@ -4391,13 +4589,18 @@ void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_read_eeprom_efuse);
|
||||
|
||||
int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
static int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
|
||||
u16 word;
|
||||
u8 *mac;
|
||||
u8 default_lna_gain;
|
||||
|
||||
/*
|
||||
* Read the EEPROM.
|
||||
*/
|
||||
rt2800_read_eeprom(rt2x00dev);
|
||||
|
||||
/*
|
||||
* Start validation of the data that has been read.
|
||||
*/
|
||||
@ -4520,9 +4723,8 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_validate_eeprom);
|
||||
|
||||
int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
u32 reg;
|
||||
u16 value;
|
||||
@ -4561,6 +4763,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
case RT3071:
|
||||
case RT3090:
|
||||
case RT3290:
|
||||
case RT3352:
|
||||
case RT3390:
|
||||
case RT3572:
|
||||
case RT5390:
|
||||
@ -4583,6 +4786,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
case RF3052:
|
||||
case RF3290:
|
||||
case RF3320:
|
||||
case RF3322:
|
||||
case RF5360:
|
||||
case RF5370:
|
||||
case RF5372:
|
||||
@ -4607,6 +4811,7 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
|
||||
if (rt2x00_rt(rt2x00dev, RT3070) ||
|
||||
rt2x00_rt(rt2x00dev, RT3090) ||
|
||||
rt2x00_rt(rt2x00dev, RT3352) ||
|
||||
rt2x00_rt(rt2x00dev, RT3390)) {
|
||||
value = rt2x00_get_field16(eeprom,
|
||||
EEPROM_NIC_CONF1_ANT_DIVERSITY);
|
||||
@ -4680,7 +4885,6 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_init_eeprom);
|
||||
|
||||
/*
|
||||
* RF value list for rt28xx
|
||||
@ -4823,7 +5027,7 @@ static const struct rf_channel rf_vals_3x[] = {
|
||||
{173, 0x61, 0, 9},
|
||||
};
|
||||
|
||||
int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct hw_mode_spec *spec = &rt2x00dev->spec;
|
||||
struct channel_info *info;
|
||||
@ -4900,6 +5104,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
rt2x00_rf(rt2x00dev, RF3022) ||
|
||||
rt2x00_rf(rt2x00dev, RF3290) ||
|
||||
rt2x00_rf(rt2x00dev, RF3320) ||
|
||||
rt2x00_rf(rt2x00dev, RF3322) ||
|
||||
rt2x00_rf(rt2x00dev, RF5360) ||
|
||||
rt2x00_rf(rt2x00dev, RF5370) ||
|
||||
rt2x00_rf(rt2x00dev, RF5372) ||
|
||||
@ -4999,7 +5204,72 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_probe_hw_mode);
|
||||
|
||||
int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
int retval;
|
||||
u32 reg;
|
||||
|
||||
/*
|
||||
* Allocate eeprom data.
|
||||
*/
|
||||
retval = rt2800_validate_eeprom(rt2x00dev);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
retval = rt2800_init_eeprom(rt2x00dev);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/*
|
||||
* Enable rfkill polling by setting GPIO direction of the
|
||||
* rfkill switch GPIO pin correctly.
|
||||
*/
|
||||
rt2800_register_read(rt2x00dev, GPIO_CTRL, ®);
|
||||
rt2x00_set_field32(®, GPIO_CTRL_DIR2, 1);
|
||||
rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
|
||||
|
||||
/*
|
||||
* Initialize hw specifications.
|
||||
*/
|
||||
retval = rt2800_probe_hw_mode(rt2x00dev);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/*
|
||||
* Set device capabilities.
|
||||
*/
|
||||
__set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags);
|
||||
__set_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags);
|
||||
if (!rt2x00_is_usb(rt2x00dev))
|
||||
__set_bit(CAPABILITY_PRE_TBTT_INTERRUPT, &rt2x00dev->cap_flags);
|
||||
|
||||
/*
|
||||
* Set device requirements.
|
||||
*/
|
||||
if (!rt2x00_is_soc(rt2x00dev))
|
||||
__set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags);
|
||||
__set_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags);
|
||||
__set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags);
|
||||
if (!rt2800_hwcrypt_disabled(rt2x00dev))
|
||||
__set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
|
||||
__set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
|
||||
__set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags);
|
||||
if (rt2x00_is_usb(rt2x00dev))
|
||||
__set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags);
|
||||
else {
|
||||
__set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags);
|
||||
__set_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the rssi offset.
|
||||
*/
|
||||
rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_probe_hw);
|
||||
|
||||
/*
|
||||
* IEEE80211 stack callback functions.
|
||||
|
@ -43,6 +43,9 @@ struct rt2800_ops {
|
||||
const unsigned int offset,
|
||||
const struct rt2x00_field32 field, u32 *reg);
|
||||
|
||||
void (*read_eeprom)(struct rt2x00_dev *rt2x00dev);
|
||||
bool (*hwcrypt_disabled)(struct rt2x00_dev *rt2x00dev);
|
||||
|
||||
int (*drv_write_firmware)(struct rt2x00_dev *rt2x00dev,
|
||||
const u8 *data, const size_t len);
|
||||
int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev);
|
||||
@ -114,6 +117,20 @@ static inline int rt2800_regbusy_read(struct rt2x00_dev *rt2x00dev,
|
||||
return rt2800ops->regbusy_read(rt2x00dev, offset, field, reg);
|
||||
}
|
||||
|
||||
static inline void rt2800_read_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
|
||||
|
||||
rt2800ops->read_eeprom(rt2x00dev);
|
||||
}
|
||||
|
||||
static inline bool rt2800_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv;
|
||||
|
||||
return rt2800ops->hwcrypt_disabled(rt2x00dev);
|
||||
}
|
||||
|
||||
static inline int rt2800_drv_write_firmware(struct rt2x00_dev *rt2x00dev,
|
||||
const u8 *data, const size_t len)
|
||||
{
|
||||
@ -191,9 +208,8 @@ void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev);
|
||||
|
||||
int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev);
|
||||
void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev);
|
||||
int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev);
|
||||
int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev);
|
||||
int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev);
|
||||
|
||||
int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev);
|
||||
|
||||
void rt2800_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx, u32 *iv32,
|
||||
u16 *iv16);
|
||||
|
@ -54,6 +54,11 @@ static bool modparam_nohwcrypt = false;
|
||||
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
|
||||
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
|
||||
|
||||
static bool rt2800pci_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
return modparam_nohwcrypt;
|
||||
}
|
||||
|
||||
static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
|
||||
{
|
||||
unsigned int i;
|
||||
@ -965,76 +970,14 @@ static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance)
|
||||
/*
|
||||
* Device probe functions.
|
||||
*/
|
||||
static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
static void rt2800pci_read_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
/*
|
||||
* Read EEPROM into buffer
|
||||
*/
|
||||
if (rt2x00_is_soc(rt2x00dev))
|
||||
rt2800pci_read_eeprom_soc(rt2x00dev);
|
||||
else if (rt2800pci_efuse_detect(rt2x00dev))
|
||||
rt2800pci_read_eeprom_efuse(rt2x00dev);
|
||||
else
|
||||
rt2800pci_read_eeprom_pci(rt2x00dev);
|
||||
|
||||
return rt2800_validate_eeprom(rt2x00dev);
|
||||
}
|
||||
|
||||
static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
int retval;
|
||||
|
||||
/*
|
||||
* Allocate eeprom data.
|
||||
*/
|
||||
retval = rt2800pci_validate_eeprom(rt2x00dev);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
retval = rt2800_init_eeprom(rt2x00dev);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/*
|
||||
* Initialize hw specifications.
|
||||
*/
|
||||
retval = rt2800_probe_hw_mode(rt2x00dev);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/*
|
||||
* This device has multiple filters for control frames
|
||||
* and has a separate filter for PS Poll frames.
|
||||
*/
|
||||
__set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags);
|
||||
__set_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags);
|
||||
|
||||
/*
|
||||
* This device has a pre tbtt interrupt and thus fetches
|
||||
* a new beacon directly prior to transmission.
|
||||
*/
|
||||
__set_bit(CAPABILITY_PRE_TBTT_INTERRUPT, &rt2x00dev->cap_flags);
|
||||
|
||||
/*
|
||||
* This device requires firmware.
|
||||
*/
|
||||
if (!rt2x00_is_soc(rt2x00dev))
|
||||
__set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags);
|
||||
__set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags);
|
||||
__set_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags);
|
||||
__set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags);
|
||||
__set_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags);
|
||||
if (!modparam_nohwcrypt)
|
||||
__set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
|
||||
__set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
|
||||
__set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags);
|
||||
|
||||
/*
|
||||
* Set the rssi offset.
|
||||
*/
|
||||
rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ieee80211_ops rt2800pci_mac80211_ops = {
|
||||
@ -1072,6 +1015,8 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = {
|
||||
.register_multiread = rt2x00pci_register_multiread,
|
||||
.register_multiwrite = rt2x00pci_register_multiwrite,
|
||||
.regbusy_read = rt2x00pci_regbusy_read,
|
||||
.read_eeprom = rt2800pci_read_eeprom,
|
||||
.hwcrypt_disabled = rt2800pci_hwcrypt_disabled,
|
||||
.drv_write_firmware = rt2800pci_write_firmware,
|
||||
.drv_init_registers = rt2800pci_init_registers,
|
||||
.drv_get_txwi = rt2800pci_get_txwi,
|
||||
@ -1084,7 +1029,7 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
|
||||
.tbtt_tasklet = rt2800pci_tbtt_tasklet,
|
||||
.rxdone_tasklet = rt2800pci_rxdone_tasklet,
|
||||
.autowake_tasklet = rt2800pci_autowake_tasklet,
|
||||
.probe_hw = rt2800pci_probe_hw,
|
||||
.probe_hw = rt2800_probe_hw,
|
||||
.get_firmware_name = rt2800pci_get_firmware_name,
|
||||
.check_firmware = rt2800_check_firmware,
|
||||
.load_firmware = rt2800_load_firmware,
|
||||
|
@ -49,6 +49,11 @@ static bool modparam_nohwcrypt;
|
||||
module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
|
||||
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
|
||||
|
||||
static bool rt2800usb_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
return modparam_nohwcrypt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Queue handlers.
|
||||
*/
|
||||
@ -667,8 +672,16 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
|
||||
skb_pull(entry->skb, RXINFO_DESC_SIZE);
|
||||
|
||||
/*
|
||||
* FIXME: we need to check for rx_pkt_len validity
|
||||
* Check for rx_pkt_len validity. Return if invalid, leaving
|
||||
* rxdesc->size zeroed out by the upper level.
|
||||
*/
|
||||
if (unlikely(rx_pkt_len == 0 ||
|
||||
rx_pkt_len > entry->queue->data_size)) {
|
||||
ERROR(entry->queue->rt2x00dev,
|
||||
"Bad frame size %d, forcing to 0\n", rx_pkt_len);
|
||||
return;
|
||||
}
|
||||
|
||||
rxd = (__le32 *)(entry->skb->data + rx_pkt_len);
|
||||
|
||||
/*
|
||||
@ -722,64 +735,27 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
|
||||
/*
|
||||
* Device probe functions.
|
||||
*/
|
||||
static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
static void rt2800usb_read_eeprom(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
if (rt2800_efuse_detect(rt2x00dev))
|
||||
rt2800_read_eeprom_efuse(rt2x00dev);
|
||||
else
|
||||
rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom,
|
||||
EEPROM_SIZE);
|
||||
|
||||
return rt2800_validate_eeprom(rt2x00dev);
|
||||
}
|
||||
|
||||
static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
int retval;
|
||||
|
||||
/*
|
||||
* Allocate eeprom data.
|
||||
*/
|
||||
retval = rt2800usb_validate_eeprom(rt2x00dev);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
retval = rt2800_init_eeprom(rt2x00dev);
|
||||
retval = rt2800_probe_hw(rt2x00dev);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/*
|
||||
* Initialize hw specifications.
|
||||
* Set txstatus timer function.
|
||||
*/
|
||||
retval = rt2800_probe_hw_mode(rt2x00dev);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/*
|
||||
* This device has multiple filters for control frames
|
||||
* and has a separate filter for PS Poll frames.
|
||||
*/
|
||||
__set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags);
|
||||
__set_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags);
|
||||
|
||||
/*
|
||||
* This device requires firmware.
|
||||
*/
|
||||
__set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags);
|
||||
__set_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags);
|
||||
if (!modparam_nohwcrypt)
|
||||
__set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
|
||||
__set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
|
||||
__set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags);
|
||||
__set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags);
|
||||
__set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags);
|
||||
|
||||
rt2x00dev->txstatus_timer.function = rt2800usb_tx_sta_fifo_timeout,
|
||||
|
||||
/*
|
||||
* Set the rssi offset.
|
||||
*/
|
||||
rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;
|
||||
rt2x00dev->txstatus_timer.function = rt2800usb_tx_sta_fifo_timeout;
|
||||
|
||||
/*
|
||||
* Overwrite TX done handler
|
||||
@ -825,6 +801,8 @@ static const struct rt2800_ops rt2800usb_rt2800_ops = {
|
||||
.register_multiread = rt2x00usb_register_multiread,
|
||||
.register_multiwrite = rt2x00usb_register_multiwrite,
|
||||
.regbusy_read = rt2x00usb_regbusy_read,
|
||||
.read_eeprom = rt2800usb_read_eeprom,
|
||||
.hwcrypt_disabled = rt2800usb_hwcrypt_disabled,
|
||||
.drv_write_firmware = rt2800usb_write_firmware,
|
||||
.drv_init_registers = rt2800usb_init_registers,
|
||||
.drv_get_txwi = rt2800usb_get_txwi,
|
||||
@ -1157,6 +1135,8 @@ static struct usb_device_id rt2800usb_device_table[] = {
|
||||
{ USB_DEVICE(0x1690, 0x0744) },
|
||||
{ USB_DEVICE(0x1690, 0x0761) },
|
||||
{ USB_DEVICE(0x1690, 0x0764) },
|
||||
/* ASUS */
|
||||
{ USB_DEVICE(0x0b05, 0x179d) },
|
||||
/* Cisco */
|
||||
{ USB_DEVICE(0x167b, 0x4001) },
|
||||
/* EnGenius */
|
||||
@ -1222,7 +1202,6 @@ static struct usb_device_id rt2800usb_device_table[] = {
|
||||
{ USB_DEVICE(0x0b05, 0x1760) },
|
||||
{ USB_DEVICE(0x0b05, 0x1761) },
|
||||
{ USB_DEVICE(0x0b05, 0x1790) },
|
||||
{ USB_DEVICE(0x0b05, 0x179d) },
|
||||
/* AzureWave */
|
||||
{ USB_DEVICE(0x13d3, 0x3262) },
|
||||
{ USB_DEVICE(0x13d3, 0x3284) },
|
||||
|
@ -188,6 +188,7 @@ struct rt2x00_chip {
|
||||
#define RT3071 0x3071
|
||||
#define RT3090 0x3090 /* 2.4GHz PCIe */
|
||||
#define RT3290 0x3290
|
||||
#define RT3352 0x3352 /* WSOC */
|
||||
#define RT3390 0x3390
|
||||
#define RT3572 0x3572
|
||||
#define RT3593 0x3593
|
||||
|
@ -629,7 +629,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp)
|
||||
*/
|
||||
if (unlikely(rxdesc.size == 0 ||
|
||||
rxdesc.size > entry->queue->data_size)) {
|
||||
WARNING(rt2x00dev, "Wrong frame size %d max %d.\n",
|
||||
ERROR(rt2x00dev, "Wrong frame size %d max %d.\n",
|
||||
rxdesc.size, entry->queue->data_size);
|
||||
dev_kfree_skb(entry->skb);
|
||||
goto renew_skb;
|
||||
|
@ -243,7 +243,7 @@ static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
|
||||
u32 reg;
|
||||
|
||||
rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®);
|
||||
return rt2x00_get_field32(reg, MAC_CSR13_BIT5);
|
||||
return rt2x00_get_field32(reg, MAC_CSR13_VAL5);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RT2X00_LIB_LEDS
|
||||
@ -715,11 +715,11 @@ static void rt61pci_config_antenna_2529_rx(struct rt2x00_dev *rt2x00dev,
|
||||
|
||||
rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®);
|
||||
|
||||
rt2x00_set_field32(®, MAC_CSR13_BIT4, p1);
|
||||
rt2x00_set_field32(®, MAC_CSR13_BIT12, 0);
|
||||
rt2x00_set_field32(®, MAC_CSR13_DIR4, 0);
|
||||
rt2x00_set_field32(®, MAC_CSR13_VAL4, p1);
|
||||
|
||||
rt2x00_set_field32(®, MAC_CSR13_BIT3, !p2);
|
||||
rt2x00_set_field32(®, MAC_CSR13_BIT11, 0);
|
||||
rt2x00_set_field32(®, MAC_CSR13_DIR3, 0);
|
||||
rt2x00_set_field32(®, MAC_CSR13_VAL3, !p2);
|
||||
|
||||
rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
|
||||
}
|
||||
@ -2832,6 +2832,7 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
int retval;
|
||||
u32 reg;
|
||||
|
||||
/*
|
||||
* Disable power saving.
|
||||
@ -2849,6 +2850,14 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/*
|
||||
* Enable rfkill polling by setting GPIO direction of the
|
||||
* rfkill switch GPIO pin correctly.
|
||||
*/
|
||||
rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®);
|
||||
rt2x00_set_field32(®, MAC_CSR13_DIR5, 1);
|
||||
rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg);
|
||||
|
||||
/*
|
||||
* Initialize hw specifications.
|
||||
*/
|
||||
|
@ -357,21 +357,22 @@ struct hw_pairwise_ta_entry {
|
||||
|
||||
/*
|
||||
* MAC_CSR13: GPIO.
|
||||
* MAC_CSR13_VALx: GPIO value
|
||||
* MAC_CSR13_DIRx: GPIO direction: 0 = output; 1 = input
|
||||
*/
|
||||
#define MAC_CSR13 0x3034
|
||||
#define MAC_CSR13_BIT0 FIELD32(0x00000001)
|
||||
#define MAC_CSR13_BIT1 FIELD32(0x00000002)
|
||||
#define MAC_CSR13_BIT2 FIELD32(0x00000004)
|
||||
#define MAC_CSR13_BIT3 FIELD32(0x00000008)
|
||||
#define MAC_CSR13_BIT4 FIELD32(0x00000010)
|
||||
#define MAC_CSR13_BIT5 FIELD32(0x00000020)
|
||||
#define MAC_CSR13_BIT6 FIELD32(0x00000040)
|
||||
#define MAC_CSR13_BIT7 FIELD32(0x00000080)
|
||||
#define MAC_CSR13_BIT8 FIELD32(0x00000100)
|
||||
#define MAC_CSR13_BIT9 FIELD32(0x00000200)
|
||||
#define MAC_CSR13_BIT10 FIELD32(0x00000400)
|
||||
#define MAC_CSR13_BIT11 FIELD32(0x00000800)
|
||||
#define MAC_CSR13_BIT12 FIELD32(0x00001000)
|
||||
#define MAC_CSR13_VAL0 FIELD32(0x00000001)
|
||||
#define MAC_CSR13_VAL1 FIELD32(0x00000002)
|
||||
#define MAC_CSR13_VAL2 FIELD32(0x00000004)
|
||||
#define MAC_CSR13_VAL3 FIELD32(0x00000008)
|
||||
#define MAC_CSR13_VAL4 FIELD32(0x00000010)
|
||||
#define MAC_CSR13_VAL5 FIELD32(0x00000020)
|
||||
#define MAC_CSR13_DIR0 FIELD32(0x00000100)
|
||||
#define MAC_CSR13_DIR1 FIELD32(0x00000200)
|
||||
#define MAC_CSR13_DIR2 FIELD32(0x00000400)
|
||||
#define MAC_CSR13_DIR3 FIELD32(0x00000800)
|
||||
#define MAC_CSR13_DIR4 FIELD32(0x00001000)
|
||||
#define MAC_CSR13_DIR5 FIELD32(0x00002000)
|
||||
|
||||
/*
|
||||
* MAC_CSR14: LED control register.
|
||||
|
@ -189,7 +189,7 @@ static int rt73usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
|
||||
u32 reg;
|
||||
|
||||
rt2x00usb_register_read(rt2x00dev, MAC_CSR13, ®);
|
||||
return rt2x00_get_field32(reg, MAC_CSR13_BIT7);
|
||||
return rt2x00_get_field32(reg, MAC_CSR13_VAL7);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_RT2X00_LIB_LEDS
|
||||
@ -2177,6 +2177,7 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
||||
static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
int retval;
|
||||
u32 reg;
|
||||
|
||||
/*
|
||||
* Allocate eeprom data.
|
||||
@ -2189,6 +2190,14 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
/*
|
||||
* Enable rfkill polling by setting GPIO direction of the
|
||||
* rfkill switch GPIO pin correctly.
|
||||
*/
|
||||
rt2x00usb_register_read(rt2x00dev, MAC_CSR13, ®);
|
||||
rt2x00_set_field32(®, MAC_CSR13_DIR7, 0);
|
||||
rt2x00usb_register_write(rt2x00dev, MAC_CSR13, reg);
|
||||
|
||||
/*
|
||||
* Initialize hw specifications.
|
||||
*/
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user