diff options
Diffstat (limited to 'drivers')
48 files changed, 1086 insertions, 1442 deletions
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 908fdbc3e0ee..fe4bf4da255f 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -240,6 +240,7 @@ enum ATH_DEBUG { ATH_DBG_BTCOEX = 0x00002000, ATH_DBG_WMI = 0x00004000, ATH_DBG_BSTUCK = 0x00008000, + ATH_DBG_MCI = 0x00010000, ATH_DBG_ANY = 0xffffffff }; diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 36ed3c46fec6..49d3f25f509d 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -4,6 +4,7 @@ ath9k-y += beacon.o \ main.o \ recv.o \ xmit.o \ + mci.o \ ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o ath9k-$(CONFIG_ATH9K_PCI) += pci.o diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index fe96997921d3..04b060af5087 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -198,12 +198,14 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, synth_freq = chan->channel; } } else { - range = 10; + range = AR_SREV_9462(ah) ? 5 : 10; max_spur_cnts = 4; synth_freq = chan->channel; } 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)) cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index 9c51b395b4ff..259a6f312afb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h @@ -43,16 +43,16 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, - {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, - {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, + {0x00009824, 0x5ac640de, 0x5ac640d0, 0x5ac640d0, 0x5ac640de}, + {0x00009828, 0x0796be89, 0x0696b081, 0x0696b881, 0x0796be89}, {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, - {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e}, - {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3039605e, 0x33795d5e}, + {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x92c84d2e}, + {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e}, {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, @@ -688,8 +688,8 @@ static const u32 ar9462_2p0_mac_postamble_emulation[][5] = { static const u32 ar9462_2p0_radio_postamble_sys3ant[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, - {0x00016140, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, - {0x00016540, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, + {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, + {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, }; static const u32 ar9462_2p0_baseband_postamble_emulation[][5] = { @@ -717,8 +717,8 @@ static const u32 ar9462_2p0_baseband_postamble_emulation[][5] = { static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, - {0x00016140, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, - {0x00016540, 0x10804008, 0x10804008, 0x90804008, 0x90804008}, + {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, + {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, }; static const u32 ar9462_common_wo_xlna_rx_gain_table_2p0[][2] = { @@ -1059,7 +1059,7 @@ static const u32 ar9462_modes_low_ob_db_tx_gain_table_2p0[][5] = { static const u32 ar9462_2p0_soc_postamble[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00007010, 0x00002233, 0x00002233, 0x00002233, 0x00002233}, + {0x00007010, 0x00000033, 0x00000033, 0x00000033, 0x00000033}, }; static const u32 ar9462_2p0_baseband_core[][2] = { @@ -1257,8 +1257,8 @@ static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = { {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, + {0x0000a54c, 0x59025eb6, 0x59025eb6, 0x42001a83, 0x42001a83}, + {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001c84, 0x44001c84}, {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, @@ -1850,8 +1850,8 @@ static const u32 ar9462_modes_green_ob_db_tx_gain_table_2p0[][5] = { {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, + {0x0000a54c, 0x59025eb6, 0x59025eb6, 0x42001a83, 0x42001a83}, + {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001c84, 0x44001c84}, {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 1c269f50822b..4415e89bd3d9 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -25,6 +25,7 @@ #include "debug.h" #include "common.h" +#include "mci.h" /* * Header for the ath9k.ko driver core *only* -- hw code nor any other driver @@ -443,7 +444,9 @@ struct ath_btcoex { u32 btcoex_no_stomp; /* in usec */ u32 btcoex_period; /* in usec */ u32 btscan_no_stomp; /* in usec */ + u32 duty_cycle; struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ + struct ath_mci_profile mci; }; int ath_init_btcoex_timer(struct ath_softc *sc); diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 655576c8fdab..2c279dcaf4ba 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -189,8 +189,8 @@ static void ath_btcoex_period_timer(unsigned long data) bool is_btscan; ath9k_ps_wakeup(sc); - ath_detect_bt_priority(sc); - + if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) + ath_detect_bt_priority(sc); is_btscan = sc->sc_flags & SC_OP_BT_SCAN; spin_lock_bh(&btcoex->btcoex_lock); @@ -212,8 +212,9 @@ static void ath_btcoex_period_timer(unsigned long data) } ath9k_ps_restore(sc); + timer_period = btcoex->btcoex_period / 1000; mod_timer(&btcoex->period_timer, jiffies + - msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD)); + msecs_to_jiffies(timer_period)); } /* diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index b479160dc262..27471f80d8b2 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -2334,7 +2334,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) ah->enabled_cals |= TX_IQ_ON_AGC_CAL; } if (AR_SREV_9462(ah)) - pCap->hw_caps |= ATH9K_HW_CAP_RTT; + pCap->hw_caps |= ATH9K_HW_CAP_RTT | ATH9K_HW_CAP_MCI; return 0; } @@ -2582,7 +2582,7 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) struct ath9k_channel *chan = ah->curchan; struct ieee80211_channel *channel = chan->chan; - reg->power_limit = min_t(int, limit, MAX_RATE_POWER); + reg->power_limit = min_t(u32, limit, MAX_RATE_POWER); if (test) channel->max_power = MAX_RATE_POWER / 2; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index f389b3c93cf3..33e8f2f9d425 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -203,6 +203,7 @@ enum ath9k_hw_caps { ATH9K_HW_CAP_5GHZ = BIT(14), ATH9K_HW_CAP_APM = BIT(15), ATH9K_HW_CAP_RTT = BIT(16), + ATH9K_HW_CAP_MCI = BIT(17), }; struct ath9k_hw_capabilities { @@ -419,6 +420,16 @@ enum ath9k_rx_qtype { ATH9K_RX_QUEUE_MAX, }; +enum ath_mci_gpm_coex_profile_type { + MCI_GPM_COEX_PROFILE_UNKNOWN, + MCI_GPM_COEX_PROFILE_RFCOMM, + MCI_GPM_COEX_PROFILE_A2DP, + MCI_GPM_COEX_PROFILE_HID, + MCI_GPM_COEX_PROFILE_BNEP, + MCI_GPM_COEX_PROFILE_VOICE, + MCI_GPM_COEX_PROFILE_MAX +}; + struct ath9k_beacon_state { u32 bs_nexttbtt; u32 bs_nextdtim; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index af1b32549531..e8af5821a963 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -423,6 +423,8 @@ static int ath9k_init_btcoex(struct ath_softc *sc) txq = sc->tx.txq_map[WME_AC_BE]; ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; + sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; + INIT_LIST_HEAD(&sc->btcoex.mci.info); break; default: WARN_ON(1); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 93fbe6f40898..e1e006d81f73 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -1133,8 +1133,9 @@ static int ath9k_start(struct ieee80211_hw *hw) if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) && !ah->btcoex_hw.enabled) { - ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, - AR_STOMP_LOW_WLAN_WGHT); + if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) + ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, + AR_STOMP_LOW_WLAN_WGHT); ath9k_hw_btcoex_enable(ah); if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) @@ -1237,6 +1238,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) ath9k_hw_btcoex_disable(ah); if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) ath9k_btcoex_timer_pause(sc); + ath_mci_flush_profile(&sc->btcoex.mci); } spin_lock_bh(&sc->sc_pcu_lock); diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c new file mode 100644 index 000000000000..0fbb141bc302 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2010-2011 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "ath9k.h" +#include "mci.h" + +u8 ath_mci_duty_cycle[] = { 0, 50, 60, 70, 80, 85, 90, 95, 98 }; + +static struct ath_mci_profile_info* +ath_mci_find_profile(struct ath_mci_profile *mci, + struct ath_mci_profile_info *info) +{ + struct ath_mci_profile_info *entry; + + list_for_each_entry(entry, &mci->info, list) { + if (entry->conn_handle == info->conn_handle) + break; + } + return entry; +} + +static bool ath_mci_add_profile(struct ath_common *common, + struct ath_mci_profile *mci, + struct ath_mci_profile_info *info) +{ + struct ath_mci_profile_info *entry; + + if ((mci->num_sco == ATH_MCI_MAX_SCO_PROFILE) && + (info->type == MCI_GPM_COEX_PROFILE_VOICE)) { + ath_dbg(common, ATH_DBG_MCI, + "Too many SCO profile, failed to add new profile\n"); + return false; + } + + if (((NUM_PROF(mci) - mci->num_sco) == ATH_MCI_MAX_ACL_PROFILE) && + (info->type != MCI_GPM_COEX_PROFILE_VOICE)) { + ath_dbg(common, ATH_DBG_MCI, + "Too many ACL profile, failed to add new profile\n"); + return false; + } + + entry = ath_mci_find_profile(mci, info); + + if (entry) + memcpy(entry, info, 10); + else { + entry = kzalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + return false; + + memcpy(entry, info, 10); + INC_PROF(mci, info); + list_add_tail(&info->list, &mci->info); + } + return true; +} + +static void ath_mci_del_profile(struct ath_common *common, + struct ath_mci_profile *mci, + struct ath_mci_profile_info *info) +{ + struct ath_mci_profile_info *entry; + + entry = ath_mci_find_profile(mci, info); + + if (!entry) { + ath_dbg(common, ATH_DBG_MCI, + "Profile to be deleted not found\n"); + return; + } + DEC_PROF(mci, entry); + list_del(&entry->list); + kfree(entry); +} + +void ath_mci_flush_profile(struct ath_mci_profile *mci) +{ + struct ath_mci_profile_info *info, *tinfo; + + list_for_each_entry_safe(info, tinfo, &mci->info, list) { + list_del(&info->list); + DEC_PROF(mci, info); + kfree(info); + } + mci->aggr_limit = 0; +} + +static void ath_mci_adjust_aggr_limit(struct ath_btcoex *btcoex) +{ + struct ath_mci_profile *mci = &btcoex->mci; + u32 wlan_airtime = btcoex->btcoex_period * + (100 - btcoex->duty_cycle) / 100; + + /* + * Scale: wlan_airtime is in ms, aggr_limit is in 0.25 ms. + * When wlan_airtime is less than 4ms, aggregation limit has to be + * adjusted half of wlan_airtime to ensure that the aggregation can fit + * without collision with BT traffic. + */ + if ((wlan_airtime <= 4) && + (!mci->aggr_limit || (mci->aggr_limit > (2 * wlan_airtime)))) + mci->aggr_limit = 2 * wlan_airtime; +} + +static void ath_mci_update_scheme(struct ath_softc *sc) +{ + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_btcoex *btcoex = &sc->btcoex; + struct ath_mci_profile *mci = &btcoex->mci; + struct ath_mci_profile_info *info; + u32 num_profile = NUM_PROF(mci); + + if (num_profile == 1) { + info = list_first_entry(&mci->info, + struct ath_mci_profile_info, + list); + if (mci->num_sco && info->T == 12) { + mci->aggr_limit = 8; + ath_dbg(common, ATH_DBG_MCI, + "Single SCO, aggregation limit 2 ms\n"); + } else if ((info->type == MCI_GPM_COEX_PROFILE_BNEP) && + !info->master) { + btcoex->btcoex_period = 60; + ath_dbg(common, ATH_DBG_MCI, + "Single slave PAN/FTP, bt period 60 ms\n"); + } else if ((info->type == MCI_GPM_COEX_PROFILE_HID) && + (info->T > 0 && info->T < 50) && + (info->A > 1 || info->W > 1)) { + btcoex->duty_cycle = 30; + mci->aggr_limit = 8; + ath_dbg(common, ATH_DBG_MCI, + "Multiple attempt/timeout single HID " + "aggregation limit 2 ms dutycycle 30%%\n"); + } + } else if ((num_profile == 2) && (mci->num_hid == 2)) { + btcoex->duty_cycle = 30; + mci->aggr_limit = 8; + ath_dbg(common, ATH_DBG_MCI, + "Two HIDs aggregation limit 2 ms dutycycle 30%%\n"); + } else if (num_profile > 3) { + mci->aggr_limit = 6; + ath_dbg(common, ATH_DBG_MCI, + "Three or more profiles aggregation limit 1.5 ms\n"); + } + + if (IS_CHAN_2GHZ(sc->sc_ah->curchan)) { + if (IS_CHAN_HT(sc->sc_ah->curchan)) + ath_mci_adjust_aggr_limit(btcoex); + else + btcoex->btcoex_period >>= 1; + } + + ath9k_hw_btcoex_disable(sc->sc_ah); + ath9k_btcoex_timer_pause(sc); + + if (IS_CHAN_5GHZ(sc->sc_ah->curchan)) + return; + + btcoex->duty_cycle += (mci->num_bdr ? ATH_MCI_MAX_DUTY_CYCLE : 0); + if (btcoex->duty_cycle > ATH_MCI_MAX_DUTY_CYCLE) + btcoex->duty_cycle = ATH_MCI_MAX_DUTY_CYCLE; + + btcoex->btcoex_period *= 1000; + btcoex->btcoex_no_stomp = btcoex->btcoex_period * + (100 - btcoex->duty_cycle) / 100; + + ath9k_hw_btcoex_enable(sc->sc_ah); + ath9k_btcoex_timer_resume(sc); +} + +void ath_mci_process_profile(struct ath_softc *sc, + struct ath_mci_profile_info *info) +{ + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_btcoex *btcoex = &sc->btcoex; + struct ath_mci_profile *mci = &btcoex->mci; + + if (info->start) { + if (!ath_mci_add_profile(common, mci, info)) + return; + } else + ath_mci_del_profile(common, mci, info); + + btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD; + mci->aggr_limit = mci->num_sco ? 6 : 0; + if (NUM_PROF(mci)) { + btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW; + btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)]; + } else { + btcoex->bt_stomp_type = mci->num_mgmt ? ATH_BTCOEX_STOMP_ALL : + ATH_BTCOEX_STOMP_LOW; + btcoex->duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; + } + + ath_mci_update_scheme(sc); +} + +void ath_mci_process_status(struct ath_softc *sc, + struct ath_mci_profile_status *status) +{ + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + struct ath_btcoex *btcoex = &sc->btcoex; + struct ath_mci_profile *mci = &btcoex->mci; + struct ath_mci_profile_info info; + int i = 0, old_num_mgmt = mci->num_mgmt; + + /* Link status type are not handled */ + if (status->is_link) { + ath_dbg(common, ATH_DBG_MCI, + "Skip link type status update\n"); + return; + } + + memset(&info, 0, sizeof(struct ath_mci_profile_info)); + + info.conn_handle = status->conn_handle; + if (ath_mci_find_profile(mci, &info)) { + ath_dbg(common, ATH_DBG_MCI, + "Skip non link state update for existing profile %d\n", + status->conn_handle); + return; + } + if (status->conn_handle >= ATH_MCI_MAX_PROFILE) { + ath_dbg(common, ATH_DBG_MCI, + "Ignore too many non-link update\n"); + return; + } + if (status->is_critical) + __set_bit(status->conn_handle, mci->status); + else + __clear_bit(status->conn_handle, mci->status); + + mci->num_mgmt = 0; + do { + if (test_bit(i, mci->status)) + mci->num_mgmt++; + } while (++i < ATH_MCI_MAX_PROFILE); + + if (old_num_mgmt != mci->num_mgmt) + ath_mci_update_scheme(sc); +} diff --git a/drivers/net/wireless/ath/ath9k/mci.h b/drivers/net/wireless/ath/ath9k/mci.h new file mode 100644 index 000000000000..9590c61822d1 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/mci.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2010-2011 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MCI_H +#define MCI_H + +#define ATH_MCI_DEF_BT_PERIOD 40 +#define ATH_MCI_BDR_DUTY_CYCLE 20 +#define ATH_MCI_MAX_DUTY_CYCLE 90 + +#define ATH_MCI_DEF_AGGR_LIMIT 6 /* in 0.24 ms */ +#define ATH_MCI_MAX_ACL_PROFILE 7 +#define ATH_MCI_MAX_SCO_PROFILE 1 +#define ATH_MCI_MAX_PROFILE (ATH_MCI_MAX_ACL_PROFILE +\ + ATH_MCI_MAX_SCO_PROFILE) + +#define INC_PROF(_mci, _info) do { \ + switch (_info->type) { \ + case MCI_GPM_COEX_PROFILE_RFCOMM:\ + _mci->num_other_acl++; \ + break; \ + case MCI_GPM_COEX_PROFILE_A2DP: \ + _mci->num_a2dp++; \ + if (!_info->edr) \ + _mci->num_bdr++; \ + break; \ + case MCI_GPM_COEX_PROFILE_HID: \ + _mci->num_hid++; \ + break; \ + case MCI_GPM_COEX_PROFILE_BNEP: \ + _mci->num_pan++; \ + break; \ + case MCI_GPM_COEX_PROFILE_VOICE: \ + _mci->num_sco++; \ + break; \ + default: \ + break; \ + } \ + } while (0) + +#define DEC_PROF(_mci, _info) do { \ + switch (_info->type) { \ + case MCI_GPM_COEX_PROFILE_RFCOMM:\ + _mci->num_other_acl--; \ + break; \ + case MCI_GPM_COEX_PROFILE_A2DP: \ + _mci->num_a2dp--; \ + if (!_info->edr) \ + _mci->num_bdr--; \ + break; \ + case MCI_GPM_COEX_PROFILE_HID: \ + _mci->num_hid--; \ + break; \ + case MCI_GPM_COEX_PROFILE_BNEP: \ + _mci->num_pan--; \ + break; \ + case MCI_GPM_COEX_PROFILE_VOICE: \ + _mci->num_sco--; \ + break; \ + default: \ + break; \ + } \ + } while (0) + +#define NUM_PROF(_mci) (_mci->num_other_acl + _mci->num_a2dp + \ + _mci->num_hid + _mci->num_pan + _mci->num_sco) + +struct ath_mci_profile_info { + u8 type; + u8 conn_handle; + bool start; + bool master; + bool edr; + u8 voice_type; + u16 T; /* Voice: Tvoice, HID: Tsniff, in slots */ + u8 W; /* Voice: Wvoice, HID: Sniff timeout, in slots */ + u8 A; /* HID: Sniff attempt, in slots */ + struct list_head list; +}; + +struct ath_mci_profile_status { + bool is_critical; + bool is_link; + u8 conn_handle; +}; + +struct ath_mci_profile { + struct list_head info; + DECLARE_BITMAP(status, ATH_MCI_MAX_PROFILE); + u16 aggr_limit; + u8 num_mgmt; + u8 num_sco; + u8 num_a2dp; + u8 num_hid; + u8 num_pan; + u8 num_other_acl; + u8 num_bdr; +}; + +void ath_mci_flush_profile(struct ath_mci_profile *mci); +void ath_mci_process_profile(struct ath_softc *sc, + struct ath_mci_profile_info *info); +void ath_mci_process_status(struct ath_softc *sc, + struct ath_mci_profile_status *status); +#endif diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 03b0a651a591..55d077e7135d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -601,6 +601,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, struct sk_buff *skb; struct ieee80211_tx_info *tx_info; struct ieee80211_tx_rate *rates; + struct ath_mci_profile *mci = &sc->btcoex.mci; u32 max_4ms_framelen, frmlen; u16 aggr_limit, legacy = 0; int i; @@ -645,7 +646,9 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy) return 0; - if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED) + if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit) + aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4; + else if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED) aggr_limit = min((max_4ms_framelen * 3) / 8, (u32)ATH_AMPDU_LIMIT_MAX); else diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 4645766b4070..6da519e7578f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -87,7 +87,7 @@ #define TOE_TX_CSUM_OL 0x00000001 #define TOE_RX_CSUM_OL 0x00000002 -#define BRCMF_BSS_INFO_VERSION 108 /* current ver of brcmf_bss_info struct */ +#define BRCMF_BSS_INFO_VERSION 108 /* curr ver of brcmf_bss_info_le struct */ /* size of brcmf_scan_params not including variable length array */ #define BRCMF_SCAN_PARAMS_FIXED_SIZE 64 @@ -122,8 +122,6 @@ /* For supporting multiple interfaces */ #define BRCMF_MAX_IFS 16 -#define BRCMF_DEL_IF -0xe -#define BRCMF_BAD_IF -0xf #define DOT11_BSSTYPE_ANY 2 #define DOT11_MAX_DEFAULT_KEYS 4 @@ -365,7 +363,7 @@ struct brcmf_pkt_filter_enable_le { * Applications MUST CHECK ie_offset field and length field to access IEs and * next bss_info structure in a vector (in struct brcmf_scan_results) */ -struct brcmf_bss_info { +struct brcmf_bss_info_le { __le32 version; /* version field */ __le32 length; /* byte length of data in this record, * starting at version and including IEs @@ -466,14 +464,13 @@ struct brcmf_scan_results { u32 buflen; u32 version; u32 count; - struct brcmf_bss_info bss_info[1]; + struct brcmf_bss_info_le bss_info_le[]; }; struct brcmf_scan_results_le { __le32 buflen; __le32 version; __le32 count; - struct brcmf_bss_info bss_info[1]; }; /* used for association with a specific BSSID and chanspec list */ @@ -493,10 +490,6 @@ struct brcmf_join_params { struct brcmf_assoc_params_le params_le; }; -/* size of brcmf_scan_results not including variable length array */ -#define BRCMF_SCAN_RESULTS_FIXED_SIZE \ - (sizeof(struct brcmf_scan_results) - sizeof(struct brcmf_bss_info)) - /* incremental scan results struct */ struct brcmf_iscan_results { union { @@ -511,7 +504,7 @@ struct brcmf_iscan_results { /* size of brcmf_iscan_results not including variable length array */ #define BRCMF_ISCAN_RESULTS_FIXED_SIZE \ - (BRCMF_SCAN_RESULTS_FIXED_SIZE + \ + (sizeof(struct brcmf_scan_results) + \ offsetof(struct brcmf_iscan_results, results)) struct brcmf_wsec_key { @@ -734,8 +727,7 @@ extern int brcmf_c_host_event(struct brcmf_info *drvr_priv, int *idx, extern void brcmf_c_init(void); extern int brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, - struct net_device *ndev, char *name, u8 *mac_addr, - u32 flags, u8 bssidx); + char *name, u8 *mac_addr); extern void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx); /* Send packet to dongle via data channel */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 891826197f96..40928e58b6a6 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -488,10 +488,9 @@ brcmf_c_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) { if (ifevent->action == BRCMF_E_IF_ADD) - brcmf_add_if(drvr_priv, ifevent->ifidx, NULL, + brcmf_add_if(drvr_priv, ifevent->ifidx, event->ifname, - pvt_data->eth.h_dest, - ifevent->flags, ifevent->bssidx); + pvt_data->eth.h_dest); else brcmf_del_if(drvr_priv, ifevent->ifidx); } else { diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 4acbac5a74c6..719fd9397eb6 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -58,7 +58,6 @@ struct brcmf_if { struct net_device *ndev; struct net_device_stats stats; int idx; /* iface idx in dongle */ - int state; /* interface state */ u8 mac_addr[ETH_ALEN]; /* assigned MAC address */ }; @@ -80,20 +79,6 @@ struct brcmf_info { /* Error bits */ module_param(brcmf_msg_level, int, 0); - -static int brcmf_net2idx(struct brcmf_info *drvr_priv, struct net_device *ndev) -{ - int i = 0; - - while (i < BRCMF_MAX_IFS) { - if (drvr_priv->iflist[i] && drvr_priv->iflist[i]->ndev == ndev) - return i; - i++; - } - - return BRCMF_BAD_IF; -} - int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name) { int i = BRCMF_MAX_IFS; @@ -285,14 +270,9 @@ _brcmf_set_mac_address(struct work_struct *work) static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) { - struct brcmf_info *drvr_priv = *(struct brcmf_info **) - netdev_priv(ndev); + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_info *drvr_priv = ifp->info; struct sockaddr *sa = (struct sockaddr *)addr; - int ifidx; - - ifidx = brcmf_net2idx(drvr_priv, ndev); - if (ifidx == BRCMF_BAD_IF) - return -1; memcpy(&drvr_priv->macvalue, sa->sa_data, ETH_ALEN); schedule_work(&drvr_priv->setmacaddr_work); @@ -301,13 +281,8 @@ static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) static void brcmf_netdev_set_multicast_list(struct net_device *ndev) { - struct brcmf_info *drvr_priv = *(struct brcmf_info **) - netdev_priv(ndev); - int ifidx; - - ifidx = brcmf_net2idx(drvr_priv, ndev); - if (ifidx == BRCMF_BAD_IF) - return; + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_info *drvr_priv = ifp->info; schedule_work(&drvr_priv->multicast_work); } @@ -341,9 +316,8 @@ int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf) static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) { int ret; - struct brcmf_info *drvr_priv = *(struct brcmf_info **) - netdev_priv(ndev); - int ifidx; + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_info *drvr_priv = ifp->info; brcmf_dbg(TRACE, "Enter\n"); @@ -355,9 +329,8 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) return -ENODEV; } - ifidx = brcmf_net2idx(drvr_priv, ndev); - if (ifidx == BRCMF_BAD_IF) { - brcmf_dbg(ERROR, "bad ifidx %d\n", ifidx); + if (!drvr_priv->iflist[ifp->idx]) { + brcmf_dbg(ERROR, "bad ifidx %d\n", ifp->idx); netif_stop_queue(ndev); return -ENODEV; } @@ -367,20 +340,20 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) struct sk_buff *skb2; brcmf_dbg(INFO, "%s: insufficient headroom\n", - brcmf_ifname(&drvr_priv->pub, ifidx)); + brcmf_ifname(&drvr_priv->pub, ifp->idx)); drvr_priv->pub.tx_realloc++; skb2 = skb_realloc_headroom(skb, drvr_priv->pub.hdrlen); dev_kfree_skb(skb); skb = skb2; if (skb == NULL) { brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n", - brcmf_ifname(&drvr_priv->pub, ifidx)); + brcmf_ifname(&drvr_priv->pub, ifp->idx)); ret = -ENOMEM; goto done; } } - ret = brcmf_sendpkt(&drvr_priv->pub, ifidx, skb); + ret = brcmf_sendpkt(&drvr_priv->pub, ifp->idx, skb); done: if (ret) @@ -482,12 +455,10 @@ void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, struct sk_buff *skb, skb_mac_header(skb), &event, &data); - if (drvr_priv->iflist[ifidx] && - !drvr_priv->iflist[ifidx]->state) + if (drvr_priv->iflist[ifidx]) { ifp = drvr_priv->iflist[ifidx]; - - if (ifp->ndev) ifp->ndev->last_rx = jiffies; + } drvr->dstats.rx_bytes += skb->len; drvr->rx_packets++; /* Local count */ @@ -524,19 +495,11 @@ void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp, bool success) static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) { - struct brcmf_info *drvr_priv = *(struct brcmf_info **) - netdev_priv(ndev); - struct brcmf_if *ifp; - int ifidx; + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_info *drvr_priv = ifp->info; brcmf_dbg(TRACE, "Enter\n"); - ifidx = brcmf_net2idx(drvr_priv, ndev); - if (ifidx == BRCMF_BAD_IF) - return NULL; - - ifp = drvr_priv->iflist[ifidx]; - if (drvr_priv->pub.up) /* Use the protocol to get dongle stats */ brcmf_proto_dstats(&drvr_priv->pub); @@ -637,8 +600,8 @@ static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol) static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) { - struct brcmf_info *drvr_priv = *(struct brcmf_info **) - netdev_priv(ndev); + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_info *drvr_priv = ifp->info; sprintf(info->driver, KBUILD_MODNAME); sprintf(info->version, "%lu", drvr_priv->pub.drv_version); @@ -765,14 +728,12 @@ static int brcmf_ethtool(struct brcmf_info *drvr_priv, void __user *uaddr) static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr, int cmd) { - struct brcmf_info *drvr_priv = *(struct brcmf_info **) - netdev_priv(ndev); - int ifidx; + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_info *drvr_priv = ifp->info; - ifidx = brcmf_net2idx(drvr_priv, ndev); - brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifidx, cmd); + brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifp->idx, cmd); - if (ifidx == BRCMF_BAD_IF) + if (!drvr_priv->iflist[ifp->idx]) return -1; if (cmd == SIOCETHTOOL) @@ -788,17 +749,14 @@ s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len) s32 err = 0; int buflen = 0; bool is_set_key_cmd; - struct brcmf_info *drvr_priv = *(struct brcmf_info **) - netdev_priv(ndev); - int ifidx; + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_info *drvr_priv = ifp->info; memset(&dcmd, 0, sizeof(dcmd)); dcmd.cmd = cmd; dcmd.buf = arg; dcmd.len = len; - ifidx = brcmf_net2idx(drvr_priv, ndev); - if (dcmd.buf != NULL) buflen = min_t(uint, dcmd.len, BRCMF_DCMD_MAXLEN); @@ -826,7 +784,7 @@ s32 brcmf_exec_dcmd(struct net_device *ndev, u32 cmd, void *arg, u32 len) if (is_set_key_cmd) brcmf_netdev_wait_pend8021x(ndev); - err = brcmf_proto_dcmd(&drvr_priv->pub, ifidx, &dcmd, buflen); + err = brcmf_proto_dcmd(&drvr_priv->pub, ifp->idx, &dcmd, buflen); done: if (err > 0) @@ -837,7 +795,8 @@ done: static int brcmf_netdev_stop(struct net_device *ndev) { - struct brcmf_pub *drvr = *(struct brcmf_pub **) netdev_priv(ndev); + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_pub *drvr = &ifp->info->pub; brcmf_dbg(TRACE, "Enter\n"); brcmf_cfg80211_down(drvr->config); @@ -853,16 +812,14 @@ static int brcmf_netdev_stop(struct net_device *ndev) static int brcmf_netdev_open(struct net_device *ndev) { - struct brcmf_info *drvr_priv = *(struct brcmf_info **) - netdev_priv(ndev); + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_info *drvr_priv = ifp->info; u32 toe_ol; - int ifidx = brcmf_net2idx(drvr_priv, ndev); s32 ret = 0; - brcmf_dbg(TRACE, "ifidx %d\n", ifidx); - - if (ifidx == 0) { /* do it only for primary eth0 */ + brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); + if (ifp->idx == 0) { /* do it only for primary eth0 */ /* try to bring up bus */ ret = brcmf_bus_start(&drvr_priv->pub); if (ret != 0) { @@ -874,12 +831,12 @@ static int brcmf_netdev_open(struct net_device *ndev) memcpy(ndev->dev_addr, drvr_priv->pub.mac, ETH_ALEN); /* Get current TOE mode from dongle */ - if (brcmf_toe_get(drvr_priv, ifidx, &toe_ol) >= 0 + if (brcmf_toe_get(drvr_priv, ifp->idx, &toe_ol) >= 0 && (toe_ol & TOE_TX_CSUM_OL) != 0) - drvr_priv->iflist[ifidx]->ndev->features |= + drvr_priv->iflist[ifp->idx]->ndev->features |= NETIF_F_IP_CSUM; else - drvr_priv->iflist[ifidx]->ndev->features &= + drvr_priv->iflist[ifp->idx]->ndev->features &= ~NETIF_F_IP_CSUM; } /* Allow transmit calls */ @@ -893,75 +850,62 @@ static int brcmf_netdev_open(struct net_device *ndev) return ret; } +static const struct net_device_ops brcmf_netdev_ops_pri = { + .ndo_open = brcmf_netdev_open, + .ndo_stop = brcmf_netdev_stop, + .ndo_get_stats = brcmf_netdev_get_stats, + .ndo_do_ioctl = brcmf_netdev_ioctl_entry, + .ndo_start_xmit = brcmf_netdev_start_xmit, + .ndo_set_mac_address = brcmf_netdev_set_mac_address, + .ndo_set_rx_mode = brcmf_netdev_set_multicast_list +}; + int -brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, struct net_device *ndev, - char *name, u8 *mac_addr, u32 flags, u8 bssidx) +brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, char *name, u8 *mac_addr) { struct brcmf_if *ifp; - int ret = 0, err = 0; + struct net_device *ndev; - brcmf_dbg(TRACE, "idx %d, handle->%p\n", ifidx, ndev); + brcmf_dbg(TRACE, "idx %d\n", ifidx); ifp = drvr_priv->iflist[ifidx]; - if (!ifp) { - ifp = kmalloc(sizeof(struct brcmf_if), GFP_ATOMIC); - if (!ifp) - return -ENOMEM; + /* + * Delete the existing interface before overwriting it + * in case we missed the BRCMF_E_IF_DEL event. + */ + if (ifp) { + brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n", + ifp->ndev->name); + netif_stop_queue(ifp->ndev); + unregister_netdev(ifp->ndev); + free_netdev(ifp->ndev); + drvr_priv->iflist[ifidx] = NULL; + } + + /* Allocate netdev, including space for private structure */ + ndev = alloc_netdev(sizeof(struct brcmf_if), name, ether_setup); + if (!ndev) { + brcmf_dbg(ERROR, "OOM - alloc_netdev\n"); + return -ENOMEM; } - memset(ifp, 0, sizeof(struct brcmf_if)); + ifp = netdev_priv(ndev); + ifp->ndev = ndev; ifp->info = drvr_priv; drvr_priv->iflist[ifidx] = ifp; + ifp->idx = ifidx; if (mac_addr != NULL) memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); - if (ndev == NULL) { - ifp->state = BRCMF_E_IF_ADD; - ifp->idx = ifidx; - /* - * Delete the existing interface before overwriting it - * in case we missed the BRCMF_E_IF_DEL event. - */ - if (ifp->ndev != NULL) { - brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n", - ifp->ndev->name); - netif_stop_queue(ifp->ndev); - unregister_netdev(ifp->ndev); - free_netdev(ifp->ndev); - } - - /* Allocate netdev, including space for private structure */ - ifp->ndev = alloc_netdev(sizeof(drvr_priv), "wlan%d", - ether_setup); - if (!ifp->ndev) { - brcmf_dbg(ERROR, "OOM - alloc_netdev\n"); - ret = -ENOMEM; - } - - if (ret == 0) { - memcpy(netdev_priv(ifp->ndev), &drvr_priv, - sizeof(drvr_priv)); - err = brcmf_net_attach(&drvr_priv->pub, ifp->idx); - if (err != 0) { - brcmf_dbg(ERROR, "brcmf_net_attach failed, err %d\n", - err); - ret = -EOPNOTSUPP; - } else { - brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n", - current->pid, ifp->ndev->name); - ifp->state = 0; - } - } - - if (ret < 0) { - if (ifp->ndev) - free_netdev(ifp->ndev); + if (brcmf_net_attach(&drvr_priv->pub, ifp->idx)) { + brcmf_dbg(ERROR, "brcmf_net_attach failed"); + free_netdev(ifp->ndev); + drvr_priv->iflist[ifidx] = NULL; + return -EOPNOTSUPP; + } - drvr_priv->iflist[ifp->idx] = NULL; - kfree(ifp); - } - } else - ifp->ndev = ndev; + brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n", + current->pid, ifp->ndev->name); return 0; } @@ -977,47 +921,36 @@ void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx) brcmf_dbg(ERROR, "Null interface\n"); return; } + if (ifp->ndev) { + if (ifidx == 0) { + if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { + rtnl_lock(); + brcmf_netdev_stop(ifp->ndev); + rtnl_unlock(); + } + } else { + netif_stop_queue(ifp->ndev); + } - ifp->state = BRCMF_E_IF_DEL; - ifp->idx = ifidx; - if (ifp->ndev != NULL) { - netif_stop_queue(ifp->ndev); unregister_netdev(ifp->ndev); - free_netdev(ifp->ndev); drvr_priv->iflist[ifidx] = NULL; - kfree(ifp); + if (ifidx == 0) + brcmf_cfg80211_detach(drvr_priv->pub.config); + free_netdev(ifp->ndev); } } struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen) { struct brcmf_info *drvr_priv = NULL; - struct net_device *ndev; brcmf_dbg(TRACE, "Enter\n"); - /* Allocate netdev, including space for private structure */ - ndev = alloc_netdev(sizeof(drvr_priv), "wlan%d", ether_setup); - if (!ndev) { - brcmf_dbg(ERROR, "OOM - alloc_netdev\n"); - goto fail; - } - /* Allocate primary brcmf_info */ drvr_priv = kzalloc(sizeof(struct brcmf_info), GFP_ATOMIC); if (!drvr_priv) goto fail; - /* - * Save the brcmf_info into the priv - */ - memcpy(netdev_priv(ndev), &drvr_priv, sizeof(drvr_priv)); - - if (brcmf_add_if(drvr_priv, 0, ndev, ndev->name, NULL, 0, 0) == - BRCMF_BAD_IF) - goto fail; - - ndev->netdev_ops = NULL; mutex_init(&drvr_priv->proto_block); /* Link to info module */ @@ -1033,29 +966,12 @@ struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen) goto fail; } - /* Attach and link in the cfg80211 */ - drvr_priv->pub.config = - brcmf_cfg80211_attach(ndev, - brcmf_bus_get_device(bus), - &drvr_priv->pub); - if (drvr_priv->pub.config == NULL) { - brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n"); - goto fail; - } - INIT_WORK(&drvr_priv->setmacaddr_work, _brcmf_set_mac_address); INIT_WORK(&drvr_priv->multicast_work, _brcmf_set_multicast_list); - /* - * Save the brcmf_info into the priv - */ - memcpy(netdev_priv(ndev), &drvr_priv, sizeof(drvr_priv)); - return &drvr_priv->pub; fail: - if (ndev) - free_netdev(ndev); if (drvr_priv) brcmf_detach(&drvr_priv->pub); @@ -1123,16 +1039,6 @@ int brcmf_bus_start(struct brcmf_pub *drvr) return 0; } -static struct net_device_ops brcmf_netdev_ops_pri = { - .ndo_open = brcmf_netdev_open, - .ndo_stop = brcmf_netdev_stop, - .ndo_get_stats = brcmf_netdev_get_stats, - .ndo_do_ioctl = brcmf_netdev_ioctl_entry, - .ndo_start_xmit = brcmf_netdev_start_xmit, - .ndo_set_mac_address = brcmf_netdev_set_mac_address, - .ndo_set_rx_mode = brcmf_netdev_set_multicast_list -}; - int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) { struct brcmf_info *drvr_priv = drvr->info; @@ -1169,6 +1075,18 @@ int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) memcpy(ndev->dev_addr, temp_addr, ETH_ALEN); + /* attach to cfg80211 for primary interface */ + if (!ifidx) { + drvr->config = + brcmf_cfg80211_attach(ndev, + brcmf_bus_get_device(drvr->bus), + drvr); + if (drvr->config == NULL) { + brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n"); + goto fail; + } + } + if (register_netdev(ndev) != 0) { brcmf_dbg(ERROR, "couldn't register the net device\n"); goto fail; @@ -1210,21 +1128,13 @@ void brcmf_detach(struct brcmf_pub *drvr) if (drvr) { drvr_priv = drvr->info; if (drvr_priv) { - struct brcmf_if *ifp; int i; - for (i = 1; i < BRCMF_MAX_IFS; i++) + /* make sure primary interface removed last */ + for (i = BRCMF_MAX_IFS-1; i > -1; i--) if (drvr_priv->iflist[i]) brcmf_del_if(drvr_priv, i); - ifp = drvr_priv->iflist[0]; - if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { - rtnl_lock(); - brcmf_netdev_stop(ifp->ndev); - rtnl_unlock(); - unregister_netdev(ifp->ndev); - } - cancel_work_sync(&drvr_priv->setmacaddr_work); cancel_work_sync(&drvr_priv->multicast_work); @@ -1233,10 +1143,6 @@ void brcmf_detach(struct brcmf_pub *drvr) if (drvr->prot) brcmf_proto_detach(drvr); - brcmf_cfg80211_detach(drvr->config); - - free_netdev(ifp->ndev); - kfree(ifp); kfree(drvr_priv); } } @@ -1302,7 +1208,8 @@ static int brcmf_get_pend_8021x_cnt(struct brcmf_info *drvr_priv) int brcmf_netdev_wait_pend8021x(struct net_device *ndev) { - struct brcmf_info *drvr_priv = *(struct brcmf_info **)netdev_priv(ndev); + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_info *drvr_priv = ifp->info; int timeout = 10 * HZ / 1000; int ntimes = MAX_WAIT_FOR_8021X_TX; int pend = brcmf_get_pend_8021x_cnt(drvr_priv); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 313b8bf592d1..6de489b1a162 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -574,7 +574,7 @@ struct brcmf_bus { uint txminmax; struct sk_buff *glomd; /* Packet containing glomming descriptor */ - struct sk_buff *glom; /* Packet chain for glommed superframe */ + struct sk_buff_head glom; /* Packet list for glommed superframe */ uint glomerr; /* Glom packet read errors */ u8 *rxbuf; /* Buffer for receiving control packets */ @@ -1222,6 +1222,29 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_bus *bus, bool abort, bool rtx) bus->drvr->busstate = BRCMF_BUS_DOWN; } +/* copy a buffer into a pkt buffer chain */ +static uint brcmf_sdbrcm_glom_from_buf(struct brcmf_bus *bus, uint len) +{ + uint n, ret = 0; + struct sk_buff *p; + u8 *buf; + + buf = bus->dataptr; + + /* copy the data */ + skb_queue_walk(&bus->glom, p) { + n = min_t(uint, p->len, len); + memcpy(p->data, buf, n); + buf += n; + len -= n; + ret += n; + if (!len) + break; + } + + return ret; +} + static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) { u16 dlen, totlen; @@ -1240,7 +1263,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) /* If packets, issue read(s) and send up packet chain */ /* Return sequence numbers consumed? */ - brcmf_dbg(TRACE, "start: glomd %p glom %p\n", bus->glomd, bus->glom); + brcmf_dbg(TRACE, "start: glomd %p glom %p\n", + bus->glomd, skb_peek(&bus->glom)); /* If there's a descriptor, generate the packet chain */ if (bus->glomd) { @@ -1287,12 +1311,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) num, sublen); break; } - if (!pfirst) { - pfirst = plast = pnext; - } else { - plast->next = pnext; - plast = pnext; - } + skb_queue_tail(&bus->glom, pnext); /* Adhere to start alignment requirements */ pkt_align(pnext, sublen, BRCMF_SDALIGN); @@ -1308,12 +1327,13 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) brcmf_dbg(GLOM, "glomdesc mismatch: nextlen %d glomdesc %d rxseq %d\n", bus->nextlen, totlen, rxseq); } - bus->glom = pfirst; pfirst = pnext = NULL; } else { - if (pfirst) - brcmu_pkt_buf_free_skb(pfirst); - bus->glom = NULL; + if (!skb_queue_empty(&bus->glom)) + skb_queue_walk_safe(&bus->glom, pfirst, pnext) { + skb_unlink(pfirst, &bus->glom); + brcmu_pkt_buf_free_skb(pfirst); + } num = 0; } @@ -1325,17 +1345,17 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) /* Ok -- either we just generated a packet chain, or had one from before */ - if (bus->glom) { + if (!skb_queue_empty(&bus->glom)) { if (BRCMF_GLOM_ON()) { brcmf_dbg(GLOM, "try superframe read, packet chain:\n"); - for (pnext = bus->glom; pnext; pnext = pnext->next) { + skb_queue_walk(&bus->glom, pnext) { brcmf_dbg(GLOM, " %p: %p len 0x%04x (%d)\n", pnext, (u8 *) (pnext->data), pnext->len, pnext->len); } } - pfirst = bus->glom; + pfirst = skb_peek(&bus->glom); dlen = (u16) brcmu_pkttotlen(pfirst); /* Do an SDIO read for the superframe. Configurable iovar to @@ -1354,8 +1374,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) SDIO_FUNC_2, F2SYNC, bus->dataptr, dlen, NULL); - sublen = (u16) brcmu_pktfrombuf(pfirst, 0, dlen, - bus->dataptr); + sublen = (u16) brcmf_sdbrcm_glom_from_buf(bus, dlen); if (sublen != dlen) { brcmf_dbg(ERROR, "FAILED TO COPY, dlen %d sublen %d\n", dlen, sublen); @@ -1380,9 +1399,11 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) } else { bus->glomerr = 0; brcmf_sdbrcm_rxfail(bus, true, false); - brcmu_pkt_buf_free_skb(bus->glom); bus->rxglomfail++; - bus->glom = NULL; + skb_queue_walk_safe(&bus->glom, pfirst, pnext) { + skb_unlink(pfirst, &bus->glom); + brcmu_pkt_buf_free_skb(pfirst); + } } return 0; } @@ -1503,9 +1524,11 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) } else { bus->glomerr = 0; brcmf_sdbrcm_rxfail(bus, true, false); - brcmu_pkt_buf_free_skb(bus->glom); bus->rxglomfail++; - bus->glom = NULL; + skb_queue_walk_safe(&bus->glom, pfirst, pnext) { + skb_unlink(pfirst, &bus->glom); + brcmu_pkt_buf_free_skb(pfirst); + } } bus->nextlen = 0; return 0; @@ -1513,7 +1536,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) /* Basic SD framing looks ok - process each packet (header) */ save_pfirst = pfirst; - bus->glom = NULL; plast = NULL; for (num = 0; pfirst; rxseq++, pfirst = pnext) { @@ -1850,10 +1872,10 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) rxseq++, rxleft--) { /* Handle glomming separately */ - if (bus->glom || bus->glomd) { + if (bus->glomd || !skb_queue_empty(&bus->glom)) { u8 cnt; brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n", - bus->glomd, bus->glom); + bus->glomd, skb_peek(&bus->glom)); cnt = brcmf_sdbrcm_rxglom(bus, rxseq); brcmf_dbg(GLOM, "rxglom returned %d\n", cnt); rxseq += cnt - 1; @@ -3602,6 +3624,8 @@ void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus) u8 saveclk; uint retries; int err; + struct sk_buff *cur; + struct sk_buff *next; brcmf_dbg(TRACE, "Enter\n"); @@ -3661,11 +3685,11 @@ void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus) /* Clear any held glomming stuff */ if (bus->glomd) brcmu_pkt_buf_free_skb(bus->glomd); - - if (bus->glom) - brcmu_pkt_buf_free_skb(bus->glom); - - bus->glom = bus->glomd = NULL; + if (!skb_queue_empty(&bus->glom)) + skb_queue_walk_safe(&bus->glom, cur, next) { + skb_unlink(cur, &bus->glom); + brcmu_pkt_buf_free_skb(cur); + } /* Clear rx control and wake any waiters */ bus->rxlen = 0; @@ -4440,6 +4464,7 @@ void *brcmf_sdbrcm_probe(u16 bus_no, u16 slot, u16 func, uint bustype, bus->sdiodev = sdiodev; sdiodev->bus = bus; + skb_queue_head_init(&bus->glom); bus->txbound = BRCMF_TXBOUND; bus->rxbound = BRCMF_RXBOUND; bus->txminmax = BRCMF_TXMINMAX; @@ -4521,9 +4546,10 @@ void *brcmf_sdbrcm_probe(u16 bus_no, u16 slot, u16 func, uint bustype, goto fail; } } - /* Ok, have the per-port tell the stack we're open for business */ - if (brcmf_net_attach(bus->drvr, 0) != 0) { - brcmf_dbg(ERROR, "Net attach failed!!\n"); + + /* add interface and open for business */ + if (brcmf_add_if((struct brcmf_info *)bus->drvr, 0, "wlan%d", NULL)) { + brcmf_dbg(ERROR, "Add primary net device interface failed!!\n"); goto fail; } @@ -4554,10 +4580,6 @@ struct device *brcmf_bus_get_device(struct brcmf_bus *bus) void brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick) { - /* don't start the wd until fw is loaded */ - if (bus->drvr->busstate == BRCMF_BUS_DOWN) - return; - /* Totally stop the timer */ if (!wdtick && bus->wd_timer_valid == true) { del_timer_sync(&bus->timer); @@ -4566,6 +4588,10 @@ brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick) return; } + /* don't start the wd until fw is loaded */ + if (bus->drvr->busstate == BRCMF_BUS_DOWN) + return; + if (wdtick) { if (bus->save_ms != BRCMF_WD_POLL_MS) { if (bus->wd_timer_valid == true) diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 5eddabe5228a..73be2c8d4cee 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -1997,7 +1997,7 @@ done: } static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, - struct brcmf_bss_info *bi) + struct brcmf_bss_info_le *bi) { struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); struct ieee80211_channel *notify_channel; @@ -2057,10 +2057,19 @@ static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, return err; } +static struct brcmf_bss_info_le * +next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss) +{ + if (bss == NULL) + return list->bss_info_le; + return (struct brcmf_bss_info_le *)((unsigned long)bss + + le32_to_cpu(bss->length)); +} + static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv) { struct brcmf_scan_results *bss_list; - struct brcmf_bss_info *bi = NULL; /* must be initialized */ + struct brcmf_bss_info_le *bi = NULL; /* must be initialized */ s32 err = 0; int i; @@ -2072,7 +2081,7 @@ static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv) } WL_SCAN("scanned AP count (%d)\n", bss_list->count); for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) { - bi = next_bss(bss_list, bi); + bi = next_bss_le(bss_list, bi); err = brcmf_inform_single_bss(cfg_priv, bi); if (err) break; @@ -2085,7 +2094,7 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, { struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); struct ieee80211_channel *notify_channel; - struct brcmf_bss_info *bi = NULL; + struct brcmf_bss_info_le *bi = NULL; struct ieee80211_supported_band *band; u8 *buf = NULL; s32 err = 0; @@ -2114,7 +2123,7 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, goto CleanUp; } - bi = (struct brcmf_bss_info *)(buf + 4); + bi = (struct brcmf_bss_info_le *)(buf + 4); channel = bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec)); @@ -2188,7 +2197,7 @@ static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key) static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv) { - struct brcmf_bss_info *bi; + struct brcmf_bss_info_le *bi; struct brcmf_ssid *ssid; struct brcmf_tlv *tim; u16 beacon_interval; @@ -2211,7 +2220,7 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv) goto update_bss_info_out; } - bi = (struct brcmf_bss_info *)(cfg_priv->extra_buf + 4); + bi = (struct brcmf_bss_info_le *)(cfg_priv->extra_buf + 4); err = brcmf_inform_single_bss(cfg_priv, bi); if (err) goto update_bss_info_out; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index 62dc46144ede..a613b49cb13f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h @@ -352,15 +352,6 @@ brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_priv *cfg) return &cfg->conn_info; } -static inline struct brcmf_bss_info *next_bss(struct brcmf_scan_results *list, - struct brcmf_bss_info *bss) -{ - return bss = bss ? - (struct brcmf_bss_info *)((unsigned long)bss + - le32_to_cpu(bss->length)) : - list->bss_info; -} - extern struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev, struct device *busdev, void *data); diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h index 106a7424a7cd..b51d1e421e24 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h @@ -38,88 +38,12 @@ /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */ #define SI_PCIE_DMA_H32 0x80000000 -/* core codes */ -#define NODEV_CORE_ID 0x700 /* Invalid coreid */ -#define CC_CORE_ID 0x800 /* chipcommon core */ -#define ILINE20_CORE_ID 0x801 /* iline20 core */ -#define SRAM_CORE_ID 0x802 /* sram core */ -#define SDRAM_CORE_ID 0x803 /* sdram core */ -#define PCI_CORE_ID 0x804 /* pci core */ -#define MIPS_CORE_ID 0x805 /* mips core */ -#define ENET_CORE_ID 0x806 /* enet mac core */ -#define CODEC_CORE_ID 0x807 /* v90 codec core */ -#define USB_CORE_ID 0x808 /* usb 1.1 host/device core */ -#define ADSL_CORE_ID 0x809 /* ADSL core */ -#define ILINE100_CORE_ID 0x80a /* iline100 core */ -#define IPSEC_CORE_ID 0x80b /* ipsec core */ -#define UTOPIA_CORE_ID 0x80c /* utopia core */ -#define PCMCIA_CORE_ID 0x80d /* pcmcia core */ -#define SOCRAM_CORE_ID 0x80e /* internal memory core */ -#define MEMC_CORE_ID 0x80f /* memc sdram core */ -#define OFDM_CORE_ID 0x810 /* OFDM phy core */ -#define EXTIF_CORE_ID 0x811 /* external interface core */ -#define D11_CORE_ID 0x812 /* 802.11 MAC core */ -#define APHY_CORE_ID 0x813 /* 802.11a phy core */ -#define BPHY_CORE_ID 0x814 /* 802.11b phy core */ -#define GPHY_CORE_ID 0x815 /* 802.11g phy core */ -#define MIPS33_CORE_ID 0x816 /* mips3302 core */ -#define USB11H_CORE_ID 0x817 /* usb 1.1 host core */ -#define USB11D_CORE_ID 0x818 /* usb 1.1 device core */ -#define USB20H_CORE_ID 0x819 /* usb 2.0 host core */ -#define USB20D_CORE_ID 0x81a /* usb 2.0 device core */ -#define SDIOH_CORE_ID 0x81b /* sdio host core */ -#define ROBO_CORE_ID 0x81c /* roboswitch core */ -#define ATA100_CORE_ID 0x81d /* parallel ATA core */ -#define SATAXOR_CORE_ID 0x81e /* serial ATA & XOR DMA core */ -#define GIGETH_CORE_ID 0x81f /* gigabit ethernet core */ -#define PCIE_CORE_ID 0x820 /* pci express core */ -#define NPHY_CORE_ID 0x821 /* 802.11n 2x2 phy core */ -#define SRAMC_CORE_ID 0x822 /* SRAM controller core */ -#define MINIMAC_CORE_ID 0x823 /* MINI MAC/phy core */ -#define ARM11_CORE_ID 0x824 /* ARM 1176 core */ -#define ARM7S_CORE_ID 0x825 /* ARM7tdmi-s core */ -#define LPPHY_CORE_ID 0x826 /* 802.11a/b/g phy core */ -#define PMU_CORE_ID 0x827 /* PMU core */ -#define SSNPHY_CORE_ID 0x828 /* 802.11n single-stream phy core */ -#define SDIOD_CORE_ID 0x829 /* SDIO device core */ -#define ARMCM3_CORE_ID 0x82a /* ARM Cortex M3 core */ -#define HTPHY_CORE_ID 0x82b /* 802.11n 4x4 phy core */ -#define MIPS74K_CORE_ID 0x82c /* mips 74k core */ -#define GMAC_CORE_ID 0x82d /* Gigabit MAC core */ -#define DMEMC_CORE_ID 0x82e /* DDR1/2 memory controller core */ -#define PCIERC_CORE_ID 0x82f /* PCIE Root Complex core */ -#define OCP_CORE_ID 0x830 /* OCP2OCP bridge core */ -#define SC_CORE_ID 0x831 /* shared common core */ -#define AHB_CORE_ID 0x832 /* OCP2AHB bridge core */ -#define SPIH_CORE_ID 0x833 /* SPI host core */ -#define I2S_CORE_ID 0x834 /* I2S core */ -#define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ -#define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ -#define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ -#define DEF_AI_COMP 0xfff /* Default component, in ai chips it - * maps all unused address ranges - */ - /* chipcommon being the first core: */ #define SI_CC_IDX 0 /* SOC Interconnect types (aka chip types) */ #define SOCI_AI 1 -/* Common core control flags */ -#define SICF_BIST_EN 0x8000 -#define SICF_PME_EN 0x4000 -#define SICF_CORE_BITS 0x3ffc -#define SICF_FGC 0x0002 -#define SICF_CLOCK_EN 0x0001 - -/* Common core status flags */ -#define SISF_BIST_DONE 0x8000 -#define SISF_BIST_ERROR 0x4000 -#define SISF_GATED_CLK 0x2000 -#define SISF_DMA64 0x1000 -#define SISF_CORE_BITS 0x0fff - /* A register that is common to all cores to * communicate w/PMU regarding clock control. */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c index 6ebec8f42846..e286fb4d4813 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c @@ -14,7 +14,6 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <linux/slab.h> -#include <linux/skbuff.h> #include <linux/delay.h> #include <linux/pci.h> @@ -22,6 +21,7 @@ #include <aiutils.h> #include "types.h" #include "dma.h" +#include "soc.h" /* * DMA hardware requires each descriptor ring to be 8kB aligned, and fit within @@ -901,7 +901,7 @@ static struct sk_buff *_dma_getnextrxp(struct dma_info *di, bool forceall) /* * !! rx entry routine - * returns a pointer to the next frame received, or NULL if there are no more + * returns the number packages in the next frame, or 0 if there are no more * if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is * supported with pkts chain * otherwise, it's treated as giant pkt and will be tossed. @@ -909,38 +909,40 @@ static struct sk_buff *_dma_getnextrxp(struct dma_info *di, bool forceall) * buffer data. After it reaches the max size of buffer, the data continues * in next DMA descriptor buffer WITHOUT DMA header */ -struct sk_buff *dma_rx(struct dma_pub *pub) +int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) { struct dma_info *di = (struct dma_info *)pub; - struct sk_buff *p, *head, *tail; + struct sk_buff_head dma_frames; + struct sk_buff *p, *next; uint len; uint pkt_len; int resid = 0; + int pktcnt = 1; + skb_queue_head_init(&dma_frames); next_frame: - head = _dma_getnextrxp(di, false); - if (head == NULL) - return NULL; + p = _dma_getnextrxp(di, false); + if (p == NULL) + return 0; - len = le16_to_cpu(*(__le16 *) (head->data)); + len = le16_to_cpu(*(__le16 *) (p->data)); DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); - dma_spin_for_len(len, head); + dma_spin_for_len(len, p); /* set actual length */ pkt_len = min((di->rxoffset + len), di->rxbufsize); - __skb_trim(head, pkt_len); + __skb_trim(p, pkt_len); + skb_queue_tail(&dma_frames, p); resid = len - (di->rxbufsize - di->rxoffset); /* check for single or multi-buffer rx */ if (resid > 0) { - tail = head; while ((resid > 0) && (p = _dma_getnextrxp(di, false))) { - tail->next = p; pkt_len = min_t(uint, resid, di->rxbufsize); __skb_trim(p, pkt_len); - - tail = p; + skb_queue_tail(&dma_frames, p); resid -= di->rxbufsize; + pktcnt++; } #ifdef BCMDBG @@ -959,13 +961,18 @@ struct sk_buff *dma_rx(struct dma_pub *pub) if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); - brcmu_pkt_buf_free_skb(head); + skb_queue_walk_safe(&dma_frames, p, next) { + skb_unlink(p, &dma_frames); + brcmu_pkt_buf_free_skb(p); + } di->dma.rxgiants++; + pktcnt = 1; goto next_frame; } } - return head; + skb_queue_splice_tail(&dma_frames, skb_list); + return pktcnt; } static bool dma64_rxidle(struct dma_info *di) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.h b/drivers/net/wireless/brcm80211/brcmsmac/dma.h index ebc5bc546f3b..d317c7c12f91 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.h @@ -18,6 +18,7 @@ #define _BRCM_DMA_H_ #include <linux/delay.h> +#include <linux/skbuff.h> #include "types.h" /* forward structure declarations */ /* map/unmap direction */ @@ -80,7 +81,7 @@ extern struct dma_pub *dma_attach(char *name, struct si_pub *sih, uint nrxpost, uint rxoffset, uint *msg_level); void dma_rxinit(struct dma_pub *pub); -struct sk_buff *dma_rx(struct dma_pub *pub); +int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list); bool dma_rxfill(struct dma_pub *pub); bool dma_rxreset(struct dma_pub *pub); bool dma_txreset(struct dma_pub *pub); diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index ac8d02bd34f2..8e35c62d0bb1 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -215,8 +215,7 @@ static const struct ieee80211_supported_band brcms_band_2GHz_nphy_template = { .ht_cap = { /* from include/linux/ieee80211.h */ .cap = IEEE80211_HT_CAP_GRN_FLD | - IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, + IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40, .ht_supported = true, .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, .ampdu_density = AMPDU_DEF_MPDU_DENSITY, @@ -237,8 +236,7 @@ static const struct ieee80211_supported_band brcms_band_5GHz_nphy_template = { BRCMS_LEGACY_5G_RATE_OFFSET, .ht_cap = { .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_SGI_40 | - IEEE80211_HT_CAP_40MHZ_INTOLERANT, /* No 40 mhz yet */ + IEEE80211_HT_CAP_SGI_40, .ht_supported = true, .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, .ampdu_density = AMPDU_DEF_MPDU_DENSITY, @@ -286,6 +284,7 @@ static int brcms_ops_start(struct ieee80211_hw *hw) { struct brcms_info *wl = hw->priv; bool blocked; + int err; ieee80211_wake_queues(hw); spin_lock_bh(&wl->lock); @@ -294,57 +293,69 @@ static int brcms_ops_start(struct ieee80211_hw *hw) if (!blocked) wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); - return 0; + spin_lock_bh(&wl->lock); + /* avoid acknowledging frames before a non-monitor device is added */ + wl->mute_tx = true; + + if (!wl->pub->up) + err = brcms_up(wl); + else + err = -ENODEV; + spin_unlock_bh(&wl->lock); + + if (err != 0) + wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__, + err); + return err; } static void brcms_ops_stop(struct ieee80211_hw *hw) { + struct brcms_info *wl = hw->priv; + int status; + ieee80211_stop_queues(hw); + + if (wl->wlc == NULL) + return; + + spin_lock_bh(&wl->lock); + status = brcms_c_chipmatch(wl->wlc->hw->vendorid, + wl->wlc->hw->deviceid); + spin_unlock_bh(&wl->lock); + if (!status) { + wiphy_err(wl->wiphy, + "wl: brcms_ops_stop: chipmatch failed\n"); + return; + } + + /* put driver in down state */ + spin_lock_bh(&wl->lock); + brcms_down(wl); + spin_unlock_bh(&wl->lock); } static int brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct brcms_info *wl; - int err; + struct brcms_info *wl = hw->priv; /* Just STA for now */ - if (vif->type != NL80211_IFTYPE_AP && - vif->type != NL80211_IFTYPE_MESH_POINT && - vif->type != NL80211_IFTYPE_STATION && - vif->type != NL80211_IFTYPE_WDS && - vif->type != NL80211_IFTYPE_ADHOC) { + if (vif->type != NL80211_IFTYPE_STATION) { wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only" " STA for now\n", __func__, vif->type); return -EOPNOTSUPP; } - wl = hw->priv; - spin_lock_bh(&wl->lock); - if (!wl->pub->up) - err = brcms_up(wl); - else - err = -ENODEV; - spin_unlock_bh(&wl->lock); - - if (err != 0) - wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__, - err); + wl->mute_tx = false; + brcms_c_mute(wl->wlc, false); - return err; + return 0; } static void brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - struct brcms_info *wl; - - wl = hw->priv; - - /* put driver in down state */ - spin_lock_bh(&wl->lock); - brcms_down(wl); - spin_unlock_bh(&wl->lock); } static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) @@ -876,37 +887,18 @@ static void brcms_free(struct brcms_info *wl) } /* -* called from both kernel as from this kernel module. +* called from both kernel as from this kernel module (error flow on attach) * precondition: perimeter lock is not acquired. */ static void brcms_remove(struct pci_dev *pdev) { - struct brcms_info *wl; - struct ieee80211_hw *hw; - int status; - - hw = pci_get_drvdata(pdev); - wl = hw->priv; - if (!wl) { - pr_err("wl: brcms_remove: pci_get_drvdata failed\n"); - return; - } + struct ieee80211_hw *hw = pci_get_drvdata(pdev); + struct brcms_info *wl = hw->priv; - spin_lock_bh(&wl->lock); - status = brcms_c_chipmatch(pdev->vendor, pdev->device); - spin_unlock_bh(&wl->lock); - if (!status) { - wiphy_err(wl->wiphy, "wl: brcms_remove: chipmatch " - "failed\n"); - return; - } if (wl->wlc) { wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false); wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); ieee80211_unregister_hw(hw); - spin_lock_bh(&wl->lock); - brcms_down(wl); - spin_unlock_bh(&wl->lock); } pci_disable_device(pdev); @@ -1080,9 +1072,6 @@ static struct brcms_info *brcms_attach(u16 vendor, u16 device, wl->pub->ieee_hw = hw; - /* disable mpc */ - brcms_c_set_radio_mpc(wl->wlc, false); - /* register our interrupt handler */ if (request_irq(irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit); @@ -1318,8 +1307,7 @@ void brcms_init(struct brcms_info *wl) { BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit); brcms_reset(wl); - - brcms_c_init(wl->wlc); + brcms_c_init(wl->wlc, wl->mute_tx); } /* @@ -1336,6 +1324,14 @@ uint brcms_reset(struct brcms_info *wl) return 0; } +void brcms_fatal_error(struct brcms_info *wl) +{ + wiphy_err(wl->wlc->wiphy, "wl%d: fatal error, reinitializing\n", + wl->wlc->pub->unit); + brcms_reset(wl); + ieee80211_restart_hw(wl->pub->ieee_hw); +} + /* * These are interrupt on/off entry points. Disable interrupts * during interrupt state transition. diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h index 177f0e44e4b6..6242f188b717 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h @@ -80,6 +80,7 @@ struct brcms_info { struct brcms_firmware fw; struct wiphy *wiphy; struct brcms_ucode ucode; + bool mute_tx; }; /* misc callbacks */ @@ -104,5 +105,6 @@ extern bool brcms_del_timer(struct brcms_timer *timer); extern void brcms_msleep(struct brcms_info *wl, uint ms); extern void brcms_dpc(unsigned long data); extern void brcms_timer(struct brcms_timer *t); +extern void brcms_fatal_error(struct brcms_info *wl); #endif /* _BRCM_MAC80211_IF_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 510e9bb52287..f193fab675dc 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -30,44 +30,21 @@ #include "mac80211_if.h" #include "ucode_loader.h" #include "main.h" +#include "soc.h" /* * Indication for txflowcontrol that all priority bits in * TXQ_STOP_FOR_PRIOFC_MASK are to be considered. */ -#define ALLPRIO -1 - -/* - * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. - */ -#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) +#define ALLPRIO -1 /* watchdog timer, in unit of ms */ -#define TIMER_INTERVAL_WATCHDOG 1000 +#define TIMER_INTERVAL_WATCHDOG 1000 /* radio monitor timer, in unit of ms */ -#define TIMER_INTERVAL_RADIOCHK 800 - -/* Max MPC timeout, in unit of watchdog */ -#ifndef BRCMS_MPC_MAX_DELAYCNT -#define BRCMS_MPC_MAX_DELAYCNT 10 -#endif +#define TIMER_INTERVAL_RADIOCHK 800 -/* Min MPC timeout, in unit of watchdog */ -#define BRCMS_MPC_MIN_DELAYCNT 1 -#define BRCMS_MPC_THRESHOLD 3 /* MPC count threshold level */ - -/* beacon interval, in unit of 1024TU */ -#define BEACON_INTERVAL_DEFAULT 100 -/* DTIM interval, in unit of beacon interval */ -#define DTIM_INTERVAL_DEFAULT 3 - -/* Scale down delays to accommodate QT slow speed */ /* beacon interval, in unit of 1024TU */ -#define BEACON_INTERVAL_DEF_QT 20 -/* DTIM interval, in unit of beacon interval */ -#define DTIM_INTERVAL_DEF_QT 1 - -#define TBTT_ALIGN_LEEWAY_US 100 /* min leeway before first TBTT in us */ +#define BEACON_INTERVAL_DEFAULT 100 /* n-mode support capability */ /* 2x2 includes both 1x1 & 2x2 devices @@ -78,113 +55,76 @@ #define WL_11N_3x3 3 #define WL_11N_4x4 4 -/* define 11n feature disable flags */ -#define WLFEATURE_DISABLE_11N 0x00000001 -#define WLFEATURE_DISABLE_11N_STBC_TX 0x00000002 -#define WLFEATURE_DISABLE_11N_STBC_RX 0x00000004 -#define WLFEATURE_DISABLE_11N_SGI_TX 0x00000008 -#define WLFEATURE_DISABLE_11N_SGI_RX 0x00000010 -#define WLFEATURE_DISABLE_11N_AMPDU_TX 0x00000020 -#define WLFEATURE_DISABLE_11N_AMPDU_RX 0x00000040 -#define WLFEATURE_DISABLE_11N_GF 0x00000080 - -#define EDCF_ACI_MASK 0x60 -#define EDCF_ACI_SHIFT 5 -#define EDCF_ECWMIN_MASK 0x0f -#define EDCF_ECWMAX_SHIFT 4 -#define EDCF_AIFSN_MASK 0x0f -#define EDCF_AIFSN_MAX 15 -#define EDCF_ECWMAX_MASK 0xf0 - -#define EDCF_AC_BE_TXOP_STA 0x0000 -#define EDCF_AC_BK_TXOP_STA 0x0000 -#define EDCF_AC_VO_ACI_STA 0x62 -#define EDCF_AC_VO_ECW_STA 0x32 -#define EDCF_AC_VI_ACI_STA 0x42 -#define EDCF_AC_VI_ECW_STA 0x43 -#define EDCF_AC_BK_ECW_STA 0xA4 -#define EDCF_AC_VI_TXOP_STA 0x005e -#define EDCF_AC_VO_TXOP_STA 0x002f -#define EDCF_AC_BE_ACI_STA 0x03 -#define EDCF_AC_BE_ECW_STA 0xA4 -#define EDCF_AC_BK_ACI_STA 0x27 -#define EDCF_AC_VO_TXOP_AP 0x002f - -#define EDCF_TXOP2USEC(txop) ((txop) << 5) -#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) - -#define APHY_SYMBOL_TIME 4 -#define APHY_PREAMBLE_TIME 16 -#define APHY_SIGNAL_TIME 4 -#define APHY_SIFS_TIME 16 -#define APHY_SERVICE_NBITS 16 -#define APHY_TAIL_NBITS 6 -#define BPHY_SIFS_TIME 10 -#define BPHY_PLCP_SHORT_TIME 96 - -#define PREN_PREAMBLE 24 -#define PREN_MM_EXT 12 -#define PREN_PREAMBLE_EXT 4 +#define EDCF_ACI_MASK 0x60 +#define EDCF_ACI_SHIFT 5 +#define EDCF_ECWMIN_MASK 0x0f +#define EDCF_ECWMAX_SHIFT 4 +#define EDCF_AIFSN_MASK 0x0f +#define EDCF_AIFSN_MAX 15 +#define EDCF_ECWMAX_MASK 0xf0 + +#define EDCF_AC_BE_TXOP_STA 0x0000 +#define EDCF_AC_BK_TXOP_STA 0x0000 +#define EDCF_AC_VO_ACI_STA 0x62 +#define EDCF_AC_VO_ECW_STA 0x32 +#define EDCF_AC_VI_ACI_STA 0x42 +#define EDCF_AC_VI_ECW_STA 0x43 +#define EDCF_AC_BK_ECW_STA 0xA4 +#define EDCF_AC_VI_TXOP_STA 0x005e +#define EDCF_AC_VO_TXOP_STA 0x002f +#define EDCF_AC_BE_ACI_STA 0x03 +#define EDCF_AC_BE_ECW_STA 0xA4 +#define EDCF_AC_BK_ACI_STA 0x27 +#define EDCF_AC_VO_TXOP_AP 0x002f + +#define EDCF_TXOP2USEC(txop) ((txop) << 5) +#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) + +#define APHY_SYMBOL_TIME 4 +#define APHY_PREAMBLE_TIME 16 +#define APHY_SIGNAL_TIME 4 +#define APHY_SIFS_TIME 16 +#define APHY_SERVICE_NBITS 16 +#define APHY_TAIL_NBITS 6 +#define BPHY_SIFS_TIME 10 +#define BPHY_PLCP_SHORT_TIME 96 + +#define PREN_PREAMBLE 24 +#define PREN_MM_EXT 12 +#define PREN_PREAMBLE_EXT 4 #define DOT11_MAC_HDR_LEN 24 -#define DOT11_ACK_LEN 10 -#define DOT11_BA_LEN 4 +#define DOT11_ACK_LEN 10 +#define DOT11_BA_LEN 4 #define DOT11_OFDM_SIGNAL_EXTENSION 6 #define DOT11_MIN_FRAG_LEN 256 -#define DOT11_RTS_LEN 16 -#define DOT11_CTS_LEN 10 +#define DOT11_RTS_LEN 16 +#define DOT11_CTS_LEN 10 #define DOT11_BA_BITMAP_LEN 128 #define DOT11_MIN_BEACON_PERIOD 1 #define DOT11_MAX_BEACON_PERIOD 0xFFFF -#define DOT11_MAXNUMFRAGS 16 +#define DOT11_MAXNUMFRAGS 16 #define DOT11_MAX_FRAG_LEN 2346 -#define BPHY_PLCP_TIME 192 -#define RIFS_11N_TIME 2 +#define BPHY_PLCP_TIME 192 +#define RIFS_11N_TIME 2 -#define WME_VER 1 -#define WME_SUBTYPE_PARAM_IE 1 -#define WME_TYPE 2 -#define WME_OUI "\x00\x50\xf2" +#define AC_BE 0 +#define AC_BK 1 +#define AC_VI 2 +#define AC_VO 3 -#define AC_BE 0 -#define AC_BK 1 -#define AC_VI 2 -#define AC_VO 3 - -#define BCN_TMPL_LEN 512 /* length of the BCN template area */ +/* length of the BCN template area */ +#define BCN_TMPL_LEN 512 /* brcms_bss_info flag bit values */ -#define BRCMS_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */ - -/* Flags used in brcms_c_txq_info.stopped */ -/* per prio flow control bits */ -#define TXQ_STOP_FOR_PRIOFC_MASK 0x000000FF -/* stop txq enqueue for packet drain */ -#define TXQ_STOP_FOR_PKT_DRAIN 0x00000100 -/* stop txq enqueue for ampdu flow control */ -#define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL 0x00000200 - -#define BRCMS_HWRXOFF 38 /* chip rx buffer offset */ - -/* Find basic rate for a given rate */ -static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec) -{ - if (is_mcs_rate(rspec)) - return wlc->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK] - .leg_ofdm]; - return wlc->band->basic_rate[rspec & RSPEC_RATE_MASK]; -} +#define BRCMS_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */ -static u16 frametype(u32 rspec, u8 mimoframe) -{ - if (is_mcs_rate(rspec)) - return mimoframe; - return is_cck_rate(rspec) ? FT_CCK : FT_OFDM; -} +/* chip rx buffer offset */ +#define BRCMS_HWRXOFF 38 /* rfdisable delay timer 500 ms, runs of ALP clock */ -#define RFDISABLE_DEFAULT 10000000 +#define RFDISABLE_DEFAULT 10000000 #define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */ @@ -194,87 +134,83 @@ static u16 frametype(u32 rspec, u8 mimoframe) * These constants are used ONLY by wlc_prio2prec_map. Do not use them * elsewhere. */ -#define _BRCMS_PREC_NONE 0 /* None = - */ -#define _BRCMS_PREC_BK 2 /* BK - Background */ -#define _BRCMS_PREC_BE 4 /* BE - Best-effort */ -#define _BRCMS_PREC_EE 6 /* EE - Excellent-effort */ -#define _BRCMS_PREC_CL 8 /* CL - Controlled Load */ -#define _BRCMS_PREC_VI 10 /* Vi - Video */ -#define _BRCMS_PREC_VO 12 /* Vo - Voice */ -#define _BRCMS_PREC_NC 14 /* NC - Network Control */ - -/* The BSS is generating beacons in HW */ -#define BRCMS_BSSCFG_HW_BCN 0x20 - -#define SYNTHPU_DLY_APHY_US 3700 /* a phy synthpu_dly time in us */ -#define SYNTHPU_DLY_BPHY_US 1050 /* b/g phy synthpu_dly time in us */ -#define SYNTHPU_DLY_NPHY_US 2048 /* n phy REV3 synthpu_dly time in us */ -#define SYNTHPU_DLY_LPPHY_US 300 /* lpphy synthpu_dly time in us */ - -#define SYNTHPU_DLY_PHY_US_QT 100 /* QT synthpu_dly time in us */ - -#define ANTCNT 10 /* vanilla M_MAX_ANTCNT value */ +#define _BRCMS_PREC_NONE 0 /* None = - */ +#define _BRCMS_PREC_BK 2 /* BK - Background */ +#define _BRCMS_PREC_BE 4 /* BE - Best-effort */ +#define _BRCMS_PREC_EE 6 /* EE - Excellent-effort */ +#define _BRCMS_PREC_CL 8 /* CL - Controlled Load */ +#define _BRCMS_PREC_VI 10 /* Vi - Video */ +#define _BRCMS_PREC_VO 12 /* Vo - Voice */ +#define _BRCMS_PREC_NC 14 /* NC - Network Control */ + +/* synthpu_dly times in us */ +#define SYNTHPU_DLY_APHY_US 3700 +#define SYNTHPU_DLY_BPHY_US 1050 +#define SYNTHPU_DLY_NPHY_US 2048 +#define SYNTHPU_DLY_LPPHY_US 300 + +#define ANTCNT 10 /* vanilla M_MAX_ANTCNT val */ /* Per-AC retry limit register definitions; uses defs.h bitfield macros */ -#define EDCF_SHORT_S 0 -#define EDCF_SFB_S 4 -#define EDCF_LONG_S 8 -#define EDCF_LFB_S 12 -#define EDCF_SHORT_M BITFIELD_MASK(4) -#define EDCF_SFB_M BITFIELD_MASK(4) -#define EDCF_LONG_M BITFIELD_MASK(4) -#define EDCF_LFB_M BITFIELD_MASK(4) +#define EDCF_SHORT_S 0 +#define EDCF_SFB_S 4 +#define EDCF_LONG_S 8 +#define EDCF_LFB_S 12 +#define EDCF_SHORT_M BITFIELD_MASK(4) +#define EDCF_SFB_M BITFIELD_MASK(4) +#define EDCF_LONG_M BITFIELD_MASK(4) +#define EDCF_LFB_M BITFIELD_MASK(4) -#define RETRY_SHORT_DEF 7 /* Default Short retry Limit */ -#define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */ -#define RETRY_LONG_DEF 4 /* Default Long retry count */ -#define RETRY_SHORT_FB 3 /* Short count for fallback rate */ -#define RETRY_LONG_FB 2 /* Long count for fallback rate */ +#define RETRY_SHORT_DEF 7 /* Default Short retry Limit */ +#define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */ +#define RETRY_LONG_DEF 4 /* Default Long retry count */ +#define RETRY_SHORT_FB 3 /* Short count for fb rate */ +#define RETRY_LONG_FB 2 /* Long count for fb rate */ -#define APHY_CWMIN 15 -#define PHY_CWMAX 1023 +#define APHY_CWMIN 15 +#define PHY_CWMAX 1023 -#define EDCF_AIFSN_MIN 1 +#define EDCF_AIFSN_MIN 1 -#define FRAGNUM_MASK 0xF +#define FRAGNUM_MASK 0xF -#define APHY_SLOT_TIME 9 -#define BPHY_SLOT_TIME 20 +#define APHY_SLOT_TIME 9 +#define BPHY_SLOT_TIME 20 -#define WL_SPURAVOID_OFF 0 -#define WL_SPURAVOID_ON1 1 -#define WL_SPURAVOID_ON2 2 +#define WL_SPURAVOID_OFF 0 +#define WL_SPURAVOID_ON1 1 +#define WL_SPURAVOID_ON2 2 /* invalid core flags, use the saved coreflags */ -#define BRCMS_USE_COREFLAGS 0xffffffff +#define BRCMS_USE_COREFLAGS 0xffffffff /* values for PLCPHdr_override */ -#define BRCMS_PLCP_AUTO -1 -#define BRCMS_PLCP_SHORT 0 -#define BRCMS_PLCP_LONG 1 +#define BRCMS_PLCP_AUTO -1 +#define BRCMS_PLCP_SHORT 0 +#define BRCMS_PLCP_LONG 1 /* values for g_protection_override and n_protection_override */ #define BRCMS_PROTECTION_AUTO -1 #define BRCMS_PROTECTION_OFF 0 #define BRCMS_PROTECTION_ON 1 #define BRCMS_PROTECTION_MMHDR_ONLY 2 -#define BRCMS_PROTECTION_CTS_ONLY 3 +#define BRCMS_PROTECTION_CTS_ONLY 3 /* values for g_protection_control and n_protection_control */ -#define BRCMS_PROTECTION_CTL_OFF 0 +#define BRCMS_PROTECTION_CTL_OFF 0 #define BRCMS_PROTECTION_CTL_LOCAL 1 #define BRCMS_PROTECTION_CTL_OVERLAP 2 /* values for n_protection */ #define BRCMS_N_PROTECTION_OFF 0 #define BRCMS_N_PROTECTION_OPTIONAL 1 -#define BRCMS_N_PROTECTION_20IN40 2 +#define BRCMS_N_PROTECTION_20IN40 2 #define BRCMS_N_PROTECTION_MIXEDMODE 3 /* values for band specific 40MHz capabilities */ -#define BRCMS_N_BW_20ALL 0 -#define BRCMS_N_BW_40ALL 1 -#define BRCMS_N_BW_20IN2G_40IN5G 2 +#define BRCMS_N_BW_20ALL 0 +#define BRCMS_N_BW_40ALL 1 +#define BRCMS_N_BW_20IN2G_40IN5G 2 /* bitflags for SGI support (sgi_rx iovar) */ #define BRCMS_N_SGI_20 0x01 @@ -282,48 +218,42 @@ static u16 frametype(u32 rspec, u8 mimoframe) /* defines used by the nrate iovar */ /* MSC in use,indicates b0-6 holds an mcs */ -#define NRATE_MCS_INUSE 0x00000080 +#define NRATE_MCS_INUSE 0x00000080 /* rate/mcs value */ -#define NRATE_RATE_MASK 0x0000007f +#define NRATE_RATE_MASK 0x0000007f /* stf mode mask: siso, cdd, stbc, sdm */ -#define NRATE_STF_MASK 0x0000ff00 +#define NRATE_STF_MASK 0x0000ff00 /* stf mode shift */ -#define NRATE_STF_SHIFT 8 -/* bit indicates override both rate & mode */ -#define NRATE_OVERRIDE 0x80000000 +#define NRATE_STF_SHIFT 8 /* bit indicate to override mcs only */ -#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 -#define NRATE_SGI_MASK 0x00800000 /* sgi mode */ -#define NRATE_SGI_SHIFT 23 /* sgi mode */ -#define NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */ -#define NRATE_LDPC_SHIFT 22 /* ldpc shift */ +#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 +#define NRATE_SGI_MASK 0x00800000 /* sgi mode */ +#define NRATE_SGI_SHIFT 23 /* sgi mode */ +#define NRATE_LDPC_CODING 0x00400000 /* adv coding in use */ +#define NRATE_LDPC_SHIFT 22 /* ldpc shift */ -#define NRATE_STF_SISO 0 /* stf mode SISO */ -#define NRATE_STF_CDD 1 /* stf mode CDD */ -#define NRATE_STF_STBC 2 /* stf mode STBC */ -#define NRATE_STF_SDM 3 /* stf mode SDM */ +#define NRATE_STF_SISO 0 /* stf mode SISO */ +#define NRATE_STF_CDD 1 /* stf mode CDD */ +#define NRATE_STF_STBC 2 /* stf mode STBC */ +#define NRATE_STF_SDM 3 /* stf mode SDM */ -#define MAX_DMA_SEGS 4 +#define MAX_DMA_SEGS 4 /* Max # of entries in Tx FIFO based on 4kb page size */ -#define NTXD 256 +#define NTXD 256 /* Max # of entries in Rx FIFO based on 4kb page size */ -#define NRXD 256 +#define NRXD 256 /* try to keep this # rbufs posted to the chip */ -#define NRXBUFPOST 32 +#define NRXBUFPOST 32 /* data msg txq hiwat mark */ -#define BRCMS_DATAHIWAT 50 - -/* bounded rx loops */ -#define RXBND 8 /* max # frames to process in brcms_c_recv() */ -#define TXSBND 8 /* max # tx status to process in wlc_txstatus() */ +#define BRCMS_DATAHIWAT 50 -/* - * 32 SSID chars, max of 4 chars for each SSID char "\xFF", plus NULL. - */ -#define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) +/* max # frames to process in brcms_c_recv() */ +#define RXBND 8 +/* max # tx status to process in wlc_txstatus() */ +#define TXSBND 8 /* brcmu_format_flags() bit description structure */ struct brcms_c_bit_desc { @@ -405,13 +335,6 @@ static const u16 xmtfifo_sz[][NFIFO] = { {9, 58, 22, 14, 14, 5}, }; -static const u8 acbitmap2maxprio[] = { - PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK, - PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, - PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, - PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO -}; - #ifdef BCMDBG static const char * const fifo_names[] = { "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; @@ -424,6 +347,22 @@ static const char fifo_names[6][0]; static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); #endif +/* Find basic rate for a given rate */ +static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec) +{ + if (is_mcs_rate(rspec)) + return wlc->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK] + .leg_ofdm]; + return wlc->band->basic_rate[rspec & RSPEC_RATE_MASK]; +} + +static u16 frametype(u32 rspec, u8 mimoframe) +{ + if (is_mcs_rate(rspec)) + return mimoframe; + return is_cck_rate(rspec) ? FT_CCK : FT_OFDM; +} + /* currently the best mechanism for determining SIFS is the band in use */ static u16 get_sifs(struct brcms_band *band) { @@ -470,20 +409,6 @@ static int brcms_chspec_bw(u16 chanspec) return BRCMS_10_MHZ; } -/* - * return true if Minimum Power Consumption should - * be entered, false otherwise - */ -static bool brcms_c_is_non_delay_mpc(struct brcms_c_info *wlc) -{ - return false; -} - -static bool brcms_c_ismpc(struct brcms_c_info *wlc) -{ - return (wlc->mpc_delay_off == 0) && (brcms_c_is_non_delay_mpc(wlc)); -} - static void brcms_c_bsscfg_mfree(struct brcms_bss_cfg *cfg) { if (cfg == NULL) @@ -669,9 +594,8 @@ static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw, * calculate frame duration of a given rate and length, return * time in usec unit */ -uint -brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec, - u8 preamble_type, uint mac_len) +static uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec, + u8 preamble_type, uint mac_len) { uint nsyms, dur = 0, Ndps, kNdps; uint rate = rspec2rate(ratespec); @@ -2352,13 +2276,6 @@ void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type) wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type); } -static void brcms_c_fatal_error(struct brcms_c_info *wlc) -{ - wiphy_err(wlc->wiphy, "wl%d: fatal error, reinitializing\n", - wlc->pub->unit); - brcms_init(wlc->wl); -} - static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) { bool fatal = false; @@ -2414,7 +2331,7 @@ static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) } if (fatal) { - brcms_c_fatal_error(wlc_hw->wlc); /* big hammer */ + brcms_fatal_error(wlc_hw->wlc->wl); /* big hammer */ break; } else W_REG(®s->intctrlregs[idx].intstatus, @@ -2479,6 +2396,7 @@ void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask) W_REG(&wlc_hw->regs->macintmask, wlc->macintmask); } +/* assumes that the d11 MAC is enabled */ static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw, uint tx_fifo) { @@ -2535,11 +2453,12 @@ static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw, } } -static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool on, u32 flags) +/* precondition: requires the mac core to be enabled */ +static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool mute_tx) { static const u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; - if (on) { + if (mute_tx) { /* suspend tx fifos */ brcms_b_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO); brcms_b_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO); @@ -2561,14 +2480,20 @@ static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool on, u32 flags) wlc_hw->etheraddr); } - wlc_phy_mute_upd(wlc_hw->band->pi, on, flags); + wlc_phy_mute_upd(wlc_hw->band->pi, mute_tx, 0); - if (on) + if (mute_tx) brcms_c_ucode_mute_override_set(wlc_hw); else brcms_c_ucode_mute_override_clear(wlc_hw); } +void +brcms_c_mute(struct brcms_c_info *wlc, bool mute_tx) +{ + brcms_b_mute(wlc->hw, mute_tx); +} + /* * Read and clear macintmask and macintstatus and intstatus registers. * This routine should be called with interrupts off @@ -3437,8 +3362,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) } void -static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec, - bool mute) { +static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) { u32 macintmask; bool fastclk; struct brcms_c_info *wlc = wlc_hw->wlc; @@ -3463,10 +3387,6 @@ static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec, /* core-specific initialization */ brcms_b_coreinit(wlc); - /* suspend the tx fifos and mute the phy for preism cac time */ - if (mute) - brcms_b_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM); - /* band-specific inits */ brcms_b_bsinit(wlc, chanspec); @@ -3979,7 +3899,7 @@ static void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, u16 chanspec) void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, - bool mute, struct txpwr_limits *txpwr) + bool mute_tx, struct txpwr_limits *txpwr) { uint bandunit; @@ -4005,7 +3925,7 @@ brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, } } - wlc_phy_initcal_enable(wlc_hw->band->pi, !mute); + wlc_phy_initcal_enable(wlc_hw->band->pi, !mute_tx); if (!wlc_hw->up) { if (wlc_hw->clk) @@ -4017,7 +3937,7 @@ brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec); /* Update muting of the channel */ - brcms_b_mute(wlc_hw, mute, 0); + brcms_b_mute(wlc_hw, mute_tx); } } @@ -4242,7 +4162,7 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, } } -void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend) +static void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend) { u16 aci; int i_ac; @@ -4277,17 +4197,6 @@ void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend) } } -/* maintain LED behavior in down state */ -static void brcms_c_down_led_upd(struct brcms_c_info *wlc) -{ - /* - * maintain LEDs while in down state, turn on sbclk if - * not available yet. Turn on sbclk if necessary - */ - brcms_b_pllreq(wlc->hw, true, BRCMS_PLLREQ_FLIP); - brcms_b_pllreq(wlc->hw, false, BRCMS_PLLREQ_FLIP); -} - static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc) { /* Don't start the timer if HWRADIO feature is disabled */ @@ -4299,28 +4208,6 @@ static void brcms_c_radio_monitor_start(struct brcms_c_info *wlc) brcms_add_timer(wlc->radio_timer, TIMER_INTERVAL_RADIOCHK, true); } -static void brcms_c_radio_disable(struct brcms_c_info *wlc) -{ - if (!wlc->pub->up) { - brcms_c_down_led_upd(wlc); - return; - } - - brcms_c_radio_monitor_start(wlc); - brcms_down(wlc->wl); -} - -static void brcms_c_radio_enable(struct brcms_c_info *wlc) -{ - if (wlc->pub->up) - return; - - if (brcms_deviceremoved(wlc)) - return; - - brcms_up(wlc->wl); -} - static bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc) { if (!wlc->radio_monitor) @@ -4343,18 +4230,6 @@ static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc) mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); } -/* - * centralized radio disable/enable function, - * invoke radio enable/disable after updating hwradio status - */ -static void brcms_c_radio_upd(struct brcms_c_info *wlc) -{ - if (wlc->pub->radio_disabled) - brcms_c_radio_disable(wlc); - else - brcms_c_radio_enable(wlc); -} - /* update hwradio status and return it */ bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc) { @@ -4376,12 +4251,7 @@ static void brcms_c_radio_timer(void *arg) return; } - /* cap mpc off count */ - if (wlc->mpc_offcnt < BRCMS_MPC_MAX_DELAYCNT) - wlc->mpc_offcnt++; - brcms_c_radio_hwdisable_upd(wlc); - brcms_c_radio_upd(wlc); } /* common low-level watchdog code */ @@ -4407,60 +4277,6 @@ static void brcms_b_watchdog(void *arg) wlc_phy_watchdog(wlc_hw->band->pi); } -static void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc) -{ - bool mpc_radio, radio_state; - - /* - * Clear the WL_RADIO_MPC_DISABLE bit when mpc feature is disabled - * in case the WL_RADIO_MPC_DISABLE bit was set. Stop the radio - * monitor also when WL_RADIO_MPC_DISABLE is the only reason that - * the radio is going down. - */ - if (!wlc->mpc) { - if (!wlc->pub->radio_disabled) - return; - mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); - brcms_c_radio_upd(wlc); - if (!wlc->pub->radio_disabled) - brcms_c_radio_monitor_stop(wlc); - return; - } - - /* - * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in - * wlc->pub->radio_disabled to go ON, always call radio_upd - * synchronously to go OFF, postpone radio_upd to later when - * context is safe(e.g. watchdog) - */ - radio_state = - (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF : - ON); - mpc_radio = (brcms_c_ismpc(wlc) == true) ? OFF : ON; - - if (radio_state == ON && mpc_radio == OFF) - wlc->mpc_delay_off = wlc->mpc_dlycnt; - else if (radio_state == OFF && mpc_radio == ON) { - mboolclr(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE); - brcms_c_radio_upd(wlc); - if (wlc->mpc_offcnt < BRCMS_MPC_THRESHOLD) - wlc->mpc_dlycnt = BRCMS_MPC_MAX_DELAYCNT; - else - wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT; - } - /* - * Below logic is meant to capture the transition from mpc off - * to mpc on for reasons other than wlc->mpc_delay_off keeping - * the mpc off. In that case reset wlc->mpc_delay_off to - * wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off - */ - if ((wlc->prev_non_delay_mpc == false) && - (brcms_c_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) - wlc->mpc_delay_off = wlc->mpc_dlycnt; - - wlc->prev_non_delay_mpc = brcms_c_is_non_delay_mpc(wlc); -} - /* common watchdog code */ static void brcms_c_watchdog(void *arg) { @@ -4481,21 +4297,7 @@ static void brcms_c_watchdog(void *arg) /* increment second count */ wlc->pub->now++; - /* delay radio disable */ - if (wlc->mpc_delay_off) { - if (--wlc->mpc_delay_off == 0) { - mboolset(wlc->pub->radio_disabled, - WL_RADIO_MPC_DISABLE); - if (wlc->mpc && brcms_c_ismpc(wlc)) - wlc->mpc_offcnt = 0; - } - } - - /* mpc sync */ - brcms_c_radio_mpc_upd(wlc); - /* radio sync: sw/hw/mpc --> radio_disable/radio_enable */ brcms_c_radio_hwdisable_upd(wlc); - brcms_c_radio_upd(wlc); /* if radio is disable, driver may be down, quit here */ if (wlc->pub->radio_disabled) return; @@ -4599,9 +4401,6 @@ static void brcms_c_info_init(struct brcms_c_info *wlc, int unit) /* WME QoS mode is Auto by default */ wlc->pub->_ampdu = AMPDU_AGG_HOST; wlc->pub->bcmerror = 0; - - /* initialize mpc delay */ - wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT; } static uint brcms_c_attach_module(struct brcms_c_info *wlc) @@ -5259,9 +5058,6 @@ static void brcms_c_ap_upd(struct brcms_c_info *wlc) { /* STA-BSS; short capable */ wlc->PLCPHdr_override = BRCMS_PLCP_SHORT; - - /* fixup mpc */ - wlc->mpc = true; } /* Initialize just the hardware when coming out of POR or S3/S5 system states */ @@ -5575,7 +5371,6 @@ uint brcms_c_down(struct brcms_c_info *wlc) if (!wlc->pub->up) return callbacks; - /* in between, mpc could try to bring down again.. */ wlc->going_down = true; callbacks += brcms_b_bmac_down_prep(wlc->hw); @@ -6103,7 +5898,6 @@ void brcms_c_print_txdesc(struct d11txh *txh) u8 *rtsph = txh->RTSPhyHeader; struct ieee80211_rts rts = txh->rts_frame; - char hexbuf[256]; /* add plcp header along with txh descriptor */ printk(KERN_DEBUG "Raw TxDesc + plcp header:\n"); @@ -6124,17 +5918,16 @@ void brcms_c_print_txdesc(struct d11txh *txh) printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft); printk(KERN_DEBUG "\n"); - brcmu_format_hex(hexbuf, iv, sizeof(txh->IV)); - printk(KERN_DEBUG "SecIV: %s\n", hexbuf); - brcmu_format_hex(hexbuf, ra, sizeof(txh->TxFrameRA)); - printk(KERN_DEBUG "RA: %s\n", hexbuf); + print_hex_dump_bytes("SecIV:", DUMP_PREFIX_OFFSET, iv, sizeof(txh->IV)); + print_hex_dump_bytes("RA:", DUMP_PREFIX_OFFSET, + ra, sizeof(txh->TxFrameRA)); printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb); - brcmu_format_hex(hexbuf, rtspfb, sizeof(txh->RTSPLCPFallback)); - printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf); + print_hex_dump_bytes("Fb RTS PLCP:", DUMP_PREFIX_OFFSET, + rtspfb, sizeof(txh->RTSPLCPFallback)); printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb); - brcmu_format_hex(hexbuf, fragpfb, sizeof(txh->FragPLCPFallback)); - printk(KERN_DEBUG "PLCP: %s ", hexbuf); + print_hex_dump_bytes("PLCP:", DUMP_PREFIX_OFFSET, + fragpfb, sizeof(txh->FragPLCPFallback)); printk(KERN_DEBUG "DUR: %04x", fragdfb); printk(KERN_DEBUG "\n"); @@ -6149,18 +5942,18 @@ void brcms_c_print_txdesc(struct d11txh *txh) printk(KERN_DEBUG "MaxAggbyte_fb: %04x\n", mabyte_f); printk(KERN_DEBUG "MinByte: %04x\n", mmbyte); - brcmu_format_hex(hexbuf, rtsph, sizeof(txh->RTSPhyHeader)); - printk(KERN_DEBUG "RTS PLCP: %s ", hexbuf); - brcmu_format_hex(hexbuf, (u8 *) &rts, sizeof(txh->rts_frame)); - printk(KERN_DEBUG "RTS Frame: %s", hexbuf); + print_hex_dump_bytes("RTS PLCP:", DUMP_PREFIX_OFFSET, + rtsph, sizeof(txh->RTSPhyHeader)); + print_hex_dump_bytes("RTS Frame:", DUMP_PREFIX_OFFSET, + (u8 *)&rts, sizeof(txh->rts_frame)); printk(KERN_DEBUG "\n"); } #endif /* defined(BCMDBG) */ #if defined(BCMDBG) -int +static int brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf, - int len) + int len) { int i; char *p = buf; @@ -8253,12 +8046,6 @@ int brcms_c_get_tx_power(struct brcms_c_info *wlc) return (int)(qdbm / BRCMS_TXPWR_DB_FACTOR); } -void brcms_c_set_radio_mpc(struct brcms_c_info *wlc, bool mpc) -{ - wlc->mpc = mpc; - brcms_c_radio_mpc_upd(wlc); -} - /* Process received frames */ /* * Return true if more frames need to be processed. false otherwise. @@ -8328,21 +8115,17 @@ static bool brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) { struct sk_buff *p; - struct sk_buff *head = NULL; - struct sk_buff *tail = NULL; + struct sk_buff *next = NULL; + struct sk_buff_head recv_frames; + uint n = 0; uint bound_limit = bound ? RXBND : -1; BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - /* gather received frames */ - while ((p = dma_rx(wlc_hw->di[fifo]))) { + skb_queue_head_init(&recv_frames); - if (!tail) - head = tail = p; - else { - tail->prev = p; - tail = p; - } + /* gather received frames */ + while (dma_rx(wlc_hw->di[fifo], &recv_frames)) { /* !give others some time to run! */ if (++n >= bound_limit) @@ -8353,12 +8136,11 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) dma_rxfill(wlc_hw->di[fifo]); /* process each frame */ - while ((p = head) != NULL) { + skb_queue_walk_safe(&recv_frames, p, next) { struct d11rxhdr_le *rxh_le; struct d11rxhdr *rxh; - head = head->prev; - p->prev = NULL; + skb_unlink(p, &recv_frames); rxh_le = (struct d11rxhdr_le *)p->data; rxh = (struct d11rxhdr *)p->data; @@ -8448,8 +8230,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", __func__, wlc_hw->sih->chip, wlc_hw->sih->chiprev); - /* big hammer */ - brcms_init(wlc->wl); + brcms_fatal_error(wlc_hw->wlc->wl); } /* gptimer timeout */ @@ -8470,15 +8251,14 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) return wlc->macintstatus != 0; fatal: - brcms_init(wlc->wl); + brcms_fatal_error(wlc_hw->wlc->wl); return wlc->macintstatus != 0; } -void brcms_c_init(struct brcms_c_info *wlc) +void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) { struct d11regs __iomem *regs; u16 chanspec; - bool mute = false; BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); @@ -8494,7 +8274,7 @@ void brcms_c_init(struct brcms_c_info *wlc) else chanspec = brcms_c_init_chanspec(wlc); - brcms_b_init(wlc->hw, chanspec, mute); + brcms_b_init(wlc->hw, chanspec); /* update beacon listen interval */ brcms_c_bcn_li_upd(wlc); @@ -8560,15 +8340,16 @@ void brcms_c_init(struct brcms_c_info *wlc) /* ..now really unleash hell (allow the MAC out of suspend) */ brcms_c_enable_mac(wlc); + /* suspend the tx fifos and mute the phy for preism cac time */ + if (mute_tx) + brcms_b_mute(wlc->hw, true); + /* clear tx flow control */ brcms_c_txflowcontrol_reset(wlc); /* enable the RF Disable Delay timer */ W_REG(&wlc->regs->rfdisabledly, RFDISABLE_DEFAULT); - /* initialize mpc delay */ - wlc->mpc_delay_off = wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT; - /* * Initialize WME parameters; if they haven't been set by some other * mechanism (IOVar, etc) then read them from the hardware. @@ -8754,8 +8535,6 @@ brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit, brcms_c_ht_update_sgi_rx(wlc, 0); } - /* initialize radio_mpc_disable according to wlc->mpc */ - brcms_c_radio_mpc_upd(wlc); brcms_b_antsel_set(wlc->hw, wlc->asi->antsel_avail); if (perr) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h index c0e0fcfdfaf8..9a7535d3838d 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h @@ -427,11 +427,6 @@ struct brcms_txq_info { * bandinit_pending: track band init in auto band. * radio_monitor: radio timer is running. * going_down: down path intermediate variable. - * mpc: enable minimum power consumption. - * mpc_dlycnt: # of watchdog cnt before turn disable radio. - * mpc_offcnt: # of watchdog cnt that radio is disabled. - * mpc_delay_off: delay radio disable by # of watchdog cnt. - * prev_non_delay_mpc: prev state brcms_c_is_non_delay_mpc. * wdtimer: timer for watchdog routine. * radio_timer: timer for hw radio button monitor routine. * monitor: monitor (MPDU sniffing) mode. @@ -522,12 +517,6 @@ struct brcms_c_info { bool radio_monitor; bool going_down; - bool mpc; - u8 mpc_dlycnt; - u8 mpc_offcnt; - u8 mpc_delay_off; - u8 prev_non_delay_mpc; - struct brcms_timer *wdtimer; struct brcms_timer *radio_timer; diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c index a3149254cbcd..2faea509f017 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c @@ -112,7 +112,7 @@ static const struct chan_info_basic chan_info_all[] = { {216, 50800} }; -const u8 ofdm_rate_lookup[] = { +static const u8 ofdm_rate_lookup[] = { BRCM_RATE_48M, BRCM_RATE_24M, diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h index bea85241a244..5f9478b1c993 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h @@ -774,11 +774,6 @@ struct brcms_phy { s16 nphy_noise_win[PHY_CORE_MAX][PHY_NOISE_WINDOW_SZ]; u8 nphy_noise_index; - u8 nphy_txpid2g[PHY_CORE_NUM_2]; - u8 nphy_txpid5g[PHY_CORE_NUM_2]; - u8 nphy_txpid5gl[PHY_CORE_NUM_2]; - u8 nphy_txpid5gh[PHY_CORE_NUM_2]; - bool nphy_gain_boost; bool nphy_elna_gain_config; u16 old_bphy_test; diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c index cd19c2f7a347..ec9b56639d54 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c @@ -29,6 +29,7 @@ #include "phy_radio.h" #include "phyreg_n.h" #include "phytbl_n.h" +#include "soc.h" #define READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name) \ read_radio_reg(pi, radio_type##_##jspace##_##reg_name | \ @@ -14417,12 +14418,6 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) switch (band_num) { case 0: - pi->nphy_txpid2g[PHY_CORE_0] = - (u8) wlapi_getintvar(shim, - BRCMS_SROM_TXPID2GA0); - pi->nphy_txpid2g[PHY_CORE_1] = - (u8) wlapi_getintvar(shim, - BRCMS_SROM_TXPID2GA1); pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g = (s8) wlapi_getintvar(shim, BRCMS_SROM_MAXP2GA0); @@ -14486,12 +14481,6 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) break; case 1: - pi->nphy_txpid5g[PHY_CORE_0] = - (u8) wlapi_getintvar(shim, - BRCMS_SROM_TXPID5GA0); - pi->nphy_txpid5g[PHY_CORE_1] = - (u8) wlapi_getintvar(shim, - BRCMS_SROM_TXPID5GA1); pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm = (s8) wlapi_getintvar(shim, BRCMS_SROM_MAXP5GA0); pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm = @@ -14551,12 +14540,6 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) break; case 2: - pi->nphy_txpid5gl[0] = - (u8) wlapi_getintvar(shim, - BRCMS_SROM_TXPID5GLA0); - pi->nphy_txpid5gl[1] = - (u8) wlapi_getintvar(shim, - BRCMS_SROM_TXPID5GLA1); pi->nphy_pwrctrl_info[0].max_pwr_5gl = (s8) wlapi_getintvar(shim, BRCMS_SROM_MAXP5GLA0); @@ -14615,12 +14598,6 @@ static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) break; case 3: - pi->nphy_txpid5gh[0] = - (u8) wlapi_getintvar(shim, - BRCMS_SROM_TXPID5GHA0); - pi->nphy_txpid5gh[1] = - (u8) wlapi_getintvar(shim, - BRCMS_SROM_TXPID5GHA1); pi->nphy_pwrctrl_info[0].max_pwr_5gh = (s8) wlapi_getintvar(shim, BRCMS_SROM_MAXP5GHA0); @@ -27994,20 +27971,11 @@ void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi) chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0); switch (chan_freq_range) { case WL_CHAN_FREQ_RANGE_2G: - txpi[0] = pi->nphy_txpid2g[0]; - txpi[1] = pi->nphy_txpid2g[1]; - break; case WL_CHAN_FREQ_RANGE_5GL: - txpi[0] = pi->nphy_txpid5gl[0]; - txpi[1] = pi->nphy_txpid5gl[1]; - break; case WL_CHAN_FREQ_RANGE_5GM: - txpi[0] = pi->nphy_txpid5g[0]; - txpi[1] = pi->nphy_txpid5g[1]; - break; case WL_CHAN_FREQ_RANGE_5GH: - txpi[0] = pi->nphy_txpid5gh[0]; - txpi[1] = pi->nphy_txpid5gh[1]; + txpi[0] = 0; + txpi[1] = 0; break; default: txpi[0] = txpi[1] = 91; diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pmu.c b/drivers/net/wireless/brcm80211/brcmsmac/pmu.c index 3b36e3acfd74..12ba575f5785 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/pmu.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/pmu.c @@ -23,6 +23,7 @@ #include "pub.h" #include "aiutils.h" #include "pmu.h" +#include "soc.h" /* * external LPO crystal frequency diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h index 37bb2dcc113f..022523a5a532 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h @@ -170,22 +170,6 @@ enum brcms_srom_id { BRCMS_SROM_TSSIPOS2G, BRCMS_SROM_TSSIPOS5G, BRCMS_SROM_TXCHAIN, - BRCMS_SROM_TXPID2GA0, - BRCMS_SROM_TXPID2GA1, - BRCMS_SROM_TXPID2GA2, - BRCMS_SROM_TXPID2GA3, - BRCMS_SROM_TXPID5GA0, - BRCMS_SROM_TXPID5GA1, - BRCMS_SROM_TXPID5GA2, - BRCMS_SROM_TXPID5GA3, - BRCMS_SROM_TXPID5GHA0, - BRCMS_SROM_TXPID5GHA1, - BRCMS_SROM_TXPID5GHA2, - BRCMS_SROM_TXPID5GHA3, - BRCMS_SROM_TXPID5GLA0, - BRCMS_SROM_TXPID5GLA1, - BRCMS_SROM_TXPID5GLA2, - BRCMS_SROM_TXPID5GLA3, /* * per-path identifiers (see srom.c) */ @@ -225,10 +209,6 @@ enum brcms_srom_id { BRCMS_SROM_PA2GW2A1, BRCMS_SROM_PA2GW2A2, BRCMS_SROM_PA2GW2A3, - BRCMS_SROM_PA2GW3A0, - BRCMS_SROM_PA2GW3A1, - BRCMS_SROM_PA2GW3A2, - BRCMS_SROM_PA2GW3A3, BRCMS_SROM_PA5GHW0A0, BRCMS_SROM_PA5GHW0A1, BRCMS_SROM_PA5GHW0A2, @@ -241,10 +221,6 @@ enum brcms_srom_id { BRCMS_SROM_PA5GHW2A1, BRCMS_SROM_PA5GHW2A2, BRCMS_SROM_PA5GHW2A3, - BRCMS_SROM_PA5GHW3A0, - BRCMS_SROM_PA5GHW3A1, - BRCMS_SROM_PA5GHW3A2, - BRCMS_SROM_PA5GHW3A3, BRCMS_SROM_PA5GLW0A0, BRCMS_SROM_PA5GLW0A1, BRCMS_SROM_PA5GLW0A2, @@ -257,10 +233,6 @@ enum brcms_srom_id { BRCMS_SROM_PA5GLW2A1, BRCMS_SROM_PA5GLW2A2, BRCMS_SROM_PA5GLW2A3, - BRCMS_SROM_PA5GLW3A0, - BRCMS_SROM_PA5GLW3A1, - BRCMS_SROM_PA5GLW3A2, - BRCMS_SROM_PA5GLW3A3, BRCMS_SROM_PA5GW0A0, BRCMS_SROM_PA5GW0A1, BRCMS_SROM_PA5GW0A2, @@ -273,10 +245,6 @@ enum brcms_srom_id { BRCMS_SROM_PA5GW2A1, BRCMS_SROM_PA5GW2A2, BRCMS_SROM_PA5GW2A3, - BRCMS_SROM_PA5GW3A0, - BRCMS_SROM_PA5GW3A1, - BRCMS_SROM_PA5GW3A2, - BRCMS_SROM_PA5GW3A3, }; #define BRCMS_NUMRATES 16 /* max # of rates in a rateset */ @@ -572,7 +540,7 @@ extern int brcms_c_up(struct brcms_c_info *wlc); extern uint brcms_c_down(struct brcms_c_info *wlc); extern bool brcms_c_chipmatch(u16 vendor, u16 device); -extern void brcms_c_init(struct brcms_c_info *wlc); +extern void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx); extern void brcms_c_reset(struct brcms_c_info *wlc); extern void brcms_c_intrson(struct brcms_c_info *wlc); @@ -628,7 +596,7 @@ extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval); extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr); extern int brcms_c_get_tx_power(struct brcms_c_info *wlc); -extern void brcms_c_set_radio_mpc(struct brcms_c_info *wlc, bool mpc); extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); +extern void brcms_c_mute(struct brcms_c_info *wlc, bool on); #endif /* _BRCM_PUB_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/rate.h b/drivers/net/wireless/brcm80211/brcmsmac/rate.h index e7b9dc2f2731..980d578825cc 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/rate.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/rate.h @@ -19,6 +19,7 @@ #include "types.h" #include "d11.h" +#include "phy_hal.h" extern const u8 rate_info[]; extern const struct brcms_c_rateset cck_ofdm_mimo_rates; @@ -198,11 +199,9 @@ static inline u8 cck_rspec(u8 cck) /* Convert encoded rate value in plcp header to numerical rates in 500 KHz * increments */ -extern const u8 ofdm_rate_lookup[]; - static inline u8 ofdm_phy2mac_rate(u8 rlpt) { - return ofdm_rate_lookup[rlpt & 0x7]; + return wlc_phy_get_ofdm_rate_lookup()[rlpt & 0x7]; } static inline u8 cck_phy2mac_rate(u8 signal) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/srom.c b/drivers/net/wireless/brcm80211/brcmsmac/srom.c index 99f791048e84..0539a6a831c5 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/srom.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/srom.c @@ -28,6 +28,7 @@ #include "aiutils.h" #include "otp.h" #include "srom.h" +#include "soc.h" /* * SROM CRC8 polynomial value: @@ -62,9 +63,6 @@ #define SROM_MACHI_ET1 42 #define SROM_MACMID_ET1 43 #define SROM_MACLO_ET1 44 -#define SROM3_MACHI 37 -#define SROM3_MACMID 38 -#define SROM3_MACLO 39 #define SROM_BXARSSI2G 40 #define SROM_BXARSSI5G 41 @@ -101,7 +99,6 @@ #define SROM_BFL 57 #define SROM_BFL2 28 -#define SROM3_BFL2 61 #define SROM_AG10 58 @@ -109,99 +106,16 @@ #define SROM_OPO 60 -#define SROM3_LEDDC 62 - #define SROM_CRCREV 63 -/* SROM Rev 4: Reallocate the software part of the srom to accommodate - * MIMO features. It assumes up to two PCIE functions and 440 bytes - * of usable srom i.e. the usable storage in chips with OTP that - * implements hardware redundancy. - */ - #define SROM4_WORDS 220 -#define SROM4_SIGN 32 -#define SROM4_SIGNATURE 0x5372 - -#define SROM4_BREV 33 - -#define SROM4_BFL0 34 -#define SROM4_BFL1 35 -#define SROM4_BFL2 36 -#define SROM4_BFL3 37 -#define SROM5_BFL0 37 -#define SROM5_BFL1 38 -#define SROM5_BFL2 39 -#define SROM5_BFL3 40 - -#define SROM4_MACHI 38 -#define SROM4_MACMID 39 -#define SROM4_MACLO 40 -#define SROM5_MACHI 41 -#define SROM5_MACMID 42 -#define SROM5_MACLO 43 - -#define SROM4_CCODE 41 -#define SROM4_REGREV 42 -#define SROM5_CCODE 34 -#define SROM5_REGREV 35 - -#define SROM4_LEDBH10 43 -#define SROM4_LEDBH32 44 -#define SROM5_LEDBH10 59 -#define SROM5_LEDBH32 60 - -#define SROM4_LEDDC 45 -#define SROM5_LEDDC 45 - -#define SROM4_AA 46 - -#define SROM4_AG10 47 -#define SROM4_AG32 48 - -#define SROM4_TXPID2G 49 -#define SROM4_TXPID5G 51 -#define SROM4_TXPID5GL 53 -#define SROM4_TXPID5GH 55 - -#define SROM4_TXRXC 61 #define SROM4_TXCHAIN_MASK 0x000f -#define SROM4_TXCHAIN_SHIFT 0 #define SROM4_RXCHAIN_MASK 0x00f0 -#define SROM4_RXCHAIN_SHIFT 4 #define SROM4_SWITCH_MASK 0xff00 -#define SROM4_SWITCH_SHIFT 8 /* Per-path fields */ #define MAX_PATH_SROM 4 -#define SROM4_PATH0 64 -#define SROM4_PATH1 87 -#define SROM4_PATH2 110 -#define SROM4_PATH3 133 - -#define SROM4_2G_ITT_MAXP 0 -#define SROM4_2G_PA 1 -#define SROM4_5G_ITT_MAXP 5 -#define SROM4_5GLH_MAXP 6 -#define SROM4_5G_PA 7 -#define SROM4_5GL_PA 11 -#define SROM4_5GH_PA 15 - -/* All the miriad power offsets */ -#define SROM4_2G_CCKPO 156 -#define SROM4_2G_OFDMPO 157 -#define SROM4_5G_OFDMPO 159 -#define SROM4_5GL_OFDMPO 161 -#define SROM4_5GH_OFDMPO 163 -#define SROM4_2G_MCSPO 165 -#define SROM4_5G_MCSPO 173 -#define SROM4_5GL_MCSPO 181 -#define SROM4_5GH_MCSPO 189 -#define SROM4_CDDPO 197 -#define SROM4_STBCPO 198 -#define SROM4_BW40PO 199 -#define SROM4_BWDUPPO 200 #define SROM4_CRCREV 219 @@ -424,103 +338,32 @@ struct brcms_varbuf { static const struct brcms_sromvar pci_sromvars[] = { {BRCMS_SROM_DEVID, 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, 0xffff}, - {BRCMS_SROM_BOARDREV, 0x0000000e, SRFL_PRHEX, SROM_AABREV, - SROM_BR_MASK}, - {BRCMS_SROM_BOARDREV, 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff}, {BRCMS_SROM_BOARDREV, 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff}, - {BRCMS_SROM_BOARDFLAGS, 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff}, - {BRCMS_SROM_BOARDFLAGS, 0x00000004, SRFL_PRHEX | SRFL_MORE, SROM_BFL, - 0xffff}, - {BRCMS_SROM_CONT, 0, 0, SROM_BFL2, 0xffff}, - {BRCMS_SROM_BOARDFLAGS, 0x00000008, SRFL_PRHEX | SRFL_MORE, SROM_BFL, - 0xffff}, - {BRCMS_SROM_CONT, 0, 0, SROM3_BFL2, 0xffff}, - {BRCMS_SROM_BOARDFLAGS, 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL0, - 0xffff}, - {BRCMS_SROM_CONT, 0, 0, SROM4_BFL1, 0xffff}, - {BRCMS_SROM_BOARDFLAGS, 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL0, - 0xffff}, - {BRCMS_SROM_CONT, 0, 0, SROM5_BFL1, 0xffff}, {BRCMS_SROM_BOARDFLAGS, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0, 0xffff}, {BRCMS_SROM_CONT, 0, 0, SROM8_BFL1, 0xffff}, - {BRCMS_SROM_BOARDFLAGS2, 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL2, - 0xffff}, - {BRCMS_SROM_CONT, 0, 0, SROM4_BFL3, 0xffff}, - {BRCMS_SROM_BOARDFLAGS2, 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL2, - 0xffff}, - {BRCMS_SROM_CONT, 0, 0, SROM5_BFL3, 0xffff}, {BRCMS_SROM_BOARDFLAGS2, 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2, 0xffff}, {BRCMS_SROM_CONT, 0, 0, SROM8_BFL3, 0xffff}, {BRCMS_SROM_BOARDTYPE, 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff}, - {BRCMS_SROM_BOARDNUM, 0x00000006, 0, SROM_MACLO_IL0, 0xffff}, - {BRCMS_SROM_BOARDNUM, 0x00000008, 0, SROM3_MACLO, 0xffff}, - {BRCMS_SROM_BOARDNUM, 0x00000010, 0, SROM4_MACLO, 0xffff}, - {BRCMS_SROM_BOARDNUM, 0x000000e0, 0, SROM5_MACLO, 0xffff}, {BRCMS_SROM_BOARDNUM, 0xffffff00, 0, SROM8_MACLO, 0xffff}, - {BRCMS_SROM_CC, 0x00000002, 0, SROM_AABREV, SROM_CC_MASK}, - {BRCMS_SROM_REGREV, 0x00000008, 0, SROM_OPO, 0xff00}, - {BRCMS_SROM_REGREV, 0x00000010, 0, SROM4_REGREV, 0x00ff}, - {BRCMS_SROM_REGREV, 0x000000e0, 0, SROM5_REGREV, 0x00ff}, {BRCMS_SROM_REGREV, 0xffffff00, 0, SROM8_REGREV, 0x00ff}, - {BRCMS_SROM_LEDBH0, 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0x00ff}, - {BRCMS_SROM_LEDBH1, 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00}, - {BRCMS_SROM_LEDBH2, 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0x00ff}, - {BRCMS_SROM_LEDBH3, 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00}, - {BRCMS_SROM_LEDBH0, 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0x00ff}, - {BRCMS_SROM_LEDBH1, 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00}, - {BRCMS_SROM_LEDBH2, 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0x00ff}, - {BRCMS_SROM_LEDBH3, 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00}, - {BRCMS_SROM_LEDBH0, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0x00ff}, - {BRCMS_SROM_LEDBH1, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00}, - {BRCMS_SROM_LEDBH2, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0x00ff}, - {BRCMS_SROM_LEDBH3, 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00}, {BRCMS_SROM_LEDBH0, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff}, {BRCMS_SROM_LEDBH1, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00}, {BRCMS_SROM_LEDBH2, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff}, {BRCMS_SROM_LEDBH3, 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00}, - {BRCMS_SROM_PA0B0, 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff}, - {BRCMS_SROM_PA0B1, 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff}, - {BRCMS_SROM_PA0B2, 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff}, - {BRCMS_SROM_PA0ITSSIT, 0x0000000e, 0, SROM_ITT, 0x00ff}, - {BRCMS_SROM_PA0MAXPWR, 0x0000000e, 0, SROM_WL10MAXP, 0x00ff}, {BRCMS_SROM_PA0B0, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff}, {BRCMS_SROM_PA0B1, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff}, {BRCMS_SROM_PA0B2, 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff}, {BRCMS_SROM_PA0ITSSIT, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00}, {BRCMS_SROM_PA0MAXPWR, 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff}, - {BRCMS_SROM_OPO, 0x0000000c, 0, SROM_OPO, 0x00ff}, {BRCMS_SROM_OPO, 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff}, - {BRCMS_SROM_AA2G, 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK}, - {BRCMS_SROM_AA2G, 0x000000f0, 0, SROM4_AA, 0x00ff}, {BRCMS_SROM_AA2G, 0xffffff00, 0, SROM8_AA, 0x00ff}, - {BRCMS_SROM_AA5G, 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK}, - {BRCMS_SROM_AA5G, 0x000000f0, 0, SROM4_AA, 0xff00}, {BRCMS_SROM_AA5G, 0xffffff00, 0, SROM8_AA, 0xff00}, - {BRCMS_SROM_AG0, 0x0000000e, 0, SROM_AG10, 0x00ff}, - {BRCMS_SROM_AG1, 0x0000000e, 0, SROM_AG10, 0xff00}, - {BRCMS_SROM_AG0, 0x000000f0, 0, SROM4_AG10, 0x00ff}, - {BRCMS_SROM_AG1, 0x000000f0, 0, SROM4_AG10, 0xff00}, - {BRCMS_SROM_AG2, 0x000000f0, 0, SROM4_AG32, 0x00ff}, - {BRCMS_SROM_AG3, 0x000000f0, 0, SROM4_AG32, 0xff00}, {BRCMS_SROM_AG0, 0xffffff00, 0, SROM8_AG10, 0x00ff}, {BRCMS_SROM_AG1, 0xffffff00, 0, SROM8_AG10, 0xff00}, {BRCMS_SROM_AG2, 0xffffff00, 0, SROM8_AG32, 0x00ff}, {BRCMS_SROM_AG3, 0xffffff00, 0, SROM8_AG32, 0xff00}, - {BRCMS_SROM_PA1B0, 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff}, - {BRCMS_SROM_PA1B1, 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff}, - {BRCMS_SROM_PA1B2, 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff}, - {BRCMS_SROM_PA1LOB0, 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff}, - {BRCMS_SROM_PA1LOB1, 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff}, - {BRCMS_SROM_PA1LOB2, 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff}, - {BRCMS_SROM_PA1HIB0, 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff}, - {BRCMS_SROM_PA1HIB1, 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff}, - {BRCMS_SROM_PA1HIB2, 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff}, - {BRCMS_SROM_PA1ITSSIT, 0x0000000e, 0, SROM_ITT, 0xff00}, - {BRCMS_SROM_PA1MAXPWR, 0x0000000e, 0, SROM_WL10MAXP, 0xff00}, - {BRCMS_SROM_PA1LOMAXPWR, 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00}, - {BRCMS_SROM_PA1HIMAXPWR, 0x0000000c, 0, SROM_WL1LHMAXP, 0x00ff}, {BRCMS_SROM_PA1B0, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff}, {BRCMS_SROM_PA1B1, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff}, {BRCMS_SROM_PA1B2, 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff}, @@ -534,40 +377,20 @@ static const struct brcms_sromvar pci_sromvars[] = { {BRCMS_SROM_PA1MAXPWR, 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff}, {BRCMS_SROM_PA1LOMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00}, {BRCMS_SROM_PA1HIMAXPWR, 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff}, - {BRCMS_SROM_BXA2G, 0x00000008, 0, SROM_BXARSSI2G, 0x1800}, - {BRCMS_SROM_RSSISAV2G, 0x00000008, 0, SROM_BXARSSI2G, 0x0700}, - {BRCMS_SROM_RSSISMC2G, 0x00000008, 0, SROM_BXARSSI2G, 0x00f0}, - {BRCMS_SROM_RSSISMF2G, 0x00000008, 0, SROM_BXARSSI2G, 0x000f}, {BRCMS_SROM_BXA2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800}, {BRCMS_SROM_RSSISAV2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700}, {BRCMS_SROM_RSSISMC2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0}, {BRCMS_SROM_RSSISMF2G, 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f}, - {BRCMS_SROM_BXA5G, 0x00000008, 0, SROM_BXARSSI5G, 0x1800}, - {BRCMS_SROM_RSSISAV5G, 0x00000008, 0, SROM_BXARSSI5G, 0x0700}, - {BRCMS_SROM_RSSISMC5G, 0x00000008, 0, SROM_BXARSSI5G, 0x00f0}, - {BRCMS_SROM_RSSISMF5G, 0x00000008, 0, SROM_BXARSSI5G, 0x000f}, {BRCMS_SROM_BXA5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800}, {BRCMS_SROM_RSSISAV5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700}, {BRCMS_SROM_RSSISMC5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0}, {BRCMS_SROM_RSSISMF5G, 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f}, - {BRCMS_SROM_TRI2G, 0x00000008, 0, SROM_TRI52G, 0x00ff}, - {BRCMS_SROM_TRI5G, 0x00000008, 0, SROM_TRI52G, 0xff00}, - {BRCMS_SROM_TRI5GL, 0x00000008, 0, SROM_TRI5GHL, 0x00ff}, - {BRCMS_SROM_TRI5GH, 0x00000008, 0, SROM_TRI5GHL, 0xff00}, {BRCMS_SROM_TRI2G, 0xffffff00, 0, SROM8_TRI52G, 0x00ff}, {BRCMS_SROM_TRI5G, 0xffffff00, 0, SROM8_TRI52G, 0xff00}, {BRCMS_SROM_TRI5GL, 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff}, {BRCMS_SROM_TRI5GH, 0xffffff00, 0, SROM8_TRI5GHL, 0xff00}, - {BRCMS_SROM_RXPO2G, 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0x00ff}, - {BRCMS_SROM_RXPO5G, 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00}, {BRCMS_SROM_RXPO2G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff}, {BRCMS_SROM_RXPO5G, 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00}, - {BRCMS_SROM_TXCHAIN, 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, - SROM4_TXCHAIN_MASK}, - {BRCMS_SROM_RXCHAIN, 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, - SROM4_RXCHAIN_MASK}, - {BRCMS_SROM_ANTSWITCH, 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, - SROM4_SWITCH_MASK}, {BRCMS_SROM_TXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_TXCHAIN_MASK}, {BRCMS_SROM_RXCHAIN, 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, @@ -594,43 +417,11 @@ static const struct brcms_sromvar pci_sromvars[] = { SROM8_FEM_ANTSWLUT_MASK}, {BRCMS_SROM_TEMPTHRESH, 0xffffff00, 0, SROM8_THERMAL, 0xff00}, {BRCMS_SROM_TEMPOFFSET, 0xffffff00, 0, SROM8_THERMAL, 0x00ff}, - {BRCMS_SROM_TXPID2GA0, 0x000000f0, 0, SROM4_TXPID2G, 0x00ff}, - {BRCMS_SROM_TXPID2GA1, 0x000000f0, 0, SROM4_TXPID2G, 0xff00}, - {BRCMS_SROM_TXPID2GA2, 0x000000f0, 0, SROM4_TXPID2G + 1, 0x00ff}, - {BRCMS_SROM_TXPID2GA3, 0x000000f0, 0, SROM4_TXPID2G + 1, 0xff00}, - {BRCMS_SROM_TXPID5GA0, 0x000000f0, 0, SROM4_TXPID5G, 0x00ff}, - {BRCMS_SROM_TXPID5GA1, 0x000000f0, 0, SROM4_TXPID5G, 0xff00}, - {BRCMS_SROM_TXPID5GA2, 0x000000f0, 0, SROM4_TXPID5G + 1, 0x00ff}, - {BRCMS_SROM_TXPID5GA3, 0x000000f0, 0, SROM4_TXPID5G + 1, 0xff00}, - {BRCMS_SROM_TXPID5GLA0, 0x000000f0, 0, SROM4_TXPID5GL, 0x00ff}, - {BRCMS_SROM_TXPID5GLA1, 0x000000f0, 0, SROM4_TXPID5GL, 0xff00}, - {BRCMS_SROM_TXPID5GLA2, 0x000000f0, 0, SROM4_TXPID5GL + 1, 0x00ff}, - {BRCMS_SROM_TXPID5GLA3, 0x000000f0, 0, SROM4_TXPID5GL + 1, 0xff00}, - {BRCMS_SROM_TXPID5GHA0, 0x000000f0, 0, SROM4_TXPID5GH, 0x00ff}, - {BRCMS_SROM_TXPID5GHA1, 0x000000f0, 0, SROM4_TXPID5GH, 0xff00}, - {BRCMS_SROM_TXPID5GHA2, 0x000000f0, 0, SROM4_TXPID5GH + 1, 0x00ff}, - {BRCMS_SROM_TXPID5GHA3, 0x000000f0, 0, SROM4_TXPID5GH + 1, 0xff00}, - - {BRCMS_SROM_CCODE, 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff}, - {BRCMS_SROM_CCODE, 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff}, - {BRCMS_SROM_CCODE, 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff}, + {BRCMS_SROM_CCODE, 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff}, {BRCMS_SROM_MACADDR, 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff}, - {BRCMS_SROM_MACADDR, 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff}, - {BRCMS_SROM_MACADDR, 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff}, - {BRCMS_SROM_MACADDR, 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff}, - {BRCMS_SROM_IL0MACADDR, 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0, - 0xffff}, - {BRCMS_SROM_ET1MACADDR, 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1, - 0xffff}, {BRCMS_SROM_LEDDC, 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC, 0xffff}, - {BRCMS_SROM_LEDDC, 0x000000e0, SRFL_NOFFS | SRFL_LEDDC, SROM5_LEDDC, - 0xffff}, - {BRCMS_SROM_LEDDC, 0x00000010, SRFL_NOFFS | SRFL_LEDDC, SROM4_LEDDC, - 0xffff}, - {BRCMS_SROM_LEDDC, 0x00000008, SRFL_NOFFS | SRFL_LEDDC, SROM3_LEDDC, - 0xffff}, {BRCMS_SROM_RAWTEMPSENSE, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0x01ff}, {BRCMS_SROM_MEASPOWER, 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, @@ -650,16 +441,7 @@ static const struct brcms_sromvar pci_sromvars[] = { {BRCMS_SROM_PHYCAL_TEMPDELTA, 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA, 0x00ff}, - {BRCMS_SROM_CCK2GPO, 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff}, {BRCMS_SROM_CCK2GPO, 0x00000100, 0, SROM8_2G_CCKPO, 0xffff}, - {BRCMS_SROM_OFDM2GPO, 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff}, - {BRCMS_SROM_CONT, 0, 0, SROM4_2G_OFDMPO + 1, 0xffff}, - {BRCMS_SROM_OFDM5GPO, 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff}, - {BRCMS_SROM_CONT, 0, 0, SROM4_5G_OFDMPO + 1, 0xffff}, - {BRCMS_SROM_OFDM5GLPO, 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff}, - {BRCMS_SROM_CONT, 0, 0, SROM4_5GL_OFDMPO + 1, 0xffff}, - {BRCMS_SROM_OFDM5GHPO, 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff}, - {BRCMS_SROM_CONT, 0, 0, SROM4_5GH_OFDMPO + 1, 0xffff}, {BRCMS_SROM_OFDM2GPO, 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff}, {BRCMS_SROM_CONT, 0, 0, SROM8_2G_OFDMPO + 1, 0xffff}, {BRCMS_SROM_OFDM5GPO, 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff}, @@ -668,38 +450,6 @@ static const struct brcms_sromvar pci_sromvars[] = { {BRCMS_SROM_CONT, 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff}, {BRCMS_SROM_OFDM5GHPO, 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff}, {BRCMS_SROM_CONT, 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff}, - {BRCMS_SROM_MCS2GPO0, 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff}, - {BRCMS_SROM_MCS2GPO1, 0x000000f0, 0, SROM4_2G_MCSPO + 1, 0xffff}, - {BRCMS_SROM_MCS2GPO2, 0x000000f0, 0, SROM4_2G_MCSPO + 2, 0xffff}, - {BRCMS_SROM_MCS2GPO3, 0x000000f0, 0, SROM4_2G_MCSPO + 3, 0xffff}, - {BRCMS_SROM_MCS2GPO4, 0x000000f0, 0, SROM4_2G_MCSPO + 4, 0xffff}, - {BRCMS_SROM_MCS2GPO5, 0x000000f0, 0, SROM4_2G_MCSPO + 5, 0xffff}, - {BRCMS_SROM_MCS2GPO6, 0x000000f0, 0, SROM4_2G_MCSPO + 6, 0xffff}, - {BRCMS_SROM_MCS2GPO7, 0x000000f0, 0, SROM4_2G_MCSPO + 7, 0xffff}, - {BRCMS_SROM_MCS5GPO0, 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff}, - {BRCMS_SROM_MCS5GPO1, 0x000000f0, 0, SROM4_5G_MCSPO + 1, 0xffff}, - {BRCMS_SROM_MCS5GPO2, 0x000000f0, 0, SROM4_5G_MCSPO + 2, 0xffff}, - {BRCMS_SROM_MCS5GPO3, 0x000000f0, 0, SROM4_5G_MCSPO + 3, 0xffff}, - {BRCMS_SROM_MCS5GPO4, 0x000000f0, 0, SROM4_5G_MCSPO + 4, 0xffff}, - {BRCMS_SROM_MCS5GPO5, 0x000000f0, 0, SROM4_5G_MCSPO + 5, 0xffff}, - {BRCMS_SROM_MCS5GPO6, 0x000000f0, 0, SROM4_5G_MCSPO + 6, 0xffff}, - {BRCMS_SROM_MCS5GPO7, 0x000000f0, 0, SROM4_5G_MCSPO + 7, 0xffff}, - {BRCMS_SROM_MCS5GLPO0, 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff}, - {BRCMS_SROM_MCS5GLPO1, 0x000000f0, 0, SROM4_5GL_MCSPO + 1, 0xffff}, - {BRCMS_SROM_MCS5GLPO2, 0x000000f0, 0, SROM4_5GL_MCSPO + 2, 0xffff}, - {BRCMS_SROM_MCS5GLPO3, 0x000000f0, 0, SROM4_5GL_MCSPO + 3, 0xffff}, - {BRCMS_SROM_MCS5GLPO4, 0x000000f0, 0, SROM4_5GL_MCSPO + 4, 0xffff}, - {BRCMS_SROM_MCS5GLPO5, 0x000000f0, 0, SROM4_5GL_MCSPO + 5, 0xffff}, - {BRCMS_SROM_MCS5GLPO6, 0x000000f0, 0, SROM4_5GL_MCSPO + 6, 0xffff}, - {BRCMS_SROM_MCS5GLPO7, 0x000000f0, 0, SROM4_5GL_MCSPO + 7, 0xffff}, - {BRCMS_SROM_MCS5GHPO0, 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff}, - {BRCMS_SROM_MCS5GHPO1, 0x000000f0, 0, SROM4_5GH_MCSPO + 1, 0xffff}, - {BRCMS_SROM_MCS5GHPO2, 0x000000f0, 0, SROM4_5GH_MCSPO + 2, 0xffff}, - {BRCMS_SROM_MCS5GHPO3, 0x000000f0, 0, SROM4_5GH_MCSPO + 3, 0xffff}, - {BRCMS_SROM_MCS5GHPO4, 0x000000f0, 0, SROM4_5GH_MCSPO + 4, 0xffff}, - {BRCMS_SROM_MCS5GHPO5, 0x000000f0, 0, SROM4_5GH_MCSPO + 5, 0xffff}, - {BRCMS_SROM_MCS5GHPO6, 0x000000f0, 0, SROM4_5GH_MCSPO + 6, 0xffff}, - {BRCMS_SROM_MCS5GHPO7, 0x000000f0, 0, SROM4_5GH_MCSPO + 7, 0xffff}, {BRCMS_SROM_MCS2GPO0, 0x00000100, 0, SROM8_2G_MCSPO, 0xffff}, {BRCMS_SROM_MCS2GPO1, 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff}, {BRCMS_SROM_MCS2GPO2, 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff}, @@ -732,10 +482,6 @@ static const struct brcms_sromvar pci_sromvars[] = { {BRCMS_SROM_MCS5GHPO5, 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff}, {BRCMS_SROM_MCS5GHPO6, 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff}, {BRCMS_SROM_MCS5GHPO7, 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff}, - {BRCMS_SROM_CDDPO, 0x000000f0, 0, SROM4_CDDPO, 0xffff}, - {BRCMS_SROM_STBCPO, 0x000000f0, 0, SROM4_STBCPO, 0xffff}, - {BRCMS_SROM_BW40PO, 0x000000f0, 0, SROM4_BW40PO, 0xffff}, - {BRCMS_SROM_BWDUPPO, 0x000000f0, 0, SROM4_BWDUPPO, 0xffff}, {BRCMS_SROM_CDDPO, 0x00000100, 0, SROM8_CDDPO, 0xffff}, {BRCMS_SROM_STBCPO, 0x00000100, 0, SROM8_STBCPO, 0xffff}, {BRCMS_SROM_BW40PO, 0x00000100, 0, SROM8_BW40PO, 0xffff}, @@ -811,34 +557,6 @@ static const struct brcms_sromvar pci_sromvars[] = { }; static const struct brcms_sromvar perpath_pci_sromvars[] = { - {BRCMS_SROM_MAXP2GA0, 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff}, - {BRCMS_SROM_ITT2GA0, 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00}, - {BRCMS_SROM_ITT5GA0, 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00}, - {BRCMS_SROM_PA2GW0A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff}, - {BRCMS_SROM_PA2GW1A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 1, 0xffff}, - {BRCMS_SROM_PA2GW2A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 2, 0xffff}, - {BRCMS_SROM_PA2GW3A0, 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 3, 0xffff}, - {BRCMS_SROM_MAXP5GA0, 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0x00ff}, - {BRCMS_SROM_MAXP5GHA0, 0x000000f0, 0, SROM4_5GLH_MAXP, 0x00ff}, - {BRCMS_SROM_MAXP5GLA0, 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00}, - {BRCMS_SROM_PA5GW0A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff}, - {BRCMS_SROM_PA5GW1A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 1, 0xffff}, - {BRCMS_SROM_PA5GW2A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 2, 0xffff}, - {BRCMS_SROM_PA5GW3A0, 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 3, 0xffff}, - {BRCMS_SROM_PA5GLW0A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff}, - {BRCMS_SROM_PA5GLW1A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 1, - 0xffff}, - {BRCMS_SROM_PA5GLW2A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 2, - 0xffff}, - {BRCMS_SROM_PA5GLW3A0, 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 3, - 0xffff}, - {BRCMS_SROM_PA5GHW0A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff}, - {BRCMS_SROM_PA5GHW1A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 1, - 0xffff}, - {BRCMS_SROM_PA5GHW2A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 2, - 0xffff}, - {BRCMS_SROM_PA5GHW3A0, 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 3, - 0xffff}, {BRCMS_SROM_MAXP2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff}, {BRCMS_SROM_ITT2GA0, 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00}, {BRCMS_SROM_ITT5GA0, 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00}, @@ -868,24 +586,17 @@ static const struct brcms_sromvar perpath_pci_sromvars[] = { * shared between devices. */ static u8 brcms_srom_crc8_table[CRC8_TABLE_SIZE]; -static u16 __iomem * +static u8 __iomem * srom_window_address(struct si_pub *sih, u8 __iomem *curmap) { if (sih->ccrev < 32) - return (u16 __iomem *)(curmap + PCI_BAR0_SPROM_OFFSET); + return curmap + PCI_BAR0_SPROM_OFFSET; if (sih->cccaps & CC_CAP_SROM) - return (u16 __iomem *) - (curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP); + return curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP; return NULL; } -/* Parse SROM and create name=value pairs. 'srom' points to - * the SROM word array. 'off' specifies the offset of the - * first word 'srom' points to, which should be either 0 or - * SROM3_SWRG_OFF (full SROM or software region). - */ - static uint mask_shift(u16 mask) { uint i; @@ -906,18 +617,16 @@ static uint mask_width(u16 mask) return 0; } -static inline void ltoh16_buf(u16 *buf, unsigned int size) +static inline void le16_to_cpu_buf(u16 *buf, uint nwords) { - size /= 2; - while (size--) - *(buf + size) = le16_to_cpu(*(__le16 *)(buf + size)); + while (nwords--) + *(buf + nwords) = le16_to_cpu(*(__le16 *)(buf + nwords)); } -static inline void htol16_buf(u16 *buf, unsigned int size) +static inline void cpu_to_le16_buf(u16 *buf, uint nwords) { - size /= 2; - while (size--) - *(__le16 *)(buf + size) = cpu_to_le16(*(buf + size)); + while (nwords--) + *(__le16 *)(buf + nwords) = cpu_to_le16(*(buf + nwords)); } /* @@ -934,6 +643,9 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list) uint width; uint flags; u32 sr = (1 << sromrev); + uint p; + uint pb = SROM8_PATH0; + const uint psz = SROM8_PATH1 - SROM8_PATH0; /* first store the srom revision */ entry = kzalloc(sizeof(struct brcms_srom_list_head), GFP_KERNEL); @@ -1031,47 +743,34 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list) list_add(&entry->var_list, var_list); } - if (sromrev >= 4) { - /* Do per-path variables */ - uint p, pb, psz; - - if (sromrev >= 8) { - pb = SROM8_PATH0; - psz = SROM8_PATH1 - SROM8_PATH0; - } else { - pb = SROM4_PATH0; - psz = SROM4_PATH1 - SROM4_PATH0; - } - - for (p = 0; p < MAX_PATH_SROM; p++) { - for (srv = perpath_pci_sromvars; - srv->varid != BRCMS_SROM_NULL; srv++) { - if ((srv->revmask & sr) == 0) - continue; + for (p = 0; p < MAX_PATH_SROM; p++) { + for (srv = perpath_pci_sromvars; + srv->varid != BRCMS_SROM_NULL; srv++) { + if ((srv->revmask & sr) == 0) + continue; - if (srv->flags & SRFL_NOVAR) - continue; + if (srv->flags & SRFL_NOVAR) + continue; - w = srom[pb + srv->off]; - val = (w & srv->mask) >> mask_shift(srv->mask); - width = mask_width(srv->mask); + w = srom[pb + srv->off]; + val = (w & srv->mask) >> mask_shift(srv->mask); + width = mask_width(srv->mask); - /* Cheating: no per-path var is more than - * 1 word */ - if ((srv->flags & SRFL_NOFFS) - && ((int)val == (1 << width) - 1)) - continue; + /* Cheating: no per-path var is more than + * 1 word */ + if ((srv->flags & SRFL_NOFFS) + && ((int)val == (1 << width) - 1)) + continue; - entry = - kzalloc(sizeof(struct brcms_srom_list_head), - GFP_KERNEL); - entry->varid = srv->varid+p; - entry->var_type = BRCMS_SROM_UNUMBER; - entry->uval = val; - list_add(&entry->var_list, var_list); - } - pb += psz; + entry = + kzalloc(sizeof(struct brcms_srom_list_head), + GFP_KERNEL); + entry->varid = srv->varid+p; + entry->var_type = BRCMS_SROM_UNUMBER; + entry->uval = val; + list_add(&entry->var_list, var_list); } + pb += psz; } } @@ -1080,41 +779,38 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, struct list_head *var_list) * Return 0 on success, nonzero on error. */ static int -sprom_read_pci(struct si_pub *sih, u16 __iomem *sprom, uint wordoff, +sprom_read_pci(struct si_pub *sih, u8 __iomem *sprom, uint wordoff, u16 *buf, uint nwords, bool check_crc) { int err = 0; uint i; + u8 *bbuf = (u8 *)buf; /* byte buffer */ + uint nbytes = nwords << 1; - /* read the sprom */ - for (i = 0; i < nwords; i++) - buf[i] = R_REG(&sprom[wordoff + i]); - - if (check_crc) { + /* read the sprom in bytes */ + for (i = 0; i < nbytes; i++) + bbuf[i] = readb(sprom+i); - if (buf[0] == 0xffff) - /* - * The hardware thinks that an srom that starts with - * 0xffff is blank, regardless of the rest of the - * content, so declare it bad. - */ - return -ENODATA; - - /* fixup the endianness so crc8 will pass */ - htol16_buf(buf, nwords * 2); - if (crc8(brcms_srom_crc8_table, (u8 *) buf, nwords * 2, - CRC8_INIT_VALUE) != - CRC8_GOOD_VALUE(brcms_srom_crc8_table)) - /* DBG only pci always read srom4 first, then srom8/9 */ - err = -EIO; + if (buf[0] == 0xffff) + /* + * The hardware thinks that an srom that starts with + * 0xffff is blank, regardless of the rest of the + * content, so declare it bad. + */ + return -ENODATA; + if (check_crc && + crc8(brcms_srom_crc8_table, bbuf, nbytes, CRC8_INIT_VALUE) != + CRC8_GOOD_VALUE(brcms_srom_crc8_table)) + err = -EIO; + else /* now correct the endianness of the byte array */ - ltoh16_buf(buf, nwords * 2); - } + le16_to_cpu_buf(buf, nwords); + return err; } -static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz) +static int otp_read_pci(struct si_pub *sih, u16 *buf, uint nwords) { u8 *otp; uint sz = OTP_SZ_MAX / 2; /* size in words */ @@ -1126,7 +822,8 @@ static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz) err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz); - memcpy(buf, otp, bufsz); + sz = min_t(uint, sz, nwords); + memcpy(buf, otp, sz * 2); kfree(otp); @@ -1138,14 +835,12 @@ static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz) */ return -ENODATA; - /* fixup the endianness so crc8 will pass */ - htol16_buf(buf, bufsz); - if (crc8(brcms_srom_crc8_table, (u8 *) buf, SROM4_WORDS * 2, + if (crc8(brcms_srom_crc8_table, (u8 *) buf, sz * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE(brcms_srom_crc8_table)) err = -EIO; - - /* now correct the endianness of the byte array */ - ltoh16_buf(buf, bufsz); + else + /* now correct the endianness of the byte array */ + le16_to_cpu_buf(buf, sz); return err; } @@ -1157,7 +852,7 @@ static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz) static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap) { u16 *srom; - u16 __iomem *sromwindow; + u8 __iomem *sromwindow; u8 sromrev = 0; u32 sr; int err = 0; @@ -1173,29 +868,16 @@ static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap) crc8_populate_lsb(brcms_srom_crc8_table, SROM_CRC8_POLY); if (ai_is_sprom_available(sih)) { - err = sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS, - true); - - if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) || - (((sih->buscoretype == PCIE_CORE_ID) - && (sih->buscorerev >= 6)) - || ((sih->buscoretype == PCI_CORE_ID) - && (sih->buscorerev >= 0xe)))) { - /* sromrev >= 4, read more */ - err = sprom_read_pci(sih, sromwindow, 0, srom, - SROM4_WORDS, true); - sromrev = srom[SROM4_CRCREV] & 0xff; - } else if (err == 0) { - /* srom is good and is rev < 4 */ + err = sprom_read_pci(sih, sromwindow, 0, srom, + SROM4_WORDS, true); + + if (err == 0) + /* srom read and passed crc */ /* top word of sprom contains version and crc8 */ - sromrev = srom[SROM_CRCREV] & 0xff; - /* bcm4401 sroms misprogrammed */ - if (sromrev == 0x10) - sromrev = 1; - } + sromrev = srom[SROM4_CRCREV] & 0xff; } else { /* Use OTP if SPROM not available */ - err = otp_read_pci(sih, srom, SROM_MAX); + err = otp_read_pci(sih, srom, SROM4_WORDS); if (err == 0) /* OTP only contain SROM rev8/rev9 for now */ sromrev = srom[SROM4_CRCREV] & 0xff; @@ -1208,10 +890,9 @@ static int initvars_srom_pci(struct si_pub *sih, void __iomem *curmap) sr = 1 << sromrev; /* - * srom version check: Current valid versions: 1, 2, 3, 4, 5, 8, - * 9 + * srom version check: Current valid versions: 8, 9 */ - if ((sr & 0x33e) == 0) { + if ((sr & 0x300) == 0) { err = -EINVAL; goto errout; } diff --git a/drivers/net/wireless/brcm80211/brcmsmac/srom.h b/drivers/net/wireless/brcm80211/brcmsmac/srom.h index 708c43ff51cc..c81df9798e50 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/srom.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/srom.h @@ -26,9 +26,4 @@ extern void srom_free_vars(struct si_pub *sih); extern int srom_read(struct si_pub *sih, uint bus, void *curmap, uint byteoff, uint nbytes, u16 *buf, bool check_crc); -/* parse standard PCMCIA cis, normally used by SB/PCMCIA/SDIO/SPI/OTP - * and extract from it into name=value pairs - */ -extern int srom_parsecis(u8 **pcis, uint ciscnt, - char **vars, uint *count); #endif /* _BRCM_SROM_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c index f27c48910827..12b795ffd369 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/utils.c +++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c @@ -16,6 +16,7 @@ #include <linux/netdevice.h> #include <linux/module.h> + #include <brcmu_utils.h> MODULE_AUTHOR("Broadcom Corporation"); @@ -66,36 +67,6 @@ void brcmu_pkt_buf_free_skb(struct sk_buff *skb) EXPORT_SYMBOL(brcmu_pkt_buf_free_skb); -/* copy a buffer into a pkt buffer chain */ -uint brcmu_pktfrombuf(struct sk_buff *p, uint offset, int len, - unsigned char *buf) -{ - uint n, ret = 0; - - /* skip 'offset' bytes */ - for (; p && offset; p = p->next) { - if (offset < (uint) (p->len)) - break; - offset -= p->len; - } - - if (!p) - return 0; - - /* copy the data */ - for (; p && len; p = p->next) { - n = min((uint) (p->len) - offset, (uint) len); - memcpy(p->data + offset, buf, n); - buf += n; - len -= n; - ret += n; - offset = 0; - } - - return ret; -} -EXPORT_SYMBOL(brcmu_pktfrombuf); - /* return total length of buffer chain */ uint brcmu_pkttotlen(struct sk_buff *p) { @@ -364,23 +335,3 @@ void brcmu_prpkt(const char *msg, struct sk_buff *p0) } EXPORT_SYMBOL(brcmu_prpkt); #endif /* defined(BCMDBG) */ - -#if defined(BCMDBG) -/* - * print bytes formatted as hex to a string. return the resulting - * string length - */ -int brcmu_format_hex(char *str, const void *bytes, int len) -{ - int i; - char *p = str; - const u8 *src = (const u8 *)bytes; - - for (i = 0; i < len; i++) { - p += snprintf(p, 3, "%02X", *src); - src++; - } - return (int)(p - str); -} -EXPORT_SYMBOL(brcmu_format_hex); -#endif /* defined(BCMDBG) */ diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h index 7d0f46e0eb95..ccf60151953c 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h @@ -173,23 +173,18 @@ extern void brcmu_pktq_flush(struct pktq *pq, bool dir, /* externs */ /* packet */ -extern uint brcmu_pktfrombuf(struct sk_buff *p, - uint offset, int len, unsigned char *buf); extern uint brcmu_pkttotlen(struct sk_buff *p); /* ip address */ struct ipv4_addr; + +/* externs */ +/* format/print */ #ifdef BCMDBG extern void brcmu_prpkt(const char *msg, struct sk_buff *p0); #else #define brcmu_prpkt(a, b) #endif /* BCMDBG */ -/* externs */ -/* format/print */ -#if defined(BCMDBG) -extern int brcmu_format_hex(char *str, const void *bytes, int len); -#endif - #endif /* _BRCMU_UTILS_H_ */ diff --git a/drivers/net/wireless/brcm80211/include/defs.h b/drivers/net/wireless/brcm80211/include/defs.h index 1e5f310af1e7..f0d8c04a9c8c 100644 --- a/drivers/net/wireless/brcm80211/include/defs.h +++ b/drivers/net/wireless/brcm80211/include/defs.h @@ -62,7 +62,6 @@ #define WL_RADIO_SW_DISABLE (1<<0) #define WL_RADIO_HW_DISABLE (1<<1) -#define WL_RADIO_MPC_DISABLE (1<<2) /* some countries don't support any channel */ #define WL_RADIO_COUNTRY_DISABLE (1<<3) diff --git a/drivers/net/wireless/brcm80211/include/soc.h b/drivers/net/wireless/brcm80211/include/soc.h index 4fcb956ad9e0..4e9b7e4827ea 100644 --- a/drivers/net/wireless/brcm80211/include/soc.h +++ b/drivers/net/wireless/brcm80211/include/soc.h @@ -77,8 +77,9 @@ #define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ #define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ #define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ -/* Default component, in ai chips it maps all unused address ranges */ -#define DEF_AI_COMP 0xfff +#define DEF_AI_COMP 0xfff /* Default component, in ai chips it + * maps all unused address ranges + */ /* Common core control flags */ #define SICF_BIST_EN 0x8000 @@ -87,4 +88,11 @@ #define SICF_FGC 0x0002 #define SICF_CLOCK_EN 0x0001 +/* Common core status flags */ +#define SISF_BIST_DONE 0x8000 +#define SISF_BIST_ERROR 0x4000 +#define SISF_GATED_CLK 0x2000 +#define SISF_DMA64 0x1000 +#define SISF_CORE_BITS 0x0fff + #endif /* _BRCM_SOC_H */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index ccba69b7f8a7..9d463cf40380 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2028,6 +2028,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, .tkip = &tkip_cmd, .use_tkip = false, }; + struct iwlagn_d3_config_cmd d3_cfg_cmd = {}; int ret, i; u16 seq; @@ -2085,13 +2086,14 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, if (wowlan->four_way_handshake) wakeup_filter_cmd.enabled |= cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE); - if (wowlan->rfkill_release) - wakeup_filter_cmd.enabled |= - cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_RFKILL); if (wowlan->n_patterns) wakeup_filter_cmd.enabled |= cpu_to_le32(IWLAGN_WOWLAN_WAKEUP_PATTERN_MATCH); + if (wowlan->rfkill_release) + d3_cfg_cmd.wakeup_flags |= + cpu_to_le32(IWLAGN_D3_WAKEUP_RFKILL); + iwl_scan_cancel_timeout(priv, 200); memcpy(&rxon, &ctx->active, sizeof(rxon)); @@ -2179,6 +2181,11 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, } } + ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_D3_CONFIG, CMD_SYNC, + sizeof(d3_cfg_cmd), &d3_cfg_cmd); + if (ret) + goto error; + ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_WOWLAN_WAKEUP_FILTER, CMD_SYNC, sizeof(wakeup_filter_cmd), &wakeup_filter_cmd); @@ -3171,7 +3178,7 @@ static int iwl_set_hw_params(struct iwl_priv *priv) } /* This function both allocates and initializes hw and priv. */ -static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg) +static struct ieee80211_hw *iwl_alloc_all(void) { struct iwl_priv *priv; /* mac80211 allocates memory for this device instance, including @@ -3179,11 +3186,8 @@ static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg) struct ieee80211_hw *hw; hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwlagn_hw_ops); - if (hw == NULL) { - pr_err("%s: Can not allocate network device\n", - cfg->name); + if (!hw) goto out; - } priv = hw->priv; priv->hw = hw; @@ -3204,8 +3208,9 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, /************************ * 1. Allocating HW data ************************/ - hw = iwl_alloc_all(cfg); + hw = iwl_alloc_all(); if (!hw) { + pr_err("%s: Cannot allocate network device\n", cfg->name); err = -ENOMEM; goto out; } diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 69d5f85d11e2..f4eccf583775 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -198,6 +198,7 @@ enum { REPLY_WOWLAN_TKIP_PARAMS = 0xe3, REPLY_WOWLAN_KEK_KCK_MATERIAL = 0xe4, REPLY_WOWLAN_GET_STATUS = 0xe5, + REPLY_D3_CONFIG = 0xd3, REPLY_MAX = 0xff }; @@ -3801,6 +3802,19 @@ struct iwl_bt_coex_prot_env_cmd { } __attribute__((packed)); /* + * REPLY_D3_CONFIG + */ +enum iwlagn_d3_wakeup_filters { + IWLAGN_D3_WAKEUP_RFKILL = BIT(0), + IWLAGN_D3_WAKEUP_SYSASSERT = BIT(1), +}; + +struct iwlagn_d3_config_cmd { + __le32 min_sleep_time; + __le32 wakeup_flags; +} __packed; + +/* * REPLY_WOWLAN_PATTERNS */ #define IWLAGN_WOWLAN_MIN_PATTERN_LEN 16 @@ -3830,19 +3844,16 @@ enum iwlagn_wowlan_wakeup_filters { IWLAGN_WOWLAN_WAKEUP_BEACON_MISS = BIT(2), IWLAGN_WOWLAN_WAKEUP_LINK_CHANGE = BIT(3), IWLAGN_WOWLAN_WAKEUP_GTK_REKEY_FAIL = BIT(4), - IWLAGN_WOWLAN_WAKEUP_RFKILL = BIT(5), - IWLAGN_WOWLAN_WAKEUP_UCODE_ERROR = BIT(6), - IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ = BIT(7), - IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE = BIT(8), - IWLAGN_WOWLAN_WAKEUP_ALWAYS = BIT(9), - IWLAGN_WOWLAN_WAKEUP_ENABLE_NET_DETECT = BIT(10), + IWLAGN_WOWLAN_WAKEUP_EAP_IDENT_REQ = BIT(5), + IWLAGN_WOWLAN_WAKEUP_4WAY_HANDSHAKE = BIT(6), + IWLAGN_WOWLAN_WAKEUP_ALWAYS = BIT(7), + IWLAGN_WOWLAN_WAKEUP_ENABLE_NET_DETECT = BIT(8), }; struct iwlagn_wowlan_wakeup_filter_cmd { __le32 enabled; __le16 non_qos_seq; - u8 min_sleep_seconds; - u8 reserved; + __le16 reserved; __le16 qos_seq[8]; }; diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index b9f3267e720c..fbc3095c7b44 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -284,8 +284,8 @@ #define CSR_HW_REV_TYPE_6x35 CSR_HW_REV_TYPE_6x05 #define CSR_HW_REV_TYPE_2x30 (0x00000C0) #define CSR_HW_REV_TYPE_2x00 (0x0000100) -#define CSR_HW_REV_TYPE_200 (0x0000110) -#define CSR_HW_REV_TYPE_230 (0x0000120) +#define CSR_HW_REV_TYPE_105 (0x0000110) +#define CSR_HW_REV_TYPE_135 (0x0000120) #define CSR_HW_REV_TYPE_NONE (0x00001F0) /* EEPROM REG */ diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c index a635a7e75447..2a2c8de64a04 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c @@ -28,7 +28,7 @@ /* sparse doesn't like tracepoint macros */ #ifndef __CHECKER__ -#include "iwl-dev.h" +#include "iwl-trans.h" #define CREATE_TRACE_POINTS #include "iwl-devtrace.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 8a51c5ccda1e..f9d3319ecad5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -29,7 +29,6 @@ #include <linux/tracepoint.h> -struct iwl_priv; #if !defined(CONFIG_IWLWIFI_DEVICE_TRACING) || defined(__CHECKER__) #undef TRACE_EVENT @@ -37,14 +36,14 @@ struct iwl_priv; static inline void trace_ ## name(proto) {} #endif -#define PRIV_ENTRY __field(struct iwl_priv *, priv) +#define PRIV_ENTRY __field(void *, priv) #define PRIV_ASSIGN __entry->priv = priv #undef TRACE_SYSTEM #define TRACE_SYSTEM iwlwifi_io TRACE_EVENT(iwlwifi_dev_ioread32, - TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val), + TP_PROTO(void *priv, u32 offs, u32 val), TP_ARGS(priv, offs, val), TP_STRUCT__entry( PRIV_ENTRY @@ -60,7 +59,7 @@ TRACE_EVENT(iwlwifi_dev_ioread32, ); TRACE_EVENT(iwlwifi_dev_iowrite8, - TP_PROTO(struct iwl_priv *priv, u32 offs, u8 val), + TP_PROTO(void *priv, u32 offs, u8 val), TP_ARGS(priv, offs, val), TP_STRUCT__entry( PRIV_ENTRY @@ -76,7 +75,7 @@ TRACE_EVENT(iwlwifi_dev_iowrite8, ); TRACE_EVENT(iwlwifi_dev_iowrite32, - TP_PROTO(struct iwl_priv *priv, u32 offs, u32 val), + TP_PROTO(void *priv, u32 offs, u32 val), TP_ARGS(priv, offs, val), TP_STRUCT__entry( PRIV_ENTRY @@ -95,7 +94,7 @@ TRACE_EVENT(iwlwifi_dev_iowrite32, #define TRACE_SYSTEM iwlwifi_ucode TRACE_EVENT(iwlwifi_dev_ucode_cont_event, - TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev), + TP_PROTO(void *priv, u32 time, u32 data, u32 ev), TP_ARGS(priv, time, data, ev), TP_STRUCT__entry( PRIV_ENTRY @@ -115,7 +114,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_cont_event, ); TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, - TP_PROTO(struct iwl_priv *priv, u32 wraps, u32 n_entry, u32 p_entry), + TP_PROTO(void *priv, u32 wraps, u32 n_entry, u32 p_entry), TP_ARGS(priv, wraps, n_entry, p_entry), TP_STRUCT__entry( PRIV_ENTRY @@ -139,7 +138,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_wrap_event, #define TRACE_SYSTEM iwlwifi TRACE_EVENT(iwlwifi_dev_hcmd, - TP_PROTO(struct iwl_priv *priv, u32 flags, + TP_PROTO(void *priv, u32 flags, const void *hcmd0, size_t len0, const void *hcmd1, size_t len1, const void *hcmd2, size_t len2), @@ -164,7 +163,7 @@ TRACE_EVENT(iwlwifi_dev_hcmd, ); TRACE_EVENT(iwlwifi_dev_rx, - TP_PROTO(struct iwl_priv *priv, void *rxbuf, size_t len), + TP_PROTO(void *priv, void *rxbuf, size_t len), TP_ARGS(priv, rxbuf, len), TP_STRUCT__entry( PRIV_ENTRY @@ -179,7 +178,7 @@ TRACE_EVENT(iwlwifi_dev_rx, ); TRACE_EVENT(iwlwifi_dev_tx, - TP_PROTO(struct iwl_priv *priv, void *tfd, size_t tfdlen, + TP_PROTO(void *priv, void *tfd, size_t tfdlen, void *buf0, size_t buf0_len, void *buf1, size_t buf1_len), TP_ARGS(priv, tfd, tfdlen, buf0, buf0_len, buf1, buf1_len), @@ -211,7 +210,7 @@ TRACE_EVENT(iwlwifi_dev_tx, ); TRACE_EVENT(iwlwifi_dev_ucode_error, - TP_PROTO(struct iwl_priv *priv, u32 desc, u32 tsf_low, + TP_PROTO(void *priv, u32 desc, u32 tsf_low, u32 data1, u32 data2, u32 line, u32 blink1, u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time, u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver, @@ -271,7 +270,7 @@ TRACE_EVENT(iwlwifi_dev_ucode_error, ); TRACE_EVENT(iwlwifi_dev_ucode_event, - TP_PROTO(struct iwl_priv *priv, u32 time, u32 data, u32 ev), + TP_PROTO(void *priv, u32 time, u32 data, u32 ev), TP_ARGS(priv, time, data, ev), TP_STRUCT__entry( PRIV_ENTRY diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index e5d727f537d0..a26fbd33a5d9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -678,7 +678,8 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) priv->contexts[IWL_RXON_CTX_BSS].active.flags & RXON_FLG_CHANNEL_MODE_MSK) >> RXON_FLG_CHANNEL_MODE_POS; - if (chan_mod == CHANNEL_MODE_PURE_40) { + if ((priv->scan_request && priv->scan_request->no_cck) || + chan_mod == CHANNEL_MODE_PURE_40) { rate = IWL_RATE_6M_PLCP; } else { rate = IWL_RATE_1M_PLCP; diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c index c42be81e979e..48e8218fd23b 100644 --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c @@ -165,11 +165,15 @@ static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, struct key_params *params) { struct iwm_priv *iwm = ndev_to_iwm(ndev); - struct iwm_key *key = &iwm->keys[key_index]; + struct iwm_key *key; int ret; IWM_DBG_WEXT(iwm, DBG, "Adding key for %pM\n", mac_addr); + if (key_index >= IWM_NUM_KEYS) + return -ENOENT; + + key = &iwm->keys[key_index]; memset(key, 0, sizeof(struct iwm_key)); ret = iwm_key_init(key, key_index, mac_addr, params); if (ret < 0) { @@ -214,8 +218,12 @@ static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_index, bool pairwise, const u8 *mac_addr) { struct iwm_priv *iwm = ndev_to_iwm(ndev); - struct iwm_key *key = &iwm->keys[key_index]; + struct iwm_key *key; + if (key_index >= IWM_NUM_KEYS) + return -ENOENT; + + key = &iwm->keys[key_index]; if (!iwm->keys[key_index].key_len) { IWM_DBG_WEXT(iwm, DBG, "Key %d not used\n", key_index); return 0; @@ -236,6 +244,9 @@ static int iwm_cfg80211_set_default_key(struct wiphy *wiphy, IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index); + if (key_index >= IWM_NUM_KEYS) + return -ENOENT; + if (!iwm->keys[key_index].key_len) { IWM_ERR(iwm, "Key %d not used\n", key_index); return -EINVAL; diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 68455a2307cb..477100d0b117 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -1747,6 +1747,8 @@ static int __init init_mac80211_hwsim(void) IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | IEEE80211_HW_AMPDU_AGGREGATION; + hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; + /* ask mac80211 to reserve space for magic */ hw->vif_data_size = sizeof(struct hwsim_vif_priv); hw->sta_data_size = sizeof(struct hwsim_sta_priv); diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 0c13840a7de5..83f3e5282aea 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -414,6 +414,7 @@ struct ndis_80211_pmkid { #define RNDIS_WLAN_ALG_TKIP (1<<1) #define RNDIS_WLAN_ALG_CCMP (1<<2) +#define RNDIS_WLAN_NUM_KEYS 4 #define RNDIS_WLAN_KEY_MGMT_NONE 0 #define RNDIS_WLAN_KEY_MGMT_802_1X (1<<0) #define RNDIS_WLAN_KEY_MGMT_PSK (1<<1) @@ -516,7 +517,7 @@ struct rndis_wlan_private { /* encryption stuff */ int encr_tx_key_index; - struct rndis_wlan_encr_key encr_keys[4]; + struct rndis_wlan_encr_key encr_keys[RNDIS_WLAN_NUM_KEYS]; int wpa_version; u8 command_buffer[COMMAND_BUFFER_SIZE]; @@ -1535,6 +1536,9 @@ static int remove_key(struct usbnet *usbdev, int index, const u8 *bssid) bool is_wpa; int ret; + if (index >= RNDIS_WLAN_NUM_KEYS) + return -ENOENT; + if (priv->encr_keys[index].len == 0) return 0; @@ -2451,6 +2455,9 @@ static int rndis_set_default_key(struct wiphy *wiphy, struct net_device *netdev, netdev_dbg(usbdev->net, "%s(%i)\n", __func__, key_index); + if (key_index >= RNDIS_WLAN_NUM_KEYS) + return -ENOENT; + priv->encr_tx_key_index = key_index; if (is_wpa_key(priv, key_index)) diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index feed1ed8d9b6..b9a158e5eb0e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -274,6 +274,8 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8191, rtl92cu_hal_cfg)}, /****** 8188CU ********/ + /* RTL8188CTV */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x018a, rtl92cu_hal_cfg)}, /* 8188CE-VAU USB minCard */ {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8170, rtl92cu_hal_cfg)}, /* 8188cu 1*1 dongle */ @@ -290,14 +292,14 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817e, rtl92cu_hal_cfg)}, /* 8188RU in Alfa AWUS036NHR */ {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817f, rtl92cu_hal_cfg)}, + /* RTL8188CUS-VL */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x818a, rtl92cu_hal_cfg)}, /* 8188 Combo for BC4 */ {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)}, /****** 8192CU ********/ - /* 8191cu 1*2 */ - {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8177, rtl92cu_hal_cfg)}, /* 8192cu 2*2 */ - {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817b, rtl92cu_hal_cfg)}, + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8178, rtl92cu_hal_cfg)}, /* 8192CE-VAU USB minCard */ {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817c, rtl92cu_hal_cfg)}, @@ -308,13 +310,17 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ - {RTL_USB_DEVICE(0x0Df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ + {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ + {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ /* HP - Lite-On ,8188CUS Slim Combo */ {RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)}, {RTL_USB_DEVICE(0x13d3, 0x3357, rtl92cu_hal_cfg)}, /* AzureWave */ {RTL_USB_DEVICE(0x2001, 0x3308, rtl92cu_hal_cfg)}, /*D-Link - Alpha*/ + {RTL_USB_DEVICE(0x2019, 0x4902, rtl92cu_hal_cfg)}, /*Planex - Etop*/ {RTL_USB_DEVICE(0x2019, 0xab2a, rtl92cu_hal_cfg)}, /*Planex - Abocom*/ + /*SW-WF02-AD15 -Abocom*/ + {RTL_USB_DEVICE(0x2019, 0xab2e, rtl92cu_hal_cfg)}, {RTL_USB_DEVICE(0x2019, 0xed17, rtl92cu_hal_cfg)}, /*PCI - Edimax*/ {RTL_USB_DEVICE(0x20f4, 0x648b, rtl92cu_hal_cfg)}, /*TRENDnet - Cameo*/ {RTL_USB_DEVICE(0x7392, 0x7811, rtl92cu_hal_cfg)}, /*Edimax - Edimax*/ @@ -325,14 +331,36 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(0x4855, 0x0091, rtl92cu_hal_cfg)}, /* NetweeN-Feixun */ {RTL_USB_DEVICE(0x9846, 0x9041, rtl92cu_hal_cfg)}, /* Netgear Cameo */ + /****** 8188 RU ********/ + /* Netcore */ + {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x317f, rtl92cu_hal_cfg)}, + + /****** 8188CUS Slim Solo********/ + {RTL_USB_DEVICE(0x04f2, 0xaff7, rtl92cu_hal_cfg)}, /*Xavi*/ + {RTL_USB_DEVICE(0x04f2, 0xaff9, rtl92cu_hal_cfg)}, /*Xavi*/ + {RTL_USB_DEVICE(0x04f2, 0xaffa, rtl92cu_hal_cfg)}, /*Xavi*/ + + /****** 8188CUS Slim Combo ********/ + {RTL_USB_DEVICE(0x04f2, 0xaff8, rtl92cu_hal_cfg)}, /*Xavi*/ + {RTL_USB_DEVICE(0x04f2, 0xaffb, rtl92cu_hal_cfg)}, /*Xavi*/ + {RTL_USB_DEVICE(0x04f2, 0xaffc, rtl92cu_hal_cfg)}, /*Xavi*/ + {RTL_USB_DEVICE(0x2019, 0x1201, rtl92cu_hal_cfg)}, /*Planex-Vencer*/ + /****** 8192CU ********/ + {RTL_USB_DEVICE(0x050d, 0x2102, rtl92cu_hal_cfg)}, /*Belcom-Sercomm*/ + {RTL_USB_DEVICE(0x050d, 0x2103, rtl92cu_hal_cfg)}, /*Belcom-Edimax*/ {RTL_USB_DEVICE(0x0586, 0x341f, rtl92cu_hal_cfg)}, /*Zyxel -Abocom*/ {RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/ {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ + {RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/ + {RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/ + {RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/ + {RTL_USB_DEVICE(0x0e66, 0x0019, rtl92cu_hal_cfg)}, /*Hawking-Edimax*/ {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/ {RTL_USB_DEVICE(0x2001, 0x3309, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ {RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ {RTL_USB_DEVICE(0x2019, 0xab2b, rtl92cu_hal_cfg)}, /*Planex -Abocom*/ + {RTL_USB_DEVICE(0x20f4, 0x624d, rtl92cu_hal_cfg)}, /*TRENDNet*/ {RTL_USB_DEVICE(0x7392, 0x7822, rtl92cu_hal_cfg)}, /*Edimax -Edimax*/ {} }; |