mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
Merge branch 'master' of git://git.infradead.org/users/linville/wireless-next into for-davem
This commit is contained in:
commit
41ebe9cde7
@ -23,6 +23,10 @@ radiotap headers and used to control injection:
|
||||
IEEE80211_RADIOTAP_F_FRAG: frame will be fragmented if longer than the
|
||||
current fragmentation threshold.
|
||||
|
||||
* IEEE80211_RADIOTAP_TX_FLAGS
|
||||
|
||||
IEEE80211_RADIOTAP_F_TX_NOACK: frame should be sent without waiting for
|
||||
an ACK even if it is a unicast frame
|
||||
|
||||
The injection code can also skip all other currently defined radiotap fields
|
||||
facilitating replay of captured radiotap headers directly.
|
||||
|
@ -271,6 +271,7 @@ config MWL8K
|
||||
source "drivers/net/wireless/ath/Kconfig"
|
||||
source "drivers/net/wireless/b43/Kconfig"
|
||||
source "drivers/net/wireless/b43legacy/Kconfig"
|
||||
source "drivers/net/wireless/brcm80211/Kconfig"
|
||||
source "drivers/net/wireless/hostap/Kconfig"
|
||||
source "drivers/net/wireless/ipw2x00/Kconfig"
|
||||
source "drivers/net/wireless/iwlwifi/Kconfig"
|
||||
|
@ -58,3 +58,6 @@ obj-$(CONFIG_WL12XX_PLATFORM_DATA) += wl12xx/
|
||||
obj-$(CONFIG_IWM) += iwmc3200wifi/
|
||||
|
||||
obj-$(CONFIG_MWIFIEX) += mwifiex/
|
||||
obj-$(CONFIG_BRCMFMAC) += brcm80211/
|
||||
obj-$(CONFIG_BRCMUMAC) += brcm80211/
|
||||
obj-$(CONFIG_BRCMSMAC) += brcm80211/
|
||||
|
@ -71,9 +71,7 @@ struct ath_regulatory {
|
||||
char alpha2[2];
|
||||
u16 country_code;
|
||||
u16 max_power_level;
|
||||
u32 tp_scale;
|
||||
u16 current_rd;
|
||||
u16 current_rd_ext;
|
||||
int16_t power_limit;
|
||||
struct reg_dmn_pair_mapping *regpair;
|
||||
};
|
||||
|
@ -921,12 +921,6 @@ ath5k_txq_setup(struct ath5k_hw *ah,
|
||||
*/
|
||||
return ERR_PTR(qnum);
|
||||
}
|
||||
if (qnum >= ARRAY_SIZE(ah->txqs)) {
|
||||
ATH5K_ERR(ah, "hw qnum %u out of range, max %tu!\n",
|
||||
qnum, ARRAY_SIZE(ah->txqs));
|
||||
ath5k_hw_release_tx_queue(ah, qnum);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
txq = &ah->txqs[qnum];
|
||||
if (!txq->setup) {
|
||||
txq->qnum = qnum;
|
||||
|
@ -21,6 +21,7 @@ ath9k_hw-y:= \
|
||||
ar5008_phy.o \
|
||||
ar9002_calib.o \
|
||||
ar9003_calib.o \
|
||||
ar9003_rtt.o \
|
||||
calib.o \
|
||||
eeprom.o \
|
||||
eeprom_def.o \
|
||||
|
@ -504,9 +504,6 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
|
||||
ATH9K_ANI_CCK_WEAK_SIG_THR);
|
||||
|
||||
ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
|
||||
ATH9K_RX_FILTER_PHYERR);
|
||||
|
||||
ath9k_ani_restart(ah);
|
||||
return;
|
||||
}
|
||||
@ -527,8 +524,6 @@ static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning)
|
||||
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
|
||||
aniState->firstepLevel);
|
||||
|
||||
ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
|
||||
~ATH9K_RX_FILTER_PHYERR);
|
||||
ath9k_ani_restart(ah);
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
@ -763,10 +763,8 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
|
||||
static int ar5008_hw_process_ini(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int i, regWrites = 0;
|
||||
struct ieee80211_channel *channel = chan->chan;
|
||||
u32 modesIndex, freqIndex;
|
||||
|
||||
switch (chan->chanmode) {
|
||||
@ -903,14 +901,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
|
||||
ar5008_hw_set_channel_regs(ah, chan);
|
||||
ar5008_hw_init_chain_masks(ah);
|
||||
ath9k_olc_init(ah);
|
||||
|
||||
/* Set TX power */
|
||||
ah->eep_ops->set_txpower(ah, chan,
|
||||
ath9k_regd_get_ctl(regulatory, chan),
|
||||
channel->max_antenna_gain * 2,
|
||||
channel->max_power * 2,
|
||||
min((u32) MAX_RATE_POWER,
|
||||
(u32) regulatory->power_limit), false);
|
||||
ath9k_hw_apply_txpower(ah, chan);
|
||||
|
||||
/* Write analog registers */
|
||||
if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
|
||||
|
@ -24,11 +24,11 @@ static const u32 ar9300_2p2_radio_postamble[][5] = {
|
||||
{0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31},
|
||||
{0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800},
|
||||
{0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20},
|
||||
{0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0001610c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
|
||||
{0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
|
||||
{0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0001650c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
|
||||
{0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
|
||||
{0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0001690c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000},
|
||||
{0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
|
||||
};
|
||||
|
||||
@ -190,7 +190,7 @@ static const u32 ar9300_2p2_radio_core[][2] = {
|
||||
{0x00016288, 0x05a20408},
|
||||
{0x0001628c, 0x00038c07},
|
||||
{0x00016290, 0x00000004},
|
||||
{0x00016294, 0x458aa14f},
|
||||
{0x00016294, 0x458a214f},
|
||||
{0x00016380, 0x00000000},
|
||||
{0x00016384, 0x00000000},
|
||||
{0x00016388, 0x00800700},
|
||||
@ -835,107 +835,107 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
|
||||
|
||||
static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
|
||||
{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
|
||||
{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
|
||||
{0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
|
||||
{0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
|
||||
{0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
|
||||
{0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
|
||||
{0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402},
|
||||
{0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404},
|
||||
{0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
|
||||
{0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
|
||||
{0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
|
||||
{0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
|
||||
{0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
|
||||
{0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
|
||||
{0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
|
||||
{0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
|
||||
{0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
|
||||
{0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861},
|
||||
{0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81},
|
||||
{0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83},
|
||||
{0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84},
|
||||
{0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3},
|
||||
{0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5},
|
||||
{0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9},
|
||||
{0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb},
|
||||
{0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202},
|
||||
{0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400},
|
||||
{0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402},
|
||||
{0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404},
|
||||
{0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603},
|
||||
{0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02},
|
||||
{0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04},
|
||||
{0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20},
|
||||
{0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20},
|
||||
{0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22},
|
||||
{0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24},
|
||||
{0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640},
|
||||
{0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660},
|
||||
{0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861},
|
||||
{0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81},
|
||||
{0x0000a54c, 0x5a08442e, 0x5a08442e, 0x47001a83, 0x47001a83},
|
||||
{0x0000a550, 0x5e0a4431, 0x5e0a4431, 0x4a001c84, 0x4a001c84},
|
||||
{0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3},
|
||||
{0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5},
|
||||
{0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9},
|
||||
{0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb},
|
||||
{0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec},
|
||||
{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
|
||||
{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
|
||||
{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
|
||||
{0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
|
||||
{0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
|
||||
{0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
|
||||
{0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402},
|
||||
{0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404},
|
||||
{0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
|
||||
{0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
|
||||
{0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
|
||||
{0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
|
||||
{0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
|
||||
{0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
|
||||
{0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
|
||||
{0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
|
||||
{0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
|
||||
{0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861},
|
||||
{0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81},
|
||||
{0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83},
|
||||
{0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84},
|
||||
{0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3},
|
||||
{0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5},
|
||||
{0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9},
|
||||
{0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb},
|
||||
{0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202},
|
||||
{0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400},
|
||||
{0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402},
|
||||
{0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404},
|
||||
{0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603},
|
||||
{0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02},
|
||||
{0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04},
|
||||
{0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20},
|
||||
{0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20},
|
||||
{0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22},
|
||||
{0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24},
|
||||
{0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640},
|
||||
{0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660},
|
||||
{0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861},
|
||||
{0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81},
|
||||
{0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83},
|
||||
{0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84},
|
||||
{0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3},
|
||||
{0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5},
|
||||
{0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9},
|
||||
{0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb},
|
||||
{0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec},
|
||||
{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
|
||||
{0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
|
||||
{0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
|
||||
{0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
|
||||
{0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
|
||||
{0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
|
||||
{0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
|
||||
{0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
|
||||
{0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
|
||||
{0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
|
||||
{0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
|
||||
{0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
|
||||
{0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
|
||||
{0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000},
|
||||
{0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000},
|
||||
{0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501},
|
||||
{0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501},
|
||||
{0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03},
|
||||
{0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
|
||||
{0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04},
|
||||
{0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
|
||||
{0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
|
||||
{0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
|
||||
{0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
|
||||
{0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005},
|
||||
{0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
|
||||
{0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584},
|
||||
{0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800},
|
||||
{0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
|
||||
{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
|
||||
{0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
|
||||
{0x00016048, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
|
||||
{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
{0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
|
||||
{0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
|
||||
{0x00016448, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
|
||||
{0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
{0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
|
||||
{0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
|
||||
{0x00016848, 0x61200001, 0x61200001, 0x66480001, 0x66480001},
|
||||
{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
|
||||
};
|
||||
|
||||
|
@ -17,8 +17,9 @@
|
||||
#include "hw.h"
|
||||
#include "hw-ops.h"
|
||||
#include "ar9003_phy.h"
|
||||
#include "ar9003_rtt.h"
|
||||
|
||||
#define MAX_MEASUREMENT 8
|
||||
#define MAX_MEASUREMENT MAX_IQCAL_MEASUREMENT
|
||||
#define MAX_MAG_DELTA 11
|
||||
#define MAX_PHS_DELTA 10
|
||||
|
||||
@ -659,10 +660,12 @@ static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
|
||||
|
||||
static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
|
||||
u8 num_chains,
|
||||
struct coeff *coeff)
|
||||
struct coeff *coeff,
|
||||
bool is_reusable)
|
||||
{
|
||||
int i, im, nmeasurement;
|
||||
u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
|
||||
struct ath9k_hw_cal_data *caldata = ah->caldata;
|
||||
|
||||
memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
|
||||
for (i = 0; i < MAX_MEASUREMENT / 2; i++) {
|
||||
@ -712,7 +715,13 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
|
||||
REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
|
||||
AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
|
||||
coeff->iqc_coeff[0]);
|
||||
|
||||
if (caldata)
|
||||
caldata->tx_corr_coeff[im][i] =
|
||||
coeff->iqc_coeff[0];
|
||||
}
|
||||
if (caldata)
|
||||
caldata->num_measures[i] = nmeasurement;
|
||||
}
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
|
||||
@ -720,8 +729,10 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
|
||||
REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
|
||||
AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
|
||||
|
||||
return;
|
||||
if (caldata)
|
||||
caldata->done_txiqcal_once = is_reusable;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
|
||||
@ -748,7 +759,7 @@ static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
|
||||
static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah, bool is_reusable)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
|
||||
@ -837,7 +848,8 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
|
||||
coeff.phs_coeff[i][im] -= 128;
|
||||
}
|
||||
}
|
||||
ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff);
|
||||
ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains,
|
||||
&coeff, is_reusable);
|
||||
|
||||
return;
|
||||
|
||||
@ -845,11 +857,129 @@ tx_iqcal_fail:
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah)
|
||||
{
|
||||
struct ath9k_hw_cal_data *caldata = ah->caldata;
|
||||
u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
|
||||
int i, im;
|
||||
|
||||
memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
|
||||
for (i = 0; i < MAX_MEASUREMENT / 2; i++) {
|
||||
tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] =
|
||||
AR_PHY_TX_IQCAL_CORR_COEFF_B0(i);
|
||||
if (!AR_SREV_9485(ah)) {
|
||||
tx_corr_coeff[i * 2][1] =
|
||||
tx_corr_coeff[(i * 2) + 1][1] =
|
||||
AR_PHY_TX_IQCAL_CORR_COEFF_B1(i);
|
||||
|
||||
tx_corr_coeff[i * 2][2] =
|
||||
tx_corr_coeff[(i * 2) + 1][2] =
|
||||
AR_PHY_TX_IQCAL_CORR_COEFF_B2(i);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
|
||||
if (!(ah->txchainmask & (1 << i)))
|
||||
continue;
|
||||
|
||||
for (im = 0; im < caldata->num_measures[i]; im++) {
|
||||
if ((im % 2) == 0)
|
||||
REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
|
||||
AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
|
||||
caldata->tx_corr_coeff[im][i]);
|
||||
else
|
||||
REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
|
||||
AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
|
||||
caldata->tx_corr_coeff[im][i]);
|
||||
}
|
||||
}
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
|
||||
AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
|
||||
AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
|
||||
}
|
||||
|
||||
static bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath9k_rtt_hist *hist;
|
||||
u32 *table;
|
||||
int i;
|
||||
bool restore;
|
||||
|
||||
if (!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT) || !ah->caldata)
|
||||
return false;
|
||||
|
||||
hist = &ah->caldata->rtt_hist;
|
||||
ar9003_hw_rtt_enable(ah);
|
||||
ar9003_hw_rtt_set_mask(ah, 0x10);
|
||||
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
|
||||
if (!(ah->rxchainmask & (1 << i)))
|
||||
continue;
|
||||
table = &hist->table[i][hist->num_readings][0];
|
||||
ar9003_hw_rtt_load_hist(ah, i, table);
|
||||
}
|
||||
restore = ar9003_hw_rtt_force_restore(ah);
|
||||
ar9003_hw_rtt_disable(ah);
|
||||
|
||||
return restore;
|
||||
}
|
||||
|
||||
static bool ar9003_hw_init_cal(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
bool txiqcal_done = false;
|
||||
struct ath9k_hw_cal_data *caldata = ah->caldata;
|
||||
bool txiqcal_done = false, txclcal_done = false;
|
||||
bool is_reusable = true, status = true;
|
||||
bool run_rtt_cal = false, run_agc_cal;
|
||||
bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT);
|
||||
u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL |
|
||||
AR_PHY_AGC_CONTROL_FLTR_CAL |
|
||||
AR_PHY_AGC_CONTROL_PKDET_CAL;
|
||||
int i, j;
|
||||
u32 cl_idx[AR9300_MAX_CHAINS] = { AR_PHY_CL_TAB_0,
|
||||
AR_PHY_CL_TAB_1,
|
||||
AR_PHY_CL_TAB_2 };
|
||||
|
||||
if (rtt) {
|
||||
if (!ar9003_hw_rtt_restore(ah, chan))
|
||||
run_rtt_cal = true;
|
||||
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE, "RTT restore %s\n",
|
||||
run_rtt_cal ? "failed" : "succeed");
|
||||
}
|
||||
run_agc_cal = run_rtt_cal;
|
||||
|
||||
if (run_rtt_cal) {
|
||||
ar9003_hw_rtt_enable(ah);
|
||||
ar9003_hw_rtt_set_mask(ah, 0x00);
|
||||
ar9003_hw_rtt_clear_hist(ah);
|
||||
}
|
||||
|
||||
if (rtt && !run_rtt_cal) {
|
||||
agc_ctrl = REG_READ(ah, AR_PHY_AGC_CONTROL);
|
||||
agc_supp_cals &= agc_ctrl;
|
||||
agc_ctrl &= ~(AR_PHY_AGC_CONTROL_OFFSET_CAL |
|
||||
AR_PHY_AGC_CONTROL_FLTR_CAL |
|
||||
AR_PHY_AGC_CONTROL_PKDET_CAL);
|
||||
REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl);
|
||||
}
|
||||
|
||||
if (ah->enabled_cals & TX_CL_CAL) {
|
||||
if (caldata && caldata->done_txclcal_once)
|
||||
REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL,
|
||||
AR_PHY_CL_CAL_ENABLE);
|
||||
else {
|
||||
REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL,
|
||||
AR_PHY_CL_CAL_ENABLE);
|
||||
run_agc_cal = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(ah->enabled_cals & TX_IQ_CAL))
|
||||
goto skip_tx_iqcal;
|
||||
|
||||
/* Do Tx IQ Calibration */
|
||||
REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
|
||||
@ -860,30 +990,96 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
|
||||
* For AR9485 or later chips, TxIQ cal runs as part of
|
||||
* AGC calibration
|
||||
*/
|
||||
if (AR_SREV_9485_OR_LATER(ah))
|
||||
txiqcal_done = true;
|
||||
else {
|
||||
txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
|
||||
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
|
||||
udelay(5);
|
||||
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
|
||||
if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
|
||||
if (caldata && !caldata->done_txiqcal_once)
|
||||
REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
|
||||
AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
|
||||
else
|
||||
REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0,
|
||||
AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL);
|
||||
txiqcal_done = run_agc_cal = true;
|
||||
goto skip_tx_iqcal;
|
||||
} else if (caldata && !caldata->done_txiqcal_once)
|
||||
run_agc_cal = true;
|
||||
|
||||
txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
|
||||
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
|
||||
udelay(5);
|
||||
REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
|
||||
|
||||
skip_tx_iqcal:
|
||||
if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
|
||||
/* Calibrate the AGC */
|
||||
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
|
||||
REG_READ(ah, AR_PHY_AGC_CONTROL) |
|
||||
AR_PHY_AGC_CONTROL_CAL);
|
||||
|
||||
/* Poll for offset calibration complete */
|
||||
status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
|
||||
AR_PHY_AGC_CONTROL_CAL,
|
||||
0, AH_WAIT_TIMEOUT);
|
||||
}
|
||||
if (rtt && !run_rtt_cal) {
|
||||
agc_ctrl |= agc_supp_cals;
|
||||
REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl);
|
||||
}
|
||||
|
||||
/* Calibrate the AGC */
|
||||
REG_WRITE(ah, AR_PHY_AGC_CONTROL,
|
||||
REG_READ(ah, AR_PHY_AGC_CONTROL) |
|
||||
AR_PHY_AGC_CONTROL_CAL);
|
||||
if (!status) {
|
||||
if (run_rtt_cal)
|
||||
ar9003_hw_rtt_disable(ah);
|
||||
|
||||
/* Poll for offset calibration complete */
|
||||
if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
|
||||
0, AH_WAIT_TIMEOUT)) {
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"offset calibration failed to complete in 1ms; noisy environment?\n");
|
||||
"offset calibration failed to complete in 1ms;"
|
||||
"noisy environment?\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (txiqcal_done)
|
||||
ar9003_hw_tx_iq_cal_post_proc(ah);
|
||||
ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable);
|
||||
else if (caldata && caldata->done_txiqcal_once)
|
||||
ar9003_hw_tx_iq_cal_reload(ah);
|
||||
|
||||
#define CL_TAB_ENTRY(reg_base) (reg_base + (4 * j))
|
||||
if (caldata && (ah->enabled_cals & TX_CL_CAL)) {
|
||||
txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) &
|
||||
AR_PHY_AGC_CONTROL_CLC_SUCCESS);
|
||||
if (caldata->done_txclcal_once) {
|
||||
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
|
||||
if (!(ah->txchainmask & (1 << i)))
|
||||
continue;
|
||||
for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
|
||||
REG_WRITE(ah, CL_TAB_ENTRY(cl_idx[i]),
|
||||
caldata->tx_clcal[i][j]);
|
||||
}
|
||||
} else if (is_reusable && txclcal_done) {
|
||||
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
|
||||
if (!(ah->txchainmask & (1 << i)))
|
||||
continue;
|
||||
for (j = 0; j < MAX_CL_TAB_ENTRY; j++)
|
||||
caldata->tx_clcal[i][j] =
|
||||
REG_READ(ah,
|
||||
CL_TAB_ENTRY(cl_idx[i]));
|
||||
}
|
||||
caldata->done_txclcal_once = true;
|
||||
}
|
||||
}
|
||||
#undef CL_TAB_ENTRY
|
||||
|
||||
if (run_rtt_cal && caldata) {
|
||||
struct ath9k_rtt_hist *hist = &caldata->rtt_hist;
|
||||
if (is_reusable && (hist->num_readings < RTT_HIST_MAX)) {
|
||||
u32 *table;
|
||||
|
||||
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
|
||||
if (!(ah->rxchainmask & (1 << i)))
|
||||
continue;
|
||||
table = &hist->table[i][hist->num_readings][0];
|
||||
ar9003_hw_rtt_fill_hist(ah, i, table);
|
||||
}
|
||||
}
|
||||
|
||||
ar9003_hw_rtt_disable(ah);
|
||||
}
|
||||
|
||||
ath9k_hw_loadnf(ah, chan);
|
||||
ath9k_hw_start_nfcal(ah, true);
|
||||
@ -912,8 +1108,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
|
||||
if (ah->cal_list_curr)
|
||||
ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
|
||||
|
||||
if (ah->caldata)
|
||||
ah->caldata->CalValid = 0;
|
||||
if (caldata)
|
||||
caldata->CalValid = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -2995,8 +2995,6 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
|
||||
return get_unaligned_be16(eep->macAddr + 4);
|
||||
case EEP_REG_0:
|
||||
return le16_to_cpu(pBase->regDmn[0]);
|
||||
case EEP_REG_1:
|
||||
return le16_to_cpu(pBase->regDmn[1]);
|
||||
case EEP_OP_CAP:
|
||||
return pBase->deviceCap;
|
||||
case EEP_OP_MODE:
|
||||
@ -3021,6 +3019,10 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
|
||||
return (pBase->miscConfiguration >> 0x3) & 0x1;
|
||||
case EEP_ANT_DIV_CTL1:
|
||||
return eep->base_ext1.ant_div_control;
|
||||
case EEP_ANTENNA_GAIN_5G:
|
||||
return eep->modalHeader5G.antennaGain;
|
||||
case EEP_ANTENNA_GAIN_2G:
|
||||
return eep->modalHeader2G.antennaGain;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -3554,7 +3556,7 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
|
||||
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
|
||||
REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
|
||||
else if (AR_SREV_9480(ah))
|
||||
else if (AR_SREV_9462(ah))
|
||||
REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
|
||||
else {
|
||||
REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
|
||||
@ -3633,20 +3635,20 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
|
||||
|
||||
u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
|
||||
|
||||
if (AR_SREV_9480(ah)) {
|
||||
if (AR_SREV_9480_10(ah)) {
|
||||
if (AR_SREV_9462(ah)) {
|
||||
if (AR_SREV_9462_10(ah)) {
|
||||
value &= ~AR_SWITCH_TABLE_COM_SPDT;
|
||||
value |= 0x00100000;
|
||||
}
|
||||
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
|
||||
AR_SWITCH_TABLE_COM_AR9480_ALL, value);
|
||||
AR_SWITCH_TABLE_COM_AR9462_ALL, value);
|
||||
} else
|
||||
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
|
||||
AR_SWITCH_TABLE_COM_ALL, value);
|
||||
|
||||
|
||||
/*
|
||||
* AR9480 defines new switch table for BT/WLAN,
|
||||
* AR9462 defines new switch table for BT/WLAN,
|
||||
* here's new field name in XXX.ref for both 2G and 5G.
|
||||
* Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
|
||||
* 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX
|
||||
@ -3658,7 +3660,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
|
||||
* 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
|
||||
* SWITCH_TABLE_COM_SPDT_WLAN_IDLE
|
||||
*/
|
||||
if (AR_SREV_9480_20_OR_LATER(ah)) {
|
||||
if (AR_SREV_9462_20_OR_LATER(ah)) {
|
||||
value = ar9003_switch_com_spdt_get(ah, is2ghz);
|
||||
REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
|
||||
AR_SWITCH_TABLE_COM_SPDT_ALL, value);
|
||||
@ -3907,7 +3909,7 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
|
||||
REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
|
||||
if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
|
||||
return;
|
||||
} else if (AR_SREV_9480(ah)) {
|
||||
} else if (AR_SREV_9462(ah)) {
|
||||
reg_val = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
|
||||
REG_WRITE(ah, AR_PHY_PMU1, reg_val);
|
||||
} else {
|
||||
@ -3938,7 +3940,7 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
|
||||
while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
|
||||
AR_PHY_PMU2_PGM))
|
||||
udelay(10);
|
||||
} else if (AR_SREV_9480(ah))
|
||||
} else if (AR_SREV_9462(ah))
|
||||
REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
|
||||
else {
|
||||
reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) |
|
||||
@ -4525,7 +4527,7 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah,
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
|
||||
|
||||
if (AR_SREV_9480_20(ah))
|
||||
if (AR_SREV_9462_20(ah))
|
||||
REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
|
||||
AR_PHY_TPC_19_B1_ALPHA_THERM, tempSlope);
|
||||
|
||||
@ -4764,20 +4766,14 @@ static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
|
||||
static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
u8 *pPwrArray, u16 cfgCtl,
|
||||
u8 twiceAntennaReduction,
|
||||
u8 twiceMaxRegulatoryPower,
|
||||
u8 antenna_reduction,
|
||||
u16 powerLimit)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
|
||||
u16 twiceMaxEdgePower = MAX_RATE_POWER;
|
||||
static const u16 tpScaleReductionTable[5] = {
|
||||
0, 3, 6, 9, MAX_RATE_POWER
|
||||
};
|
||||
int i;
|
||||
int16_t twiceLargestAntenna;
|
||||
u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
|
||||
u16 scaledPower = 0, minCtlPower;
|
||||
static const u16 ctlModesFor11a[] = {
|
||||
CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
|
||||
};
|
||||
@ -4795,28 +4791,7 @@ static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
|
||||
bool is2ghz = IS_CHAN_2GHZ(chan);
|
||||
|
||||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
|
||||
/* Compute TxPower reduction due to Antenna Gain */
|
||||
if (is2ghz)
|
||||
twiceLargestAntenna = pEepData->modalHeader2G.antennaGain;
|
||||
else
|
||||
twiceLargestAntenna = pEepData->modalHeader5G.antennaGain;
|
||||
|
||||
twiceLargestAntenna = (int16_t)min((twiceAntennaReduction) -
|
||||
twiceLargestAntenna, 0);
|
||||
|
||||
/*
|
||||
* scaledPower is the minimum of the user input power level
|
||||
* and the regulatory allowed power level
|
||||
*/
|
||||
maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
|
||||
|
||||
if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
|
||||
maxRegAllowedPower -=
|
||||
(tpScaleReductionTable[(regulatory->tp_scale)] * 2);
|
||||
}
|
||||
|
||||
scaledPower = min(powerLimit, maxRegAllowedPower);
|
||||
scaledPower = powerLimit - antenna_reduction;
|
||||
|
||||
/*
|
||||
* Reduce scaled Power by number of chains active to get
|
||||
@ -5003,7 +4978,6 @@ static inline u8 mcsidx_to_tgtpwridx(unsigned int mcs_idx, u8 base_pwridx)
|
||||
static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan, u16 cfgCtl,
|
||||
u8 twiceAntennaReduction,
|
||||
u8 twiceMaxRegulatoryPower,
|
||||
u8 powerLimit, bool test)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
@ -5056,7 +5030,6 @@ static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
|
||||
ar9003_hw_set_power_per_rate_table(ah, chan,
|
||||
targetPowerValT2, cfgCtl,
|
||||
twiceAntennaReduction,
|
||||
twiceMaxRegulatoryPower,
|
||||
powerLimit);
|
||||
|
||||
if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) {
|
||||
|
@ -22,8 +22,8 @@
|
||||
#include "ar9330_1p1_initvals.h"
|
||||
#include "ar9330_1p2_initvals.h"
|
||||
#include "ar9580_1p0_initvals.h"
|
||||
#include "ar9480_1p0_initvals.h"
|
||||
#include "ar9480_2p0_initvals.h"
|
||||
#include "ar9462_1p0_initvals.h"
|
||||
#include "ar9462_2p0_initvals.h"
|
||||
|
||||
/* General hardware code for the AR9003 hadware family */
|
||||
|
||||
@ -35,13 +35,13 @@
|
||||
static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
{
|
||||
#define PCIE_PLL_ON_CREQ_DIS_L1_2P0 \
|
||||
ar9480_pciephy_pll_on_clkreq_disable_L1_2p0
|
||||
ar9462_pciephy_pll_on_clkreq_disable_L1_2p0
|
||||
|
||||
#define AR9480_BB_CTX_COEFJ(x) \
|
||||
ar9480_##x##_baseband_core_txfir_coeff_japan_2484
|
||||
#define AR9462_BB_CTX_COEFJ(x) \
|
||||
ar9462_##x##_baseband_core_txfir_coeff_japan_2484
|
||||
|
||||
#define AR9480_BBC_TXIFR_COEFFJ \
|
||||
ar9480_2p0_baseband_core_txfir_coeff_japan_2484
|
||||
#define AR9462_BBC_TXIFR_COEFFJ \
|
||||
ar9462_2p0_baseband_core_txfir_coeff_japan_2484
|
||||
if (AR_SREV_9330_11(ah)) {
|
||||
/* mac */
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
|
||||
@ -264,107 +264,107 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
ar9485_1_1_pcie_phy_clkreq_disable_L1,
|
||||
ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
|
||||
2);
|
||||
} else if (AR_SREV_9480_10(ah)) {
|
||||
} else if (AR_SREV_9462_10(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9480_1p0_mac_core,
|
||||
ARRAY_SIZE(ar9480_1p0_mac_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_1p0_mac_core,
|
||||
ARRAY_SIZE(ar9462_1p0_mac_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
|
||||
ar9480_1p0_mac_postamble,
|
||||
ARRAY_SIZE(ar9480_1p0_mac_postamble),
|
||||
ar9462_1p0_mac_postamble,
|
||||
ARRAY_SIZE(ar9462_1p0_mac_postamble),
|
||||
5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
|
||||
ar9480_1p0_baseband_core,
|
||||
ARRAY_SIZE(ar9480_1p0_baseband_core),
|
||||
ar9462_1p0_baseband_core,
|
||||
ARRAY_SIZE(ar9462_1p0_baseband_core),
|
||||
2);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
|
||||
ar9480_1p0_baseband_postamble,
|
||||
ARRAY_SIZE(ar9480_1p0_baseband_postamble), 5);
|
||||
ar9462_1p0_baseband_postamble,
|
||||
ARRAY_SIZE(ar9462_1p0_baseband_postamble), 5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
|
||||
ar9480_1p0_radio_core,
|
||||
ARRAY_SIZE(ar9480_1p0_radio_core), 2);
|
||||
ar9462_1p0_radio_core,
|
||||
ARRAY_SIZE(ar9462_1p0_radio_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
|
||||
ar9480_1p0_radio_postamble,
|
||||
ARRAY_SIZE(ar9480_1p0_radio_postamble), 5);
|
||||
ar9462_1p0_radio_postamble,
|
||||
ARRAY_SIZE(ar9462_1p0_radio_postamble), 5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
|
||||
ar9480_1p0_soc_preamble,
|
||||
ARRAY_SIZE(ar9480_1p0_soc_preamble), 2);
|
||||
ar9462_1p0_soc_preamble,
|
||||
ARRAY_SIZE(ar9462_1p0_soc_preamble), 2);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
|
||||
ar9480_1p0_soc_postamble,
|
||||
ARRAY_SIZE(ar9480_1p0_soc_postamble), 5);
|
||||
ar9462_1p0_soc_postamble,
|
||||
ARRAY_SIZE(ar9462_1p0_soc_postamble), 5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9480_common_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9480_common_rx_gain_table_1p0), 2);
|
||||
ar9462_common_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9462_common_rx_gain_table_1p0), 2);
|
||||
|
||||
/* Awake -> Sleep Setting */
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
ar9480_pcie_phy_clkreq_disable_L1_1p0,
|
||||
ARRAY_SIZE(ar9480_pcie_phy_clkreq_disable_L1_1p0),
|
||||
ar9462_pcie_phy_clkreq_disable_L1_1p0,
|
||||
ARRAY_SIZE(ar9462_pcie_phy_clkreq_disable_L1_1p0),
|
||||
2);
|
||||
|
||||
/* Sleep -> Awake Setting */
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
|
||||
ar9480_pcie_phy_clkreq_disable_L1_1p0,
|
||||
ARRAY_SIZE(ar9480_pcie_phy_clkreq_disable_L1_1p0),
|
||||
ar9462_pcie_phy_clkreq_disable_L1_1p0,
|
||||
ARRAY_SIZE(ar9462_pcie_phy_clkreq_disable_L1_1p0),
|
||||
2);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
ar9480_modes_fast_clock_1p0,
|
||||
ARRAY_SIZE(ar9480_modes_fast_clock_1p0), 3);
|
||||
ar9462_modes_fast_clock_1p0,
|
||||
ARRAY_SIZE(ar9462_modes_fast_clock_1p0), 3);
|
||||
INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
|
||||
AR9480_BB_CTX_COEFJ(1p0),
|
||||
ARRAY_SIZE(AR9480_BB_CTX_COEFJ(1p0)), 2);
|
||||
AR9462_BB_CTX_COEFJ(1p0),
|
||||
ARRAY_SIZE(AR9462_BB_CTX_COEFJ(1p0)), 2);
|
||||
|
||||
} else if (AR_SREV_9480_20(ah)) {
|
||||
} else if (AR_SREV_9462_20(ah)) {
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9480_2p0_mac_core,
|
||||
ARRAY_SIZE(ar9480_2p0_mac_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core,
|
||||
ARRAY_SIZE(ar9462_2p0_mac_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
|
||||
ar9480_2p0_mac_postamble,
|
||||
ARRAY_SIZE(ar9480_2p0_mac_postamble), 5);
|
||||
ar9462_2p0_mac_postamble,
|
||||
ARRAY_SIZE(ar9462_2p0_mac_postamble), 5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
|
||||
ar9480_2p0_baseband_core,
|
||||
ARRAY_SIZE(ar9480_2p0_baseband_core), 2);
|
||||
ar9462_2p0_baseband_core,
|
||||
ARRAY_SIZE(ar9462_2p0_baseband_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
|
||||
ar9480_2p0_baseband_postamble,
|
||||
ARRAY_SIZE(ar9480_2p0_baseband_postamble), 5);
|
||||
ar9462_2p0_baseband_postamble,
|
||||
ARRAY_SIZE(ar9462_2p0_baseband_postamble), 5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
|
||||
ar9480_2p0_radio_core,
|
||||
ARRAY_SIZE(ar9480_2p0_radio_core), 2);
|
||||
ar9462_2p0_radio_core,
|
||||
ARRAY_SIZE(ar9462_2p0_radio_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
|
||||
ar9480_2p0_radio_postamble,
|
||||
ARRAY_SIZE(ar9480_2p0_radio_postamble), 5);
|
||||
ar9462_2p0_radio_postamble,
|
||||
ARRAY_SIZE(ar9462_2p0_radio_postamble), 5);
|
||||
INIT_INI_ARRAY(&ah->ini_radio_post_sys2ant,
|
||||
ar9480_2p0_radio_postamble_sys2ant,
|
||||
ARRAY_SIZE(ar9480_2p0_radio_postamble_sys2ant),
|
||||
ar9462_2p0_radio_postamble_sys2ant,
|
||||
ARRAY_SIZE(ar9462_2p0_radio_postamble_sys2ant),
|
||||
5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
|
||||
ar9480_2p0_soc_preamble,
|
||||
ARRAY_SIZE(ar9480_2p0_soc_preamble), 2);
|
||||
ar9462_2p0_soc_preamble,
|
||||
ARRAY_SIZE(ar9462_2p0_soc_preamble), 2);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
|
||||
ar9480_2p0_soc_postamble,
|
||||
ARRAY_SIZE(ar9480_2p0_soc_postamble), 5);
|
||||
ar9462_2p0_soc_postamble,
|
||||
ARRAY_SIZE(ar9462_2p0_soc_postamble), 5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9480_common_rx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9480_common_rx_gain_table_2p0), 2);
|
||||
ar9462_common_rx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9462_common_rx_gain_table_2p0), 2);
|
||||
|
||||
INIT_INI_ARRAY(&ah->ini_BTCOEX_MAX_TXPWR,
|
||||
ar9480_2p0_BTCOEX_MAX_TXPWR_table,
|
||||
ARRAY_SIZE(ar9480_2p0_BTCOEX_MAX_TXPWR_table),
|
||||
ar9462_2p0_BTCOEX_MAX_TXPWR_table,
|
||||
ARRAY_SIZE(ar9462_2p0_BTCOEX_MAX_TXPWR_table),
|
||||
2);
|
||||
|
||||
/* Awake -> Sleep Setting */
|
||||
@ -380,15 +380,15 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
|
||||
/* Fast clock modal settings */
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
ar9480_modes_fast_clock_2p0,
|
||||
ARRAY_SIZE(ar9480_modes_fast_clock_2p0), 3);
|
||||
ar9462_modes_fast_clock_2p0,
|
||||
ARRAY_SIZE(ar9462_modes_fast_clock_2p0), 3);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
|
||||
AR9480_BB_CTX_COEFJ(2p0),
|
||||
ARRAY_SIZE(AR9480_BB_CTX_COEFJ(2p0)), 2);
|
||||
AR9462_BB_CTX_COEFJ(2p0),
|
||||
ARRAY_SIZE(AR9462_BB_CTX_COEFJ(2p0)), 2);
|
||||
|
||||
INIT_INI_ARRAY(&ah->ini_japan2484, AR9480_BBC_TXIFR_COEFFJ,
|
||||
ARRAY_SIZE(AR9480_BBC_TXIFR_COEFFJ), 2);
|
||||
INIT_INI_ARRAY(&ah->ini_japan2484, AR9462_BBC_TXIFR_COEFFJ,
|
||||
ARRAY_SIZE(AR9462_BBC_TXIFR_COEFFJ), 2);
|
||||
|
||||
} else if (AR_SREV_9580(ah)) {
|
||||
/* mac */
|
||||
@ -537,15 +537,15 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah)
|
||||
ar9580_1p0_lowest_ob_db_tx_gain_table,
|
||||
ARRAY_SIZE(ar9580_1p0_lowest_ob_db_tx_gain_table),
|
||||
5);
|
||||
else if (AR_SREV_9480_10(ah))
|
||||
else if (AR_SREV_9462_10(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9480_modes_low_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9480_modes_low_ob_db_tx_gain_table_1p0),
|
||||
ar9462_modes_low_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9462_modes_low_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
else if (AR_SREV_9480_20(ah))
|
||||
else if (AR_SREV_9462_20(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9480_modes_low_ob_db_tx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9480_modes_low_ob_db_tx_gain_table_2p0),
|
||||
ar9462_modes_low_ob_db_tx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9462_modes_low_ob_db_tx_gain_table_2p0),
|
||||
5);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
@ -581,15 +581,15 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah)
|
||||
ar9580_1p0_high_ob_db_tx_gain_table,
|
||||
ARRAY_SIZE(ar9580_1p0_high_ob_db_tx_gain_table),
|
||||
5);
|
||||
else if (AR_SREV_9480_10(ah))
|
||||
else if (AR_SREV_9462_10(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9480_modes_high_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9480_modes_high_ob_db_tx_gain_table_1p0),
|
||||
ar9462_modes_high_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9462_modes_high_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
else if (AR_SREV_9480_20(ah))
|
||||
else if (AR_SREV_9462_20(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9480_modes_high_ob_db_tx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9480_modes_high_ob_db_tx_gain_table_2p0),
|
||||
ar9462_modes_high_ob_db_tx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9462_modes_high_ob_db_tx_gain_table_2p0),
|
||||
5);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
@ -712,15 +712,15 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
|
||||
ar9580_1p0_rx_gain_table,
|
||||
ARRAY_SIZE(ar9580_1p0_rx_gain_table),
|
||||
2);
|
||||
else if (AR_SREV_9480_10(ah))
|
||||
else if (AR_SREV_9462_10(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9480_common_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9480_common_rx_gain_table_1p0),
|
||||
ar9462_common_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9462_common_rx_gain_table_1p0),
|
||||
2);
|
||||
else if (AR_SREV_9480_20(ah))
|
||||
else if (AR_SREV_9462_20(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9480_common_rx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9480_common_rx_gain_table_2p0),
|
||||
ar9462_common_rx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9462_common_rx_gain_table_2p0),
|
||||
2);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
@ -751,15 +751,15 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
|
||||
ar9485Common_wo_xlna_rx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
|
||||
2);
|
||||
else if (AR_SREV_9480_10(ah))
|
||||
else if (AR_SREV_9462_10(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9480_common_wo_xlna_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9480_common_wo_xlna_rx_gain_table_1p0),
|
||||
ar9462_common_wo_xlna_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9462_common_wo_xlna_rx_gain_table_1p0),
|
||||
2);
|
||||
else if (AR_SREV_9480_20(ah))
|
||||
else if (AR_SREV_9462_20(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9480_common_wo_xlna_rx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9480_common_wo_xlna_rx_gain_table_2p0),
|
||||
ar9462_common_wo_xlna_rx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9462_common_wo_xlna_rx_gain_table_2p0),
|
||||
2);
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
@ -775,14 +775,14 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
|
||||
|
||||
static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9480_10(ah))
|
||||
if (AR_SREV_9462_10(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9480_common_mixed_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9480_common_mixed_rx_gain_table_1p0), 2);
|
||||
else if (AR_SREV_9480_20(ah))
|
||||
ar9462_common_mixed_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9462_common_mixed_rx_gain_table_1p0), 2);
|
||||
else if (AR_SREV_9462_20(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9480_common_mixed_rx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9480_common_mixed_rx_gain_table_2p0), 2);
|
||||
ar9462_common_mixed_rx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9462_common_mixed_rx_gain_table_2p0), 2);
|
||||
}
|
||||
|
||||
static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
|
||||
|
@ -525,8 +525,8 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
|
||||
rxs->rs_status |= ATH9K_RXERR_DECRYPT;
|
||||
else if (rxsp->status11 & AR_MichaelErr)
|
||||
rxs->rs_status |= ATH9K_RXERR_MIC;
|
||||
else if (rxsp->status11 & AR_KeyMiss)
|
||||
rxs->rs_status |= ATH9K_RXERR_DECRYPT;
|
||||
if (rxsp->status11 & AR_KeyMiss)
|
||||
rxs->rs_status |= ATH9K_RXERR_KEYMISS;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
void ar9003_paprd_enable(struct ath_hw *ah, bool val)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
|
||||
|
||||
@ -54,13 +53,7 @@ void ar9003_paprd_enable(struct ath_hw *ah, bool val)
|
||||
|
||||
if (val) {
|
||||
ah->paprd_table_write_done = true;
|
||||
|
||||
ah->eep_ops->set_txpower(ah, chan,
|
||||
ath9k_regd_get_ctl(regulatory, chan),
|
||||
chan->chan->max_antenna_gain * 2,
|
||||
chan->chan->max_power * 2,
|
||||
min((u32) MAX_RATE_POWER,
|
||||
(u32) regulatory->power_limit), false);
|
||||
ath9k_hw_apply_txpower(ah, chan);
|
||||
}
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
|
||||
@ -207,7 +200,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
|
||||
AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
|
||||
AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1);
|
||||
val = AR_SREV_9480(ah) ? 0x91 : 147;
|
||||
val = AR_SREV_9462(ah) ? 0x91 : 147;
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL2,
|
||||
AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, val);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
|
||||
@ -218,7 +211,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
|
||||
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
|
||||
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1);
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9480(ah))
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9462(ah))
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
|
||||
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
|
||||
-3);
|
||||
@ -226,7 +219,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
|
||||
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
|
||||
-6);
|
||||
val = AR_SREV_9480(ah) ? -10 : -15;
|
||||
val = AR_SREV_9462(ah) ? -10 : -15;
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
|
||||
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE,
|
||||
val);
|
||||
|
@ -559,7 +559,7 @@ static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
|
||||
|
||||
if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7))
|
||||
REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
|
||||
else if (AR_SREV_9480(ah))
|
||||
else if (AR_SREV_9462(ah))
|
||||
/* xxx only when MCI support is enabled */
|
||||
REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
|
||||
else
|
||||
@ -631,9 +631,7 @@ static void ar9003_hw_prog_ini(struct ath_hw *ah,
|
||||
static int ar9003_hw_process_ini(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
unsigned int regWrites = 0, i;
|
||||
struct ieee80211_channel *channel = chan->chan;
|
||||
u32 modesIndex;
|
||||
|
||||
switch (chan->chanmode) {
|
||||
@ -664,7 +662,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
|
||||
ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex);
|
||||
ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex);
|
||||
ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex);
|
||||
if (i == ATH_INI_POST && AR_SREV_9480_20(ah))
|
||||
if (i == ATH_INI_POST && AR_SREV_9462_20(ah))
|
||||
ar9003_hw_prog_ini(ah,
|
||||
&ah->ini_radio_post_sys2ant,
|
||||
modesIndex);
|
||||
@ -687,20 +685,27 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
|
||||
if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
|
||||
REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites);
|
||||
|
||||
if (AR_SREV_9480(ah))
|
||||
if (AR_SREV_9462(ah))
|
||||
ar9003_hw_prog_ini(ah, &ah->ini_BTCOEX_MAX_TXPWR, 1);
|
||||
|
||||
ah->modes_index = modesIndex;
|
||||
ar9003_hw_override_ini(ah);
|
||||
ar9003_hw_set_channel_regs(ah, chan);
|
||||
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
|
||||
ath9k_hw_apply_txpower(ah, chan);
|
||||
|
||||
/* Set TX power */
|
||||
ah->eep_ops->set_txpower(ah, chan,
|
||||
ath9k_regd_get_ctl(regulatory, chan),
|
||||
channel->max_antenna_gain * 2,
|
||||
channel->max_power * 2,
|
||||
min((u32) MAX_RATE_POWER,
|
||||
(u32) regulatory->power_limit), false);
|
||||
if (AR_SREV_9462(ah)) {
|
||||
if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0,
|
||||
AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL))
|
||||
ah->enabled_cals |= TX_IQ_CAL;
|
||||
else
|
||||
ah->enabled_cals &= ~TX_IQ_CAL;
|
||||
|
||||
if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE)
|
||||
ah->enabled_cals |= TX_CL_CAL;
|
||||
else
|
||||
ah->enabled_cals &= ~TX_CL_CAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1256,6 +1261,73 @@ static void ar9003_hw_antdiv_comb_conf_set(struct ath_hw *ah,
|
||||
REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
|
||||
}
|
||||
|
||||
static int ar9003_hw_fast_chan_change(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
u8 *ini_reloaded)
|
||||
{
|
||||
unsigned int regWrites = 0;
|
||||
u32 modesIndex;
|
||||
|
||||
switch (chan->chanmode) {
|
||||
case CHANNEL_A:
|
||||
case CHANNEL_A_HT20:
|
||||
modesIndex = 1;
|
||||
break;
|
||||
case CHANNEL_A_HT40PLUS:
|
||||
case CHANNEL_A_HT40MINUS:
|
||||
modesIndex = 2;
|
||||
break;
|
||||
case CHANNEL_G:
|
||||
case CHANNEL_G_HT20:
|
||||
case CHANNEL_B:
|
||||
modesIndex = 4;
|
||||
break;
|
||||
case CHANNEL_G_HT40PLUS:
|
||||
case CHANNEL_G_HT40MINUS:
|
||||
modesIndex = 3;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (modesIndex == ah->modes_index) {
|
||||
*ini_reloaded = false;
|
||||
goto set_rfmode;
|
||||
}
|
||||
|
||||
ar9003_hw_prog_ini(ah, &ah->iniSOC[ATH_INI_POST], modesIndex);
|
||||
ar9003_hw_prog_ini(ah, &ah->iniMac[ATH_INI_POST], modesIndex);
|
||||
ar9003_hw_prog_ini(ah, &ah->iniBB[ATH_INI_POST], modesIndex);
|
||||
ar9003_hw_prog_ini(ah, &ah->iniRadio[ATH_INI_POST], modesIndex);
|
||||
if (AR_SREV_9462_20(ah))
|
||||
ar9003_hw_prog_ini(ah,
|
||||
&ah->ini_radio_post_sys2ant,
|
||||
modesIndex);
|
||||
|
||||
REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
|
||||
|
||||
/*
|
||||
* For 5GHz channels requiring Fast Clock, apply
|
||||
* different modal values.
|
||||
*/
|
||||
if (IS_CHAN_A_FAST_CLOCK(ah, chan))
|
||||
REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, regWrites);
|
||||
|
||||
if (AR_SREV_9330(ah))
|
||||
REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites);
|
||||
|
||||
if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
|
||||
REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites);
|
||||
|
||||
ah->modes_index = modesIndex;
|
||||
*ini_reloaded = true;
|
||||
|
||||
set_rfmode:
|
||||
ar9003_hw_set_rfmode(ah, chan);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
@ -1284,6 +1356,7 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
|
||||
priv_ops->do_getnf = ar9003_hw_do_getnf;
|
||||
priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
|
||||
priv_ops->set_radar_params = ar9003_hw_set_radar_params;
|
||||
priv_ops->fast_chan_change = ar9003_hw_fast_chan_change;
|
||||
|
||||
ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get;
|
||||
ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set;
|
||||
|
@ -325,10 +325,10 @@
|
||||
|
||||
#define AR_PHY_RX_OCGAIN (AR_AGC_BASE + 0x200)
|
||||
|
||||
#define AR_PHY_CCA_NOM_VAL_9300_2GHZ -110
|
||||
#define AR_PHY_CCA_NOM_VAL_9300_5GHZ -115
|
||||
#define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ -125
|
||||
#define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ -125
|
||||
#define AR_PHY_CCA_NOM_VAL_9300_2GHZ (AR_SREV_9462(ah) ? -127 : -110)
|
||||
#define AR_PHY_CCA_NOM_VAL_9300_5GHZ (AR_SREV_9462(ah) ? -127 : -115)
|
||||
#define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ (AR_SREV_9462(ah) ? -127 : -125)
|
||||
#define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ (AR_SREV_9462(ah) ? -127 : -125)
|
||||
#define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ -95
|
||||
#define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ -100
|
||||
|
||||
@ -572,6 +572,8 @@
|
||||
|
||||
#define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300)
|
||||
|
||||
#define AR_PHY_TX_IQCAL_CONTROL_0 (AR_SM_BASE + AR_SREV_9485(ah) ? \
|
||||
0x3c4 : 0x444)
|
||||
#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + AR_SREV_9485(ah) ? \
|
||||
0x3c8 : 0x448)
|
||||
#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + AR_SREV_9485(ah) ? \
|
||||
@ -582,8 +584,6 @@
|
||||
(AR_SREV_9485(ah) ? \
|
||||
0x3d0 : 0x450) + ((_i) << 2))
|
||||
#define AR_PHY_RTT_CTRL (AR_SM_BASE + 0x380)
|
||||
#define AR_PHY_RTT_TABLE_SW_INTF_B (AR_SM_BASE + 0x384)
|
||||
#define AR_PHY_RTT_TABLE_SW_INTF_1_B0 (AR_SM_BASE + 0x388)
|
||||
|
||||
#define AR_PHY_WATCHDOG_STATUS (AR_SM_BASE + 0x5c0)
|
||||
#define AR_PHY_WATCHDOG_CTL_1 (AR_SM_BASE + 0x5c4)
|
||||
@ -608,9 +608,9 @@
|
||||
#define AR_PHY_AIC_CTRL_1_B0 (AR_SM_BASE + 0x4b4)
|
||||
#define AR_PHY_AIC_CTRL_2_B0 (AR_SM_BASE + 0x4b8)
|
||||
#define AR_PHY_AIC_CTRL_3_B0 (AR_SM_BASE + 0x4bc)
|
||||
#define AR_PHY_AIC_STAT_0_B0 (AR_SM_BASE + (AR_SREV_9480_10(ah) ? \
|
||||
#define AR_PHY_AIC_STAT_0_B0 (AR_SM_BASE + (AR_SREV_9462_10(ah) ? \
|
||||
0x4c0 : 0x4c4))
|
||||
#define AR_PHY_AIC_STAT_1_B0 (AR_SM_BASE + (AR_SREV_9480_10(ah) ? \
|
||||
#define AR_PHY_AIC_STAT_1_B0 (AR_SM_BASE + (AR_SREV_9462_10(ah) ? \
|
||||
0x4c4 : 0x4c8))
|
||||
#define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0)
|
||||
#define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc)
|
||||
@ -625,7 +625,7 @@
|
||||
#define AR_PHY_65NM_CH0_RXTX4 0x1610c
|
||||
|
||||
#define AR_CH0_TOP (AR_SREV_9300(ah) ? 0x16288 : \
|
||||
((AR_SREV_9480(ah) ? 0x1628c : 0x16280)))
|
||||
((AR_SREV_9462(ah) ? 0x1628c : 0x16280)))
|
||||
#define AR_CH0_TOP_XPABIASLVL (0x300)
|
||||
#define AR_CH0_TOP_XPABIASLVL_S (8)
|
||||
|
||||
@ -638,8 +638,8 @@
|
||||
|
||||
#define AR_SWITCH_TABLE_COM_ALL (0xffff)
|
||||
#define AR_SWITCH_TABLE_COM_ALL_S (0)
|
||||
#define AR_SWITCH_TABLE_COM_AR9480_ALL (0xffffff)
|
||||
#define AR_SWITCH_TABLE_COM_AR9480_ALL_S (0)
|
||||
#define AR_SWITCH_TABLE_COM_AR9462_ALL (0xffffff)
|
||||
#define AR_SWITCH_TABLE_COM_AR9462_ALL_S (0)
|
||||
#define AR_SWITCH_TABLE_COM_SPDT (0x00f00000)
|
||||
#define AR_SWITCH_TABLE_COM_SPDT_ALL (0x0000fff0)
|
||||
#define AR_SWITCH_TABLE_COM_SPDT_ALL_S (4)
|
||||
@ -679,11 +679,11 @@
|
||||
#define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000
|
||||
#define AR_CH0_XTAL_CAPOUTDAC_S 17
|
||||
|
||||
#define AR_PHY_PMU1 (AR_SREV_9480(ah) ? 0x16340 : 0x16c40)
|
||||
#define AR_PHY_PMU1 (AR_SREV_9462(ah) ? 0x16340 : 0x16c40)
|
||||
#define AR_PHY_PMU1_PWD 0x1
|
||||
#define AR_PHY_PMU1_PWD_S 0
|
||||
|
||||
#define AR_PHY_PMU2 (AR_SREV_9480(ah) ? 0x16344 : 0x16c44)
|
||||
#define AR_PHY_PMU2 (AR_SREV_9462(ah) ? 0x16344 : 0x16c44)
|
||||
#define AR_PHY_PMU2_PGM 0x00200000
|
||||
#define AR_PHY_PMU2_PGM_S 21
|
||||
|
||||
@ -823,6 +823,22 @@
|
||||
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000
|
||||
#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24
|
||||
#define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004
|
||||
#define AR_PHY_RTT_CTRL_ENA_RADIO_RETENTION 0x00000001
|
||||
#define AR_PHY_RTT_CTRL_ENA_RADIO_RETENTION_S 0
|
||||
#define AR_PHY_RTT_CTRL_RESTORE_MASK 0x0000007E
|
||||
#define AR_PHY_RTT_CTRL_RESTORE_MASK_S 1
|
||||
#define AR_PHY_RTT_CTRL_FORCE_RADIO_RESTORE 0x00000080
|
||||
#define AR_PHY_RTT_CTRL_FORCE_RADIO_RESTORE_S 7
|
||||
#define AR_PHY_RTT_SW_RTT_TABLE_ACCESS 0x00000001
|
||||
#define AR_PHY_RTT_SW_RTT_TABLE_ACCESS_S 0
|
||||
#define AR_PHY_RTT_SW_RTT_TABLE_WRITE 0x00000002
|
||||
#define AR_PHY_RTT_SW_RTT_TABLE_WRITE_S 1
|
||||
#define AR_PHY_RTT_SW_RTT_TABLE_ADDR 0x0000001C
|
||||
#define AR_PHY_RTT_SW_RTT_TABLE_ADDR_S 2
|
||||
#define AR_PHY_RTT_SW_RTT_TABLE_DATA 0xFFFFFFF0
|
||||
#define AR_PHY_RTT_SW_RTT_TABLE_DATA_S 4
|
||||
#define AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL 0x80000000
|
||||
#define AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL_S 31
|
||||
#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000
|
||||
#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18
|
||||
#define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001
|
||||
@ -905,9 +921,9 @@
|
||||
#define AR_PHY_AIC_CTRL_0_B1 (AR_SM1_BASE + 0x4b0)
|
||||
#define AR_PHY_AIC_CTRL_1_B1 (AR_SM1_BASE + 0x4b4)
|
||||
#define AR_PHY_AIC_CTRL_2_B1 (AR_SM1_BASE + 0x4b8)
|
||||
#define AR_PHY_AIC_STAT_0_B1 (AR_SM1_BASE + (AR_SREV_9480_10(ah) ? \
|
||||
#define AR_PHY_AIC_STAT_0_B1 (AR_SM1_BASE + (AR_SREV_9462_10(ah) ? \
|
||||
0x4c0 : 0x4c4))
|
||||
#define AR_PHY_AIC_STAT_1_B1 (AR_SM1_BASE + (AR_SREV_9480_10(ah) ? \
|
||||
#define AR_PHY_AIC_STAT_1_B1 (AR_SM1_BASE + (AR_SREV_9462_10(ah) ? \
|
||||
0x4c4 : 0x4c8))
|
||||
#define AR_PHY_AIC_CTRL_4_B1 (AR_SM1_BASE + 0x4c0)
|
||||
#define AR_PHY_AIC_STAT_2_B1 (AR_SM1_BASE + 0x4cc)
|
||||
@ -915,6 +931,10 @@
|
||||
#define AR_PHY_AIC_SRAM_ADDR_B1 (AR_SM1_BASE + 0x5f0)
|
||||
#define AR_PHY_AIC_SRAM_DATA_B1 (AR_SM1_BASE + 0x5f4)
|
||||
|
||||
#define AR_PHY_RTT_TABLE_SW_INTF_B(i) (0x384 + (i) ? \
|
||||
AR_SM1_BASE : AR_SM_BASE)
|
||||
#define AR_PHY_RTT_TABLE_SW_INTF_1_B(i) (0x388 + (i) ? \
|
||||
AR_SM1_BASE : AR_SM_BASE)
|
||||
/*
|
||||
* Channel 2 Register Map
|
||||
*/
|
||||
@ -981,7 +1001,7 @@
|
||||
#define AR_GLB_BASE 0x20000
|
||||
#define AR_PHY_GLB_CONTROL (AR_GLB_BASE + 0x44)
|
||||
#define AR_GLB_SCRATCH(_ah) (AR_GLB_BASE + \
|
||||
(AR_SREV_9480_20(_ah) ? 0x4c : 0x50))
|
||||
(AR_SREV_9462_20(_ah) ? 0x4c : 0x50))
|
||||
#define AR_GLB_STATUS (AR_GLB_BASE + 0x48)
|
||||
|
||||
/*
|
||||
|
153
drivers/net/wireless/ath/ath9k/ar9003_rtt.c
Normal file
153
drivers/net/wireless/ath/ath9k/ar9003_rtt.c
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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 "hw.h"
|
||||
#include "ar9003_phy.h"
|
||||
|
||||
#define RTT_RESTORE_TIMEOUT 1000
|
||||
#define RTT_ACCESS_TIMEOUT 100
|
||||
#define RTT_BAD_VALUE 0x0bad0bad
|
||||
|
||||
/*
|
||||
* RTT (Radio Retention Table) hardware implementation information
|
||||
*
|
||||
* There is an internal table (i.e. the rtt) for each chain (or bank).
|
||||
* Each table contains 6 entries and each entry is corresponding to
|
||||
* a specific calibration parameter as depicted below.
|
||||
* 0~2 - DC offset DAC calibration: loop, low, high (offsetI/Q_...)
|
||||
* 3 - Filter cal (filterfc)
|
||||
* 4 - RX gain settings
|
||||
* 5 - Peak detector offset calibration (agc_caldac)
|
||||
*/
|
||||
|
||||
void ar9003_hw_rtt_enable(struct ath_hw *ah)
|
||||
{
|
||||
REG_WRITE(ah, AR_PHY_RTT_CTRL, 1);
|
||||
}
|
||||
|
||||
void ar9003_hw_rtt_disable(struct ath_hw *ah)
|
||||
{
|
||||
REG_WRITE(ah, AR_PHY_RTT_CTRL, 0);
|
||||
}
|
||||
|
||||
void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask)
|
||||
{
|
||||
REG_RMW_FIELD(ah, AR_PHY_RTT_CTRL,
|
||||
AR_PHY_RTT_CTRL_RESTORE_MASK, rtt_mask);
|
||||
}
|
||||
|
||||
bool ar9003_hw_rtt_force_restore(struct ath_hw *ah)
|
||||
{
|
||||
if (!ath9k_hw_wait(ah, AR_PHY_RTT_CTRL,
|
||||
AR_PHY_RTT_CTRL_FORCE_RADIO_RESTORE,
|
||||
0, RTT_RESTORE_TIMEOUT))
|
||||
return false;
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_RTT_CTRL,
|
||||
AR_PHY_RTT_CTRL_FORCE_RADIO_RESTORE, 1);
|
||||
|
||||
if (!ath9k_hw_wait(ah, AR_PHY_RTT_CTRL,
|
||||
AR_PHY_RTT_CTRL_FORCE_RADIO_RESTORE,
|
||||
0, RTT_RESTORE_TIMEOUT))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ar9003_hw_rtt_load_hist_entry(struct ath_hw *ah, u8 chain,
|
||||
u32 index, u32 data28)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = SM(data28, AR_PHY_RTT_SW_RTT_TABLE_DATA);
|
||||
REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain), val);
|
||||
|
||||
val = SM(0, AR_PHY_RTT_SW_RTT_TABLE_ACCESS) |
|
||||
SM(1, AR_PHY_RTT_SW_RTT_TABLE_WRITE) |
|
||||
SM(index, AR_PHY_RTT_SW_RTT_TABLE_ADDR);
|
||||
REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
|
||||
udelay(1);
|
||||
|
||||
val |= SM(1, AR_PHY_RTT_SW_RTT_TABLE_ACCESS);
|
||||
REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
|
||||
udelay(1);
|
||||
|
||||
if (!ath9k_hw_wait(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain),
|
||||
AR_PHY_RTT_SW_RTT_TABLE_ACCESS, 0,
|
||||
RTT_ACCESS_TIMEOUT))
|
||||
return;
|
||||
|
||||
val &= ~SM(1, AR_PHY_RTT_SW_RTT_TABLE_WRITE);
|
||||
REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
|
||||
udelay(1);
|
||||
|
||||
ath9k_hw_wait(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain),
|
||||
AR_PHY_RTT_SW_RTT_TABLE_ACCESS, 0,
|
||||
RTT_ACCESS_TIMEOUT);
|
||||
}
|
||||
|
||||
void ar9003_hw_rtt_load_hist(struct ath_hw *ah, u8 chain, u32 *table)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++)
|
||||
ar9003_hw_rtt_load_hist_entry(ah, chain, i, table[i]);
|
||||
}
|
||||
|
||||
static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = SM(0, AR_PHY_RTT_SW_RTT_TABLE_ACCESS) |
|
||||
SM(0, AR_PHY_RTT_SW_RTT_TABLE_WRITE) |
|
||||
SM(index, AR_PHY_RTT_SW_RTT_TABLE_ADDR);
|
||||
|
||||
REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
|
||||
udelay(1);
|
||||
|
||||
val |= SM(1, AR_PHY_RTT_SW_RTT_TABLE_ACCESS);
|
||||
REG_WRITE(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain), val);
|
||||
udelay(1);
|
||||
|
||||
if (!ath9k_hw_wait(ah, AR_PHY_RTT_TABLE_SW_INTF_B(chain),
|
||||
AR_PHY_RTT_SW_RTT_TABLE_ACCESS, 0,
|
||||
RTT_ACCESS_TIMEOUT))
|
||||
return RTT_BAD_VALUE;
|
||||
|
||||
val = REG_READ(ah, AR_PHY_RTT_TABLE_SW_INTF_1_B(chain));
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void ar9003_hw_rtt_fill_hist(struct ath_hw *ah, u8 chain, u32 *table)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++)
|
||||
table[i] = ar9003_hw_rtt_fill_hist_entry(ah, chain, i);
|
||||
}
|
||||
|
||||
void ar9003_hw_rtt_clear_hist(struct ath_hw *ah)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
|
||||
if (!(ah->rxchainmask & (1 << i)))
|
||||
continue;
|
||||
for (j = 0; j < MAX_RTT_TABLE_ENTRY; j++)
|
||||
ar9003_hw_rtt_load_hist_entry(ah, i, j, 0);
|
||||
}
|
||||
}
|
28
drivers/net/wireless/ath/ath9k/ar9003_rtt.h
Normal file
28
drivers/net/wireless/ath/ath9k/ar9003_rtt.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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 AR9003_RTT_H
|
||||
#define AR9003_RTT_H
|
||||
|
||||
void ar9003_hw_rtt_enable(struct ath_hw *ah);
|
||||
void ar9003_hw_rtt_disable(struct ath_hw *ah);
|
||||
void ar9003_hw_rtt_set_mask(struct ath_hw *ah, u32 rtt_mask);
|
||||
bool ar9003_hw_rtt_force_restore(struct ath_hw *ah);
|
||||
void ar9003_hw_rtt_load_hist(struct ath_hw *ah, u8 chain, u32 *table);
|
||||
void ar9003_hw_rtt_fill_hist(struct ath_hw *ah, u8 chain, u32 *table);
|
||||
void ar9003_hw_rtt_clear_hist(struct ath_hw *ah);
|
||||
|
||||
#endif
|
@ -14,12 +14,12 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef INITVALS_9480_1P0_H
|
||||
#define INITVALS_9480_1P0_H
|
||||
#ifndef INITVALS_9462_1P0_H
|
||||
#define INITVALS_9462_1P0_H
|
||||
|
||||
/* AR9480 1.0 */
|
||||
/* AR9462 1.0 */
|
||||
|
||||
static const u32 ar9480_1p0_mac_core[][2] = {
|
||||
static const u32 ar9462_1p0_mac_core[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00000008, 0x00000000},
|
||||
{0x00000030, 0x00060085},
|
||||
@ -183,27 +183,27 @@ static const u32 ar9480_1p0_mac_core[][2] = {
|
||||
{0x000083d0, 0x000301ff},
|
||||
};
|
||||
|
||||
static const u32 ar9480_1p0_baseband_core_txfir_coeff_japan_2484[][2] = {
|
||||
static const u32 ar9462_1p0_baseband_core_txfir_coeff_japan_2484[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a398, 0x00000000},
|
||||
{0x0000a39c, 0x6f7f0301},
|
||||
{0x0000a3a0, 0xca9228ee},
|
||||
};
|
||||
|
||||
static const u32 ar9480_1p0_sys3ant[][2] = {
|
||||
static const u32 ar9462_1p0_sys3ant[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00063280, 0x00040807},
|
||||
{0x00063284, 0x104ccccc},
|
||||
};
|
||||
|
||||
static const u32 ar9480_pcie_phy_clkreq_enable_L1_1p0[][2] = {
|
||||
static const u32 ar9462_pcie_phy_clkreq_enable_L1_1p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00018c00, 0x10053e5e},
|
||||
{0x00018c04, 0x000801d8},
|
||||
{0x00018c08, 0x0000580c},
|
||||
};
|
||||
|
||||
static const u32 ar9480_1p0_mac_core_emulation[][2] = {
|
||||
static const u32 ar9462_1p0_mac_core_emulation[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00000030, 0x00060085},
|
||||
{0x00000044, 0x00000008},
|
||||
@ -211,7 +211,7 @@ static const u32 ar9480_1p0_mac_core_emulation[][2] = {
|
||||
{0x00008344, 0xaa4a105b},
|
||||
};
|
||||
|
||||
static const u32 ar9480_common_rx_gain_table_ar9280_2p0_1p0[][2] = {
|
||||
static const u32 ar9462_common_rx_gain_table_ar9280_2p0_1p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a000, 0x02000101},
|
||||
{0x0000a004, 0x02000102},
|
||||
@ -513,7 +513,7 @@ static const u32 ar9200_ar9280_2p0_radio_core_1p0[][2] = {
|
||||
{0x00007894, 0x5a108000},
|
||||
};
|
||||
|
||||
static const u32 ar9480_1p0_baseband_postamble_emulation[][5] = {
|
||||
static const u32 ar9462_1p0_baseband_postamble_emulation[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x00009e3c, 0xcf946221, 0xcf946221, 0xcf946221, 0xcf946221},
|
||||
@ -535,14 +535,14 @@ static const u32 ar9480_1p0_baseband_postamble_emulation[][5] = {
|
||||
{0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
};
|
||||
|
||||
static const u32 ar9480_pcie_phy_pll_on_clkreq_disable_L1_1p0[][2] = {
|
||||
static const u32 ar9462_pcie_phy_pll_on_clkreq_disable_L1_1p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00018c00, 0x10012e5e},
|
||||
{0x00018c04, 0x000801d8},
|
||||
{0x00018c08, 0x0000580c},
|
||||
};
|
||||
|
||||
static const u32 ar9480_common_rx_gain_table_1p0[][2] = {
|
||||
static const u32 ar9462_common_rx_gain_table_1p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a000, 0x00010000},
|
||||
{0x0000a004, 0x00030002},
|
||||
@ -802,7 +802,7 @@ static const u32 ar9480_common_rx_gain_table_1p0[][2] = {
|
||||
{0x0000b1fc, 0x00000196},
|
||||
};
|
||||
|
||||
static const u32 ar9480_modes_high_ob_db_tx_gain_table_1p0[][5] = {
|
||||
static const u32 ar9462_modes_high_ob_db_tx_gain_table_1p0[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
|
||||
@ -867,7 +867,7 @@ static const u32 ar9480_modes_high_ob_db_tx_gain_table_1p0[][5] = {
|
||||
{0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000},
|
||||
};
|
||||
|
||||
static const u32 ar9480_common_wo_xlna_rx_gain_table_1p0[][2] = {
|
||||
static const u32 ar9462_common_wo_xlna_rx_gain_table_1p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a000, 0x00010000},
|
||||
{0x0000a004, 0x00030002},
|
||||
@ -1127,7 +1127,7 @@ static const u32 ar9480_common_wo_xlna_rx_gain_table_1p0[][2] = {
|
||||
{0x0000b1fc, 0x00000196},
|
||||
};
|
||||
|
||||
static const u32 ar9480_1p0_mac_postamble[][5] = {
|
||||
static const u32 ar9462_1p0_mac_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
|
||||
{0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
|
||||
@ -1139,13 +1139,13 @@ static const u32 ar9480_1p0_mac_postamble[][5] = {
|
||||
{0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
|
||||
};
|
||||
|
||||
static const u32 ar9480_1p0_mac_postamble_emulation[][5] = {
|
||||
static const u32 ar9462_1p0_mac_postamble_emulation[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00008014, 0x10f810f8, 0x10f810f8, 0x10f810f8, 0x10f810f8},
|
||||
{0x0000801c, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017},
|
||||
};
|
||||
|
||||
static const u32 ar9480_1p0_tx_gain_table_baseband_postamble_emulation[][5] = {
|
||||
static const u32 ar9462_1p0_tx_gain_table_baseband_postamble_emulation[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0000a410, 0x000000d5, 0x000000d5, 0x000000d5, 0x000000d5},
|
||||
{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
@ -1163,7 +1163,7 @@ static const u32 ar9480_1p0_tx_gain_table_baseband_postamble_emulation[][5] = {
|
||||
{0x0000a534, 0x00034e8a, 0x00034e8a, 0x00034e8a, 0x00034e8a},
|
||||
};
|
||||
|
||||
static const u32 ar9480_1p0_radio_postamble[][5] = {
|
||||
static const u32 ar9462_1p0_radio_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524},
|
||||
{0x000160ac, 0xa4646c08, 0xa4646c08, 0x24646c08, 0x24646c08},
|
||||
@ -1174,12 +1174,12 @@ static const u32 ar9480_1p0_radio_postamble[][5] = {
|
||||
{0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
|
||||
};
|
||||
|
||||
static const u32 ar9480_1p0_soc_postamble_emulation[][5] = {
|
||||
static const u32 ar9462_1p0_soc_postamble_emulation[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00007010, 0x00001133, 0x00001133, 0x00001133, 0x00001133},
|
||||
};
|
||||
|
||||
static const u32 ar9480_1p0_baseband_core[][2] = {
|
||||
static const u32 ar9462_1p0_baseband_core[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00009800, 0xafe68e30},
|
||||
{0x00009804, 0xfd14e000},
|
||||
@ -1336,7 +1336,7 @@ static const u32 ar9480_1p0_baseband_core[][2] = {
|
||||
{0x0000b6b4, 0x00c00001},
|
||||
};
|
||||
|
||||
static const u32 ar9480_1p0_baseband_postamble[][5] = {
|
||||
static const u32 ar9462_1p0_baseband_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
|
||||
{0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
|
||||
@ -1386,7 +1386,7 @@ static const u32 ar9480_1p0_baseband_postamble[][5] = {
|
||||
{0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
|
||||
};
|
||||
|
||||
static const u32 ar9480_modes_fast_clock_1p0[][3] = {
|
||||
static const u32 ar9462_modes_fast_clock_1p0[][3] = {
|
||||
/* Addr 5G_HT20 5G_HT40 */
|
||||
{0x00001030, 0x00000268, 0x000004d0},
|
||||
{0x00001070, 0x0000018c, 0x00000318},
|
||||
@ -1399,7 +1399,7 @@ static const u32 ar9480_modes_fast_clock_1p0[][3] = {
|
||||
{0x0000a254, 0x00000898, 0x00001130},
|
||||
};
|
||||
|
||||
static const u32 ar9480_modes_low_ob_db_tx_gain_table_1p0[][5] = {
|
||||
static const u32 ar9462_modes_low_ob_db_tx_gain_table_1p0[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
|
||||
{0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
|
||||
@ -1464,12 +1464,12 @@ static const u32 ar9480_modes_low_ob_db_tx_gain_table_1p0[][5] = {
|
||||
{0x00016448, 0x64992000, 0x64992000, 0x64992000, 0x64992000},
|
||||
};
|
||||
|
||||
static const u32 ar9480_1p0_soc_postamble[][5] = {
|
||||
static const u32 ar9462_1p0_soc_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00007010, 0x00002233, 0x00002233, 0x00002233, 0x00002233},
|
||||
};
|
||||
|
||||
static const u32 ar9480_common_mixed_rx_gain_table_1p0[][2] = {
|
||||
static const u32 ar9462_common_mixed_rx_gain_table_1p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a000, 0x00010000},
|
||||
{0x0000a004, 0x00030002},
|
||||
@ -1729,14 +1729,14 @@ static const u32 ar9480_common_mixed_rx_gain_table_1p0[][2] = {
|
||||
{0x0000b1fc, 0x00000196},
|
||||
};
|
||||
|
||||
static const u32 ar9480_pcie_phy_clkreq_disable_L1_1p0[][2] = {
|
||||
static const u32 ar9462_pcie_phy_clkreq_disable_L1_1p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00018c00, 0x10013e5e},
|
||||
{0x00018c04, 0x000801d8},
|
||||
{0x00018c08, 0x0000580c},
|
||||
};
|
||||
|
||||
static const u32 ar9480_1p0_baseband_core_emulation[][2] = {
|
||||
static const u32 ar9462_1p0_baseband_core_emulation[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00009800, 0xafa68e30},
|
||||
{0x00009884, 0x00002842},
|
||||
@ -1758,7 +1758,7 @@ static const u32 ar9480_1p0_baseband_core_emulation[][2] = {
|
||||
{0x0000a690, 0x00000038},
|
||||
};
|
||||
|
||||
static const u32 ar9480_1p0_radio_core[][2] = {
|
||||
static const u32 ar9462_1p0_radio_core[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00016000, 0x36db6db6},
|
||||
{0x00016004, 0x6db6db40},
|
||||
@ -1818,16 +1818,16 @@ static const u32 ar9480_1p0_radio_core[][2] = {
|
||||
{0x00016548, 0x000080c0},
|
||||
};
|
||||
|
||||
static const u32 ar9480_1p0_soc_preamble[][2] = {
|
||||
static const u32 ar9462_1p0_soc_preamble[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00007020, 0x00000000},
|
||||
{0x00007034, 0x00000002},
|
||||
{0x00007038, 0x000004c2},
|
||||
};
|
||||
|
||||
static const u32 ar9480_1p0_sys2ant[][2] = {
|
||||
static const u32 ar9462_1p0_sys2ant[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00063120, 0x00801980},
|
||||
};
|
||||
|
||||
#endif /* INITVALS_9480_1P0_H */
|
||||
#endif /* INITVALS_9462_1P0_H */
|
@ -14,12 +14,12 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef INITVALS_9480_2P0_H
|
||||
#define INITVALS_9480_2P0_H
|
||||
#ifndef INITVALS_9462_2P0_H
|
||||
#define INITVALS_9462_2P0_H
|
||||
|
||||
/* AR9480 2.0 */
|
||||
/* AR9462 2.0 */
|
||||
|
||||
static const u32 ar9480_modes_fast_clock_2p0[][3] = {
|
||||
static const u32 ar9462_modes_fast_clock_2p0[][3] = {
|
||||
/* Addr 5G_HT20 5G_HT40 */
|
||||
{0x00001030, 0x00000268, 0x000004d0},
|
||||
{0x00001070, 0x0000018c, 0x00000318},
|
||||
@ -32,14 +32,14 @@ static const u32 ar9480_modes_fast_clock_2p0[][3] = {
|
||||
{0x0000a254, 0x00000898, 0x00001130},
|
||||
};
|
||||
|
||||
static const u32 ar9480_pciephy_clkreq_enable_L1_2p0[][2] = {
|
||||
static const u32 ar9462_pciephy_clkreq_enable_L1_2p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00018c00, 0x18253ede},
|
||||
{0x00018c04, 0x000801d8},
|
||||
{0x00018c08, 0x0003580c},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_baseband_postamble[][5] = {
|
||||
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},
|
||||
@ -89,7 +89,7 @@ static const u32 ar9480_2p0_baseband_postamble[][5] = {
|
||||
{0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_mac_core_emulation[][2] = {
|
||||
static const u32 ar9462_2p0_mac_core_emulation[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00000030, 0x000e0085},
|
||||
{0x00000044, 0x00000008},
|
||||
@ -97,7 +97,7 @@ static const u32 ar9480_2p0_mac_core_emulation[][2] = {
|
||||
{0x00008344, 0xaa4a105b},
|
||||
};
|
||||
|
||||
static const u32 ar9480_common_rx_gain_table_2p0[][2] = {
|
||||
static const u32 ar9462_common_rx_gain_table_2p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a000, 0x00010000},
|
||||
{0x0000a004, 0x00030002},
|
||||
@ -357,27 +357,27 @@ static const u32 ar9480_common_rx_gain_table_2p0[][2] = {
|
||||
{0x0000b1fc, 0x00000196},
|
||||
};
|
||||
|
||||
static const u32 ar9480_pciephy_clkreq_disable_L1_2p0[][2] = {
|
||||
static const u32 ar9462_pciephy_clkreq_disable_L1_2p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00018c00, 0x18213ede},
|
||||
{0x00018c04, 0x000801d8},
|
||||
{0x00018c08, 0x0003580c},
|
||||
};
|
||||
|
||||
static const u32 ar9480_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = {
|
||||
static const u32 ar9462_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00018c00, 0x18212ede},
|
||||
{0x00018c04, 0x000801d8},
|
||||
{0x00018c08, 0x0003580c},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_sys3ant[][2] = {
|
||||
static const u32 ar9462_2p0_sys3ant[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00063280, 0x00040807},
|
||||
{0x00063284, 0x104ccccc},
|
||||
};
|
||||
|
||||
static const u32 ar9480_common_rx_gain_table_ar9280_2p0[][2] = {
|
||||
static const u32 ar9462_common_rx_gain_table_ar9280_2p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a000, 0x02000101},
|
||||
{0x0000a004, 0x02000102},
|
||||
@ -679,20 +679,20 @@ static const u32 ar9200_ar9280_2p0_radio_core[][2] = {
|
||||
{0x00007894, 0x5a108000},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_mac_postamble_emulation[][5] = {
|
||||
static const u32 ar9462_2p0_mac_postamble_emulation[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00008014, 0x10f810f8, 0x10f810f8, 0x10f810f8, 0x10f810f8},
|
||||
{0x0000801c, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017, 0x0e8d8017},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_radio_postamble_sys3ant[][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},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_baseband_postamble_emulation[][5] = {
|
||||
static const u32 ar9462_2p0_baseband_postamble_emulation[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x00009e3c, 0xcf946221, 0xcf946221, 0xcf946221, 0xcf946221},
|
||||
@ -714,14 +714,14 @@ static const u32 ar9480_2p0_baseband_postamble_emulation[][5] = {
|
||||
{0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_radio_postamble_sys2ant[][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},
|
||||
};
|
||||
|
||||
static const u32 ar9480_common_wo_xlna_rx_gain_table_2p0[][2] = {
|
||||
static const u32 ar9462_common_wo_xlna_rx_gain_table_2p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a000, 0x00010000},
|
||||
{0x0000a004, 0x00030002},
|
||||
@ -981,14 +981,14 @@ static const u32 ar9480_common_wo_xlna_rx_gain_table_2p0[][2] = {
|
||||
{0x0000b1fc, 0x00000196},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_baseband_core_txfir_coeff_japan_2484[][2] = {
|
||||
static const u32 ar9462_2p0_baseband_core_txfir_coeff_japan_2484[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a398, 0x00000000},
|
||||
{0x0000a39c, 0x6f7f0301},
|
||||
{0x0000a3a0, 0xca9228ee},
|
||||
};
|
||||
|
||||
static const u32 ar9480_modes_low_ob_db_tx_gain_table_2p0[][5] = {
|
||||
static const u32 ar9462_modes_low_ob_db_tx_gain_table_2p0[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
|
||||
{0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
|
||||
@ -1057,12 +1057,12 @@ static const u32 ar9480_modes_low_ob_db_tx_gain_table_2p0[][5] = {
|
||||
{0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_soc_postamble[][5] = {
|
||||
static const u32 ar9462_2p0_soc_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00007010, 0x00002233, 0x00002233, 0x00002233, 0x00002233},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_baseband_core[][2] = {
|
||||
static const u32 ar9462_2p0_baseband_core[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00009800, 0xafe68e30},
|
||||
{0x00009804, 0xfd14e000},
|
||||
@ -1221,7 +1221,7 @@ static const u32 ar9480_2p0_baseband_core[][2] = {
|
||||
{0x0000b6b4, 0x00000001},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_radio_postamble[][5] = {
|
||||
static const u32 ar9462_2p0_radio_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524},
|
||||
{0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70},
|
||||
@ -1229,7 +1229,7 @@ static const u32 ar9480_2p0_radio_postamble[][5] = {
|
||||
{0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
|
||||
};
|
||||
|
||||
static const u32 ar9480_modes_high_ob_db_tx_gain_table_2p0[][5] = {
|
||||
static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
|
||||
{0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
|
||||
@ -1298,7 +1298,7 @@ static const u32 ar9480_modes_high_ob_db_tx_gain_table_2p0[][5] = {
|
||||
{0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_radio_core[][2] = {
|
||||
static const u32 ar9462_2p0_radio_core[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00016000, 0x36db6db6},
|
||||
{0x00016004, 0x6db6db40},
|
||||
@ -1356,7 +1356,7 @@ static const u32 ar9480_2p0_radio_core[][2] = {
|
||||
{0x00016548, 0x000080c0},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_tx_gain_table_baseband_postamble_emulation[][5] = {
|
||||
static const u32 ar9462_2p0_tx_gain_table_baseband_postamble_emulation[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x0000a410, 0x000000d5, 0x000000d5, 0x000000d5, 0x000000d5},
|
||||
{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
@ -1374,19 +1374,19 @@ static const u32 ar9480_2p0_tx_gain_table_baseband_postamble_emulation[][5] = {
|
||||
{0x0000a534, 0x00034e8a, 0x00034e8a, 0x00034e8a, 0x00034e8a},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_soc_preamble[][2] = {
|
||||
static const u32 ar9462_2p0_soc_preamble[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00007020, 0x00000000},
|
||||
{0x00007034, 0x00000002},
|
||||
{0x00007038, 0x000004c2},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_sys2ant[][2] = {
|
||||
static const u32 ar9462_2p0_sys2ant[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00063120, 0x00801980},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_mac_core[][2] = {
|
||||
static const u32 ar9462_2p0_mac_core[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00000008, 0x00000000},
|
||||
{0x00000030, 0x000e0085},
|
||||
@ -1550,7 +1550,7 @@ static const u32 ar9480_2p0_mac_core[][2] = {
|
||||
{0x000083d0, 0x000301ff},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_mac_postamble[][5] = {
|
||||
static const u32 ar9462_2p0_mac_postamble[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
|
||||
{0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
|
||||
@ -1562,7 +1562,7 @@ static const u32 ar9480_2p0_mac_postamble[][5] = {
|
||||
{0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
|
||||
};
|
||||
|
||||
static const u32 ar9480_common_mixed_rx_gain_table_2p0[][2] = {
|
||||
static const u32 ar9462_common_mixed_rx_gain_table_2p0[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x0000a000, 0x00010000},
|
||||
{0x0000a004, 0x00030002},
|
||||
@ -1822,7 +1822,7 @@ static const u32 ar9480_common_mixed_rx_gain_table_2p0[][2] = {
|
||||
{0x0000b1fc, 0x00000196},
|
||||
};
|
||||
|
||||
static const u32 ar9480_modes_green_ob_db_tx_gain_table_2p0[][5] = {
|
||||
static const u32 ar9462_modes_green_ob_db_tx_gain_table_2p0[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003},
|
||||
{0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
|
||||
@ -1891,7 +1891,7 @@ static const u32 ar9480_modes_green_ob_db_tx_gain_table_2p0[][5] = {
|
||||
{0x00016454, 0x6db60180, 0x6db60180, 0x6db60180, 0x6db60180},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_BTCOEX_MAX_TXPWR_table[][2] = {
|
||||
static const u32 ar9462_2p0_BTCOEX_MAX_TXPWR_table[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x000018c0, 0x10101010},
|
||||
{0x000018c4, 0x10101010},
|
||||
@ -1903,7 +1903,7 @@ static const u32 ar9480_2p0_BTCOEX_MAX_TXPWR_table[][2] = {
|
||||
{0x000018dc, 0x10101010},
|
||||
};
|
||||
|
||||
static const u32 ar9480_2p0_baseband_core_emulation[][2] = {
|
||||
static const u32 ar9462_2p0_baseband_core_emulation[][2] = {
|
||||
/* Addr allmodes */
|
||||
{0x00009800, 0xafa68e30},
|
||||
{0x00009884, 0x00002842},
|
||||
@ -1925,4 +1925,4 @@ static const u32 ar9480_2p0_baseband_core_emulation[][2] = {
|
||||
{0x0000a690, 0x00000038},
|
||||
};
|
||||
|
||||
#endif /* INITVALS_9480_2P0_H */
|
||||
#endif /* INITVALS_9462_2P0_H */
|
@ -458,7 +458,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc);
|
||||
#define ATH_LED_PIN_9287 8
|
||||
#define ATH_LED_PIN_9300 10
|
||||
#define ATH_LED_PIN_9485 6
|
||||
#define ATH_LED_PIN_9480 0
|
||||
#define ATH_LED_PIN_9462 0
|
||||
|
||||
#ifdef CONFIG_MAC80211_LEDS
|
||||
void ath_init_leds(struct ath_softc *sc);
|
||||
|
@ -515,7 +515,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
|
||||
sc->sc_flags |= SC_OP_TSF_RESET;
|
||||
ath9k_beacon_init(sc, nexttbtt, intval);
|
||||
sc->beacon.bmisscnt = 0;
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
}
|
||||
|
||||
@ -643,7 +643,7 @@ static void ath_beacon_config_sta(struct ath_softc *sc,
|
||||
ath9k_hw_set_sta_beacon_timers(ah, &bs);
|
||||
ah->imask |= ATH9K_INT_BMISS;
|
||||
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
}
|
||||
|
||||
@ -679,7 +679,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc,
|
||||
ath9k_beacon_init(sc, nexttbtt, intval);
|
||||
sc->beacon.bmisscnt = 0;
|
||||
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
}
|
||||
|
||||
@ -821,11 +821,11 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status)
|
||||
if (status) {
|
||||
/* Re-enable beaconing */
|
||||
ah->imask |= ATH9K_INT_SWBA;
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
} else {
|
||||
/* Disable SWBA interrupt */
|
||||
ah->imask &= ~ATH9K_INT_SWBA;
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
tasklet_kill(&sc->bcon_tasklet);
|
||||
ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq);
|
||||
}
|
||||
|
@ -161,10 +161,12 @@ EXPORT_SYMBOL(ath9k_cmn_count_streams);
|
||||
void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
|
||||
u16 new_txpow, u16 *txpower)
|
||||
{
|
||||
if (cur_txpow != new_txpow) {
|
||||
struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
|
||||
|
||||
if (reg->power_limit != new_txpow) {
|
||||
ath9k_hw_set_txpowerlimit(ah, new_txpow, false);
|
||||
/* read back in case value is clamped */
|
||||
*txpower = ath9k_hw_regulatory(ah)->power_limit;
|
||||
*txpower = reg->max_power_level;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_cmn_update_txpow);
|
||||
|
@ -523,9 +523,22 @@ static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
|
||||
if (tmp & ATH9K_RX_FILTER_PHYRADAR)
|
||||
len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR");
|
||||
if (tmp & ATH9K_RX_FILTER_MCAST_BCAST_ALL)
|
||||
len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL\n");
|
||||
else
|
||||
len += snprintf(buf + len, sizeof(buf) - len, "\n");
|
||||
len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL");
|
||||
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"\n\nReset causes:\n"
|
||||
" baseband hang: %d\n"
|
||||
" baseband watchdog: %d\n"
|
||||
" fatal hardware error interrupt: %d\n"
|
||||
" tx hardware error: %d\n"
|
||||
" tx path hang: %d\n"
|
||||
" pll rx hang: %d\n",
|
||||
sc->debug.stats.reset[RESET_TYPE_BB_HANG],
|
||||
sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG],
|
||||
sc->debug.stats.reset[RESET_TYPE_FATAL_INT],
|
||||
sc->debug.stats.reset[RESET_TYPE_TX_ERROR],
|
||||
sc->debug.stats.reset[RESET_TYPE_TX_HANG],
|
||||
sc->debug.stats.reset[RESET_TYPE_PLL_HANG]);
|
||||
|
||||
if (len > sizeof(buf))
|
||||
len = sizeof(buf);
|
||||
|
@ -25,8 +25,10 @@ struct ath_buf;
|
||||
|
||||
#ifdef CONFIG_ATH9K_DEBUGFS
|
||||
#define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++
|
||||
#define RESET_STAT_INC(sc, type) sc->debug.stats.reset[type]++
|
||||
#else
|
||||
#define TX_STAT_INC(q, c) do { } while (0)
|
||||
#define RESET_STAT_INC(sc, type) do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ATH9K_DEBUGFS
|
||||
@ -171,10 +173,21 @@ struct ath_rx_stats {
|
||||
u8 rs_antenna;
|
||||
};
|
||||
|
||||
enum ath_reset_type {
|
||||
RESET_TYPE_BB_HANG,
|
||||
RESET_TYPE_BB_WATCHDOG,
|
||||
RESET_TYPE_FATAL_INT,
|
||||
RESET_TYPE_TX_ERROR,
|
||||
RESET_TYPE_TX_HANG,
|
||||
RESET_TYPE_PLL_HANG,
|
||||
__RESET_TYPE_MAX
|
||||
};
|
||||
|
||||
struct ath_stats {
|
||||
struct ath_interrupt_stats istats;
|
||||
struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
|
||||
struct ath_rx_stats rxstats;
|
||||
u32 reset[__RESET_TYPE_MAX];
|
||||
};
|
||||
|
||||
#define ATH_DBG_MAX_SAMPLES 10
|
||||
|
@ -108,7 +108,7 @@
|
||||
#define EEP_RFSILENT_ENABLED_S 0
|
||||
#define EEP_RFSILENT_POLARITY 0x0002
|
||||
#define EEP_RFSILENT_POLARITY_S 1
|
||||
#define EEP_RFSILENT_GPIO_SEL (AR_SREV_9480(ah) ? 0x00fc : 0x001c)
|
||||
#define EEP_RFSILENT_GPIO_SEL (AR_SREV_9462(ah) ? 0x00fc : 0x001c)
|
||||
#define EEP_RFSILENT_GPIO_SEL_S 2
|
||||
|
||||
#define AR5416_OPFLAGS_11A 0x01
|
||||
@ -220,7 +220,6 @@ enum eeprom_param {
|
||||
EEP_MAC_MID,
|
||||
EEP_MAC_LSW,
|
||||
EEP_REG_0,
|
||||
EEP_REG_1,
|
||||
EEP_OP_CAP,
|
||||
EEP_OP_MODE,
|
||||
EEP_RF_SILENT,
|
||||
@ -248,7 +247,9 @@ enum eeprom_param {
|
||||
EEP_PAPRD,
|
||||
EEP_MODAL_VER,
|
||||
EEP_ANT_DIV_CTL1,
|
||||
EEP_CHAIN_MASK_REDUCE
|
||||
EEP_CHAIN_MASK_REDUCE,
|
||||
EEP_ANTENNA_GAIN_2G,
|
||||
EEP_ANTENNA_GAIN_5G
|
||||
};
|
||||
|
||||
enum ar5416_rates {
|
||||
@ -652,8 +653,7 @@ struct eeprom_ops {
|
||||
void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
|
||||
void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
|
||||
u16 cfgCtl, u8 twiceAntennaReduction,
|
||||
u8 twiceMaxRegulatoryPower, u8 powerLimit,
|
||||
bool test);
|
||||
u8 powerLimit, bool test);
|
||||
u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
|
||||
};
|
||||
|
||||
|
@ -322,8 +322,6 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
|
||||
return get_unaligned_be16(pBase->macAddr + 4);
|
||||
case EEP_REG_0:
|
||||
return pBase->regDmn[0];
|
||||
case EEP_REG_1:
|
||||
return pBase->regDmn[1];
|
||||
case EEP_OP_CAP:
|
||||
return pBase->deviceCap;
|
||||
case EEP_OP_MODE:
|
||||
@ -350,6 +348,8 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
|
||||
return pModal->antdiv_ctl1;
|
||||
case EEP_TXGAIN_TYPE:
|
||||
return pBase->txGainType;
|
||||
case EEP_ANTENNA_GAIN_2G:
|
||||
return pModal->antennaGainCh[0];
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -462,8 +462,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
int16_t *ratesArray,
|
||||
u16 cfgCtl,
|
||||
u16 AntennaReduction,
|
||||
u16 twiceMaxRegulatoryPower,
|
||||
u16 antenna_reduction,
|
||||
u16 powerLimit)
|
||||
{
|
||||
#define CMP_TEST_GRP \
|
||||
@ -472,20 +471,16 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
|
||||
|| (((cfgCtl & ~CTL_MODE_M) | (pCtlMode[ctlMode] & CTL_MODE_M)) == \
|
||||
((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))
|
||||
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
int i;
|
||||
int16_t twiceLargestAntenna;
|
||||
u16 twiceMinEdgePower;
|
||||
u16 twiceMaxEdgePower = MAX_RATE_POWER;
|
||||
u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
|
||||
u16 scaledPower = 0, minCtlPower;
|
||||
u16 numCtlModes;
|
||||
const u16 *pCtlMode;
|
||||
u16 ctlMode, freq;
|
||||
struct chan_centers centers;
|
||||
struct cal_ctl_data_4k *rep;
|
||||
struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
|
||||
static const u16 tpScaleReductionTable[5] =
|
||||
{ 0, 3, 6, 9, MAX_RATE_POWER };
|
||||
struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
|
||||
0, { 0, 0, 0, 0}
|
||||
};
|
||||
@ -503,19 +498,7 @@ static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
|
||||
|
||||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
|
||||
twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0];
|
||||
twiceLargestAntenna = (int16_t)min(AntennaReduction -
|
||||
twiceLargestAntenna, 0);
|
||||
|
||||
maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
|
||||
if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
|
||||
maxRegAllowedPower -=
|
||||
(tpScaleReductionTable[(regulatory->tp_scale)] * 2);
|
||||
}
|
||||
|
||||
scaledPower = min(powerLimit, maxRegAllowedPower);
|
||||
scaledPower = max((u16)0, scaledPower);
|
||||
|
||||
scaledPower = powerLimit - antenna_reduction;
|
||||
numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
|
||||
pCtlMode = ctlModesFor11g;
|
||||
|
||||
@ -671,7 +654,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
u16 cfgCtl,
|
||||
u8 twiceAntennaReduction,
|
||||
u8 twiceMaxRegulatoryPower,
|
||||
u8 powerLimit, bool test)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
@ -691,7 +673,6 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
|
||||
ath9k_hw_set_4k_power_per_rate_table(ah, chan,
|
||||
&ratesArray[0], cfgCtl,
|
||||
twiceAntennaReduction,
|
||||
twiceMaxRegulatoryPower,
|
||||
powerLimit);
|
||||
|
||||
ath9k_hw_set_4k_power_cal_table(ah, chan);
|
||||
|
@ -308,8 +308,6 @@ static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah,
|
||||
return get_unaligned_be16(pBase->macAddr + 4);
|
||||
case EEP_REG_0:
|
||||
return pBase->regDmn[0];
|
||||
case EEP_REG_1:
|
||||
return pBase->regDmn[1];
|
||||
case EEP_OP_CAP:
|
||||
return pBase->deviceCap;
|
||||
case EEP_OP_MODE:
|
||||
@ -336,6 +334,9 @@ static u32 ath9k_hw_ar9287_get_eeprom(struct ath_hw *ah,
|
||||
return pBase->tempSensSlopePalOn;
|
||||
else
|
||||
return 0;
|
||||
case EEP_ANTENNA_GAIN_2G:
|
||||
return max_t(u8, pModal->antennaGainCh[0],
|
||||
pModal->antennaGainCh[1]);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -554,8 +555,7 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
int16_t *ratesArray,
|
||||
u16 cfgCtl,
|
||||
u16 AntennaReduction,
|
||||
u16 twiceMaxRegulatoryPower,
|
||||
u16 antenna_reduction,
|
||||
u16 powerLimit)
|
||||
{
|
||||
#define CMP_CTL \
|
||||
@ -569,12 +569,8 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
|
||||
#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6
|
||||
#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10
|
||||
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
u16 twiceMaxEdgePower = MAX_RATE_POWER;
|
||||
static const u16 tpScaleReductionTable[5] =
|
||||
{ 0, 3, 6, 9, MAX_RATE_POWER };
|
||||
int i;
|
||||
int16_t twiceLargestAntenna;
|
||||
struct cal_ctl_data_ar9287 *rep;
|
||||
struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} },
|
||||
targetPowerCck = {0, {0, 0, 0, 0} };
|
||||
@ -582,7 +578,7 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
|
||||
targetPowerCckExt = {0, {0, 0, 0, 0} };
|
||||
struct cal_target_power_ht targetPowerHt20,
|
||||
targetPowerHt40 = {0, {0, 0, 0, 0} };
|
||||
u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
|
||||
u16 scaledPower = 0, minCtlPower;
|
||||
static const u16 ctlModesFor11g[] = {
|
||||
CTL_11B, CTL_11G, CTL_2GHT20,
|
||||
CTL_11B_EXT, CTL_11G_EXT, CTL_2GHT40
|
||||
@ -597,24 +593,7 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
|
||||
tx_chainmask = ah->txchainmask;
|
||||
|
||||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
|
||||
/* Compute TxPower reduction due to Antenna Gain */
|
||||
twiceLargestAntenna = max(pEepData->modalHeader.antennaGainCh[0],
|
||||
pEepData->modalHeader.antennaGainCh[1]);
|
||||
twiceLargestAntenna = (int16_t)min((AntennaReduction) -
|
||||
twiceLargestAntenna, 0);
|
||||
|
||||
/*
|
||||
* scaledPower is the minimum of the user input power level
|
||||
* and the regulatory allowed power level.
|
||||
*/
|
||||
maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
|
||||
|
||||
if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX)
|
||||
maxRegAllowedPower -=
|
||||
(tpScaleReductionTable[(regulatory->tp_scale)] * 2);
|
||||
|
||||
scaledPower = min(powerLimit, maxRegAllowedPower);
|
||||
scaledPower = powerLimit - antenna_reduction;
|
||||
|
||||
/*
|
||||
* Reduce scaled Power by number of chains active
|
||||
@ -815,7 +794,6 @@ static void ath9k_hw_set_ar9287_power_per_rate_table(struct ath_hw *ah,
|
||||
static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan, u16 cfgCtl,
|
||||
u8 twiceAntennaReduction,
|
||||
u8 twiceMaxRegulatoryPower,
|
||||
u8 powerLimit, bool test)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
@ -834,7 +812,6 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
|
||||
ath9k_hw_set_ar9287_power_per_rate_table(ah, chan,
|
||||
&ratesArray[0], cfgCtl,
|
||||
twiceAntennaReduction,
|
||||
twiceMaxRegulatoryPower,
|
||||
powerLimit);
|
||||
|
||||
ath9k_hw_set_ar9287_power_cal_table(ah, chan);
|
||||
|
@ -400,6 +400,7 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
|
||||
struct ar5416_eeprom_def *eep = &ah->eeprom.def;
|
||||
struct modal_eep_header *pModal = eep->modalHeader;
|
||||
struct base_eep_header *pBase = &eep->baseEepHeader;
|
||||
int band = 0;
|
||||
|
||||
switch (param) {
|
||||
case EEP_NFTHRESH_5:
|
||||
@ -414,8 +415,6 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
|
||||
return get_unaligned_be16(pBase->macAddr + 4);
|
||||
case EEP_REG_0:
|
||||
return pBase->regDmn[0];
|
||||
case EEP_REG_1:
|
||||
return pBase->regDmn[1];
|
||||
case EEP_OP_CAP:
|
||||
return pBase->deviceCap;
|
||||
case EEP_OP_MODE:
|
||||
@ -467,6 +466,14 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
|
||||
return pBase->pwr_table_offset;
|
||||
else
|
||||
return AR5416_PWR_TABLE_OFFSET_DB;
|
||||
case EEP_ANTENNA_GAIN_2G:
|
||||
band = 1;
|
||||
/* fall through */
|
||||
case EEP_ANTENNA_GAIN_5G:
|
||||
return max_t(u8, max_t(u8,
|
||||
pModal[band].antennaGainCh[0],
|
||||
pModal[band].antennaGainCh[1]),
|
||||
pModal[band].antennaGainCh[2]);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@ -986,21 +993,15 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
int16_t *ratesArray,
|
||||
u16 cfgCtl,
|
||||
u16 AntennaReduction,
|
||||
u16 twiceMaxRegulatoryPower,
|
||||
u16 antenna_reduction,
|
||||
u16 powerLimit)
|
||||
{
|
||||
#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
|
||||
#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
|
||||
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
|
||||
u16 twiceMaxEdgePower = MAX_RATE_POWER;
|
||||
static const u16 tpScaleReductionTable[5] =
|
||||
{ 0, 3, 6, 9, MAX_RATE_POWER };
|
||||
|
||||
int i;
|
||||
int16_t twiceLargestAntenna;
|
||||
struct cal_ctl_data *rep;
|
||||
struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
|
||||
0, { 0, 0, 0, 0}
|
||||
@ -1012,7 +1013,7 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
|
||||
struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
|
||||
0, {0, 0, 0, 0}
|
||||
};
|
||||
u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
|
||||
u16 scaledPower = 0, minCtlPower;
|
||||
static const u16 ctlModesFor11a[] = {
|
||||
CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
|
||||
};
|
||||
@ -1031,27 +1032,7 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
|
||||
|
||||
ath9k_hw_get_channel_centers(ah, chan, ¢ers);
|
||||
|
||||
twiceLargestAntenna = max(
|
||||
pEepData->modalHeader
|
||||
[IS_CHAN_2GHZ(chan)].antennaGainCh[0],
|
||||
pEepData->modalHeader
|
||||
[IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
|
||||
|
||||
twiceLargestAntenna = max((u8)twiceLargestAntenna,
|
||||
pEepData->modalHeader
|
||||
[IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
|
||||
|
||||
twiceLargestAntenna = (int16_t)min(AntennaReduction -
|
||||
twiceLargestAntenna, 0);
|
||||
|
||||
maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
|
||||
|
||||
if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
|
||||
maxRegAllowedPower -=
|
||||
(tpScaleReductionTable[(regulatory->tp_scale)] * 2);
|
||||
}
|
||||
|
||||
scaledPower = min(powerLimit, maxRegAllowedPower);
|
||||
scaledPower = powerLimit - antenna_reduction;
|
||||
|
||||
switch (ar5416_get_ntxchains(tx_chainmask)) {
|
||||
case 1:
|
||||
@ -1256,7 +1237,6 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
u16 cfgCtl,
|
||||
u8 twiceAntennaReduction,
|
||||
u8 twiceMaxRegulatoryPower,
|
||||
u8 powerLimit, bool test)
|
||||
{
|
||||
#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
|
||||
@ -1278,7 +1258,6 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
|
||||
ath9k_hw_set_def_power_per_rate_table(ah, chan,
|
||||
&ratesArray[0], cfgCtl,
|
||||
twiceAntennaReduction,
|
||||
twiceMaxRegulatoryPower,
|
||||
powerLimit);
|
||||
|
||||
ath9k_hw_set_def_power_cal_table(ah, chan);
|
||||
|
@ -48,8 +48,8 @@ void ath_init_leds(struct ath_softc *sc)
|
||||
sc->sc_ah->led_pin = ATH_LED_PIN_9485;
|
||||
else if (AR_SREV_9300(sc->sc_ah))
|
||||
sc->sc_ah->led_pin = ATH_LED_PIN_9300;
|
||||
else if (AR_SREV_9480(sc->sc_ah))
|
||||
sc->sc_ah->led_pin = ATH_LED_PIN_9480;
|
||||
else if (AR_SREV_9462(sc->sc_ah))
|
||||
sc->sc_ah->led_pin = ATH_LED_PIN_9462;
|
||||
else
|
||||
sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
|
||||
}
|
||||
@ -155,7 +155,7 @@ static void ath9k_gen_timer_start(struct ath_hw *ah,
|
||||
if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
ah->imask |= ATH9K_INT_GENTIMER;
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
}
|
||||
}
|
||||
@ -170,7 +170,7 @@ static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
|
||||
if (timer_table->timer_mask.val == 0) {
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
ah->imask &= ~ATH9K_INT_GENTIMER;
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
}
|
||||
}
|
||||
|
@ -205,4 +205,11 @@ static inline void ath9k_hw_setup_calibration(struct ath_hw *ah,
|
||||
ath9k_hw_private_ops(ah)->setup_calibration(ah, currCal);
|
||||
}
|
||||
|
||||
static inline int ath9k_hw_fast_chan_change(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan,
|
||||
u8 *ini_reloaded)
|
||||
{
|
||||
return ath9k_hw_private_ops(ah)->fast_chan_change(ah, chan,
|
||||
ini_reloaded);
|
||||
}
|
||||
#endif /* ATH9K_HW_OPS_H */
|
||||
|
@ -285,7 +285,7 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
|
||||
(val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
|
||||
ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
|
||||
|
||||
if (AR_SREV_9480(ah))
|
||||
if (AR_SREV_9462(ah))
|
||||
ah->is_pciexpress = true;
|
||||
else
|
||||
ah->is_pciexpress = (val &
|
||||
@ -433,7 +433,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
|
||||
|
||||
regulatory->country_code = CTRY_DEFAULT;
|
||||
regulatory->power_limit = MAX_RATE_POWER;
|
||||
regulatory->tp_scale = ATH9K_TP_SCALE_MAX;
|
||||
|
||||
ah->hw_version.magic = AR5416_MAGIC;
|
||||
ah->hw_version.subvendorid = 0;
|
||||
@ -542,6 +541,9 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (AR_SREV_9462(ah))
|
||||
ah->WARegVal &= ~AR_WA_D3_L1_DISABLE;
|
||||
|
||||
ath9k_hw_init_defaults(ah);
|
||||
ath9k_hw_init_config(ah);
|
||||
|
||||
@ -585,7 +587,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
||||
case AR_SREV_VERSION_9330:
|
||||
case AR_SREV_VERSION_9485:
|
||||
case AR_SREV_VERSION_9340:
|
||||
case AR_SREV_VERSION_9480:
|
||||
case AR_SREV_VERSION_9462:
|
||||
break;
|
||||
default:
|
||||
ath_err(common,
|
||||
@ -670,7 +672,7 @@ int ath9k_hw_init(struct ath_hw *ah)
|
||||
case AR9300_DEVID_AR9330:
|
||||
case AR9300_DEVID_AR9340:
|
||||
case AR9300_DEVID_AR9580:
|
||||
case AR9300_DEVID_AR9480:
|
||||
case AR9300_DEVID_AR9462:
|
||||
break;
|
||||
default:
|
||||
if (common->bus_ops->ath_bus_type == ATH_USB)
|
||||
@ -1389,11 +1391,17 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah,
|
||||
static bool ath9k_hw_channel_change(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ieee80211_channel *channel = chan->chan;
|
||||
u32 qnum;
|
||||
int r;
|
||||
bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
|
||||
bool band_switch, mode_diff;
|
||||
u8 ini_reloaded;
|
||||
|
||||
band_switch = (chan->channelFlags & (CHANNEL_2GHZ | CHANNEL_5GHZ)) !=
|
||||
(ah->curchan->channelFlags & (CHANNEL_2GHZ |
|
||||
CHANNEL_5GHZ));
|
||||
mode_diff = (chan->chanmode != ah->curchan->chanmode);
|
||||
|
||||
for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
|
||||
if (ath9k_hw_numtxpending(ah, qnum)) {
|
||||
@ -1408,6 +1416,18 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (edma && (band_switch || mode_diff)) {
|
||||
ath9k_hw_mark_phy_inactive(ah);
|
||||
udelay(5);
|
||||
|
||||
ath9k_hw_init_pll(ah, NULL);
|
||||
|
||||
if (ath9k_hw_fast_chan_change(ah, chan, &ini_reloaded)) {
|
||||
ath_err(common, "Failed to do fast channel change\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ath9k_hw_set_channel_regs(ah, chan);
|
||||
|
||||
r = ath9k_hw_rf_set_freq(ah, chan);
|
||||
@ -1416,14 +1436,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
|
||||
return false;
|
||||
}
|
||||
ath9k_hw_set_clockrate(ah);
|
||||
|
||||
ah->eep_ops->set_txpower(ah, chan,
|
||||
ath9k_regd_get_ctl(regulatory, chan),
|
||||
channel->max_antenna_gain * 2,
|
||||
channel->max_power * 2,
|
||||
min((u32) MAX_RATE_POWER,
|
||||
(u32) regulatory->power_limit), false);
|
||||
|
||||
ath9k_hw_apply_txpower(ah, chan);
|
||||
ath9k_hw_rfbus_done(ah);
|
||||
|
||||
if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
|
||||
@ -1431,6 +1444,18 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
|
||||
|
||||
ath9k_hw_spur_mitigate_freq(ah, chan);
|
||||
|
||||
if (edma && (band_switch || mode_diff)) {
|
||||
ah->ah_flags |= AH_FASTCC;
|
||||
if (band_switch || ini_reloaded)
|
||||
ah->eep_ops->set_board_values(ah, chan);
|
||||
|
||||
ath9k_hw_init_bb(ah, chan);
|
||||
|
||||
if (band_switch || ini_reloaded)
|
||||
ath9k_hw_init_cal(ah, chan);
|
||||
ah->ah_flags &= ~AH_FASTCC;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1486,6 +1511,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
u32 macStaId1;
|
||||
u64 tsf = 0;
|
||||
int i, r;
|
||||
bool allow_fbs = false;
|
||||
|
||||
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
|
||||
return -EIO;
|
||||
@ -1504,16 +1530,22 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
}
|
||||
ah->noise = ath9k_hw_getchan_noise(ah, chan);
|
||||
|
||||
if ((AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI) ||
|
||||
(AR_SREV_9300_20_OR_LATER(ah) && IS_CHAN_5GHZ(chan)))
|
||||
if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI)
|
||||
bChannelChange = false;
|
||||
|
||||
if (caldata &&
|
||||
caldata->done_txiqcal_once &&
|
||||
caldata->done_txclcal_once &&
|
||||
caldata->rtt_hist.num_readings)
|
||||
allow_fbs = true;
|
||||
|
||||
if (bChannelChange &&
|
||||
(ah->chip_fullsleep != true) &&
|
||||
(ah->curchan != NULL) &&
|
||||
(chan->channel != ah->curchan->channel) &&
|
||||
((chan->channelFlags & CHANNEL_ALL) ==
|
||||
(ah->curchan->channelFlags & CHANNEL_ALL))) {
|
||||
(allow_fbs ||
|
||||
((chan->channelFlags & CHANNEL_ALL) ==
|
||||
(ah->curchan->channelFlags & CHANNEL_ALL)))) {
|
||||
if (ath9k_hw_channel_change(ah, chan)) {
|
||||
ath9k_hw_loadnf(ah, ah->curchan);
|
||||
ath9k_hw_start_nfcal(ah, true);
|
||||
@ -1684,6 +1716,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
|
||||
ath9k_hw_init_bb(ah, chan);
|
||||
|
||||
if (caldata) {
|
||||
caldata->done_txiqcal_once = false;
|
||||
caldata->done_txclcal_once = false;
|
||||
caldata->rtt_hist.num_readings = 0;
|
||||
}
|
||||
if (!ath9k_hw_init_cal(ah, chan))
|
||||
return -EIO;
|
||||
|
||||
@ -1753,7 +1790,7 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
|
||||
{
|
||||
REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
|
||||
if (setChip) {
|
||||
if (AR_SREV_9480(ah)) {
|
||||
if (AR_SREV_9462(ah)) {
|
||||
REG_WRITE(ah, AR_TIMER_MODE,
|
||||
REG_READ(ah, AR_TIMER_MODE) & 0xFFFFFF00);
|
||||
REG_WRITE(ah, AR_NDP2_TIMER_MODE, REG_READ(ah,
|
||||
@ -1771,7 +1808,7 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
|
||||
*/
|
||||
REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN);
|
||||
|
||||
if (AR_SREV_9480(ah))
|
||||
if (AR_SREV_9462(ah))
|
||||
udelay(100);
|
||||
|
||||
if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah))
|
||||
@ -1779,15 +1816,14 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
|
||||
|
||||
/* Shutdown chip. Active low */
|
||||
if (!AR_SREV_5416(ah) &&
|
||||
!AR_SREV_9271(ah) && !AR_SREV_9480_10(ah)) {
|
||||
!AR_SREV_9271(ah) && !AR_SREV_9462_10(ah)) {
|
||||
REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN);
|
||||
udelay(2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */
|
||||
if (!AR_SREV_9480(ah))
|
||||
REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
|
||||
REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1818,7 +1854,7 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
|
||||
* SYS_WAKING and SYS_SLEEPING messages which will make
|
||||
* BT CPU to busy to process.
|
||||
*/
|
||||
if (AR_SREV_9480(ah)) {
|
||||
if (AR_SREV_9462(ah)) {
|
||||
val = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_EN) &
|
||||
~AR_MCI_INTERRUPT_RX_HW_MSG_MASK;
|
||||
REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, val);
|
||||
@ -1830,7 +1866,7 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
|
||||
REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
|
||||
AR_RTC_FORCE_WAKE_EN);
|
||||
|
||||
if (AR_SREV_9480(ah))
|
||||
if (AR_SREV_9462(ah))
|
||||
udelay(30);
|
||||
}
|
||||
}
|
||||
@ -2082,11 +2118,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
||||
eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
|
||||
regulatory->current_rd = eeval;
|
||||
|
||||
eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1);
|
||||
if (AR_SREV_9285_12_OR_LATER(ah))
|
||||
eeval |= AR9285_RDEXT_DEFAULT;
|
||||
regulatory->current_rd_ext = eeval;
|
||||
|
||||
if (ah->opmode != NL80211_IFTYPE_AP &&
|
||||
ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
|
||||
if (regulatory->current_rd == 0x64 ||
|
||||
@ -2294,6 +2325,14 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
||||
rx_chainmask >>= 1;
|
||||
}
|
||||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
ah->enabled_cals |= TX_IQ_CAL;
|
||||
if (!AR_SREV_9330(ah))
|
||||
ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
|
||||
}
|
||||
if (AR_SREV_9462(ah))
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_RTT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2454,7 +2493,7 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
if (AR_SREV_9480(ah))
|
||||
if (AR_SREV_9462(ah))
|
||||
bits |= ATH9K_RX_FILTER_CONTROL_WRAPPER;
|
||||
|
||||
REG_WRITE(ah, AR_RX_FILTER, bits);
|
||||
@ -2498,23 +2537,56 @@ bool ath9k_hw_disable(struct ath_hw *ah)
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_disable);
|
||||
|
||||
void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
|
||||
static int get_antenna_gain(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
struct ieee80211_channel *channel = chan->chan;
|
||||
int reg_pwr = min_t(int, MAX_RATE_POWER, limit);
|
||||
int chan_pwr = channel->max_power * 2;
|
||||
enum eeprom_param gain_param;
|
||||
|
||||
if (test)
|
||||
reg_pwr = chan_pwr = MAX_RATE_POWER;
|
||||
if (IS_CHAN_2GHZ(chan))
|
||||
gain_param = EEP_ANTENNA_GAIN_2G;
|
||||
else
|
||||
gain_param = EEP_ANTENNA_GAIN_5G;
|
||||
|
||||
regulatory->power_limit = reg_pwr;
|
||||
return ah->eep_ops->get_eeprom(ah, gain_param);
|
||||
}
|
||||
|
||||
void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
|
||||
struct ieee80211_channel *channel;
|
||||
int chan_pwr, new_pwr, max_gain;
|
||||
int ant_gain, ant_reduction = 0;
|
||||
|
||||
if (!chan)
|
||||
return;
|
||||
|
||||
channel = chan->chan;
|
||||
chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER);
|
||||
new_pwr = min_t(int, chan_pwr, reg->power_limit);
|
||||
max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2;
|
||||
|
||||
ant_gain = get_antenna_gain(ah, chan);
|
||||
if (ant_gain > max_gain)
|
||||
ant_reduction = ant_gain - max_gain;
|
||||
|
||||
ah->eep_ops->set_txpower(ah, chan,
|
||||
ath9k_regd_get_ctl(regulatory, chan),
|
||||
channel->max_antenna_gain * 2,
|
||||
chan_pwr, reg_pwr, test);
|
||||
ath9k_regd_get_ctl(reg, chan),
|
||||
ant_reduction, new_pwr, false);
|
||||
}
|
||||
|
||||
void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
|
||||
{
|
||||
struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
struct ieee80211_channel *channel = chan->chan;
|
||||
|
||||
reg->power_limit = min_t(int, limit, MAX_RATE_POWER);
|
||||
if (test)
|
||||
channel->max_power = MAX_RATE_POWER / 2;
|
||||
|
||||
ath9k_hw_apply_txpower(ah, chan);
|
||||
|
||||
if (test)
|
||||
channel->max_power = DIV_ROUND_UP(reg->max_power_level, 2);
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_set_txpowerlimit);
|
||||
|
||||
@ -2713,9 +2785,9 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah,
|
||||
REG_SET_BIT(ah, gen_tmr_configuration[timer->index].mode_addr,
|
||||
gen_tmr_configuration[timer->index].mode_mask);
|
||||
|
||||
if (AR_SREV_9480(ah)) {
|
||||
if (AR_SREV_9462(ah)) {
|
||||
/*
|
||||
* Starting from AR9480, each generic timer can select which tsf
|
||||
* Starting from AR9462, each generic timer can select which tsf
|
||||
* to use. But we still follow the old rule, 0 - 7 use tsf and
|
||||
* 8 - 15 use tsf2.
|
||||
*/
|
||||
@ -2832,7 +2904,7 @@ static struct {
|
||||
{ AR_SREV_VERSION_9330, "9330" },
|
||||
{ AR_SREV_VERSION_9340, "9340" },
|
||||
{ AR_SREV_VERSION_9485, "9485" },
|
||||
{ AR_SREV_VERSION_9480, "9480" },
|
||||
{ AR_SREV_VERSION_9462, "9462" },
|
||||
};
|
||||
|
||||
/* For devices with external radios */
|
||||
|
@ -46,7 +46,7 @@
|
||||
#define AR9300_DEVID_AR9340 0x0031
|
||||
#define AR9300_DEVID_AR9485_PCIE 0x0032
|
||||
#define AR9300_DEVID_AR9580 0x0033
|
||||
#define AR9300_DEVID_AR9480 0x0034
|
||||
#define AR9300_DEVID_AR9462 0x0034
|
||||
#define AR9300_DEVID_AR9330 0x0035
|
||||
|
||||
#define AR5416_AR9100_DEVID 0x000b
|
||||
@ -202,6 +202,7 @@ enum ath9k_hw_caps {
|
||||
ATH9K_HW_CAP_2GHZ = BIT(13),
|
||||
ATH9K_HW_CAP_5GHZ = BIT(14),
|
||||
ATH9K_HW_CAP_APM = BIT(15),
|
||||
ATH9K_HW_CAP_RTT = BIT(16),
|
||||
};
|
||||
|
||||
struct ath9k_hw_capabilities {
|
||||
@ -337,6 +338,16 @@ enum ath9k_int {
|
||||
CHANNEL_HT40PLUS | \
|
||||
CHANNEL_HT40MINUS)
|
||||
|
||||
#define MAX_RTT_TABLE_ENTRY 6
|
||||
#define RTT_HIST_MAX 3
|
||||
struct ath9k_rtt_hist {
|
||||
u32 table[AR9300_MAX_CHAINS][RTT_HIST_MAX][MAX_RTT_TABLE_ENTRY];
|
||||
u8 num_readings;
|
||||
};
|
||||
|
||||
#define MAX_IQCAL_MEASUREMENT 8
|
||||
#define MAX_CL_TAB_ENTRY 16
|
||||
|
||||
struct ath9k_hw_cal_data {
|
||||
u16 channel;
|
||||
u32 channelFlags;
|
||||
@ -346,9 +357,15 @@ struct ath9k_hw_cal_data {
|
||||
bool paprd_done;
|
||||
bool nfcal_pending;
|
||||
bool nfcal_interference;
|
||||
bool done_txiqcal_once;
|
||||
bool done_txclcal_once;
|
||||
u16 small_signal_gain[AR9300_MAX_CHAINS];
|
||||
u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ];
|
||||
u32 num_measures[AR9300_MAX_CHAINS];
|
||||
int tx_corr_coeff[MAX_IQCAL_MEASUREMENT][AR9300_MAX_CHAINS];
|
||||
u32 tx_clcal[AR9300_MAX_CHAINS][MAX_CL_TAB_ENTRY];
|
||||
struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
|
||||
struct ath9k_rtt_hist rtt_hist;
|
||||
};
|
||||
|
||||
struct ath9k_channel {
|
||||
@ -390,14 +407,6 @@ enum ath9k_power_mode {
|
||||
ATH9K_PM_UNDEFINED
|
||||
};
|
||||
|
||||
enum ath9k_tp_scale {
|
||||
ATH9K_TP_SCALE_MAX = 0,
|
||||
ATH9K_TP_SCALE_50,
|
||||
ATH9K_TP_SCALE_25,
|
||||
ATH9K_TP_SCALE_12,
|
||||
ATH9K_TP_SCALE_MIN
|
||||
};
|
||||
|
||||
enum ser_reg_mode {
|
||||
SER_REG_MODE_OFF = 0,
|
||||
SER_REG_MODE_ON = 1,
|
||||
@ -591,6 +600,8 @@ struct ath_hw_private_ops {
|
||||
void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]);
|
||||
void (*set_radar_params)(struct ath_hw *ah,
|
||||
struct ath_hw_radar_conf *conf);
|
||||
int (*fast_chan_change)(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
u8 *ini_reloaded);
|
||||
|
||||
/* ANI */
|
||||
void (*ani_cache_ini_regs)(struct ath_hw *ah);
|
||||
@ -632,9 +643,16 @@ struct ath_nf_limits {
|
||||
s16 nominal;
|
||||
};
|
||||
|
||||
enum ath_cal_list {
|
||||
TX_IQ_CAL = BIT(0),
|
||||
TX_IQ_ON_AGC_CAL = BIT(1),
|
||||
TX_CL_CAL = BIT(2),
|
||||
};
|
||||
|
||||
/* ah_flags */
|
||||
#define AH_USE_EEPROM 0x1
|
||||
#define AH_UNPLUGGED 0x2 /* The card has been physically removed. */
|
||||
#define AH_FASTCC 0x4
|
||||
|
||||
struct ath_hw {
|
||||
struct ath_ops reg_ops;
|
||||
@ -692,6 +710,7 @@ struct ath_hw {
|
||||
atomic_t intr_ref_cnt;
|
||||
bool chip_fullsleep;
|
||||
u32 atim_window;
|
||||
u32 modes_index;
|
||||
|
||||
/* Calibration */
|
||||
u32 supp_cals;
|
||||
@ -730,6 +749,7 @@ struct ath_hw {
|
||||
int32_t sign[AR5416_MAX_CHAINS];
|
||||
} meas3;
|
||||
u16 cal_samples;
|
||||
u8 enabled_cals;
|
||||
|
||||
u32 sta_id1_defaults;
|
||||
u32 misc_mode;
|
||||
@ -968,6 +988,7 @@ void ath9k_hw_htc_resetinit(struct ath_hw *ah);
|
||||
/* PHY */
|
||||
void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
|
||||
u32 *coef_mantissa, u32 *coef_exponent);
|
||||
void ath9k_hw_apply_txpower(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
|
||||
/*
|
||||
* Code Specific to AR5008, AR9001 or AR9002,
|
||||
|
@ -626,7 +626,6 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *chan;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
|
||||
int i;
|
||||
|
||||
sband = &sc->sbands[band];
|
||||
@ -635,7 +634,6 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
|
||||
ah->curchan = &ah->channels[chan->hw_value];
|
||||
ath9k_cmn_update_ichannel(ah->curchan, chan, NL80211_CHAN_HT20);
|
||||
ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true);
|
||||
chan->max_power = reg->max_power_level / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -620,8 +620,8 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
|
||||
rs->rs_status |= ATH9K_RXERR_DECRYPT;
|
||||
else if (ads.ds_rxstatus8 & AR_MichaelErr)
|
||||
rs->rs_status |= ATH9K_RXERR_MIC;
|
||||
else if (ads.ds_rxstatus8 & AR_KeyMiss)
|
||||
rs->rs_status |= ATH9K_RXERR_DECRYPT;
|
||||
if (ads.ds_rxstatus8 & AR_KeyMiss)
|
||||
rs->rs_status |= ATH9K_RXERR_KEYMISS;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -827,9 +827,9 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah)
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
|
||||
|
||||
void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
|
||||
void ath9k_hw_set_interrupts(struct ath_hw *ah)
|
||||
{
|
||||
enum ath9k_int omask = ah->imask;
|
||||
enum ath9k_int ints = ah->imask;
|
||||
u32 mask, mask2;
|
||||
struct ath9k_hw_capabilities *pCap = &ah->caps;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
@ -837,7 +837,7 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
|
||||
if (!(ints & ATH9K_INT_GLOBAL))
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
|
||||
ath_dbg(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
|
||||
ath_dbg(common, ATH_DBG_INTERRUPT, "New interrupt mask 0x%x\n", ints);
|
||||
|
||||
mask = ints & ATH9K_INT_COMMON;
|
||||
mask2 = 0;
|
||||
|
@ -75,9 +75,10 @@
|
||||
#define ATH9K_TXERR_XTXOP 0x08
|
||||
#define ATH9K_TXERR_TIMER_EXPIRED 0x10
|
||||
#define ATH9K_TX_ACKED 0x20
|
||||
#define ATH9K_TX_FLUSH 0x40
|
||||
#define ATH9K_TXERR_MASK \
|
||||
(ATH9K_TXERR_XRETRY | ATH9K_TXERR_FILT | ATH9K_TXERR_FIFO | \
|
||||
ATH9K_TXERR_XTXOP | ATH9K_TXERR_TIMER_EXPIRED)
|
||||
ATH9K_TXERR_XTXOP | ATH9K_TXERR_TIMER_EXPIRED | ATH9K_TX_FLUSH)
|
||||
|
||||
#define ATH9K_TX_BA 0x01
|
||||
#define ATH9K_TX_PWRMGMT 0x02
|
||||
@ -181,6 +182,7 @@ struct ath_htc_rx_status {
|
||||
#define ATH9K_RXERR_FIFO 0x04
|
||||
#define ATH9K_RXERR_DECRYPT 0x08
|
||||
#define ATH9K_RXERR_MIC 0x10
|
||||
#define ATH9K_RXERR_KEYMISS 0x20
|
||||
|
||||
#define ATH9K_RX_MORE 0x01
|
||||
#define ATH9K_RX_MORE_AGGR 0x02
|
||||
@ -734,7 +736,7 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah);
|
||||
|
||||
/* Interrupt Handling */
|
||||
bool ath9k_hw_intrpend(struct ath_hw *ah);
|
||||
void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
|
||||
void ath9k_hw_set_interrupts(struct ath_hw *ah);
|
||||
void ath9k_hw_enable_interrupts(struct ath_hw *ah);
|
||||
void ath9k_hw_disable_interrupts(struct ath_hw *ah);
|
||||
|
||||
|
@ -273,7 +273,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
|
||||
|
||||
ath9k_cmn_update_txpow(ah, sc->curtxpow,
|
||||
sc->config.txpowlimit, &sc->curtxpow);
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
|
||||
if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && start) {
|
||||
@ -679,6 +679,16 @@ void ath9k_tasklet(unsigned long data)
|
||||
|
||||
if ((status & ATH9K_INT_FATAL) ||
|
||||
(status & ATH9K_INT_BB_WATCHDOG)) {
|
||||
#ifdef CONFIG_ATH9K_DEBUGFS
|
||||
enum ath_reset_type type;
|
||||
|
||||
if (status & ATH9K_INT_FATAL)
|
||||
type = RESET_TYPE_FATAL_INT;
|
||||
else
|
||||
type = RESET_TYPE_BB_WATCHDOG;
|
||||
|
||||
RESET_STAT_INC(sc, type);
|
||||
#endif
|
||||
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
|
||||
goto out;
|
||||
}
|
||||
@ -823,7 +833,7 @@ irqreturn_t ath_isr(int irq, void *dev)
|
||||
|
||||
if (status & ATH9K_INT_RXEOL) {
|
||||
ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
}
|
||||
|
||||
if (status & ATH9K_INT_MIB) {
|
||||
@ -995,8 +1005,10 @@ void ath_hw_check(struct work_struct *work)
|
||||
ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, "
|
||||
"busy=%d (try %d)\n", busy, sc->hw_busy_count + 1);
|
||||
if (busy >= 99) {
|
||||
if (++sc->hw_busy_count >= 3)
|
||||
if (++sc->hw_busy_count >= 3) {
|
||||
RESET_STAT_INC(sc, RESET_TYPE_BB_HANG);
|
||||
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
|
||||
}
|
||||
|
||||
} else if (busy >= 0)
|
||||
sc->hw_busy_count = 0;
|
||||
@ -1016,6 +1028,7 @@ static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
|
||||
/* Rx is hung for more than 500ms. Reset it */
|
||||
ath_dbg(common, ATH_DBG_RESET,
|
||||
"Possible RX hang, resetting");
|
||||
RESET_STAT_INC(sc, RESET_TYPE_PLL_HANG);
|
||||
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
|
||||
count = 0;
|
||||
}
|
||||
@ -1396,7 +1409,7 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
|
||||
ah->imask &= ~ATH9K_INT_TSFOOR;
|
||||
}
|
||||
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
|
||||
/* Set up ANI */
|
||||
if (iter_data.naps > 0) {
|
||||
@ -1571,7 +1584,7 @@ static void ath9k_enable_ps(struct ath_softc *sc)
|
||||
if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
|
||||
if ((ah->imask & ATH9K_INT_TIM_TIMER) == 0) {
|
||||
ah->imask |= ATH9K_INT_TIM_TIMER;
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
}
|
||||
ath9k_hw_setrxabort(ah, 1);
|
||||
}
|
||||
@ -1591,7 +1604,7 @@ static void ath9k_disable_ps(struct ath_softc *sc)
|
||||
PS_WAIT_FOR_TX_ACK);
|
||||
if (ah->imask & ATH9K_INT_TIM_TIMER) {
|
||||
ah->imask &= ~ATH9K_INT_TIM_TIMER;
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9480 */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@ -433,12 +433,9 @@ void ath_rx_cleanup(struct ath_softc *sc)
|
||||
|
||||
u32 ath_calcrxfilter(struct ath_softc *sc)
|
||||
{
|
||||
#define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
|
||||
|
||||
u32 rfilt;
|
||||
|
||||
rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE)
|
||||
| ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
|
||||
rfilt = ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
|
||||
| ATH9K_RX_FILTER_MCAST;
|
||||
|
||||
if (sc->rx.rxfilter & FIF_PROBE_REQ)
|
||||
@ -811,6 +808,7 @@ static bool ath9k_rx_accept(struct ath_common *common,
|
||||
struct ath_rx_status *rx_stats,
|
||||
bool *decrypt_error)
|
||||
{
|
||||
struct ath_softc *sc = (struct ath_softc *) common->priv;
|
||||
bool is_mc, is_valid_tkip, strip_mic, mic_error;
|
||||
struct ath_hw *ah = common->ah;
|
||||
__le16 fc;
|
||||
@ -823,7 +821,8 @@ static bool ath9k_rx_accept(struct ath_common *common,
|
||||
test_bit(rx_stats->rs_keyix, common->tkip_keymap);
|
||||
strip_mic = is_valid_tkip && ieee80211_is_data(fc) &&
|
||||
!(rx_stats->rs_status &
|
||||
(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC));
|
||||
(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_CRC | ATH9K_RXERR_MIC |
|
||||
ATH9K_RXERR_KEYMISS));
|
||||
|
||||
if (!rx_stats->rs_datalen)
|
||||
return false;
|
||||
@ -851,6 +850,8 @@ static bool ath9k_rx_accept(struct ath_common *common,
|
||||
* descriptors.
|
||||
*/
|
||||
if (rx_stats->rs_status != 0) {
|
||||
u8 status_mask;
|
||||
|
||||
if (rx_stats->rs_status & ATH9K_RXERR_CRC) {
|
||||
rxs->flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
mic_error = false;
|
||||
@ -858,7 +859,8 @@ static bool ath9k_rx_accept(struct ath_common *common,
|
||||
if (rx_stats->rs_status & ATH9K_RXERR_PHY)
|
||||
return false;
|
||||
|
||||
if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
|
||||
if ((rx_stats->rs_status & ATH9K_RXERR_DECRYPT) ||
|
||||
(!is_mc && (rx_stats->rs_status & ATH9K_RXERR_KEYMISS))) {
|
||||
*decrypt_error = true;
|
||||
mic_error = false;
|
||||
}
|
||||
@ -868,17 +870,14 @@ static bool ath9k_rx_accept(struct ath_common *common,
|
||||
* decryption and MIC failures. For monitor mode,
|
||||
* we also ignore the CRC error.
|
||||
*/
|
||||
if (ah->is_monitoring) {
|
||||
if (rx_stats->rs_status &
|
||||
~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
|
||||
ATH9K_RXERR_CRC))
|
||||
return false;
|
||||
} else {
|
||||
if (rx_stats->rs_status &
|
||||
~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
status_mask = ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
|
||||
ATH9K_RXERR_KEYMISS;
|
||||
|
||||
if (ah->is_monitoring && (sc->rx.rxfilter & FIF_FCSFAIL))
|
||||
status_mask |= ATH9K_RXERR_CRC;
|
||||
|
||||
if (rx_stats->rs_status & ~status_mask)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1973,7 +1972,7 @@ requeue:
|
||||
|
||||
if (!(ah->imask & ATH9K_INT_RXEOL)) {
|
||||
ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_set_interrupts(ah);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -796,9 +796,9 @@
|
||||
#define AR_SREV_VERSION_9340 0x300
|
||||
#define AR_SREV_VERSION_9580 0x1C0
|
||||
#define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */
|
||||
#define AR_SREV_VERSION_9480 0x280
|
||||
#define AR_SREV_REVISION_9480_10 0
|
||||
#define AR_SREV_REVISION_9480_20 2
|
||||
#define AR_SREV_VERSION_9462 0x280
|
||||
#define AR_SREV_REVISION_9462_10 0
|
||||
#define AR_SREV_REVISION_9462_20 2
|
||||
|
||||
#define AR_SREV_5416(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
|
||||
@ -895,20 +895,20 @@
|
||||
(AR_SREV_9285_12_OR_LATER(_ah) && \
|
||||
((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
|
||||
|
||||
#define AR_SREV_9480(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9480))
|
||||
#define AR_SREV_9462(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462))
|
||||
|
||||
#define AR_SREV_9480_10(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9480) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9480_10))
|
||||
#define AR_SREV_9462_10(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_10))
|
||||
|
||||
#define AR_SREV_9480_20(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9480) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9480_20))
|
||||
#define AR_SREV_9462_20(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20))
|
||||
|
||||
#define AR_SREV_9480_20_OR_LATER(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9480) && \
|
||||
((_ah)->hw_version.macRev >= AR_SREV_REVISION_9480_20))
|
||||
#define AR_SREV_9462_20_OR_LATER(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
|
||||
((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_20))
|
||||
|
||||
#define AR_SREV_9580(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9580) && \
|
||||
@ -1933,6 +1933,7 @@ enum {
|
||||
#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 /* don't update noise floor automatically */
|
||||
#define AR_PHY_AGC_CONTROL_EXT_NF_PWR_MEAS 0x00040000 /* extend noise floor power measurement */
|
||||
#define AR_PHY_AGC_CONTROL_CLC_SUCCESS 0x00080000 /* carrier leak calibration done */
|
||||
#define AR_PHY_AGC_CONTROL_PKDET_CAL 0x00100000
|
||||
#define AR_PHY_AGC_CONTROL_YCOK_MAX 0x000003c0
|
||||
#define AR_PHY_AGC_CONTROL_YCOK_MAX_S 6
|
||||
|
||||
|
@ -373,7 +373,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
struct ath_frame_info *fi;
|
||||
int nframes;
|
||||
u8 tidno;
|
||||
bool clear_filter;
|
||||
bool flush = !!(ts->ts_status & ATH9K_TX_FLUSH);
|
||||
|
||||
skb = bf->bf_mpdu;
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
@ -462,12 +462,12 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
* the un-acked sub-frames
|
||||
*/
|
||||
txfail = 1;
|
||||
} else if (flush) {
|
||||
txpending = 1;
|
||||
} else if (fi->retries < ATH_MAX_SW_RETRIES) {
|
||||
if (!(ts->ts_status & ATH9K_TXERR_FILT) ||
|
||||
!an->sleeping)
|
||||
if (txok || !an->sleeping)
|
||||
ath_tx_set_retry(sc, txq, bf->bf_mpdu);
|
||||
|
||||
clear_filter = true;
|
||||
txpending = 1;
|
||||
} else {
|
||||
txfail = 1;
|
||||
@ -521,7 +521,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
|
||||
ath_tx_complete_buf(sc, bf, txq,
|
||||
&bf_head,
|
||||
ts, 0, 1);
|
||||
ts, 0,
|
||||
!flush);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -545,11 +546,13 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
ieee80211_sta_set_buffered(sta, tid->tidno, true);
|
||||
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
if (clear_filter)
|
||||
tid->ac->clear_ps_filter = true;
|
||||
skb_queue_splice(&bf_pending, &tid->buf_q);
|
||||
if (!an->sleeping)
|
||||
if (!an->sleeping) {
|
||||
ath_tx_queue_tid(txq, tid);
|
||||
|
||||
if (ts->ts_status & ATH9K_TXERR_FILT)
|
||||
tid->ac->clear_ps_filter = true;
|
||||
}
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
}
|
||||
|
||||
@ -564,8 +567,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
if (needreset)
|
||||
if (needreset) {
|
||||
RESET_STAT_INC(sc, RESET_TYPE_TX_ERROR);
|
||||
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
|
||||
}
|
||||
}
|
||||
|
||||
static bool ath_lookup_legacy(struct ath_buf *bf)
|
||||
@ -1255,7 +1260,6 @@ static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
|
||||
struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_tx_queue_info qi;
|
||||
static const int subtype_txq_to_hwq[] = {
|
||||
[WME_AC_BE] = ATH_TXQ_AC_BE,
|
||||
@ -1305,12 +1309,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
if (axq_qnum >= ARRAY_SIZE(sc->tx.txq)) {
|
||||
ath_err(common, "qnum %u out of range, max %zu!\n",
|
||||
axq_qnum, ARRAY_SIZE(sc->tx.txq));
|
||||
ath9k_hw_releasetxqueue(ah, axq_qnum);
|
||||
return NULL;
|
||||
}
|
||||
if (!ATH_TXQ_SETUP(sc, axq_qnum)) {
|
||||
struct ath_txq *txq = &sc->tx.txq[axq_qnum];
|
||||
|
||||
@ -1407,6 +1405,7 @@ static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq,
|
||||
struct ath_tx_status ts;
|
||||
|
||||
memset(&ts, 0, sizeof(ts));
|
||||
ts.ts_status = ATH9K_TX_FLUSH;
|
||||
INIT_LIST_HEAD(&bf_head);
|
||||
|
||||
while (!list_empty(list)) {
|
||||
@ -1473,7 +1472,8 @@ bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_txq *txq;
|
||||
int i, npend = 0;
|
||||
int i;
|
||||
u32 npend = 0;
|
||||
|
||||
if (sc->sc_flags & SC_OP_INVALID)
|
||||
return true;
|
||||
@ -1485,11 +1485,12 @@ bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
|
||||
if (!ATH_TXQ_SETUP(sc, i))
|
||||
continue;
|
||||
|
||||
npend += ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum);
|
||||
if (ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum))
|
||||
npend |= BIT(i);
|
||||
}
|
||||
|
||||
if (npend)
|
||||
ath_err(common, "Failed to stop TX DMA!\n");
|
||||
ath_err(common, "Failed to stop TX DMA, queues=0x%03x!\n", npend);
|
||||
|
||||
for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
|
||||
if (!ATH_TXQ_SETUP(sc, i))
|
||||
@ -2211,6 +2212,7 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
|
||||
if (needreset) {
|
||||
ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
|
||||
"tx hung, resetting the chip\n");
|
||||
RESET_STAT_INC(sc, RESET_TYPE_TX_HANG);
|
||||
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
|
||||
}
|
||||
|
||||
|
@ -1896,7 +1896,6 @@ static int carl9170_parse_eeprom(struct ar9170 *ar)
|
||||
ar->hw->channel_change_time = 80 * 1000;
|
||||
|
||||
regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
|
||||
regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
|
||||
|
||||
/* second part of wiphy init */
|
||||
SET_IEEE80211_PERM_ADDR(ar->hw, ar->eeprom.mac_address);
|
||||
|
@ -735,16 +735,22 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
|
||||
}
|
||||
|
||||
/* Link quality statistics */
|
||||
if ((chanstat & B43_RX_CHAN_PHYTYPE) == B43_PHYTYPE_N) {
|
||||
// s8 rssi = max(rxhdr->power0, rxhdr->power1);
|
||||
//TODO: Find out what the rssi value is (dBm or percentage?)
|
||||
// and also find out what the maximum possible value is.
|
||||
// Fill status.ssi and status.signal fields.
|
||||
} else {
|
||||
switch (chanstat & B43_RX_CHAN_PHYTYPE) {
|
||||
case B43_PHYTYPE_N:
|
||||
if (rxhdr->power0 == 16 || rxhdr->power0 == 32)
|
||||
status.signal = max(rxhdr->power1, rxhdr->power2);
|
||||
else
|
||||
status.signal = max(rxhdr->power0, rxhdr->power1);
|
||||
break;
|
||||
case B43_PHYTYPE_A:
|
||||
case B43_PHYTYPE_B:
|
||||
case B43_PHYTYPE_G:
|
||||
case B43_PHYTYPE_LP:
|
||||
status.signal = b43_rssi_postprocess(dev, rxhdr->jssi,
|
||||
(phystat0 & B43_RX_PHYST0_OFDM),
|
||||
(phystat0 & B43_RX_PHYST0_GAINCTL),
|
||||
(phystat3 & B43_RX_PHYST3_TRSTATE));
|
||||
break;
|
||||
}
|
||||
|
||||
if (phystat0 & B43_RX_PHYST0_OFDM)
|
||||
|
@ -248,7 +248,15 @@ struct b43_rxhdr_fw4 {
|
||||
__s8 power1; /* PHY RX Status 1: Power 1 */
|
||||
} __packed;
|
||||
} __packed;
|
||||
__le16 phy_status2; /* PHY RX Status 2 */
|
||||
union {
|
||||
/* RSSI for N-PHYs */
|
||||
struct {
|
||||
__s8 power2;
|
||||
PAD_BYTES(1);
|
||||
} __packed;
|
||||
|
||||
__le16 phy_status2; /* PHY RX Status 2 */
|
||||
} __packed;
|
||||
__le16 phy_status3; /* PHY RX Status 3 */
|
||||
union {
|
||||
/* Tested with 598.314, 644.1001 and 666.2 */
|
||||
|
35
drivers/net/wireless/brcm80211/Kconfig
Normal file
35
drivers/net/wireless/brcm80211/Kconfig
Normal file
@ -0,0 +1,35 @@
|
||||
config BRCMUTIL
|
||||
tristate
|
||||
|
||||
config BRCMSMAC
|
||||
tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
|
||||
depends on PCI
|
||||
depends on MAC80211
|
||||
depends on BCMA=n
|
||||
select BRCMUTIL
|
||||
select FW_LOADER
|
||||
select CRC_CCITT
|
||||
select CRC8
|
||||
select CORDIC
|
||||
---help---
|
||||
This module adds support for PCIe wireless adapters based on Broadcom
|
||||
IEEE802.11n SoftMAC chipsets. If you choose to build a module, it'll
|
||||
be called brcmsmac.ko.
|
||||
|
||||
config BRCMFMAC
|
||||
tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
|
||||
depends on MMC
|
||||
depends on CFG80211
|
||||
select BRCMUTIL
|
||||
select FW_LOADER
|
||||
---help---
|
||||
This module adds support for embedded wireless adapters based on
|
||||
Broadcom IEEE802.11n FullMAC chipsets. This driver uses the kernel's
|
||||
wireless extensions subsystem. If you choose to build a module,
|
||||
it'll be called brcmfmac.ko.
|
||||
|
||||
config BRCMDBG
|
||||
bool "Broadcom driver debug functions"
|
||||
depends on BRCMSMAC || BRCMFMAC
|
||||
---help---
|
||||
Selecting this enables additional code for debug purposes.
|
23
drivers/net/wireless/brcm80211/Makefile
Normal file
23
drivers/net/wireless/brcm80211/Makefile
Normal file
@ -0,0 +1,23 @@
|
||||
#
|
||||
# Makefile fragment for Broadcom 802.11n Networking Device Driver
|
||||
#
|
||||
# Copyright (c) 2010 Broadcom Corporation
|
||||
#
|
||||
# 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.
|
||||
|
||||
# common flags
|
||||
subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG
|
||||
|
||||
obj-$(CONFIG_BRCMUTIL) += brcmutil/
|
||||
obj-$(CONFIG_BRCMFMAC) += brcmfmac/
|
||||
obj-$(CONFIG_BRCMSMAC) += brcmsmac/
|
33
drivers/net/wireless/brcm80211/brcmfmac/Makefile
Normal file
33
drivers/net/wireless/brcm80211/brcmfmac/Makefile
Normal file
@ -0,0 +1,33 @@
|
||||
#
|
||||
# Makefile fragment for Broadcom 802.11n Networking Device Driver
|
||||
#
|
||||
# Copyright (c) 2010 Broadcom Corporation
|
||||
#
|
||||
# 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.
|
||||
|
||||
ccflags-y += \
|
||||
-Idrivers/net/wireless/brcm80211/brcmfmac \
|
||||
-Idrivers/net/wireless/brcm80211/include
|
||||
|
||||
DHDOFILES = \
|
||||
wl_cfg80211.o \
|
||||
dhd_cdc.o \
|
||||
dhd_common.o \
|
||||
dhd_sdio.o \
|
||||
dhd_linux.o \
|
||||
bcmsdh.o \
|
||||
bcmsdh_sdmmc.o
|
||||
|
||||
obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
|
||||
brcmfmac-objs += $(DHDOFILES)
|
||||
ccflags-y += -D__CHECK_ENDIAN__
|
32
drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h
Normal file
32
drivers/net/wireless/brcm80211/brcmfmac/bcmchip.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Broadcom Corporation
|
||||
*
|
||||
* 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 _bcmchip_h_
|
||||
#define _bcmchip_h_
|
||||
|
||||
/* bcm4329 */
|
||||
/* SDIO device core, ID 0x829 */
|
||||
#define BCM4329_CORE_BUS_BASE 0x18011000
|
||||
/* internal memory core, ID 0x80e */
|
||||
#define BCM4329_CORE_SOCRAM_BASE 0x18003000
|
||||
/* ARM Cortex M3 core, ID 0x82a */
|
||||
#define BCM4329_CORE_ARM_BASE 0x18002000
|
||||
#define BCM4329_RAMSIZE 0x48000
|
||||
/* firmware name */
|
||||
#define BCM4329_FW_NAME "brcm/bcm4329-fullmac-4.bin"
|
||||
#define BCM4329_NV_NAME "brcm/bcm4329-fullmac-4.txt"
|
||||
|
||||
#endif /* _bcmchip_h_ */
|
371
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
Normal file
371
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
Normal file
@ -0,0 +1,371 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
/* ****************** SDIO CARD Interface Functions **************************/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci_ids.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/mmc/sdio.h>
|
||||
#include <linux/mmc/sdio_func.h>
|
||||
#include <linux/mmc/card.h>
|
||||
|
||||
#include <defs.h>
|
||||
#include <brcm_hw_ids.h>
|
||||
#include <brcmu_utils.h>
|
||||
#include <brcmu_wifi.h>
|
||||
#include <soc.h>
|
||||
#include "dhd.h"
|
||||
#include "dhd_bus.h"
|
||||
#include "dhd_dbg.h"
|
||||
#include "sdio_host.h"
|
||||
|
||||
#define SDIOH_API_ACCESS_RETRY_LIMIT 2
|
||||
|
||||
static void brcmf_sdioh_irqhandler(struct sdio_func *func)
|
||||
{
|
||||
struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
|
||||
|
||||
brcmf_dbg(TRACE, "***IRQHandler\n");
|
||||
|
||||
sdio_release_host(func);
|
||||
|
||||
brcmf_sdbrcm_isr(sdiodev->bus);
|
||||
|
||||
sdio_claim_host(func);
|
||||
}
|
||||
|
||||
int brcmf_sdcard_intr_reg(struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
brcmf_dbg(TRACE, "Entering\n");
|
||||
|
||||
sdio_claim_host(sdiodev->func[1]);
|
||||
sdio_claim_irq(sdiodev->func[1], brcmf_sdioh_irqhandler);
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int brcmf_sdcard_intr_dereg(struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
brcmf_dbg(TRACE, "Entering\n");
|
||||
|
||||
sdio_claim_host(sdiodev->func[1]);
|
||||
sdio_release_irq(sdiodev->func[1]);
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr,
|
||||
int *err)
|
||||
{
|
||||
int status;
|
||||
s32 retry = 0;
|
||||
u8 data = 0;
|
||||
|
||||
do {
|
||||
if (retry) /* wait for 1 ms till bus get settled down */
|
||||
udelay(1000);
|
||||
status = brcmf_sdioh_request_byte(sdiodev, SDIOH_READ, fnc_num,
|
||||
addr, (u8 *) &data);
|
||||
} while (status != 0
|
||||
&& (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
|
||||
if (err)
|
||||
*err = status;
|
||||
|
||||
brcmf_dbg(INFO, "fun = %d, addr = 0x%x, u8data = 0x%x\n",
|
||||
fnc_num, addr, data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
brcmf_sdcard_cfg_write(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr,
|
||||
u8 data, int *err)
|
||||
{
|
||||
int status;
|
||||
s32 retry = 0;
|
||||
|
||||
do {
|
||||
if (retry) /* wait for 1 ms till bus get settled down */
|
||||
udelay(1000);
|
||||
status = brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, fnc_num,
|
||||
addr, (u8 *) &data);
|
||||
} while (status != 0
|
||||
&& (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
|
||||
if (err)
|
||||
*err = status;
|
||||
|
||||
brcmf_dbg(INFO, "fun = %d, addr = 0x%x, u8data = 0x%x\n",
|
||||
fnc_num, addr, data);
|
||||
}
|
||||
|
||||
int
|
||||
brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
|
||||
{
|
||||
int err = 0;
|
||||
brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW,
|
||||
(address >> 8) & SBSDIO_SBADDRLOW_MASK, &err);
|
||||
if (!err)
|
||||
brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
|
||||
SBSDIO_FUNC1_SBADDRMID,
|
||||
(address >> 16) & SBSDIO_SBADDRMID_MASK,
|
||||
&err);
|
||||
if (!err)
|
||||
brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1,
|
||||
SBSDIO_FUNC1_SBADDRHIGH,
|
||||
(address >> 24) & SBSDIO_SBADDRHIGH_MASK,
|
||||
&err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
u32 brcmf_sdcard_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size)
|
||||
{
|
||||
int status;
|
||||
u32 word = 0;
|
||||
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
|
||||
|
||||
brcmf_dbg(INFO, "fun = 1, addr = 0x%x\n", addr);
|
||||
|
||||
if (bar0 != sdiodev->sbwad) {
|
||||
if (brcmf_sdcard_set_sbaddr_window(sdiodev, bar0))
|
||||
return 0xFFFFFFFF;
|
||||
|
||||
sdiodev->sbwad = bar0;
|
||||
}
|
||||
|
||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
if (size == 4)
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
status = brcmf_sdioh_request_word(sdiodev, SDIOH_READ, SDIO_FUNC_1,
|
||||
addr, &word, size);
|
||||
|
||||
sdiodev->regfail = (status != 0);
|
||||
|
||||
brcmf_dbg(INFO, "u32data = 0x%x\n", word);
|
||||
|
||||
/* if ok, return appropriately masked word */
|
||||
if (status == 0) {
|
||||
switch (size) {
|
||||
case sizeof(u8):
|
||||
return word & 0xff;
|
||||
case sizeof(u16):
|
||||
return word & 0xffff;
|
||||
case sizeof(u32):
|
||||
return word;
|
||||
default:
|
||||
sdiodev->regfail = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* otherwise, bad sdio access or invalid size */
|
||||
brcmf_dbg(ERROR, "error reading addr 0x%04x size %d\n", addr, size);
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
u32 brcmf_sdcard_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size,
|
||||
u32 data)
|
||||
{
|
||||
int status;
|
||||
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
|
||||
int err = 0;
|
||||
|
||||
brcmf_dbg(INFO, "fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
|
||||
addr, size * 8, data);
|
||||
|
||||
if (bar0 != sdiodev->sbwad) {
|
||||
err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
sdiodev->sbwad = bar0;
|
||||
}
|
||||
|
||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
if (size == 4)
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
status =
|
||||
brcmf_sdioh_request_word(sdiodev, SDIOH_WRITE, SDIO_FUNC_1,
|
||||
addr, &data, size);
|
||||
sdiodev->regfail = (status != 0);
|
||||
|
||||
if (status == 0)
|
||||
return 0;
|
||||
|
||||
brcmf_dbg(ERROR, "error writing 0x%08x to addr 0x%04x size %d\n",
|
||||
data, addr, size);
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
bool brcmf_sdcard_regfail(struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
return sdiodev->regfail;
|
||||
}
|
||||
|
||||
int
|
||||
brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
|
||||
uint flags,
|
||||
u8 *buf, uint nbytes, struct sk_buff *pkt)
|
||||
{
|
||||
int status;
|
||||
uint incr_fix;
|
||||
uint width;
|
||||
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
|
||||
int err = 0;
|
||||
|
||||
brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, nbytes);
|
||||
|
||||
/* Async not implemented yet */
|
||||
if (flags & SDIO_REQ_ASYNC)
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (bar0 != sdiodev->sbwad) {
|
||||
err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
sdiodev->sbwad = bar0;
|
||||
}
|
||||
|
||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
|
||||
incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
|
||||
width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
|
||||
if (width == 4)
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
status = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_READ,
|
||||
fn, addr, width, nbytes, buf, pkt);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int
|
||||
brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
|
||||
uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt)
|
||||
{
|
||||
uint incr_fix;
|
||||
uint width;
|
||||
uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
|
||||
int err = 0;
|
||||
|
||||
brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, nbytes);
|
||||
|
||||
/* Async not implemented yet */
|
||||
if (flags & SDIO_REQ_ASYNC)
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (bar0 != sdiodev->sbwad) {
|
||||
err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
sdiodev->sbwad = bar0;
|
||||
}
|
||||
|
||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
|
||||
incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
|
||||
width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
|
||||
if (width == 4)
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
return brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_WRITE, fn,
|
||||
addr, width, nbytes, buf, pkt);
|
||||
}
|
||||
|
||||
int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr,
|
||||
u8 *buf, uint nbytes)
|
||||
{
|
||||
addr &= SBSDIO_SB_OFT_ADDR_MASK;
|
||||
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
|
||||
return brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC,
|
||||
(rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
|
||||
addr, 4, nbytes, buf, NULL);
|
||||
}
|
||||
|
||||
int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
|
||||
{
|
||||
char t_func = (char)fn;
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
/* issue abort cmd52 command through F0 */
|
||||
brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0,
|
||||
SDIO_CCCR_ABORT, &t_func);
|
||||
|
||||
brcmf_dbg(TRACE, "Exit\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
u32 regs = 0;
|
||||
int ret = 0;
|
||||
|
||||
ret = brcmf_sdioh_attach(sdiodev);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
regs = SI_ENUM_BASE;
|
||||
|
||||
/* Report the BAR, to fix if needed */
|
||||
sdiodev->sbwad = SI_ENUM_BASE;
|
||||
|
||||
/* try to attach to the target device */
|
||||
sdiodev->bus = brcmf_sdbrcm_probe(0, 0, 0, 0, regs, sdiodev);
|
||||
if (!sdiodev->bus) {
|
||||
brcmf_dbg(ERROR, "device attach failed\n");
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
if (ret)
|
||||
brcmf_sdio_remove(sdiodev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmf_sdio_probe);
|
||||
|
||||
int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
if (sdiodev->bus) {
|
||||
brcmf_sdbrcm_disconnect(sdiodev->bus);
|
||||
sdiodev->bus = NULL;
|
||||
}
|
||||
|
||||
brcmf_sdioh_detach(sdiodev);
|
||||
|
||||
sdiodev->sbwad = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(brcmf_sdio_remove);
|
||||
|
||||
void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable)
|
||||
{
|
||||
if (enable)
|
||||
brcmf_sdbrcm_wd_timer(sdiodev->bus, BRCMF_WD_POLL_MS);
|
||||
else
|
||||
brcmf_sdbrcm_wd_timer(sdiodev->bus, 0);
|
||||
}
|
626
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
Normal file
626
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
Normal file
@ -0,0 +1,626 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 <linux/types.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/mmc/sdio.h>
|
||||
#include <linux/mmc/core.h>
|
||||
#include <linux/mmc/sdio_func.h>
|
||||
#include <linux/mmc/sdio_ids.h>
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched.h> /* request_irq() */
|
||||
#include <linux/module.h>
|
||||
#include <net/cfg80211.h>
|
||||
|
||||
#include <defs.h>
|
||||
#include <brcm_hw_ids.h>
|
||||
#include <brcmu_utils.h>
|
||||
#include <brcmu_wifi.h>
|
||||
#include "sdio_host.h"
|
||||
#include "dhd.h"
|
||||
#include "dhd_dbg.h"
|
||||
#include "wl_cfg80211.h"
|
||||
|
||||
#define SDIO_VENDOR_ID_BROADCOM 0x02d0
|
||||
|
||||
#define DMA_ALIGN_MASK 0x03
|
||||
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
|
||||
|
||||
#define SDIO_FUNC1_BLOCKSIZE 64
|
||||
#define SDIO_FUNC2_BLOCKSIZE 512
|
||||
|
||||
/* devices we support, null terminated */
|
||||
static const struct sdio_device_id brcmf_sdmmc_ids[] = {
|
||||
{SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
|
||||
{ /* end: all zeroes */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
|
||||
|
||||
static bool
|
||||
brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
bool is_err = false;
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
is_err = atomic_read(&sdiodev->suspend);
|
||||
#endif
|
||||
return is_err;
|
||||
}
|
||||
|
||||
static void
|
||||
brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, wait_queue_head_t *wq)
|
||||
{
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
int retry = 0;
|
||||
while (atomic_read(&sdiodev->suspend) && retry++ != 30)
|
||||
wait_event_timeout(*wq, false, HZ/100);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
|
||||
uint regaddr, u8 *byte)
|
||||
{
|
||||
struct sdio_func *sdfunc = sdiodev->func[0];
|
||||
int err_ret;
|
||||
|
||||
/*
|
||||
* Can only directly write to some F0 registers.
|
||||
* Handle F2 enable/disable and Abort command
|
||||
* as a special case.
|
||||
*/
|
||||
if (regaddr == SDIO_CCCR_IOEx) {
|
||||
sdfunc = sdiodev->func[2];
|
||||
if (sdfunc) {
|
||||
sdio_claim_host(sdfunc);
|
||||
if (*byte & SDIO_FUNC_ENABLE_2) {
|
||||
/* Enable Function 2 */
|
||||
err_ret = sdio_enable_func(sdfunc);
|
||||
if (err_ret)
|
||||
brcmf_dbg(ERROR,
|
||||
"enable F2 failed:%d\n",
|
||||
err_ret);
|
||||
} else {
|
||||
/* Disable Function 2 */
|
||||
err_ret = sdio_disable_func(sdfunc);
|
||||
if (err_ret)
|
||||
brcmf_dbg(ERROR,
|
||||
"Disable F2 failed:%d\n",
|
||||
err_ret);
|
||||
}
|
||||
sdio_release_host(sdfunc);
|
||||
}
|
||||
} else if (regaddr == SDIO_CCCR_ABORT) {
|
||||
sdio_claim_host(sdfunc);
|
||||
sdio_writeb(sdfunc, *byte, regaddr, &err_ret);
|
||||
sdio_release_host(sdfunc);
|
||||
} else if (regaddr < 0xF0) {
|
||||
brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr);
|
||||
err_ret = -EPERM;
|
||||
} else {
|
||||
sdio_claim_host(sdfunc);
|
||||
sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret);
|
||||
sdio_release_host(sdfunc);
|
||||
}
|
||||
|
||||
return err_ret;
|
||||
}
|
||||
|
||||
int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func,
|
||||
uint regaddr, u8 *byte)
|
||||
{
|
||||
int err_ret;
|
||||
|
||||
brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr);
|
||||
|
||||
brcmf_pm_resume_wait(sdiodev, &sdiodev->request_byte_wait);
|
||||
if (brcmf_pm_resume_error(sdiodev))
|
||||
return -EIO;
|
||||
|
||||
if (rw && func == 0) {
|
||||
/* handle F0 separately */
|
||||
err_ret = brcmf_sdioh_f0_write_byte(sdiodev, regaddr, byte);
|
||||
} else {
|
||||
sdio_claim_host(sdiodev->func[func]);
|
||||
if (rw) /* CMD52 Write */
|
||||
sdio_writeb(sdiodev->func[func], *byte, regaddr,
|
||||
&err_ret);
|
||||
else if (func == 0) {
|
||||
*byte = sdio_f0_readb(sdiodev->func[func], regaddr,
|
||||
&err_ret);
|
||||
} else {
|
||||
*byte = sdio_readb(sdiodev->func[func], regaddr,
|
||||
&err_ret);
|
||||
}
|
||||
sdio_release_host(sdiodev->func[func]);
|
||||
}
|
||||
|
||||
if (err_ret)
|
||||
brcmf_dbg(ERROR, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n",
|
||||
rw ? "write" : "read", func, regaddr, *byte, err_ret);
|
||||
|
||||
return err_ret;
|
||||
}
|
||||
|
||||
int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
|
||||
uint rw, uint func, uint addr, u32 *word,
|
||||
uint nbytes)
|
||||
{
|
||||
int err_ret = -EIO;
|
||||
|
||||
if (func == 0) {
|
||||
brcmf_dbg(ERROR, "Only CMD52 allowed to F0\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n",
|
||||
rw, func, addr, nbytes);
|
||||
|
||||
brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait);
|
||||
if (brcmf_pm_resume_error(sdiodev))
|
||||
return -EIO;
|
||||
/* Claim host controller */
|
||||
sdio_claim_host(sdiodev->func[func]);
|
||||
|
||||
if (rw) { /* CMD52 Write */
|
||||
if (nbytes == 4)
|
||||
sdio_writel(sdiodev->func[func], *word, addr,
|
||||
&err_ret);
|
||||
else if (nbytes == 2)
|
||||
sdio_writew(sdiodev->func[func], (*word & 0xFFFF),
|
||||
addr, &err_ret);
|
||||
else
|
||||
brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes);
|
||||
} else { /* CMD52 Read */
|
||||
if (nbytes == 4)
|
||||
*word = sdio_readl(sdiodev->func[func], addr, &err_ret);
|
||||
else if (nbytes == 2)
|
||||
*word = sdio_readw(sdiodev->func[func], addr,
|
||||
&err_ret) & 0xFFFF;
|
||||
else
|
||||
brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes);
|
||||
}
|
||||
|
||||
/* Release host controller */
|
||||
sdio_release_host(sdiodev->func[func]);
|
||||
|
||||
if (err_ret)
|
||||
brcmf_dbg(ERROR, "Failed to %s word, Err: 0x%08x\n",
|
||||
rw ? "write" : "read", err_ret);
|
||||
|
||||
return err_ret;
|
||||
}
|
||||
|
||||
static int
|
||||
brcmf_sdioh_request_packet(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
|
||||
uint write, uint func, uint addr,
|
||||
struct sk_buff *pkt)
|
||||
{
|
||||
bool fifo = (fix_inc == SDIOH_DATA_FIX);
|
||||
u32 SGCount = 0;
|
||||
int err_ret = 0;
|
||||
|
||||
struct sk_buff *pnext;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
brcmf_pm_resume_wait(sdiodev, &sdiodev->request_packet_wait);
|
||||
if (brcmf_pm_resume_error(sdiodev))
|
||||
return -EIO;
|
||||
|
||||
/* Claim host controller */
|
||||
sdio_claim_host(sdiodev->func[func]);
|
||||
for (pnext = pkt; pnext; pnext = pnext->next) {
|
||||
uint pkt_len = pnext->len;
|
||||
pkt_len += 3;
|
||||
pkt_len &= 0xFFFFFFFC;
|
||||
|
||||
if ((write) && (!fifo)) {
|
||||
err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
|
||||
((u8 *) (pnext->data)),
|
||||
pkt_len);
|
||||
} else if (write) {
|
||||
err_ret = sdio_memcpy_toio(sdiodev->func[func], addr,
|
||||
((u8 *) (pnext->data)),
|
||||
pkt_len);
|
||||
} else if (fifo) {
|
||||
err_ret = sdio_readsb(sdiodev->func[func],
|
||||
((u8 *) (pnext->data)),
|
||||
addr, pkt_len);
|
||||
} else {
|
||||
err_ret = sdio_memcpy_fromio(sdiodev->func[func],
|
||||
((u8 *) (pnext->data)),
|
||||
addr, pkt_len);
|
||||
}
|
||||
|
||||
if (err_ret) {
|
||||
brcmf_dbg(ERROR, "%s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n",
|
||||
write ? "TX" : "RX", pnext, SGCount, addr,
|
||||
pkt_len, err_ret);
|
||||
} else {
|
||||
brcmf_dbg(TRACE, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n",
|
||||
write ? "TX" : "RX", pnext, SGCount, addr,
|
||||
pkt_len);
|
||||
}
|
||||
|
||||
if (!fifo)
|
||||
addr += pkt_len;
|
||||
SGCount++;
|
||||
|
||||
}
|
||||
|
||||
/* Release host controller */
|
||||
sdio_release_host(sdiodev->func[func]);
|
||||
|
||||
brcmf_dbg(TRACE, "Exit\n");
|
||||
return err_ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function takes a buffer or packet, and fixes everything up
|
||||
* so that in the end, a DMA-able packet is created.
|
||||
*
|
||||
* A buffer does not have an associated packet pointer,
|
||||
* and may or may not be aligned.
|
||||
* A packet may consist of a single packet, or a packet chain.
|
||||
* If it is a packet chain, then all the packets in the chain
|
||||
* must be properly aligned.
|
||||
*
|
||||
* If the packet data is not aligned, then there may only be
|
||||
* one packet, and in this case, it is copied to a new
|
||||
* aligned packet.
|
||||
*
|
||||
*/
|
||||
int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
|
||||
uint fix_inc, uint write, uint func, uint addr,
|
||||
uint reg_width, uint buflen_u, u8 *buffer,
|
||||
struct sk_buff *pkt)
|
||||
{
|
||||
int Status;
|
||||
struct sk_buff *mypkt = NULL;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait);
|
||||
if (brcmf_pm_resume_error(sdiodev))
|
||||
return -EIO;
|
||||
/* Case 1: we don't have a packet. */
|
||||
if (pkt == NULL) {
|
||||
brcmf_dbg(DATA, "Creating new %s Packet, len=%d\n",
|
||||
write ? "TX" : "RX", buflen_u);
|
||||
mypkt = brcmu_pkt_buf_get_skb(buflen_u);
|
||||
if (!mypkt) {
|
||||
brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
|
||||
buflen_u);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* For a write, copy the buffer data into the packet. */
|
||||
if (write)
|
||||
memcpy(mypkt->data, buffer, buflen_u);
|
||||
|
||||
Status = brcmf_sdioh_request_packet(sdiodev, fix_inc, write,
|
||||
func, addr, mypkt);
|
||||
|
||||
/* For a read, copy the packet data back to the buffer. */
|
||||
if (!write)
|
||||
memcpy(buffer, mypkt->data, buflen_u);
|
||||
|
||||
brcmu_pkt_buf_free_skb(mypkt);
|
||||
} else if (((ulong) (pkt->data) & DMA_ALIGN_MASK) != 0) {
|
||||
/*
|
||||
* Case 2: We have a packet, but it is unaligned.
|
||||
* In this case, we cannot have a chain (pkt->next == NULL)
|
||||
*/
|
||||
brcmf_dbg(DATA, "Creating aligned %s Packet, len=%d\n",
|
||||
write ? "TX" : "RX", pkt->len);
|
||||
mypkt = brcmu_pkt_buf_get_skb(pkt->len);
|
||||
if (!mypkt) {
|
||||
brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n",
|
||||
pkt->len);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* For a write, copy the buffer data into the packet. */
|
||||
if (write)
|
||||
memcpy(mypkt->data, pkt->data, pkt->len);
|
||||
|
||||
Status = brcmf_sdioh_request_packet(sdiodev, fix_inc, write,
|
||||
func, addr, mypkt);
|
||||
|
||||
/* For a read, copy the packet data back to the buffer. */
|
||||
if (!write)
|
||||
memcpy(pkt->data, mypkt->data, mypkt->len);
|
||||
|
||||
brcmu_pkt_buf_free_skb(mypkt);
|
||||
} else { /* case 3: We have a packet and
|
||||
it is aligned. */
|
||||
brcmf_dbg(DATA, "Aligned %s Packet, direct DMA\n",
|
||||
write ? "Tx" : "Rx");
|
||||
Status = brcmf_sdioh_request_packet(sdiodev, fix_inc, write,
|
||||
func, addr, pkt);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Read client card reg */
|
||||
static int
|
||||
brcmf_sdioh_card_regread(struct brcmf_sdio_dev *sdiodev, int func, u32 regaddr,
|
||||
int regsize, u32 *data)
|
||||
{
|
||||
|
||||
if ((func == 0) || (regsize == 1)) {
|
||||
u8 temp = 0;
|
||||
|
||||
brcmf_sdioh_request_byte(sdiodev, SDIOH_READ, func, regaddr,
|
||||
&temp);
|
||||
*data = temp;
|
||||
*data &= 0xff;
|
||||
brcmf_dbg(DATA, "byte read data=0x%02x\n", *data);
|
||||
} else {
|
||||
brcmf_sdioh_request_word(sdiodev, SDIOH_READ, func, regaddr,
|
||||
data, regsize);
|
||||
if (regsize == 2)
|
||||
*data &= 0xffff;
|
||||
|
||||
brcmf_dbg(DATA, "word read data=0x%08x\n", *data);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr)
|
||||
{
|
||||
/* read 24 bits and return valid 17 bit addr */
|
||||
int i;
|
||||
u32 scratch, regdata;
|
||||
__le32 scratch_le;
|
||||
u8 *ptr = (u8 *)&scratch_le;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if ((brcmf_sdioh_card_regread(sdiodev, 0, regaddr, 1,
|
||||
®data)) != SUCCESS)
|
||||
brcmf_dbg(ERROR, "Can't read!\n");
|
||||
|
||||
*ptr++ = (u8) regdata;
|
||||
regaddr++;
|
||||
}
|
||||
|
||||
/* Only the lower 17-bits are valid */
|
||||
scratch = le32_to_cpu(scratch_le);
|
||||
scratch &= 0x0001FFFF;
|
||||
return scratch;
|
||||
}
|
||||
|
||||
static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
int err_ret;
|
||||
u32 fbraddr;
|
||||
u8 func;
|
||||
|
||||
brcmf_dbg(TRACE, "\n");
|
||||
|
||||
/* Get the Card's common CIS address */
|
||||
sdiodev->func_cis_ptr[0] = brcmf_sdioh_get_cisaddr(sdiodev,
|
||||
SDIO_CCCR_CIS);
|
||||
brcmf_dbg(INFO, "Card's Common CIS Ptr = 0x%x\n",
|
||||
sdiodev->func_cis_ptr[0]);
|
||||
|
||||
/* Get the Card's function CIS (for each function) */
|
||||
for (fbraddr = SDIO_FBR_BASE(1), func = 1;
|
||||
func <= sdiodev->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) {
|
||||
sdiodev->func_cis_ptr[func] =
|
||||
brcmf_sdioh_get_cisaddr(sdiodev, SDIO_FBR_CIS + fbraddr);
|
||||
brcmf_dbg(INFO, "Function %d CIS Ptr = 0x%x\n",
|
||||
func, sdiodev->func_cis_ptr[func]);
|
||||
}
|
||||
|
||||
/* Enable Function 1 */
|
||||
sdio_claim_host(sdiodev->func[1]);
|
||||
err_ret = sdio_enable_func(sdiodev->func[1]);
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
if (err_ret)
|
||||
brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Public entry points & extern's
|
||||
*/
|
||||
int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
int err_ret = 0;
|
||||
|
||||
brcmf_dbg(TRACE, "\n");
|
||||
|
||||
sdiodev->num_funcs = 2;
|
||||
|
||||
sdio_claim_host(sdiodev->func[1]);
|
||||
err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE);
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
if (err_ret) {
|
||||
brcmf_dbg(ERROR, "Failed to set F1 blocksize\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
sdio_claim_host(sdiodev->func[2]);
|
||||
err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE);
|
||||
sdio_release_host(sdiodev->func[2]);
|
||||
if (err_ret) {
|
||||
brcmf_dbg(ERROR, "Failed to set F2 blocksize\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
brcmf_sdioh_enablefuncs(sdiodev);
|
||||
|
||||
out:
|
||||
brcmf_dbg(TRACE, "Done\n");
|
||||
return err_ret;
|
||||
}
|
||||
|
||||
void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev)
|
||||
{
|
||||
brcmf_dbg(TRACE, "\n");
|
||||
|
||||
/* Disable Function 2 */
|
||||
sdio_claim_host(sdiodev->func[2]);
|
||||
sdio_disable_func(sdiodev->func[2]);
|
||||
sdio_release_host(sdiodev->func[2]);
|
||||
|
||||
/* Disable Function 1 */
|
||||
sdio_claim_host(sdiodev->func[1]);
|
||||
sdio_disable_func(sdiodev->func[1]);
|
||||
sdio_release_host(sdiodev->func[1]);
|
||||
|
||||
}
|
||||
|
||||
static int brcmf_ops_sdio_probe(struct sdio_func *func,
|
||||
const struct sdio_device_id *id)
|
||||
{
|
||||
int ret = 0;
|
||||
struct brcmf_sdio_dev *sdiodev;
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
brcmf_dbg(TRACE, "func->class=%x\n", func->class);
|
||||
brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor);
|
||||
brcmf_dbg(TRACE, "sdio_device: 0x%04x\n", func->device);
|
||||
brcmf_dbg(TRACE, "Function#: 0x%04x\n", func->num);
|
||||
|
||||
if (func->num == 1) {
|
||||
if (dev_get_drvdata(&func->card->dev)) {
|
||||
brcmf_dbg(ERROR, "card private drvdata occupied\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL);
|
||||
if (!sdiodev)
|
||||
return -ENOMEM;
|
||||
sdiodev->func[0] = func->card->sdio_func[0];
|
||||
sdiodev->func[1] = func;
|
||||
dev_set_drvdata(&func->card->dev, sdiodev);
|
||||
|
||||
atomic_set(&sdiodev->suspend, false);
|
||||
init_waitqueue_head(&sdiodev->request_byte_wait);
|
||||
init_waitqueue_head(&sdiodev->request_word_wait);
|
||||
init_waitqueue_head(&sdiodev->request_packet_wait);
|
||||
init_waitqueue_head(&sdiodev->request_buffer_wait);
|
||||
}
|
||||
|
||||
if (func->num == 2) {
|
||||
sdiodev = dev_get_drvdata(&func->card->dev);
|
||||
if ((!sdiodev) || (sdiodev->func[1]->card != func->card))
|
||||
return -ENODEV;
|
||||
sdiodev->func[2] = func;
|
||||
|
||||
brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n");
|
||||
ret = brcmf_sdio_probe(sdiodev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void brcmf_ops_sdio_remove(struct sdio_func *func)
|
||||
{
|
||||
struct brcmf_sdio_dev *sdiodev;
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
brcmf_dbg(INFO, "func->class=%x\n", func->class);
|
||||
brcmf_dbg(INFO, "sdio_vendor: 0x%04x\n", func->vendor);
|
||||
brcmf_dbg(INFO, "sdio_device: 0x%04x\n", func->device);
|
||||
brcmf_dbg(INFO, "Function#: 0x%04x\n", func->num);
|
||||
|
||||
if (func->num == 2) {
|
||||
sdiodev = dev_get_drvdata(&func->card->dev);
|
||||
brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n");
|
||||
brcmf_sdio_remove(sdiodev);
|
||||
dev_set_drvdata(&func->card->dev, NULL);
|
||||
kfree(sdiodev);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int brcmf_sdio_suspend(struct device *dev)
|
||||
{
|
||||
mmc_pm_flag_t sdio_flags;
|
||||
struct brcmf_sdio_dev *sdiodev;
|
||||
struct sdio_func *func = dev_to_sdio_func(dev);
|
||||
int ret = 0;
|
||||
|
||||
brcmf_dbg(TRACE, "\n");
|
||||
|
||||
sdiodev = dev_get_drvdata(&func->card->dev);
|
||||
|
||||
atomic_set(&sdiodev->suspend, true);
|
||||
|
||||
sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]);
|
||||
if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
|
||||
brcmf_dbg(ERROR, "Host can't keep power while suspended\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER);
|
||||
if (ret) {
|
||||
brcmf_dbg(ERROR, "Failed to set pm_flags\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
brcmf_sdio_wdtmr_enable(sdiodev, false);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int brcmf_sdio_resume(struct device *dev)
|
||||
{
|
||||
struct brcmf_sdio_dev *sdiodev;
|
||||
struct sdio_func *func = dev_to_sdio_func(dev);
|
||||
|
||||
sdiodev = dev_get_drvdata(&func->card->dev);
|
||||
brcmf_sdio_wdtmr_enable(sdiodev, true);
|
||||
atomic_set(&sdiodev->suspend, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops brcmf_sdio_pm_ops = {
|
||||
.suspend = brcmf_sdio_suspend,
|
||||
.resume = brcmf_sdio_resume,
|
||||
};
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
static struct sdio_driver brcmf_sdmmc_driver = {
|
||||
.probe = brcmf_ops_sdio_probe,
|
||||
.remove = brcmf_ops_sdio_remove,
|
||||
.name = "brcmfmac",
|
||||
.id_table = brcmf_sdmmc_ids,
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
.drv = {
|
||||
.pm = &brcmf_sdio_pm_ops,
|
||||
},
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
};
|
||||
|
||||
/* bus register interface */
|
||||
int brcmf_bus_register(void)
|
||||
{
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
return sdio_register_driver(&brcmf_sdmmc_driver);
|
||||
}
|
||||
|
||||
void brcmf_bus_unregister(void)
|
||||
{
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
sdio_unregister_driver(&brcmf_sdmmc_driver);
|
||||
}
|
776
drivers/net/wireless/brcm80211/brcmfmac/dhd.h
Normal file
776
drivers/net/wireless/brcm80211/brcmfmac/dhd.h
Normal file
@ -0,0 +1,776 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/****************
|
||||
* Common types *
|
||||
*/
|
||||
|
||||
#ifndef _BRCMF_H_
|
||||
#define _BRCMF_H_
|
||||
|
||||
#define BRCMF_VERSION_STR "4.218.248.5"
|
||||
|
||||
/*******************************************************************************
|
||||
* IO codes that are interpreted by dongle firmware
|
||||
******************************************************************************/
|
||||
#define BRCMF_C_UP 2
|
||||
#define BRCMF_C_SET_PROMISC 10
|
||||
#define BRCMF_C_GET_RATE 12
|
||||
#define BRCMF_C_GET_INFRA 19
|
||||
#define BRCMF_C_SET_INFRA 20
|
||||
#define BRCMF_C_GET_AUTH 21
|
||||
#define BRCMF_C_SET_AUTH 22
|
||||
#define BRCMF_C_GET_BSSID 23
|
||||
#define BRCMF_C_GET_SSID 25
|
||||
#define BRCMF_C_SET_SSID 26
|
||||
#define BRCMF_C_GET_CHANNEL 29
|
||||
#define BRCMF_C_GET_SRL 31
|
||||
#define BRCMF_C_GET_LRL 33
|
||||
#define BRCMF_C_GET_RADIO 37
|
||||
#define BRCMF_C_SET_RADIO 38
|
||||
#define BRCMF_C_GET_PHYTYPE 39
|
||||
#define BRCMF_C_SET_KEY 45
|
||||
#define BRCMF_C_SET_PASSIVE_SCAN 49
|
||||
#define BRCMF_C_SCAN 50
|
||||
#define BRCMF_C_SCAN_RESULTS 51
|
||||
#define BRCMF_C_DISASSOC 52
|
||||
#define BRCMF_C_REASSOC 53
|
||||
#define BRCMF_C_SET_ROAM_TRIGGER 55
|
||||
#define BRCMF_C_SET_ROAM_DELTA 57
|
||||
#define BRCMF_C_GET_DTIMPRD 77
|
||||
#define BRCMF_C_SET_COUNTRY 84
|
||||
#define BRCMF_C_GET_PM 85
|
||||
#define BRCMF_C_SET_PM 86
|
||||
#define BRCMF_C_GET_AP 117
|
||||
#define BRCMF_C_SET_AP 118
|
||||
#define BRCMF_C_GET_RSSI 127
|
||||
#define BRCMF_C_GET_WSEC 133
|
||||
#define BRCMF_C_SET_WSEC 134
|
||||
#define BRCMF_C_GET_PHY_NOISE 135
|
||||
#define BRCMF_C_GET_BSS_INFO 136
|
||||
#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
|
||||
#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
|
||||
#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201
|
||||
#define BRCMF_C_GET_VALID_CHANNELS 217
|
||||
#define BRCMF_C_GET_KEY_PRIMARY 235
|
||||
#define BRCMF_C_SET_KEY_PRIMARY 236
|
||||
#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258
|
||||
#define BRCMF_C_GET_VAR 262
|
||||
#define BRCMF_C_SET_VAR 263
|
||||
|
||||
/* phy types (returned by WLC_GET_PHYTPE) */
|
||||
#define WLC_PHY_TYPE_A 0
|
||||
#define WLC_PHY_TYPE_B 1
|
||||
#define WLC_PHY_TYPE_G 2
|
||||
#define WLC_PHY_TYPE_N 4
|
||||
#define WLC_PHY_TYPE_LP 5
|
||||
#define WLC_PHY_TYPE_SSN 6
|
||||
#define WLC_PHY_TYPE_HT 7
|
||||
#define WLC_PHY_TYPE_LCN 8
|
||||
#define WLC_PHY_TYPE_NULL 0xf
|
||||
|
||||
#define BRCMF_EVENTING_MASK_LEN 16
|
||||
|
||||
#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 */
|
||||
|
||||
/* size of brcmf_scan_params not including variable length array */
|
||||
#define BRCMF_SCAN_PARAMS_FIXED_SIZE 64
|
||||
|
||||
/* masks for channel and ssid count */
|
||||
#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
|
||||
#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16
|
||||
|
||||
#define BRCMF_SCAN_ACTION_START 1
|
||||
#define BRCMF_SCAN_ACTION_CONTINUE 2
|
||||
#define WL_SCAN_ACTION_ABORT 3
|
||||
|
||||
#define BRCMF_ISCAN_REQ_VERSION 1
|
||||
|
||||
/* brcmf_iscan_results status values */
|
||||
#define BRCMF_SCAN_RESULTS_SUCCESS 0
|
||||
#define BRCMF_SCAN_RESULTS_PARTIAL 1
|
||||
#define BRCMF_SCAN_RESULTS_PENDING 2
|
||||
#define BRCMF_SCAN_RESULTS_ABORTED 3
|
||||
#define BRCMF_SCAN_RESULTS_NO_MEM 4
|
||||
|
||||
/* Indicates this key is using soft encrypt */
|
||||
#define WL_SOFT_KEY (1 << 0)
|
||||
/* primary (ie tx) key */
|
||||
#define BRCMF_PRIMARY_KEY (1 << 1)
|
||||
/* Reserved for backward compat */
|
||||
#define WL_KF_RES_4 (1 << 4)
|
||||
/* Reserved for backward compat */
|
||||
#define WL_KF_RES_5 (1 << 5)
|
||||
/* Indicates a group key for a IBSS PEER */
|
||||
#define WL_IBSS_PEER_GROUP_KEY (1 << 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
|
||||
|
||||
#define BRCMF_EVENT_MSG_LINK 0x01
|
||||
#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02
|
||||
#define BRCMF_EVENT_MSG_GROUP 0x04
|
||||
|
||||
struct brcmf_event_msg {
|
||||
__be16 version;
|
||||
__be16 flags;
|
||||
__be32 event_type;
|
||||
__be32 status;
|
||||
__be32 reason;
|
||||
__be32 auth_type;
|
||||
__be32 datalen;
|
||||
u8 addr[ETH_ALEN];
|
||||
char ifname[IFNAMSIZ];
|
||||
} __packed;
|
||||
|
||||
struct brcm_ethhdr {
|
||||
u16 subtype;
|
||||
u16 length;
|
||||
u8 version;
|
||||
u8 oui[3];
|
||||
u16 usr_subtype;
|
||||
} __packed;
|
||||
|
||||
struct brcmf_event {
|
||||
struct ethhdr eth;
|
||||
struct brcm_ethhdr hdr;
|
||||
struct brcmf_event_msg msg;
|
||||
} __packed;
|
||||
|
||||
struct dngl_stats {
|
||||
unsigned long rx_packets; /* total packets received */
|
||||
unsigned long tx_packets; /* total packets transmitted */
|
||||
unsigned long rx_bytes; /* total bytes received */
|
||||
unsigned long tx_bytes; /* total bytes transmitted */
|
||||
unsigned long rx_errors; /* bad packets received */
|
||||
unsigned long tx_errors; /* packet transmit problems */
|
||||
unsigned long rx_dropped; /* packets dropped by dongle */
|
||||
unsigned long tx_dropped; /* packets dropped by dongle */
|
||||
unsigned long multicast; /* multicast packets received */
|
||||
};
|
||||
|
||||
/* event codes sent by the dongle to this driver */
|
||||
#define BRCMF_E_SET_SSID 0
|
||||
#define BRCMF_E_JOIN 1
|
||||
#define BRCMF_E_START 2
|
||||
#define BRCMF_E_AUTH 3
|
||||
#define BRCMF_E_AUTH_IND 4
|
||||
#define BRCMF_E_DEAUTH 5
|
||||
#define BRCMF_E_DEAUTH_IND 6
|
||||
#define BRCMF_E_ASSOC 7
|
||||
#define BRCMF_E_ASSOC_IND 8
|
||||
#define BRCMF_E_REASSOC 9
|
||||
#define BRCMF_E_REASSOC_IND 10
|
||||
#define BRCMF_E_DISASSOC 11
|
||||
#define BRCMF_E_DISASSOC_IND 12
|
||||
#define BRCMF_E_QUIET_START 13
|
||||
#define BRCMF_E_QUIET_END 14
|
||||
#define BRCMF_E_BEACON_RX 15
|
||||
#define BRCMF_E_LINK 16
|
||||
#define BRCMF_E_MIC_ERROR 17
|
||||
#define BRCMF_E_NDIS_LINK 18
|
||||
#define BRCMF_E_ROAM 19
|
||||
#define BRCMF_E_TXFAIL 20
|
||||
#define BRCMF_E_PMKID_CACHE 21
|
||||
#define BRCMF_E_RETROGRADE_TSF 22
|
||||
#define BRCMF_E_PRUNE 23
|
||||
#define BRCMF_E_AUTOAUTH 24
|
||||
#define BRCMF_E_EAPOL_MSG 25
|
||||
#define BRCMF_E_SCAN_COMPLETE 26
|
||||
#define BRCMF_E_ADDTS_IND 27
|
||||
#define BRCMF_E_DELTS_IND 28
|
||||
#define BRCMF_E_BCNSENT_IND 29
|
||||
#define BRCMF_E_BCNRX_MSG 30
|
||||
#define BRCMF_E_BCNLOST_MSG 31
|
||||
#define BRCMF_E_ROAM_PREP 32
|
||||
#define BRCMF_E_PFN_NET_FOUND 33
|
||||
#define BRCMF_E_PFN_NET_LOST 34
|
||||
#define BRCMF_E_RESET_COMPLETE 35
|
||||
#define BRCMF_E_JOIN_START 36
|
||||
#define BRCMF_E_ROAM_START 37
|
||||
#define BRCMF_E_ASSOC_START 38
|
||||
#define BRCMF_E_IBSS_ASSOC 39
|
||||
#define BRCMF_E_RADIO 40
|
||||
#define BRCMF_E_PSM_WATCHDOG 41
|
||||
#define BRCMF_E_PROBREQ_MSG 44
|
||||
#define BRCMF_E_SCAN_CONFIRM_IND 45
|
||||
#define BRCMF_E_PSK_SUP 46
|
||||
#define BRCMF_E_COUNTRY_CODE_CHANGED 47
|
||||
#define BRCMF_E_EXCEEDED_MEDIUM_TIME 48
|
||||
#define BRCMF_E_ICV_ERROR 49
|
||||
#define BRCMF_E_UNICAST_DECODE_ERROR 50
|
||||
#define BRCMF_E_MULTICAST_DECODE_ERROR 51
|
||||
#define BRCMF_E_TRACE 52
|
||||
#define BRCMF_E_IF 54
|
||||
#define BRCMF_E_RSSI 56
|
||||
#define BRCMF_E_PFN_SCAN_COMPLETE 57
|
||||
#define BRCMF_E_EXTLOG_MSG 58
|
||||
#define BRCMF_E_ACTION_FRAME 59
|
||||
#define BRCMF_E_ACTION_FRAME_COMPLETE 60
|
||||
#define BRCMF_E_PRE_ASSOC_IND 61
|
||||
#define BRCMF_E_PRE_REASSOC_IND 62
|
||||
#define BRCMF_E_CHANNEL_ADOPTED 63
|
||||
#define BRCMF_E_AP_STARTED 64
|
||||
#define BRCMF_E_DFS_AP_STOP 65
|
||||
#define BRCMF_E_DFS_AP_RESUME 66
|
||||
#define BRCMF_E_RESERVED1 67
|
||||
#define BRCMF_E_RESERVED2 68
|
||||
#define BRCMF_E_ESCAN_RESULT 69
|
||||
#define BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70
|
||||
#define BRCMF_E_DCS_REQUEST 73
|
||||
|
||||
#define BRCMF_E_FIFO_CREDIT_MAP 74
|
||||
|
||||
#define BRCMF_E_LAST 75
|
||||
|
||||
#define BRCMF_E_STATUS_SUCCESS 0
|
||||
#define BRCMF_E_STATUS_FAIL 1
|
||||
#define BRCMF_E_STATUS_TIMEOUT 2
|
||||
#define BRCMF_E_STATUS_NO_NETWORKS 3
|
||||
#define BRCMF_E_STATUS_ABORT 4
|
||||
#define BRCMF_E_STATUS_NO_ACK 5
|
||||
#define BRCMF_E_STATUS_UNSOLICITED 6
|
||||
#define BRCMF_E_STATUS_ATTEMPT 7
|
||||
#define BRCMF_E_STATUS_PARTIAL 8
|
||||
#define BRCMF_E_STATUS_NEWSCAN 9
|
||||
#define BRCMF_E_STATUS_NEWASSOC 10
|
||||
#define BRCMF_E_STATUS_11HQUIET 11
|
||||
#define BRCMF_E_STATUS_SUPPRESS 12
|
||||
#define BRCMF_E_STATUS_NOCHANS 13
|
||||
#define BRCMF_E_STATUS_CS_ABORT 15
|
||||
#define BRCMF_E_STATUS_ERROR 16
|
||||
|
||||
#define BRCMF_E_REASON_INITIAL_ASSOC 0
|
||||
#define BRCMF_E_REASON_LOW_RSSI 1
|
||||
#define BRCMF_E_REASON_DEAUTH 2
|
||||
#define BRCMF_E_REASON_DISASSOC 3
|
||||
#define BRCMF_E_REASON_BCNS_LOST 4
|
||||
#define BRCMF_E_REASON_MINTXRATE 9
|
||||
#define BRCMF_E_REASON_TXFAIL 10
|
||||
|
||||
#define BRCMF_E_REASON_FAST_ROAM_FAILED 5
|
||||
#define BRCMF_E_REASON_DIRECTED_ROAM 6
|
||||
#define BRCMF_E_REASON_TSPEC_REJECTED 7
|
||||
#define BRCMF_E_REASON_BETTER_AP 8
|
||||
|
||||
#define BRCMF_E_PRUNE_ENCR_MISMATCH 1
|
||||
#define BRCMF_E_PRUNE_BCAST_BSSID 2
|
||||
#define BRCMF_E_PRUNE_MAC_DENY 3
|
||||
#define BRCMF_E_PRUNE_MAC_NA 4
|
||||
#define BRCMF_E_PRUNE_REG_PASSV 5
|
||||
#define BRCMF_E_PRUNE_SPCT_MGMT 6
|
||||
#define BRCMF_E_PRUNE_RADAR 7
|
||||
#define BRCMF_E_RSN_MISMATCH 8
|
||||
#define BRCMF_E_PRUNE_NO_COMMON_RATES 9
|
||||
#define BRCMF_E_PRUNE_BASIC_RATES 10
|
||||
#define BRCMF_E_PRUNE_CIPHER_NA 12
|
||||
#define BRCMF_E_PRUNE_KNOWN_STA 13
|
||||
#define BRCMF_E_PRUNE_WDS_PEER 15
|
||||
#define BRCMF_E_PRUNE_QBSS_LOAD 16
|
||||
#define BRCMF_E_PRUNE_HOME_AP 17
|
||||
|
||||
#define BRCMF_E_SUP_OTHER 0
|
||||
#define BRCMF_E_SUP_DECRYPT_KEY_DATA 1
|
||||
#define BRCMF_E_SUP_BAD_UCAST_WEP128 2
|
||||
#define BRCMF_E_SUP_BAD_UCAST_WEP40 3
|
||||
#define BRCMF_E_SUP_UNSUP_KEY_LEN 4
|
||||
#define BRCMF_E_SUP_PW_KEY_CIPHER 5
|
||||
#define BRCMF_E_SUP_MSG3_TOO_MANY_IE 6
|
||||
#define BRCMF_E_SUP_MSG3_IE_MISMATCH 7
|
||||
#define BRCMF_E_SUP_NO_INSTALL_FLAG 8
|
||||
#define BRCMF_E_SUP_MSG3_NO_GTK 9
|
||||
#define BRCMF_E_SUP_GRP_KEY_CIPHER 10
|
||||
#define BRCMF_E_SUP_GRP_MSG1_NO_GTK 11
|
||||
#define BRCMF_E_SUP_GTK_DECRYPT_FAIL 12
|
||||
#define BRCMF_E_SUP_SEND_FAIL 13
|
||||
#define BRCMF_E_SUP_DEAUTH 14
|
||||
|
||||
#define BRCMF_E_IF_ADD 1
|
||||
#define BRCMF_E_IF_DEL 2
|
||||
#define BRCMF_E_IF_CHANGE 3
|
||||
|
||||
#define BRCMF_E_IF_ROLE_STA 0
|
||||
#define BRCMF_E_IF_ROLE_AP 1
|
||||
#define BRCMF_E_IF_ROLE_WDS 2
|
||||
|
||||
#define BRCMF_E_LINK_BCN_LOSS 1
|
||||
#define BRCMF_E_LINK_DISASSOC 2
|
||||
#define BRCMF_E_LINK_ASSOC_REC 3
|
||||
#define BRCMF_E_LINK_BSSCFG_DIS 4
|
||||
|
||||
/* The level of bus communication with the dongle */
|
||||
enum brcmf_bus_state {
|
||||
BRCMF_BUS_DOWN, /* Not ready for frame transfers */
|
||||
BRCMF_BUS_LOAD, /* Download access only (CPU reset) */
|
||||
BRCMF_BUS_DATA /* Ready for frame transfers */
|
||||
};
|
||||
|
||||
/* Pattern matching filter. Specifies an offset within received packets to
|
||||
* start matching, the pattern to match, the size of the pattern, and a bitmask
|
||||
* that indicates which bits within the pattern should be matched.
|
||||
*/
|
||||
struct brcmf_pkt_filter_pattern_le {
|
||||
/*
|
||||
* Offset within received packet to start pattern matching.
|
||||
* Offset '0' is the first byte of the ethernet header.
|
||||
*/
|
||||
__le32 offset;
|
||||
/* Size of the pattern. Bitmask must be the same size.*/
|
||||
__le32 size_bytes;
|
||||
/*
|
||||
* Variable length mask and pattern data. mask starts at offset 0.
|
||||
* Pattern immediately follows mask.
|
||||
*/
|
||||
u8 mask_and_pattern[1];
|
||||
};
|
||||
|
||||
/* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */
|
||||
struct brcmf_pkt_filter_le {
|
||||
__le32 id; /* Unique filter id, specified by app. */
|
||||
__le32 type; /* Filter type (WL_PKT_FILTER_TYPE_xxx). */
|
||||
__le32 negate_match; /* Negate the result of filter matches */
|
||||
union { /* Filter definitions */
|
||||
struct brcmf_pkt_filter_pattern_le pattern; /* Filter pattern */
|
||||
} u;
|
||||
};
|
||||
|
||||
/* IOVAR "pkt_filter_enable" parameter. */
|
||||
struct brcmf_pkt_filter_enable_le {
|
||||
__le32 id; /* Unique filter id */
|
||||
__le32 enable; /* Enable/disable bool */
|
||||
};
|
||||
|
||||
/* BSS info structure
|
||||
* 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 {
|
||||
__le32 version; /* version field */
|
||||
__le32 length; /* byte length of data in this record,
|
||||
* starting at version and including IEs
|
||||
*/
|
||||
u8 BSSID[ETH_ALEN];
|
||||
__le16 beacon_period; /* units are Kusec */
|
||||
__le16 capability; /* Capability information */
|
||||
u8 SSID_len;
|
||||
u8 SSID[32];
|
||||
struct {
|
||||
__le32 count; /* # rates in this set */
|
||||
u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */
|
||||
} rateset; /* supported rates */
|
||||
__le16 chanspec; /* chanspec for bss */
|
||||
__le16 atim_window; /* units are Kusec */
|
||||
u8 dtim_period; /* DTIM period */
|
||||
__le16 RSSI; /* receive signal strength (in dBm) */
|
||||
s8 phy_noise; /* noise (in dBm) */
|
||||
|
||||
u8 n_cap; /* BSS is 802.11N Capable */
|
||||
/* 802.11N BSS Capabilities (based on HT_CAP_*): */
|
||||
__le32 nbss_cap;
|
||||
u8 ctl_ch; /* 802.11N BSS control channel number */
|
||||
__le32 reserved32[1]; /* Reserved for expansion of BSS properties */
|
||||
u8 flags; /* flags */
|
||||
u8 reserved[3]; /* Reserved for expansion of BSS properties */
|
||||
u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */
|
||||
|
||||
__le16 ie_offset; /* offset at which IEs start, from beginning */
|
||||
__le32 ie_length; /* byte length of Information Elements */
|
||||
__le16 SNR; /* average SNR of during frame reception */
|
||||
/* Add new fields here */
|
||||
/* variable length Information Elements */
|
||||
};
|
||||
|
||||
struct brcm_rateset_le {
|
||||
/* # rates in this set */
|
||||
__le32 count;
|
||||
/* rates in 500kbps units w/hi bit set if basic */
|
||||
u8 rates[WL_NUMRATES];
|
||||
};
|
||||
|
||||
struct brcmf_ssid {
|
||||
u32 SSID_len;
|
||||
unsigned char SSID[32];
|
||||
};
|
||||
|
||||
struct brcmf_ssid_le {
|
||||
__le32 SSID_len;
|
||||
unsigned char SSID[32];
|
||||
};
|
||||
|
||||
struct brcmf_scan_params_le {
|
||||
struct brcmf_ssid_le ssid_le; /* default: {0, ""} */
|
||||
u8 bssid[ETH_ALEN]; /* default: bcast */
|
||||
s8 bss_type; /* default: any,
|
||||
* DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT
|
||||
*/
|
||||
u8 scan_type; /* flags, 0 use default */
|
||||
__le32 nprobes; /* -1 use default, number of probes per channel */
|
||||
__le32 active_time; /* -1 use default, dwell time per channel for
|
||||
* active scanning
|
||||
*/
|
||||
__le32 passive_time; /* -1 use default, dwell time per channel
|
||||
* for passive scanning
|
||||
*/
|
||||
__le32 home_time; /* -1 use default, dwell time for the
|
||||
* home channel between channel scans
|
||||
*/
|
||||
__le32 channel_num; /* count of channels and ssids that follow
|
||||
*
|
||||
* low half is count of channels in
|
||||
* channel_list, 0 means default (use all
|
||||
* available channels)
|
||||
*
|
||||
* high half is entries in struct brcmf_ssid
|
||||
* array that follows channel_list, aligned for
|
||||
* s32 (4 bytes) meaning an odd channel count
|
||||
* implies a 2-byte pad between end of
|
||||
* channel_list and first ssid
|
||||
*
|
||||
* if ssid count is zero, single ssid in the
|
||||
* fixed parameter portion is assumed, otherwise
|
||||
* ssid in the fixed portion is ignored
|
||||
*/
|
||||
__le16 channel_list[1]; /* list of chanspecs */
|
||||
};
|
||||
|
||||
/* incremental scan struct */
|
||||
struct brcmf_iscan_params_le {
|
||||
__le32 version;
|
||||
__le16 action;
|
||||
__le16 scan_duration;
|
||||
struct brcmf_scan_params_le params_le;
|
||||
};
|
||||
|
||||
struct brcmf_scan_results {
|
||||
u32 buflen;
|
||||
u32 version;
|
||||
u32 count;
|
||||
struct brcmf_bss_info bss_info[1];
|
||||
};
|
||||
|
||||
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 */
|
||||
struct brcmf_assoc_params_le {
|
||||
/* 00:00:00:00:00:00: broadcast scan */
|
||||
u8 bssid[ETH_ALEN];
|
||||
/* 0: all available channels, otherwise count of chanspecs in
|
||||
* chanspec_list */
|
||||
__le32 chanspec_num;
|
||||
/* list of chanspecs */
|
||||
__le16 chanspec_list[1];
|
||||
};
|
||||
|
||||
/* used for join with or without a specific bssid and channel list */
|
||||
struct brcmf_join_params {
|
||||
struct brcmf_ssid_le ssid_le;
|
||||
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 {
|
||||
u32 status;
|
||||
__le32 status_le;
|
||||
};
|
||||
union {
|
||||
struct brcmf_scan_results results;
|
||||
struct brcmf_scan_results_le results_le;
|
||||
};
|
||||
};
|
||||
|
||||
/* size of brcmf_iscan_results not including variable length array */
|
||||
#define BRCMF_ISCAN_RESULTS_FIXED_SIZE \
|
||||
(BRCMF_SCAN_RESULTS_FIXED_SIZE + \
|
||||
offsetof(struct brcmf_iscan_results, results))
|
||||
|
||||
struct brcmf_wsec_key {
|
||||
u32 index; /* key index */
|
||||
u32 len; /* key length */
|
||||
u8 data[WLAN_MAX_KEY_LEN]; /* key data */
|
||||
u32 pad_1[18];
|
||||
u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
|
||||
u32 flags; /* misc flags */
|
||||
u32 pad_2[3];
|
||||
u32 iv_initialized; /* has IV been initialized already? */
|
||||
u32 pad_3;
|
||||
/* Rx IV */
|
||||
struct {
|
||||
u32 hi; /* upper 32 bits of IV */
|
||||
u16 lo; /* lower 16 bits of IV */
|
||||
} rxiv;
|
||||
u32 pad_4[2];
|
||||
u8 ea[ETH_ALEN]; /* per station */
|
||||
};
|
||||
|
||||
/*
|
||||
* dongle requires same struct as above but with fields in little endian order
|
||||
*/
|
||||
struct brcmf_wsec_key_le {
|
||||
__le32 index; /* key index */
|
||||
__le32 len; /* key length */
|
||||
u8 data[WLAN_MAX_KEY_LEN]; /* key data */
|
||||
__le32 pad_1[18];
|
||||
__le32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */
|
||||
__le32 flags; /* misc flags */
|
||||
__le32 pad_2[3];
|
||||
__le32 iv_initialized; /* has IV been initialized already? */
|
||||
__le32 pad_3;
|
||||
/* Rx IV */
|
||||
struct {
|
||||
__le32 hi; /* upper 32 bits of IV */
|
||||
__le16 lo; /* lower 16 bits of IV */
|
||||
} rxiv;
|
||||
__le32 pad_4[2];
|
||||
u8 ea[ETH_ALEN]; /* per station */
|
||||
};
|
||||
|
||||
/* Used to get specific STA parameters */
|
||||
struct brcmf_scb_val_le {
|
||||
__le32 val;
|
||||
u8 ea[ETH_ALEN];
|
||||
};
|
||||
|
||||
/* channel encoding */
|
||||
struct brcmf_channel_info_le {
|
||||
__le32 hw_channel;
|
||||
__le32 target_channel;
|
||||
__le32 scan_channel;
|
||||
};
|
||||
|
||||
/* Bus independent dongle command */
|
||||
struct brcmf_dcmd {
|
||||
uint cmd; /* common dongle cmd definition */
|
||||
void *buf; /* pointer to user buffer */
|
||||
uint len; /* length of user buffer */
|
||||
u8 set; /* get or set request (optional) */
|
||||
uint used; /* bytes read or written (optional) */
|
||||
uint needed; /* bytes needed (optional) */
|
||||
};
|
||||
|
||||
/* Forward decls for struct brcmf_pub (see below) */
|
||||
struct brcmf_bus; /* device bus info */
|
||||
struct brcmf_proto; /* device communication protocol info */
|
||||
struct brcmf_info; /* device driver info */
|
||||
struct brcmf_cfg80211_dev; /* cfg80211 device info */
|
||||
|
||||
/* Common structure for module and instance linkage */
|
||||
struct brcmf_pub {
|
||||
/* Linkage ponters */
|
||||
struct brcmf_bus *bus;
|
||||
struct brcmf_proto *prot;
|
||||
struct brcmf_info *info;
|
||||
struct brcmf_cfg80211_dev *config;
|
||||
|
||||
/* Internal brcmf items */
|
||||
bool up; /* Driver up/down (to OS) */
|
||||
bool txoff; /* Transmit flow-controlled */
|
||||
enum brcmf_bus_state busstate;
|
||||
uint hdrlen; /* Total BRCMF header length (proto + bus) */
|
||||
uint maxctl; /* Max size rxctl request from proto to bus */
|
||||
uint rxsz; /* Rx buffer size bus module should use */
|
||||
u8 wme_dp; /* wme discard priority */
|
||||
|
||||
/* Dongle media info */
|
||||
bool iswl; /* Dongle-resident driver is wl */
|
||||
unsigned long drv_version; /* Version of dongle-resident driver */
|
||||
u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */
|
||||
struct dngl_stats dstats; /* Stats for dongle-based data */
|
||||
|
||||
/* Additional stats for the bus level */
|
||||
|
||||
/* Data packets sent to dongle */
|
||||
unsigned long tx_packets;
|
||||
/* Multicast data packets sent to dongle */
|
||||
unsigned long tx_multicast;
|
||||
/* Errors in sending data to dongle */
|
||||
unsigned long tx_errors;
|
||||
/* Control packets sent to dongle */
|
||||
unsigned long tx_ctlpkts;
|
||||
/* Errors sending control frames to dongle */
|
||||
unsigned long tx_ctlerrs;
|
||||
/* Packets sent up the network interface */
|
||||
unsigned long rx_packets;
|
||||
/* Multicast packets sent up the network interface */
|
||||
unsigned long rx_multicast;
|
||||
/* Errors processing rx data packets */
|
||||
unsigned long rx_errors;
|
||||
/* Control frames processed from dongle */
|
||||
unsigned long rx_ctlpkts;
|
||||
|
||||
/* Errors in processing rx control frames */
|
||||
unsigned long rx_ctlerrs;
|
||||
/* Packets dropped locally (no memory) */
|
||||
unsigned long rx_dropped;
|
||||
/* Packets flushed due to unscheduled sendup thread */
|
||||
unsigned long rx_flushed;
|
||||
/* Number of times dpc scheduled by watchdog timer */
|
||||
unsigned long wd_dpc_sched;
|
||||
|
||||
/* Number of packets where header read-ahead was used. */
|
||||
unsigned long rx_readahead_cnt;
|
||||
/* Number of tx packets we had to realloc for headroom */
|
||||
unsigned long tx_realloc;
|
||||
/* Number of flow control pkts recvd */
|
||||
unsigned long fc_packets;
|
||||
|
||||
/* Last error return */
|
||||
int bcmerror;
|
||||
uint tickcnt;
|
||||
|
||||
/* Last error from dongle */
|
||||
int dongle_error;
|
||||
|
||||
/* Suspend disable flag flag */
|
||||
int suspend_disable_flag; /* "1" to disable all extra powersaving
|
||||
during suspend */
|
||||
int in_suspend; /* flag set to 1 when early suspend called */
|
||||
int dtim_skip; /* dtim skip , default 0 means wake each dtim */
|
||||
|
||||
/* Pkt filter defination */
|
||||
char *pktfilter[100];
|
||||
int pktfilter_count;
|
||||
|
||||
u8 country_code[BRCM_CNTRY_BUF_SZ];
|
||||
char eventmask[BRCMF_EVENTING_MASK_LEN];
|
||||
|
||||
};
|
||||
|
||||
struct brcmf_if_event {
|
||||
u8 ifidx;
|
||||
u8 action;
|
||||
u8 flags;
|
||||
u8 bssidx;
|
||||
};
|
||||
|
||||
struct bcmevent_name {
|
||||
uint event;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
extern const struct bcmevent_name bcmevent_names[];
|
||||
|
||||
extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen,
|
||||
char *buf, uint len);
|
||||
|
||||
/* Indication from bus module regarding presence/insertion of dongle.
|
||||
* Return struct brcmf_pub pointer, used as handle to OS module in later calls.
|
||||
* Returned structure should have bus and prot pointers filled in.
|
||||
* bus_hdrlen specifies required headroom for bus module header.
|
||||
*/
|
||||
extern struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus,
|
||||
uint bus_hdrlen);
|
||||
extern int brcmf_net_attach(struct brcmf_pub *drvr, int idx);
|
||||
extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
|
||||
|
||||
extern s32 brcmf_exec_dcmd(struct net_device *dev, u32 cmd, void *arg, u32 len);
|
||||
|
||||
/* Indication from bus module regarding removal/absence of dongle */
|
||||
extern void brcmf_detach(struct brcmf_pub *drvr);
|
||||
|
||||
/* Indication from bus module to change flow-control state */
|
||||
extern void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool on);
|
||||
|
||||
extern bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q,
|
||||
struct sk_buff *pkt, int prec);
|
||||
|
||||
/* Receive frame for delivery to OS. Callee disposes of rxp. */
|
||||
extern void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx,
|
||||
struct sk_buff *rxp, int numpkt);
|
||||
|
||||
/* Return pointer to interface name */
|
||||
extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
|
||||
|
||||
/* Notify tx completion */
|
||||
extern void brcmf_txcomplete(struct brcmf_pub *drvr, struct sk_buff *txp,
|
||||
bool success);
|
||||
|
||||
/* Query dongle */
|
||||
extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx,
|
||||
uint cmd, void *buf, uint len);
|
||||
|
||||
/* OS independent layer functions */
|
||||
extern int brcmf_os_proto_block(struct brcmf_pub *drvr);
|
||||
extern int brcmf_os_proto_unblock(struct brcmf_pub *drvr);
|
||||
#ifdef BCMDBG
|
||||
extern int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size);
|
||||
#endif /* BCMDBG */
|
||||
|
||||
extern int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name);
|
||||
extern int brcmf_c_host_event(struct brcmf_info *drvr_priv, int *idx,
|
||||
void *pktdata, struct brcmf_event_msg *,
|
||||
void **data_ptr);
|
||||
|
||||
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);
|
||||
extern void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx);
|
||||
|
||||
/* Send packet to dongle via data channel */
|
||||
extern int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx,\
|
||||
struct sk_buff *pkt);
|
||||
|
||||
extern int brcmf_bus_start(struct brcmf_pub *drvr);
|
||||
|
||||
extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg);
|
||||
extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg,
|
||||
int enable, int master_mode);
|
||||
|
||||
#define BRCMF_DCMD_SMLEN 256 /* "small" cmd buffer required */
|
||||
#define BRCMF_DCMD_MEDLEN 1536 /* "med" cmd buffer required */
|
||||
#define BRCMF_DCMD_MAXLEN 8192 /* max length cmd buffer required */
|
||||
|
||||
/* message levels */
|
||||
#define BRCMF_ERROR_VAL 0x0001
|
||||
#define BRCMF_TRACE_VAL 0x0002
|
||||
#define BRCMF_INFO_VAL 0x0004
|
||||
#define BRCMF_DATA_VAL 0x0008
|
||||
#define BRCMF_CTL_VAL 0x0010
|
||||
#define BRCMF_TIMER_VAL 0x0020
|
||||
#define BRCMF_HDRS_VAL 0x0040
|
||||
#define BRCMF_BYTES_VAL 0x0080
|
||||
#define BRCMF_INTR_VAL 0x0100
|
||||
#define BRCMF_GLOM_VAL 0x0400
|
||||
#define BRCMF_EVENT_VAL 0x0800
|
||||
#define BRCMF_BTA_VAL 0x1000
|
||||
#define BRCMF_ISCAN_VAL 0x2000
|
||||
|
||||
/* Enter idle immediately (no timeout) */
|
||||
#define BRCMF_IDLE_IMMEDIATE (-1)
|
||||
#define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change
|
||||
when idle */
|
||||
#define BRCMF_IDLE_INTERVAL 1
|
||||
|
||||
#endif /* _BRCMF_H_ */
|
57
drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
Normal file
57
drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 _BRCMF_BUS_H_
|
||||
#define _BRCMF_BUS_H_
|
||||
|
||||
/* Packet alignment for most efficient SDIO (can change based on platform) */
|
||||
#define BRCMF_SDALIGN (1 << 6)
|
||||
|
||||
/* watchdog polling interval in ms */
|
||||
#define BRCMF_WD_POLL_MS 10
|
||||
|
||||
/*
|
||||
* Exported from brcmf bus module (brcmf_usb, brcmf_sdio)
|
||||
*/
|
||||
|
||||
/* Indicate (dis)interest in finding dongles. */
|
||||
extern int brcmf_bus_register(void);
|
||||
extern void brcmf_bus_unregister(void);
|
||||
|
||||
/* obtain linux device object providing bus function */
|
||||
extern struct device *brcmf_bus_get_device(struct brcmf_bus *bus);
|
||||
|
||||
/* Stop bus module: clear pending frames, disable data flow */
|
||||
extern void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus);
|
||||
|
||||
/* Initialize bus module: prepare for communication w/dongle */
|
||||
extern int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr);
|
||||
|
||||
/* Send a data frame to the dongle. Callee disposes of txp. */
|
||||
extern int brcmf_sdbrcm_bus_txdata(struct brcmf_bus *bus, struct sk_buff *txp);
|
||||
|
||||
/* Send/receive a control message to/from the dongle.
|
||||
* Expects caller to enforce a single outstanding transaction.
|
||||
*/
|
||||
extern int
|
||||
brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen);
|
||||
|
||||
extern int
|
||||
brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen);
|
||||
|
||||
extern void brcmf_sdbrcm_wd_timer(struct brcmf_bus *bus, uint wdtick);
|
||||
|
||||
#endif /* _BRCMF_BUS_H_ */
|
498
drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
Normal file
498
drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
Normal file
@ -0,0 +1,498 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Communicates with the dongle by using dcmd codes.
|
||||
* For certain dcmd codes, the dongle interprets string data from the host.
|
||||
******************************************************************************/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/sched.h>
|
||||
#include <defs.h>
|
||||
|
||||
#include <brcmu_utils.h>
|
||||
#include <brcmu_wifi.h>
|
||||
|
||||
#include "dhd.h"
|
||||
#include "dhd_proto.h"
|
||||
#include "dhd_bus.h"
|
||||
#include "dhd_dbg.h"
|
||||
|
||||
struct brcmf_proto_cdc_dcmd {
|
||||
__le32 cmd; /* dongle command value */
|
||||
__le32 len; /* lower 16: output buflen;
|
||||
* upper 16: input buflen (excludes header) */
|
||||
__le32 flags; /* flag defns given below */
|
||||
__le32 status; /* status code returned from the device */
|
||||
};
|
||||
|
||||
/* Max valid buffer size that can be sent to the dongle */
|
||||
#define CDC_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN)
|
||||
|
||||
/* CDC flag definitions */
|
||||
#define CDC_DCMD_ERROR 0x01 /* 1=cmd failed */
|
||||
#define CDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */
|
||||
#define CDC_DCMD_IF_MASK 0xF000 /* I/F index */
|
||||
#define CDC_DCMD_IF_SHIFT 12
|
||||
#define CDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */
|
||||
#define CDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */
|
||||
#define CDC_DCMD_ID(flags) \
|
||||
(((flags) & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT)
|
||||
|
||||
/*
|
||||
* BDC header - Broadcom specific extension of CDC.
|
||||
* Used on data packets to convey priority across USB.
|
||||
*/
|
||||
#define BDC_HEADER_LEN 4
|
||||
#define BDC_PROTO_VER 1 /* Protocol version */
|
||||
#define BDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */
|
||||
#define BDC_FLAG_VER_SHIFT 4 /* Protocol version shift */
|
||||
#define BDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */
|
||||
#define BDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */
|
||||
#define BDC_PRIORITY_MASK 0x7
|
||||
#define BDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */
|
||||
#define BDC_FLAG2_IF_SHIFT 0
|
||||
|
||||
#define BDC_GET_IF_IDX(hdr) \
|
||||
((int)((((hdr)->flags2) & BDC_FLAG2_IF_MASK) >> BDC_FLAG2_IF_SHIFT))
|
||||
#define BDC_SET_IF_IDX(hdr, idx) \
|
||||
((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
|
||||
((idx) << BDC_FLAG2_IF_SHIFT)))
|
||||
|
||||
struct brcmf_proto_bdc_header {
|
||||
u8 flags;
|
||||
u8 priority; /* 802.1d Priority, 4:7 flow control info for usb */
|
||||
u8 flags2;
|
||||
u8 rssi;
|
||||
};
|
||||
|
||||
|
||||
#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
|
||||
#define BUS_HEADER_LEN (16+BRCMF_SDALIGN) /* Must be atleast SDPCM_RESERVE
|
||||
* (amount of header tha might be added)
|
||||
* plus any space that might be needed
|
||||
* for alignment padding.
|
||||
*/
|
||||
#define ROUND_UP_MARGIN 2048 /* Biggest SDIO block size possible for
|
||||
* round off at the end of buffer
|
||||
*/
|
||||
|
||||
struct brcmf_proto {
|
||||
u16 reqid;
|
||||
u8 pending;
|
||||
u32 lastcmd;
|
||||
u8 bus_header[BUS_HEADER_LEN];
|
||||
struct brcmf_proto_cdc_dcmd msg;
|
||||
unsigned char buf[BRCMF_DCMD_MAXLEN + ROUND_UP_MARGIN];
|
||||
};
|
||||
|
||||
static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct brcmf_proto *prot = drvr->prot;
|
||||
int len = le32_to_cpu(prot->msg.len) +
|
||||
sizeof(struct brcmf_proto_cdc_dcmd);
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
/* NOTE : cdc->msg.len holds the desired length of the buffer to be
|
||||
* returned. Only up to CDC_MAX_MSG_SIZE of this buffer area
|
||||
* is actually sent to the dongle
|
||||
*/
|
||||
if (len > CDC_MAX_MSG_SIZE)
|
||||
len = CDC_MAX_MSG_SIZE;
|
||||
|
||||
/* Send request */
|
||||
return brcmf_sdbrcm_bus_txctl(drvr->bus, (unsigned char *)&prot->msg,
|
||||
len);
|
||||
}
|
||||
|
||||
static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
|
||||
{
|
||||
int ret;
|
||||
struct brcmf_proto *prot = drvr->prot;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
do {
|
||||
ret = brcmf_sdbrcm_bus_rxctl(drvr->bus,
|
||||
(unsigned char *)&prot->msg,
|
||||
len + sizeof(struct brcmf_proto_cdc_dcmd));
|
||||
if (ret < 0)
|
||||
break;
|
||||
} while (CDC_DCMD_ID(le32_to_cpu(prot->msg.flags)) != id);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
|
||||
void *buf, uint len)
|
||||
{
|
||||
struct brcmf_proto *prot = drvr->prot;
|
||||
struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
|
||||
void *info;
|
||||
int ret = 0, retries = 0;
|
||||
u32 id, flags;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
|
||||
|
||||
/* Respond "bcmerror" and "bcmerrorstr" with local cache */
|
||||
if (cmd == BRCMF_C_GET_VAR && buf) {
|
||||
if (!strcmp((char *)buf, "bcmerrorstr")) {
|
||||
strncpy((char *)buf, "bcm_error",
|
||||
BCME_STRLEN);
|
||||
goto done;
|
||||
} else if (!strcmp((char *)buf, "bcmerror")) {
|
||||
*(int *)buf = drvr->dongle_error;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
|
||||
|
||||
msg->cmd = cpu_to_le32(cmd);
|
||||
msg->len = cpu_to_le32(len);
|
||||
flags = (++prot->reqid << CDC_DCMD_ID_SHIFT);
|
||||
flags = (flags & ~CDC_DCMD_IF_MASK) |
|
||||
(ifidx << CDC_DCMD_IF_SHIFT);
|
||||
msg->flags = cpu_to_le32(flags);
|
||||
|
||||
if (buf)
|
||||
memcpy(prot->buf, buf, len);
|
||||
|
||||
ret = brcmf_proto_cdc_msg(drvr);
|
||||
if (ret < 0) {
|
||||
brcmf_dbg(ERROR, "brcmf_proto_cdc_msg failed w/status %d\n",
|
||||
ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
retry:
|
||||
/* wait for interrupt and get first fragment */
|
||||
ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
||||
flags = le32_to_cpu(msg->flags);
|
||||
id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
|
||||
|
||||
if ((id < prot->reqid) && (++retries < RETRIES))
|
||||
goto retry;
|
||||
if (id != prot->reqid) {
|
||||
brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n",
|
||||
brcmf_ifname(drvr, ifidx), id, prot->reqid);
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Check info buffer */
|
||||
info = (void *)&msg[1];
|
||||
|
||||
/* Copy info buffer */
|
||||
if (buf) {
|
||||
if (ret < (int)len)
|
||||
len = ret;
|
||||
memcpy(buf, info, len);
|
||||
}
|
||||
|
||||
/* Check the ERROR flag */
|
||||
if (flags & CDC_DCMD_ERROR) {
|
||||
ret = le32_to_cpu(msg->status);
|
||||
/* Cache error from dongle */
|
||||
drvr->dongle_error = ret;
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
|
||||
void *buf, uint len)
|
||||
{
|
||||
struct brcmf_proto *prot = drvr->prot;
|
||||
struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
|
||||
int ret = 0;
|
||||
u32 flags, id;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len);
|
||||
|
||||
memset(msg, 0, sizeof(struct brcmf_proto_cdc_dcmd));
|
||||
|
||||
msg->cmd = cpu_to_le32(cmd);
|
||||
msg->len = cpu_to_le32(len);
|
||||
flags = (++prot->reqid << CDC_DCMD_ID_SHIFT) | CDC_DCMD_SET;
|
||||
flags = (flags & ~CDC_DCMD_IF_MASK) |
|
||||
(ifidx << CDC_DCMD_IF_SHIFT);
|
||||
msg->flags = cpu_to_le32(flags);
|
||||
|
||||
if (buf)
|
||||
memcpy(prot->buf, buf, len);
|
||||
|
||||
ret = brcmf_proto_cdc_msg(drvr);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
||||
ret = brcmf_proto_cdc_cmplt(drvr, prot->reqid, len);
|
||||
if (ret < 0)
|
||||
goto done;
|
||||
|
||||
flags = le32_to_cpu(msg->flags);
|
||||
id = (flags & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT;
|
||||
|
||||
if (id != prot->reqid) {
|
||||
brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n",
|
||||
brcmf_ifname(drvr, ifidx), id, prot->reqid);
|
||||
ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Check the ERROR flag */
|
||||
if (flags & CDC_DCMD_ERROR) {
|
||||
ret = le32_to_cpu(msg->status);
|
||||
/* Cache error from dongle */
|
||||
drvr->dongle_error = ret;
|
||||
}
|
||||
|
||||
done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, struct brcmf_dcmd *dcmd,
|
||||
int len)
|
||||
{
|
||||
struct brcmf_proto *prot = drvr->prot;
|
||||
int ret = -1;
|
||||
|
||||
if (drvr->busstate == BRCMF_BUS_DOWN) {
|
||||
brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n");
|
||||
return ret;
|
||||
}
|
||||
brcmf_os_proto_block(drvr);
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
if (len > BRCMF_DCMD_MAXLEN)
|
||||
goto done;
|
||||
|
||||
if (prot->pending == true) {
|
||||
brcmf_dbg(TRACE, "CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n",
|
||||
dcmd->cmd, (unsigned long)dcmd->cmd, prot->lastcmd,
|
||||
(unsigned long)prot->lastcmd);
|
||||
if (dcmd->cmd == BRCMF_C_SET_VAR ||
|
||||
dcmd->cmd == BRCMF_C_GET_VAR)
|
||||
brcmf_dbg(TRACE, "iovar cmd=%s\n", (char *)dcmd->buf);
|
||||
|
||||
goto done;
|
||||
}
|
||||
|
||||
prot->pending = true;
|
||||
prot->lastcmd = dcmd->cmd;
|
||||
if (dcmd->set)
|
||||
ret = brcmf_proto_cdc_set_dcmd(drvr, ifidx, dcmd->cmd,
|
||||
dcmd->buf, len);
|
||||
else {
|
||||
ret = brcmf_proto_cdc_query_dcmd(drvr, ifidx, dcmd->cmd,
|
||||
dcmd->buf, len);
|
||||
if (ret > 0)
|
||||
dcmd->used = ret -
|
||||
sizeof(struct brcmf_proto_cdc_dcmd);
|
||||
}
|
||||
|
||||
if (ret >= 0)
|
||||
ret = 0;
|
||||
else {
|
||||
struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
|
||||
/* len == needed when set/query fails from dongle */
|
||||
dcmd->needed = le32_to_cpu(msg->len);
|
||||
}
|
||||
|
||||
/* Intercept the wme_dp dongle cmd here */
|
||||
if (!ret && dcmd->cmd == BRCMF_C_SET_VAR &&
|
||||
!strcmp(dcmd->buf, "wme_dp")) {
|
||||
int slen;
|
||||
__le32 val = 0;
|
||||
|
||||
slen = strlen("wme_dp") + 1;
|
||||
if (len >= (int)(slen + sizeof(int)))
|
||||
memcpy(&val, (char *)dcmd->buf + slen, sizeof(int));
|
||||
drvr->wme_dp = (u8) le32_to_cpu(val);
|
||||
}
|
||||
|
||||
prot->pending = false;
|
||||
|
||||
done:
|
||||
brcmf_os_proto_unblock(drvr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool pkt_sum_needed(struct sk_buff *skb)
|
||||
{
|
||||
return skb->ip_summed == CHECKSUM_PARTIAL;
|
||||
}
|
||||
|
||||
static void pkt_set_sum_good(struct sk_buff *skb, bool x)
|
||||
{
|
||||
skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
|
||||
}
|
||||
|
||||
void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
|
||||
struct sk_buff *pktbuf)
|
||||
{
|
||||
struct brcmf_proto_bdc_header *h;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
/* Push BDC header used to convey priority for buses that don't */
|
||||
|
||||
skb_push(pktbuf, BDC_HEADER_LEN);
|
||||
|
||||
h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
|
||||
|
||||
h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT);
|
||||
if (pkt_sum_needed(pktbuf))
|
||||
h->flags |= BDC_FLAG_SUM_NEEDED;
|
||||
|
||||
h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
|
||||
h->flags2 = 0;
|
||||
h->rssi = 0;
|
||||
BDC_SET_IF_IDX(h, ifidx);
|
||||
}
|
||||
|
||||
int brcmf_proto_hdrpull(struct brcmf_pub *drvr, int *ifidx,
|
||||
struct sk_buff *pktbuf)
|
||||
{
|
||||
struct brcmf_proto_bdc_header *h;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
/* Pop BDC header used to convey priority for buses that don't */
|
||||
|
||||
if (pktbuf->len < BDC_HEADER_LEN) {
|
||||
brcmf_dbg(ERROR, "rx data too short (%d < %d)\n",
|
||||
pktbuf->len, BDC_HEADER_LEN);
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
|
||||
|
||||
*ifidx = BDC_GET_IF_IDX(h);
|
||||
if (*ifidx >= BRCMF_MAX_IFS) {
|
||||
brcmf_dbg(ERROR, "rx data ifnum out of range (%d)\n", *ifidx);
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
|
||||
BDC_PROTO_VER) {
|
||||
brcmf_dbg(ERROR, "%s: non-BDC packet received, flags 0x%x\n",
|
||||
brcmf_ifname(drvr, *ifidx), h->flags);
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
if (h->flags & BDC_FLAG_SUM_GOOD) {
|
||||
brcmf_dbg(INFO, "%s: BDC packet received with good rx-csum, flags 0x%x\n",
|
||||
brcmf_ifname(drvr, *ifidx), h->flags);
|
||||
pkt_set_sum_good(pktbuf, true);
|
||||
}
|
||||
|
||||
pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
|
||||
|
||||
skb_pull(pktbuf, BDC_HEADER_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int brcmf_proto_attach(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct brcmf_proto *cdc;
|
||||
|
||||
cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC);
|
||||
if (!cdc)
|
||||
goto fail;
|
||||
|
||||
/* ensure that the msg buf directly follows the cdc msg struct */
|
||||
if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) {
|
||||
brcmf_dbg(ERROR, "struct brcmf_proto is not correctly defined\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
drvr->prot = cdc;
|
||||
drvr->hdrlen += BDC_HEADER_LEN;
|
||||
drvr->maxctl = BRCMF_DCMD_MAXLEN +
|
||||
sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
kfree(cdc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* ~NOTE~ What if another thread is waiting on the semaphore? Holding it? */
|
||||
void brcmf_proto_detach(struct brcmf_pub *drvr)
|
||||
{
|
||||
kfree(drvr->prot);
|
||||
drvr->prot = NULL;
|
||||
}
|
||||
|
||||
void brcmf_proto_dstats(struct brcmf_pub *drvr)
|
||||
{
|
||||
/* No stats from dongle added yet, copy bus stats */
|
||||
drvr->dstats.tx_packets = drvr->tx_packets;
|
||||
drvr->dstats.tx_errors = drvr->tx_errors;
|
||||
drvr->dstats.rx_packets = drvr->rx_packets;
|
||||
drvr->dstats.rx_errors = drvr->rx_errors;
|
||||
drvr->dstats.rx_dropped = drvr->rx_dropped;
|
||||
drvr->dstats.multicast = drvr->rx_multicast;
|
||||
return;
|
||||
}
|
||||
|
||||
int brcmf_proto_init(struct brcmf_pub *drvr)
|
||||
{
|
||||
int ret = 0;
|
||||
char buf[128];
|
||||
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
|
||||
brcmf_os_proto_block(drvr);
|
||||
|
||||
/* Get the device MAC address */
|
||||
strcpy(buf, "cur_etheraddr");
|
||||
ret = brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR,
|
||||
buf, sizeof(buf));
|
||||
if (ret < 0) {
|
||||
brcmf_os_proto_unblock(drvr);
|
||||
return ret;
|
||||
}
|
||||
memcpy(drvr->mac, buf, ETH_ALEN);
|
||||
|
||||
brcmf_os_proto_unblock(drvr);
|
||||
|
||||
ret = brcmf_c_preinit_dcmds(drvr);
|
||||
|
||||
/* Always assumes wl for now */
|
||||
drvr->iswl = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void brcmf_proto_stop(struct brcmf_pub *drvr)
|
||||
{
|
||||
/* Nothing to do for CDC */
|
||||
}
|
895
drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
Normal file
895
drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
Normal file
@ -0,0 +1,895 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <defs.h>
|
||||
#include <brcmu_wifi.h>
|
||||
#include <brcmu_utils.h>
|
||||
#include "dhd.h"
|
||||
#include "dhd_bus.h"
|
||||
#include "dhd_proto.h"
|
||||
#include "dhd_dbg.h"
|
||||
|
||||
#define BRCM_OUI "\x00\x10\x18"
|
||||
#define DOT11_OUI_LEN 3
|
||||
#define BCMILCP_BCM_SUBTYPE_EVENT 1
|
||||
#define PKTFILTER_BUF_SIZE 2048
|
||||
#define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */
|
||||
|
||||
int brcmf_msg_level;
|
||||
|
||||
#define MSGTRACE_VERSION 1
|
||||
|
||||
#define BRCMF_PKT_FILTER_FIXED_LEN offsetof(struct brcmf_pkt_filter_le, u)
|
||||
#define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \
|
||||
offsetof(struct brcmf_pkt_filter_pattern_le, mask_and_pattern)
|
||||
|
||||
#ifdef BCMDBG
|
||||
static const char brcmf_version[] =
|
||||
"Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on "
|
||||
__DATE__ " at " __TIME__;
|
||||
#else
|
||||
static const char brcmf_version[] =
|
||||
"Dongle Host Driver, version " BRCMF_VERSION_STR;
|
||||
#endif
|
||||
|
||||
/* Message trace header */
|
||||
struct msgtrace_hdr {
|
||||
u8 version;
|
||||
u8 spare;
|
||||
__be16 len; /* Len of the trace */
|
||||
__be32 seqnum; /* Sequence number of message. Useful
|
||||
* if the messsage has been lost
|
||||
* because of DMA error or a bus reset
|
||||
* (ex: SDIO Func2)
|
||||
*/
|
||||
__be32 discarded_bytes; /* Number of discarded bytes because of
|
||||
trace overflow */
|
||||
__be32 discarded_printf; /* Number of discarded printf
|
||||
because of trace overflow */
|
||||
} __packed;
|
||||
|
||||
|
||||
uint
|
||||
brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
|
||||
{
|
||||
uint len;
|
||||
|
||||
len = strlen(name) + 1;
|
||||
|
||||
if ((len + datalen) > buflen)
|
||||
return 0;
|
||||
|
||||
strncpy(buf, name, buflen);
|
||||
|
||||
/* append data onto the end of the name string */
|
||||
memcpy(&buf[len], data, datalen);
|
||||
len += datalen;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void brcmf_c_init(void)
|
||||
{
|
||||
/* Init global variables at run-time, not as part of the declaration.
|
||||
* This is required to support init/de-init of the driver.
|
||||
* Initialization
|
||||
* of globals as part of the declaration results in non-deterministic
|
||||
* behaviour since the value of the globals may be different on the
|
||||
* first time that the driver is initialized vs subsequent
|
||||
* initializations.
|
||||
*/
|
||||
brcmf_msg_level = BRCMF_ERROR_VAL;
|
||||
}
|
||||
|
||||
bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q,
|
||||
struct sk_buff *pkt, int prec)
|
||||
{
|
||||
struct sk_buff *p;
|
||||
int eprec = -1; /* precedence to evict from */
|
||||
bool discard_oldest;
|
||||
|
||||
/* Fast case, precedence queue is not full and we are also not
|
||||
* exceeding total queue length
|
||||
*/
|
||||
if (!pktq_pfull(q, prec) && !pktq_full(q)) {
|
||||
brcmu_pktq_penq(q, prec, pkt);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Determine precedence from which to evict packet, if any */
|
||||
if (pktq_pfull(q, prec))
|
||||
eprec = prec;
|
||||
else if (pktq_full(q)) {
|
||||
p = brcmu_pktq_peek_tail(q, &eprec);
|
||||
if (eprec > prec)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Evict if needed */
|
||||
if (eprec >= 0) {
|
||||
/* Detect queueing to unconfigured precedence */
|
||||
discard_oldest = ac_bitmap_tst(drvr->wme_dp, eprec);
|
||||
if (eprec == prec && !discard_oldest)
|
||||
return false; /* refuse newer (incoming) packet */
|
||||
/* Evict packet according to discard policy */
|
||||
p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) :
|
||||
brcmu_pktq_pdeq_tail(q, eprec);
|
||||
if (p == NULL)
|
||||
brcmf_dbg(ERROR, "brcmu_pktq_penq() failed, oldest %d\n",
|
||||
discard_oldest);
|
||||
|
||||
brcmu_pkt_buf_free_skb(p);
|
||||
}
|
||||
|
||||
/* Enqueue */
|
||||
p = brcmu_pktq_penq(q, prec, pkt);
|
||||
if (p == NULL)
|
||||
brcmf_dbg(ERROR, "brcmu_pktq_penq() failed\n");
|
||||
|
||||
return p != NULL;
|
||||
}
|
||||
|
||||
#ifdef BCMDBG
|
||||
static void
|
||||
brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
|
||||
{
|
||||
uint i, status, reason;
|
||||
bool group = false, flush_txq = false, link = false;
|
||||
char *auth_str, *event_name;
|
||||
unsigned char *buf;
|
||||
char err_msg[256], eabuf[ETHER_ADDR_STR_LEN];
|
||||
static struct {
|
||||
uint event;
|
||||
char *event_name;
|
||||
} event_names[] = {
|
||||
{
|
||||
BRCMF_E_SET_SSID, "SET_SSID"}, {
|
||||
BRCMF_E_JOIN, "JOIN"}, {
|
||||
BRCMF_E_START, "START"}, {
|
||||
BRCMF_E_AUTH, "AUTH"}, {
|
||||
BRCMF_E_AUTH_IND, "AUTH_IND"}, {
|
||||
BRCMF_E_DEAUTH, "DEAUTH"}, {
|
||||
BRCMF_E_DEAUTH_IND, "DEAUTH_IND"}, {
|
||||
BRCMF_E_ASSOC, "ASSOC"}, {
|
||||
BRCMF_E_ASSOC_IND, "ASSOC_IND"}, {
|
||||
BRCMF_E_REASSOC, "REASSOC"}, {
|
||||
BRCMF_E_REASSOC_IND, "REASSOC_IND"}, {
|
||||
BRCMF_E_DISASSOC, "DISASSOC"}, {
|
||||
BRCMF_E_DISASSOC_IND, "DISASSOC_IND"}, {
|
||||
BRCMF_E_QUIET_START, "START_QUIET"}, {
|
||||
BRCMF_E_QUIET_END, "END_QUIET"}, {
|
||||
BRCMF_E_BEACON_RX, "BEACON_RX"}, {
|
||||
BRCMF_E_LINK, "LINK"}, {
|
||||
BRCMF_E_MIC_ERROR, "MIC_ERROR"}, {
|
||||
BRCMF_E_NDIS_LINK, "NDIS_LINK"}, {
|
||||
BRCMF_E_ROAM, "ROAM"}, {
|
||||
BRCMF_E_TXFAIL, "TXFAIL"}, {
|
||||
BRCMF_E_PMKID_CACHE, "PMKID_CACHE"}, {
|
||||
BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, {
|
||||
BRCMF_E_PRUNE, "PRUNE"}, {
|
||||
BRCMF_E_AUTOAUTH, "AUTOAUTH"}, {
|
||||
BRCMF_E_EAPOL_MSG, "EAPOL_MSG"}, {
|
||||
BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, {
|
||||
BRCMF_E_ADDTS_IND, "ADDTS_IND"}, {
|
||||
BRCMF_E_DELTS_IND, "DELTS_IND"}, {
|
||||
BRCMF_E_BCNSENT_IND, "BCNSENT_IND"}, {
|
||||
BRCMF_E_BCNRX_MSG, "BCNRX_MSG"}, {
|
||||
BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG"}, {
|
||||
BRCMF_E_ROAM_PREP, "ROAM_PREP"}, {
|
||||
BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, {
|
||||
BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST"}, {
|
||||
BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE"}, {
|
||||
BRCMF_E_JOIN_START, "JOIN_START"}, {
|
||||
BRCMF_E_ROAM_START, "ROAM_START"}, {
|
||||
BRCMF_E_ASSOC_START, "ASSOC_START"}, {
|
||||
BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC"}, {
|
||||
BRCMF_E_RADIO, "RADIO"}, {
|
||||
BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, {
|
||||
BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG"}, {
|
||||
BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, {
|
||||
BRCMF_E_PSK_SUP, "PSK_SUP"}, {
|
||||
BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, {
|
||||
BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, {
|
||||
BRCMF_E_ICV_ERROR, "ICV_ERROR"}, {
|
||||
BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, {
|
||||
BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, {
|
||||
BRCMF_E_TRACE, "TRACE"}, {
|
||||
BRCMF_E_ACTION_FRAME, "ACTION FRAME"}, {
|
||||
BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, {
|
||||
BRCMF_E_IF, "IF"}, {
|
||||
BRCMF_E_RSSI, "RSSI"}, {
|
||||
BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}
|
||||
};
|
||||
uint event_type, flags, auth_type, datalen;
|
||||
static u32 seqnum_prev;
|
||||
struct msgtrace_hdr hdr;
|
||||
u32 nblost;
|
||||
char *s, *p;
|
||||
|
||||
event_type = be32_to_cpu(event->event_type);
|
||||
flags = be16_to_cpu(event->flags);
|
||||
status = be32_to_cpu(event->status);
|
||||
reason = be32_to_cpu(event->reason);
|
||||
auth_type = be32_to_cpu(event->auth_type);
|
||||
datalen = be32_to_cpu(event->datalen);
|
||||
/* debug dump of event messages */
|
||||
sprintf(eabuf, "%pM", event->addr);
|
||||
|
||||
event_name = "UNKNOWN";
|
||||
for (i = 0; i < ARRAY_SIZE(event_names); i++) {
|
||||
if (event_names[i].event == event_type)
|
||||
event_name = event_names[i].event_name;
|
||||
}
|
||||
|
||||
brcmf_dbg(EVENT, "EVENT: %s, event ID = %d\n", event_name, event_type);
|
||||
brcmf_dbg(EVENT, "flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n",
|
||||
flags, status, reason, auth_type, eabuf);
|
||||
|
||||
if (flags & BRCMF_EVENT_MSG_LINK)
|
||||
link = true;
|
||||
if (flags & BRCMF_EVENT_MSG_GROUP)
|
||||
group = true;
|
||||
if (flags & BRCMF_EVENT_MSG_FLUSHTXQ)
|
||||
flush_txq = true;
|
||||
|
||||
switch (event_type) {
|
||||
case BRCMF_E_START:
|
||||
case BRCMF_E_DEAUTH:
|
||||
case BRCMF_E_DISASSOC:
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
|
||||
break;
|
||||
|
||||
case BRCMF_E_ASSOC_IND:
|
||||
case BRCMF_E_REASSOC_IND:
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
|
||||
break;
|
||||
|
||||
case BRCMF_E_ASSOC:
|
||||
case BRCMF_E_REASSOC:
|
||||
if (status == BRCMF_E_STATUS_SUCCESS)
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, SUCCESS\n",
|
||||
event_name, eabuf);
|
||||
else if (status == BRCMF_E_STATUS_TIMEOUT)
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, TIMEOUT\n",
|
||||
event_name, eabuf);
|
||||
else if (status == BRCMF_E_STATUS_FAIL)
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, FAILURE, reason %d\n",
|
||||
event_name, eabuf, (int)reason);
|
||||
else
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, unexpected status %d\n",
|
||||
event_name, eabuf, (int)status);
|
||||
break;
|
||||
|
||||
case BRCMF_E_DEAUTH_IND:
|
||||
case BRCMF_E_DISASSOC_IND:
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, reason %d\n",
|
||||
event_name, eabuf, (int)reason);
|
||||
break;
|
||||
|
||||
case BRCMF_E_AUTH:
|
||||
case BRCMF_E_AUTH_IND:
|
||||
if (auth_type == WLAN_AUTH_OPEN)
|
||||
auth_str = "Open System";
|
||||
else if (auth_type == WLAN_AUTH_SHARED_KEY)
|
||||
auth_str = "Shared Key";
|
||||
else {
|
||||
sprintf(err_msg, "AUTH unknown: %d", (int)auth_type);
|
||||
auth_str = err_msg;
|
||||
}
|
||||
if (event_type == BRCMF_E_AUTH_IND)
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s\n",
|
||||
event_name, eabuf, auth_str);
|
||||
else if (status == BRCMF_E_STATUS_SUCCESS)
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, SUCCESS\n",
|
||||
event_name, eabuf, auth_str);
|
||||
else if (status == BRCMF_E_STATUS_TIMEOUT)
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, TIMEOUT\n",
|
||||
event_name, eabuf, auth_str);
|
||||
else if (status == BRCMF_E_STATUS_FAIL) {
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n",
|
||||
event_name, eabuf, auth_str, (int)reason);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case BRCMF_E_JOIN:
|
||||
case BRCMF_E_ROAM:
|
||||
case BRCMF_E_SET_SSID:
|
||||
if (status == BRCMF_E_STATUS_SUCCESS)
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n",
|
||||
event_name, eabuf);
|
||||
else if (status == BRCMF_E_STATUS_FAIL)
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, failed\n", event_name);
|
||||
else if (status == BRCMF_E_STATUS_NO_NETWORKS)
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, no networks found\n",
|
||||
event_name);
|
||||
else
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, unexpected status %d\n",
|
||||
event_name, (int)status);
|
||||
break;
|
||||
|
||||
case BRCMF_E_BEACON_RX:
|
||||
if (status == BRCMF_E_STATUS_SUCCESS)
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, SUCCESS\n", event_name);
|
||||
else if (status == BRCMF_E_STATUS_FAIL)
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, FAIL\n", event_name);
|
||||
else
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, status %d\n",
|
||||
event_name, status);
|
||||
break;
|
||||
|
||||
case BRCMF_E_LINK:
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s %s\n",
|
||||
event_name, link ? "UP" : "DOWN");
|
||||
break;
|
||||
|
||||
case BRCMF_E_MIC_ERROR:
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, Group %d, Flush %d\n",
|
||||
event_name, eabuf, group, flush_txq);
|
||||
break;
|
||||
|
||||
case BRCMF_E_ICV_ERROR:
|
||||
case BRCMF_E_UNICAST_DECODE_ERROR:
|
||||
case BRCMF_E_MULTICAST_DECODE_ERROR:
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf);
|
||||
break;
|
||||
|
||||
case BRCMF_E_TXFAIL:
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, RA %s\n", event_name, eabuf);
|
||||
break;
|
||||
|
||||
case BRCMF_E_SCAN_COMPLETE:
|
||||
case BRCMF_E_PMKID_CACHE:
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name);
|
||||
break;
|
||||
|
||||
case BRCMF_E_PFN_NET_FOUND:
|
||||
case BRCMF_E_PFN_NET_LOST:
|
||||
case BRCMF_E_PFN_SCAN_COMPLETE:
|
||||
brcmf_dbg(EVENT, "PNOEVENT: %s\n", event_name);
|
||||
break;
|
||||
|
||||
case BRCMF_E_PSK_SUP:
|
||||
case BRCMF_E_PRUNE:
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s, status %d, reason %d\n",
|
||||
event_name, (int)status, (int)reason);
|
||||
break;
|
||||
|
||||
case BRCMF_E_TRACE:
|
||||
buf = (unsigned char *) event_data;
|
||||
memcpy(&hdr, buf, sizeof(struct msgtrace_hdr));
|
||||
|
||||
if (hdr.version != MSGTRACE_VERSION) {
|
||||
brcmf_dbg(ERROR,
|
||||
"MACEVENT: %s [unsupported version --> brcmf"
|
||||
" version:%d dongle version:%d]\n",
|
||||
event_name, MSGTRACE_VERSION, hdr.version);
|
||||
/* Reset datalen to avoid display below */
|
||||
datalen = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* There are 2 bytes available at the end of data */
|
||||
*(buf + sizeof(struct msgtrace_hdr)
|
||||
+ be16_to_cpu(hdr.len)) = '\0';
|
||||
|
||||
if (be32_to_cpu(hdr.discarded_bytes)
|
||||
|| be32_to_cpu(hdr.discarded_printf))
|
||||
brcmf_dbg(ERROR,
|
||||
"WLC_E_TRACE: [Discarded traces in dongle -->"
|
||||
" discarded_bytes %d discarded_printf %d]\n",
|
||||
be32_to_cpu(hdr.discarded_bytes),
|
||||
be32_to_cpu(hdr.discarded_printf));
|
||||
|
||||
nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1;
|
||||
if (nblost > 0)
|
||||
brcmf_dbg(ERROR, "WLC_E_TRACE: [Event lost --> seqnum "
|
||||
" %d nblost %d\n", be32_to_cpu(hdr.seqnum),
|
||||
nblost);
|
||||
seqnum_prev = be32_to_cpu(hdr.seqnum);
|
||||
|
||||
/* Display the trace buffer. Advance from \n to \n to
|
||||
* avoid display big
|
||||
* printf (issue with Linux printk )
|
||||
*/
|
||||
p = (char *)&buf[sizeof(struct msgtrace_hdr)];
|
||||
while ((s = strstr(p, "\n")) != NULL) {
|
||||
*s = '\0';
|
||||
printk(KERN_DEBUG"%s\n", p);
|
||||
p = s + 1;
|
||||
}
|
||||
printk(KERN_DEBUG "%s\n", p);
|
||||
|
||||
/* Reset datalen to avoid display below */
|
||||
datalen = 0;
|
||||
break;
|
||||
|
||||
case BRCMF_E_RSSI:
|
||||
brcmf_dbg(EVENT, "MACEVENT: %s %d\n",
|
||||
event_name, be32_to_cpu(*((__be32 *)event_data)));
|
||||
break;
|
||||
|
||||
default:
|
||||
brcmf_dbg(EVENT,
|
||||
"MACEVENT: %s %d, MAC %s, status %d, reason %d, "
|
||||
"auth %d\n", event_name, event_type, eabuf,
|
||||
(int)status, (int)reason, (int)auth_type);
|
||||
break;
|
||||
}
|
||||
|
||||
/* show any appended data */
|
||||
if (datalen) {
|
||||
buf = (unsigned char *) event_data;
|
||||
brcmf_dbg(EVENT, " data (%d) : ", datalen);
|
||||
for (i = 0; i < datalen; i++)
|
||||
brcmf_dbg(EVENT, " 0x%02x ", *buf++);
|
||||
brcmf_dbg(EVENT, "\n");
|
||||
}
|
||||
}
|
||||
#endif /* BCMDBG */
|
||||
|
||||
int
|
||||
brcmf_c_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata,
|
||||
struct brcmf_event_msg *event, void **data_ptr)
|
||||
{
|
||||
/* check whether packet is a BRCM event pkt */
|
||||
struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata;
|
||||
struct brcmf_if_event *ifevent;
|
||||
char *event_data;
|
||||
u32 type, status;
|
||||
u16 flags;
|
||||
int evlen;
|
||||
|
||||
if (memcmp(BRCM_OUI, &pvt_data->hdr.oui[0], DOT11_OUI_LEN)) {
|
||||
brcmf_dbg(ERROR, "mismatched OUI, bailing\n");
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
/* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */
|
||||
if (get_unaligned_be16(&pvt_data->hdr.usr_subtype) !=
|
||||
BCMILCP_BCM_SUBTYPE_EVENT) {
|
||||
brcmf_dbg(ERROR, "mismatched subtype, bailing\n");
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
*data_ptr = &pvt_data[1];
|
||||
event_data = *data_ptr;
|
||||
|
||||
/* memcpy since BRCM event pkt may be unaligned. */
|
||||
memcpy(event, &pvt_data->msg, sizeof(struct brcmf_event_msg));
|
||||
|
||||
type = get_unaligned_be32(&event->event_type);
|
||||
flags = get_unaligned_be16(&event->flags);
|
||||
status = get_unaligned_be32(&event->status);
|
||||
evlen = get_unaligned_be32(&event->datalen) +
|
||||
sizeof(struct brcmf_event);
|
||||
|
||||
switch (type) {
|
||||
case BRCMF_E_IF:
|
||||
ifevent = (struct brcmf_if_event *) event_data;
|
||||
brcmf_dbg(TRACE, "if event\n");
|
||||
|
||||
if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) {
|
||||
if (ifevent->action == BRCMF_E_IF_ADD)
|
||||
brcmf_add_if(drvr_priv, ifevent->ifidx, NULL,
|
||||
event->ifname,
|
||||
pvt_data->eth.h_dest,
|
||||
ifevent->flags, ifevent->bssidx);
|
||||
else
|
||||
brcmf_del_if(drvr_priv, ifevent->ifidx);
|
||||
} else {
|
||||
brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n",
|
||||
ifevent->ifidx, event->ifname);
|
||||
}
|
||||
|
||||
/* send up the if event: btamp user needs it */
|
||||
*ifidx = brcmf_ifname2idx(drvr_priv, event->ifname);
|
||||
break;
|
||||
|
||||
/* These are what external supplicant/authenticator wants */
|
||||
case BRCMF_E_LINK:
|
||||
case BRCMF_E_ASSOC_IND:
|
||||
case BRCMF_E_REASSOC_IND:
|
||||
case BRCMF_E_DISASSOC_IND:
|
||||
case BRCMF_E_MIC_ERROR:
|
||||
default:
|
||||
/* Fall through: this should get _everything_ */
|
||||
|
||||
*ifidx = brcmf_ifname2idx(drvr_priv, event->ifname);
|
||||
brcmf_dbg(TRACE, "MAC event %d, flags %x, status %x\n",
|
||||
type, flags, status);
|
||||
|
||||
/* put it back to BRCMF_E_NDIS_LINK */
|
||||
if (type == BRCMF_E_NDIS_LINK) {
|
||||
u32 temp1;
|
||||
__be32 temp2;
|
||||
|
||||
temp1 = get_unaligned_be32(&event->event_type);
|
||||
brcmf_dbg(TRACE, "Converted to WLC_E_LINK type %d\n",
|
||||
temp1);
|
||||
|
||||
temp2 = cpu_to_be32(BRCMF_E_NDIS_LINK);
|
||||
memcpy((void *)(&pvt_data->msg.event_type), &temp2,
|
||||
sizeof(pvt_data->msg.event_type));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef BCMDBG
|
||||
brcmf_c_show_host_event(event, event_data);
|
||||
#endif /* BCMDBG */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Convert user's input in hex pattern to byte-size mask */
|
||||
static int brcmf_c_pattern_atoh(char *src, char *dst)
|
||||
{
|
||||
int i;
|
||||
if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) {
|
||||
brcmf_dbg(ERROR, "Mask invalid format. Needs to start with 0x\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
src = src + 2; /* Skip past 0x */
|
||||
if (strlen(src) % 2 != 0) {
|
||||
brcmf_dbg(ERROR, "Mask invalid format. Length must be even.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; *src != '\0'; i++) {
|
||||
unsigned long res;
|
||||
char num[3];
|
||||
strncpy(num, src, 2);
|
||||
num[2] = '\0';
|
||||
if (kstrtoul(num, 16, &res))
|
||||
return -EINVAL;
|
||||
dst[i] = (u8)res;
|
||||
src += 2;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
void
|
||||
brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable,
|
||||
int master_mode)
|
||||
{
|
||||
unsigned long res;
|
||||
char *argv[8];
|
||||
int i = 0;
|
||||
const char *str;
|
||||
int buf_len;
|
||||
int str_len;
|
||||
char *arg_save = NULL, *arg_org = NULL;
|
||||
int rc;
|
||||
char buf[128];
|
||||
struct brcmf_pkt_filter_enable_le enable_parm;
|
||||
struct brcmf_pkt_filter_enable_le *pkt_filterp;
|
||||
__le32 mmode_le;
|
||||
|
||||
arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC);
|
||||
if (!arg_save)
|
||||
goto fail;
|
||||
|
||||
arg_org = arg_save;
|
||||
memcpy(arg_save, arg, strlen(arg) + 1);
|
||||
|
||||
argv[i] = strsep(&arg_save, " ");
|
||||
|
||||
i = 0;
|
||||
if (NULL == argv[i]) {
|
||||
brcmf_dbg(ERROR, "No args provided\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
str = "pkt_filter_enable";
|
||||
str_len = strlen(str);
|
||||
strncpy(buf, str, str_len);
|
||||
buf[str_len] = '\0';
|
||||
buf_len = str_len + 1;
|
||||
|
||||
pkt_filterp = (struct brcmf_pkt_filter_enable_le *) (buf + str_len + 1);
|
||||
|
||||
/* Parse packet filter id. */
|
||||
enable_parm.id = 0;
|
||||
if (!kstrtoul(argv[i], 0, &res))
|
||||
enable_parm.id = cpu_to_le32((u32)res);
|
||||
|
||||
/* Parse enable/disable value. */
|
||||
enable_parm.enable = cpu_to_le32(enable);
|
||||
|
||||
buf_len += sizeof(enable_parm);
|
||||
memcpy((char *)pkt_filterp, &enable_parm, sizeof(enable_parm));
|
||||
|
||||
/* Enable/disable the specified filter. */
|
||||
rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
|
||||
rc = rc >= 0 ? 0 : rc;
|
||||
if (rc)
|
||||
brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
|
||||
arg, rc);
|
||||
else
|
||||
brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg);
|
||||
|
||||
/* Contorl the master mode */
|
||||
mmode_le = cpu_to_le32(master_mode);
|
||||
brcmf_c_mkiovar("pkt_filter_mode", (char *)&mmode_le, 4, buf,
|
||||
sizeof(buf));
|
||||
rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf,
|
||||
sizeof(buf));
|
||||
rc = rc >= 0 ? 0 : rc;
|
||||
if (rc)
|
||||
brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
|
||||
arg, rc);
|
||||
|
||||
fail:
|
||||
kfree(arg_org);
|
||||
}
|
||||
|
||||
void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg)
|
||||
{
|
||||
const char *str;
|
||||
struct brcmf_pkt_filter_le pkt_filter;
|
||||
struct brcmf_pkt_filter_le *pkt_filterp;
|
||||
unsigned long res;
|
||||
int buf_len;
|
||||
int str_len;
|
||||
int rc;
|
||||
u32 mask_size;
|
||||
u32 pattern_size;
|
||||
char *argv[8], *buf = NULL;
|
||||
int i = 0;
|
||||
char *arg_save = NULL, *arg_org = NULL;
|
||||
|
||||
arg_save = kstrdup(arg, GFP_ATOMIC);
|
||||
if (!arg_save)
|
||||
goto fail;
|
||||
|
||||
arg_org = arg_save;
|
||||
|
||||
buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC);
|
||||
if (!buf)
|
||||
goto fail;
|
||||
|
||||
argv[i] = strsep(&arg_save, " ");
|
||||
while (argv[i++])
|
||||
argv[i] = strsep(&arg_save, " ");
|
||||
|
||||
i = 0;
|
||||
if (NULL == argv[i]) {
|
||||
brcmf_dbg(ERROR, "No args provided\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
str = "pkt_filter_add";
|
||||
strcpy(buf, str);
|
||||
str_len = strlen(str);
|
||||
buf_len = str_len + 1;
|
||||
|
||||
pkt_filterp = (struct brcmf_pkt_filter_le *) (buf + str_len + 1);
|
||||
|
||||
/* Parse packet filter id. */
|
||||
pkt_filter.id = 0;
|
||||
if (!kstrtoul(argv[i], 0, &res))
|
||||
pkt_filter.id = cpu_to_le32((u32)res);
|
||||
|
||||
if (NULL == argv[++i]) {
|
||||
brcmf_dbg(ERROR, "Polarity not provided\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Parse filter polarity. */
|
||||
pkt_filter.negate_match = 0;
|
||||
if (!kstrtoul(argv[i], 0, &res))
|
||||
pkt_filter.negate_match = cpu_to_le32((u32)res);
|
||||
|
||||
if (NULL == argv[++i]) {
|
||||
brcmf_dbg(ERROR, "Filter type not provided\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Parse filter type. */
|
||||
pkt_filter.type = 0;
|
||||
if (!kstrtoul(argv[i], 0, &res))
|
||||
pkt_filter.type = cpu_to_le32((u32)res);
|
||||
|
||||
if (NULL == argv[++i]) {
|
||||
brcmf_dbg(ERROR, "Offset not provided\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Parse pattern filter offset. */
|
||||
pkt_filter.u.pattern.offset = 0;
|
||||
if (!kstrtoul(argv[i], 0, &res))
|
||||
pkt_filter.u.pattern.offset = cpu_to_le32((u32)res);
|
||||
|
||||
if (NULL == argv[++i]) {
|
||||
brcmf_dbg(ERROR, "Bitmask not provided\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Parse pattern filter mask. */
|
||||
mask_size =
|
||||
brcmf_c_pattern_atoh
|
||||
(argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern);
|
||||
|
||||
if (NULL == argv[++i]) {
|
||||
brcmf_dbg(ERROR, "Pattern not provided\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Parse pattern filter pattern. */
|
||||
pattern_size =
|
||||
brcmf_c_pattern_atoh(argv[i],
|
||||
(char *)&pkt_filterp->u.pattern.
|
||||
mask_and_pattern[mask_size]);
|
||||
|
||||
if (mask_size != pattern_size) {
|
||||
brcmf_dbg(ERROR, "Mask and pattern not the same size\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
pkt_filter.u.pattern.size_bytes = cpu_to_le32(mask_size);
|
||||
buf_len += BRCMF_PKT_FILTER_FIXED_LEN;
|
||||
buf_len += (BRCMF_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);
|
||||
|
||||
/* Keep-alive attributes are set in local
|
||||
* variable (keep_alive_pkt), and
|
||||
** then memcpy'ed into buffer (keep_alive_pktp) since there is no
|
||||
** guarantee that the buffer is properly aligned.
|
||||
*/
|
||||
memcpy((char *)pkt_filterp,
|
||||
&pkt_filter,
|
||||
BRCMF_PKT_FILTER_FIXED_LEN + BRCMF_PKT_FILTER_PATTERN_FIXED_LEN);
|
||||
|
||||
rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
|
||||
rc = rc >= 0 ? 0 : rc;
|
||||
|
||||
if (rc)
|
||||
brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
|
||||
arg, rc);
|
||||
else
|
||||
brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg);
|
||||
|
||||
fail:
|
||||
kfree(arg_org);
|
||||
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
static void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode)
|
||||
{
|
||||
char iovbuf[32];
|
||||
int retcode;
|
||||
|
||||
brcmf_c_mkiovar("arp_ol", (char *)&arp_mode, 4, iovbuf, sizeof(iovbuf));
|
||||
retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
|
||||
iovbuf, sizeof(iovbuf));
|
||||
retcode = retcode >= 0 ? 0 : retcode;
|
||||
if (retcode)
|
||||
brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, retcode = %d\n",
|
||||
arp_mode, retcode);
|
||||
else
|
||||
brcmf_dbg(TRACE, "successfully set ARP offload mode to 0x%x\n",
|
||||
arp_mode);
|
||||
}
|
||||
|
||||
static void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable)
|
||||
{
|
||||
char iovbuf[32];
|
||||
int retcode;
|
||||
|
||||
brcmf_c_mkiovar("arpoe", (char *)&arp_enable, 4,
|
||||
iovbuf, sizeof(iovbuf));
|
||||
retcode = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR,
|
||||
iovbuf, sizeof(iovbuf));
|
||||
retcode = retcode >= 0 ? 0 : retcode;
|
||||
if (retcode)
|
||||
brcmf_dbg(TRACE, "failed to enable ARP offload to %d, retcode = %d\n",
|
||||
arp_enable, retcode);
|
||||
else
|
||||
brcmf_dbg(TRACE, "successfully enabled ARP offload to %d\n",
|
||||
arp_enable);
|
||||
}
|
||||
|
||||
int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr)
|
||||
{
|
||||
char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; /* Room for
|
||||
"event_msgs" + '\0' + bitvec */
|
||||
uint up = 0;
|
||||
char buf[128], *ptr;
|
||||
u32 dongle_align = BRCMF_SDALIGN;
|
||||
u32 glom = 0;
|
||||
u32 roaming = 1;
|
||||
uint bcn_timeout = 3;
|
||||
int scan_assoc_time = 40;
|
||||
int scan_unassoc_time = 40;
|
||||
int i;
|
||||
|
||||
brcmf_os_proto_block(drvr);
|
||||
|
||||
/* Set Country code */
|
||||
if (drvr->country_code[0] != 0) {
|
||||
if (brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_COUNTRY,
|
||||
drvr->country_code,
|
||||
sizeof(drvr->country_code)) < 0)
|
||||
brcmf_dbg(ERROR, "country code setting failed\n");
|
||||
}
|
||||
|
||||
/* query for 'ver' to get version info from firmware */
|
||||
memset(buf, 0, sizeof(buf));
|
||||
ptr = buf;
|
||||
brcmf_c_mkiovar("ver", NULL, 0, buf, sizeof(buf));
|
||||
brcmf_proto_cdc_query_dcmd(drvr, 0, BRCMF_C_GET_VAR, buf, sizeof(buf));
|
||||
strsep(&ptr, "\n");
|
||||
/* Print fw version info */
|
||||
brcmf_dbg(ERROR, "Firmware version = %s\n", buf);
|
||||
|
||||
/* Match Host and Dongle rx alignment */
|
||||
brcmf_c_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf,
|
||||
sizeof(iovbuf));
|
||||
brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
|
||||
sizeof(iovbuf));
|
||||
|
||||
/* disable glom option per default */
|
||||
brcmf_c_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf));
|
||||
brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
|
||||
sizeof(iovbuf));
|
||||
|
||||
/* Setup timeout if Beacons are lost and roam is off to report
|
||||
link down */
|
||||
brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
|
||||
sizeof(iovbuf));
|
||||
brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
|
||||
sizeof(iovbuf));
|
||||
|
||||
/* Enable/Disable build-in roaming to allowed ext supplicant to take
|
||||
of romaing */
|
||||
brcmf_c_mkiovar("roam_off", (char *)&roaming, 4,
|
||||
iovbuf, sizeof(iovbuf));
|
||||
brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
|
||||
sizeof(iovbuf));
|
||||
|
||||
/* Force STA UP */
|
||||
brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_UP, (char *)&up, sizeof(up));
|
||||
|
||||
/* Setup event_msgs */
|
||||
brcmf_c_mkiovar("event_msgs", drvr->eventmask, BRCMF_EVENTING_MASK_LEN,
|
||||
iovbuf, sizeof(iovbuf));
|
||||
brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf,
|
||||
sizeof(iovbuf));
|
||||
|
||||
brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_CHANNEL_TIME,
|
||||
(char *)&scan_assoc_time, sizeof(scan_assoc_time));
|
||||
brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_SCAN_UNASSOC_TIME,
|
||||
(char *)&scan_unassoc_time, sizeof(scan_unassoc_time));
|
||||
|
||||
/* Set and enable ARP offload feature */
|
||||
brcmf_c_arp_offload_set(drvr, BRCMF_ARPOL_MODE);
|
||||
brcmf_c_arp_offload_enable(drvr, true);
|
||||
|
||||
/* Set up pkt filter */
|
||||
for (i = 0; i < drvr->pktfilter_count; i++) {
|
||||
brcmf_c_pktfilter_offload_set(drvr, drvr->pktfilter[i]);
|
||||
brcmf_c_pktfilter_offload_enable(drvr, drvr->pktfilter[i],
|
||||
0, true);
|
||||
}
|
||||
|
||||
brcmf_os_proto_unblock(drvr);
|
||||
|
||||
return 0;
|
||||
}
|
58
drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
Normal file
58
drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 _BRCMF_DBG_H_
|
||||
#define _BRCMF_DBG_H_
|
||||
|
||||
#if defined(BCMDBG)
|
||||
|
||||
#define brcmf_dbg(level, fmt, ...) \
|
||||
do { \
|
||||
if (BRCMF_ERROR_VAL == BRCMF_##level##_VAL) { \
|
||||
if (brcmf_msg_level & BRCMF_##level##_VAL) { \
|
||||
if (net_ratelimit()) \
|
||||
printk(KERN_DEBUG "%s: " fmt, \
|
||||
__func__, ##__VA_ARGS__); \
|
||||
} \
|
||||
} else { \
|
||||
if (brcmf_msg_level & BRCMF_##level##_VAL) { \
|
||||
printk(KERN_DEBUG "%s: " fmt, \
|
||||
__func__, ##__VA_ARGS__); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define BRCMF_DATA_ON() (brcmf_msg_level & BRCMF_DATA_VAL)
|
||||
#define BRCMF_CTL_ON() (brcmf_msg_level & BRCMF_CTL_VAL)
|
||||
#define BRCMF_HDRS_ON() (brcmf_msg_level & BRCMF_HDRS_VAL)
|
||||
#define BRCMF_BYTES_ON() (brcmf_msg_level & BRCMF_BYTES_VAL)
|
||||
#define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL)
|
||||
|
||||
#else /* (defined BCMDBG) || (defined BCMDBG) */
|
||||
|
||||
#define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__)
|
||||
|
||||
#define BRCMF_DATA_ON() 0
|
||||
#define BRCMF_CTL_ON() 0
|
||||
#define BRCMF_HDRS_ON() 0
|
||||
#define BRCMF_BYTES_ON() 0
|
||||
#define BRCMF_GLOM_ON() 0
|
||||
|
||||
#endif /* defined(BCMDBG) */
|
||||
|
||||
extern int brcmf_msg_level;
|
||||
|
||||
#endif /* _BRCMF_DBG_H_ */
|
1356
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
Normal file
1356
drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
Normal file
File diff suppressed because it is too large
Load Diff
60
drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
Normal file
60
drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 _BRCMF_PROTO_H_
|
||||
#define _BRCMF_PROTO_H_
|
||||
|
||||
/*
|
||||
* Exported from the brcmf protocol module (brcmf_cdc)
|
||||
*/
|
||||
|
||||
/* Linkage, sets prot link and updates hdrlen in pub */
|
||||
extern int brcmf_proto_attach(struct brcmf_pub *drvr);
|
||||
|
||||
/* Unlink, frees allocated protocol memory (including brcmf_proto) */
|
||||
extern void brcmf_proto_detach(struct brcmf_pub *drvr);
|
||||
|
||||
/* Initialize protocol: sync w/dongle state.
|
||||
* Sets dongle media info (iswl, drv_version, mac address).
|
||||
*/
|
||||
extern int brcmf_proto_init(struct brcmf_pub *drvr);
|
||||
|
||||
/* Stop protocol: sync w/dongle state. */
|
||||
extern void brcmf_proto_stop(struct brcmf_pub *drvr);
|
||||
|
||||
/* Add any protocol-specific data header.
|
||||
* Caller must reserve prot_hdrlen prepend space.
|
||||
*/
|
||||
extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx,
|
||||
struct sk_buff *txp);
|
||||
|
||||
/* Remove any protocol-specific data header. */
|
||||
extern int brcmf_proto_hdrpull(struct brcmf_pub *, int *ifidx,
|
||||
struct sk_buff *rxp);
|
||||
|
||||
/* Use protocol to issue command to dongle */
|
||||
extern int brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx,
|
||||
struct brcmf_dcmd *dcmd, int len);
|
||||
|
||||
/* Update local copy of dongle statistics */
|
||||
extern void brcmf_proto_dstats(struct brcmf_pub *drvr);
|
||||
|
||||
extern int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr);
|
||||
|
||||
extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx,
|
||||
uint cmd, void *buf, uint len);
|
||||
|
||||
#endif /* _BRCMF_PROTO_H_ */
|
4591
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
Normal file
4591
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
Normal file
File diff suppressed because it is too large
Load Diff
252
drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
Normal file
252
drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
Normal file
@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 _BRCM_SDH_H_
|
||||
#define _BRCM_SDH_H_
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#define SDIO_FUNC_0 0
|
||||
#define SDIO_FUNC_1 1
|
||||
#define SDIO_FUNC_2 2
|
||||
|
||||
#define SDIOD_FBR_SIZE 0x100
|
||||
|
||||
/* io_en */
|
||||
#define SDIO_FUNC_ENABLE_1 0x02
|
||||
#define SDIO_FUNC_ENABLE_2 0x04
|
||||
|
||||
/* io_rdys */
|
||||
#define SDIO_FUNC_READY_1 0x02
|
||||
#define SDIO_FUNC_READY_2 0x04
|
||||
|
||||
/* intr_status */
|
||||
#define INTR_STATUS_FUNC1 0x2
|
||||
#define INTR_STATUS_FUNC2 0x4
|
||||
|
||||
/* Maximum number of I/O funcs */
|
||||
#define SDIOD_MAX_IOFUNCS 7
|
||||
|
||||
/* as of sdiod rev 0, supports 3 functions */
|
||||
#define SBSDIO_NUM_FUNCTION 3
|
||||
|
||||
/* function 1 miscellaneous registers */
|
||||
|
||||
/* sprom command and status */
|
||||
#define SBSDIO_SPROM_CS 0x10000
|
||||
/* sprom info register */
|
||||
#define SBSDIO_SPROM_INFO 0x10001
|
||||
/* sprom indirect access data byte 0 */
|
||||
#define SBSDIO_SPROM_DATA_LOW 0x10002
|
||||
/* sprom indirect access data byte 1 */
|
||||
#define SBSDIO_SPROM_DATA_HIGH 0x10003
|
||||
/* sprom indirect access addr byte 0 */
|
||||
#define SBSDIO_SPROM_ADDR_LOW 0x10004
|
||||
/* sprom indirect access addr byte 0 */
|
||||
#define SBSDIO_SPROM_ADDR_HIGH 0x10005
|
||||
/* xtal_pu (gpio) output */
|
||||
#define SBSDIO_CHIP_CTRL_DATA 0x10006
|
||||
/* xtal_pu (gpio) enable */
|
||||
#define SBSDIO_CHIP_CTRL_EN 0x10007
|
||||
/* rev < 7, watermark for sdio device */
|
||||
#define SBSDIO_WATERMARK 0x10008
|
||||
/* control busy signal generation */
|
||||
#define SBSDIO_DEVICE_CTL 0x10009
|
||||
|
||||
/* SB Address Window Low (b15) */
|
||||
#define SBSDIO_FUNC1_SBADDRLOW 0x1000A
|
||||
/* SB Address Window Mid (b23:b16) */
|
||||
#define SBSDIO_FUNC1_SBADDRMID 0x1000B
|
||||
/* SB Address Window High (b31:b24) */
|
||||
#define SBSDIO_FUNC1_SBADDRHIGH 0x1000C
|
||||
/* Frame Control (frame term/abort) */
|
||||
#define SBSDIO_FUNC1_FRAMECTRL 0x1000D
|
||||
/* ChipClockCSR (ALP/HT ctl/status) */
|
||||
#define SBSDIO_FUNC1_CHIPCLKCSR 0x1000E
|
||||
/* SdioPullUp (on cmd, d0-d2) */
|
||||
#define SBSDIO_FUNC1_SDIOPULLUP 0x1000F
|
||||
/* Write Frame Byte Count Low */
|
||||
#define SBSDIO_FUNC1_WFRAMEBCLO 0x10019
|
||||
/* Write Frame Byte Count High */
|
||||
#define SBSDIO_FUNC1_WFRAMEBCHI 0x1001A
|
||||
/* Read Frame Byte Count Low */
|
||||
#define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B
|
||||
/* Read Frame Byte Count High */
|
||||
#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C
|
||||
|
||||
#define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */
|
||||
#define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001C /* f1 misc register end */
|
||||
|
||||
/* function 1 OCP space */
|
||||
|
||||
/* sb offset addr is <= 15 bits, 32k */
|
||||
#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF
|
||||
#define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000
|
||||
/* with b15, maps to 32-bit SB access */
|
||||
#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000
|
||||
|
||||
/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
|
||||
|
||||
#define SBSDIO_SBADDRLOW_MASK 0x80 /* Valid bits in SBADDRLOW */
|
||||
#define SBSDIO_SBADDRMID_MASK 0xff /* Valid bits in SBADDRMID */
|
||||
#define SBSDIO_SBADDRHIGH_MASK 0xffU /* Valid bits in SBADDRHIGH */
|
||||
/* Address bits from SBADDR regs */
|
||||
#define SBSDIO_SBWINDOW_MASK 0xffff8000
|
||||
|
||||
#define SDIOH_READ 0 /* Read request */
|
||||
#define SDIOH_WRITE 1 /* Write request */
|
||||
|
||||
#define SDIOH_DATA_FIX 0 /* Fixed addressing */
|
||||
#define SDIOH_DATA_INC 1 /* Incremental addressing */
|
||||
|
||||
/* internal return code */
|
||||
#define SUCCESS 0
|
||||
#define ERROR 1
|
||||
|
||||
struct brcmf_sdreg {
|
||||
int func;
|
||||
int offset;
|
||||
int value;
|
||||
};
|
||||
|
||||
struct brcmf_sdio_dev {
|
||||
struct sdio_func *func[SDIO_MAX_FUNCS];
|
||||
u8 num_funcs; /* Supported funcs on client */
|
||||
u32 func_cis_ptr[SDIOD_MAX_IOFUNCS];
|
||||
u32 sbwad; /* Save backplane window address */
|
||||
bool regfail; /* status of last reg_r/w call */
|
||||
void *bus;
|
||||
atomic_t suspend; /* suspend flag */
|
||||
wait_queue_head_t request_byte_wait;
|
||||
wait_queue_head_t request_word_wait;
|
||||
wait_queue_head_t request_packet_wait;
|
||||
wait_queue_head_t request_buffer_wait;
|
||||
|
||||
};
|
||||
|
||||
/* Register/deregister device interrupt handler. */
|
||||
extern int
|
||||
brcmf_sdcard_intr_reg(struct brcmf_sdio_dev *sdiodev);
|
||||
|
||||
extern int brcmf_sdcard_intr_dereg(struct brcmf_sdio_dev *sdiodev);
|
||||
|
||||
/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface).
|
||||
* fn: function number
|
||||
* addr: unmodified SDIO-space address
|
||||
* data: data byte to write
|
||||
* err: pointer to error code (or NULL)
|
||||
*/
|
||||
extern u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_dev *sdiodev, uint func,
|
||||
u32 addr, int *err);
|
||||
extern void brcmf_sdcard_cfg_write(struct brcmf_sdio_dev *sdiodev, uint func,
|
||||
u32 addr, u8 data, int *err);
|
||||
|
||||
/* Synchronous access to device (client) core registers via CMD53 to F1.
|
||||
* addr: backplane address (i.e. >= regsva from attach)
|
||||
* size: register width in bytes (2 or 4)
|
||||
* data: data for register write
|
||||
*/
|
||||
extern u32
|
||||
brcmf_sdcard_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size);
|
||||
|
||||
extern u32
|
||||
brcmf_sdcard_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size,
|
||||
u32 data);
|
||||
|
||||
/* Indicate if last reg read/write failed */
|
||||
extern bool brcmf_sdcard_regfail(struct brcmf_sdio_dev *sdiodev);
|
||||
|
||||
/* Buffer transfer to/from device (client) core via cmd53.
|
||||
* fn: function number
|
||||
* addr: backplane address (i.e. >= regsva from attach)
|
||||
* flags: backplane width, address increment, sync/async
|
||||
* buf: pointer to memory data buffer
|
||||
* nbytes: number of bytes to transfer to/from buf
|
||||
* pkt: pointer to packet associated with buf (if any)
|
||||
* complete: callback function for command completion (async only)
|
||||
* handle: handle for completion callback (first arg in callback)
|
||||
* Returns 0 or error code.
|
||||
* NOTE: Async operation is not currently supported.
|
||||
*/
|
||||
extern int
|
||||
brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
|
||||
uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt);
|
||||
extern int
|
||||
brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
|
||||
uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt);
|
||||
|
||||
/* Flags bits */
|
||||
|
||||
/* Four-byte target (backplane) width (vs. two-byte) */
|
||||
#define SDIO_REQ_4BYTE 0x1
|
||||
/* Fixed address (FIFO) (vs. incrementing address) */
|
||||
#define SDIO_REQ_FIXED 0x2
|
||||
/* Async request (vs. sync request) */
|
||||
#define SDIO_REQ_ASYNC 0x4
|
||||
|
||||
/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only).
|
||||
* rw: read or write (0/1)
|
||||
* addr: direct SDIO address
|
||||
* buf: pointer to memory data buffer
|
||||
* nbytes: number of bytes to transfer to/from buf
|
||||
* Returns 0 or error code.
|
||||
*/
|
||||
extern int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw,
|
||||
u32 addr, u8 *buf, uint nbytes);
|
||||
|
||||
/* Issue an abort to the specified function */
|
||||
extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn);
|
||||
|
||||
/* platform specific/high level functions */
|
||||
extern int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
|
||||
extern int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev);
|
||||
|
||||
extern int brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev,
|
||||
u32 address);
|
||||
|
||||
/* attach, return handler on success, NULL if failed.
|
||||
* The handler shall be provided by all subsequent calls. No local cache
|
||||
* cfghdl points to the starting address of pci device mapped memory
|
||||
*/
|
||||
extern int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev);
|
||||
extern void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev);
|
||||
|
||||
/* read or write one byte using cmd52 */
|
||||
extern int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw,
|
||||
uint fnc, uint addr, u8 *byte);
|
||||
|
||||
/* read or write 2/4 bytes using cmd53 */
|
||||
extern int
|
||||
brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
|
||||
uint rw, uint fnc, uint addr,
|
||||
u32 *word, uint nbyte);
|
||||
|
||||
/* read or write any buffer using cmd53 */
|
||||
extern int
|
||||
brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
|
||||
uint fix_inc, uint rw, uint fnc_num,
|
||||
u32 addr, uint regwidth,
|
||||
u32 buflen, u8 *buffer, struct sk_buff *pkt);
|
||||
|
||||
/* Watchdog timer interface for pm ops */
|
||||
extern void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev,
|
||||
bool enable);
|
||||
|
||||
extern void *brcmf_sdbrcm_probe(u16 bus_no, u16 slot, u16 func, uint bustype,
|
||||
u32 regsva, struct brcmf_sdio_dev *sdiodev);
|
||||
extern void brcmf_sdbrcm_disconnect(void *ptr);
|
||||
extern void brcmf_sdbrcm_isr(void *arg);
|
||||
#endif /* _BRCM_SDH_H_ */
|
3868
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
Normal file
3868
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
Normal file
File diff suppressed because it is too large
Load Diff
375
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
Normal file
375
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
Normal file
@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 _wl_cfg80211_h_
|
||||
#define _wl_cfg80211_h_
|
||||
|
||||
struct brcmf_cfg80211_conf;
|
||||
struct brcmf_cfg80211_iface;
|
||||
struct brcmf_cfg80211_priv;
|
||||
struct brcmf_cfg80211_security;
|
||||
struct brcmf_cfg80211_ibss;
|
||||
|
||||
#define WL_DBG_NONE 0
|
||||
#define WL_DBG_CONN (1 << 5)
|
||||
#define WL_DBG_SCAN (1 << 4)
|
||||
#define WL_DBG_TRACE (1 << 3)
|
||||
#define WL_DBG_INFO (1 << 1)
|
||||
#define WL_DBG_ERR (1 << 0)
|
||||
#define WL_DBG_MASK ((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \
|
||||
(WL_DBG_SCAN) | (WL_DBG_CONN))
|
||||
|
||||
#define WL_ERR(fmt, args...) \
|
||||
do { \
|
||||
if (brcmf_dbg_level & WL_DBG_ERR) { \
|
||||
if (net_ratelimit()) { \
|
||||
printk(KERN_ERR "ERROR @%s : " fmt, \
|
||||
__func__, ##args); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#if (defined BCMDBG)
|
||||
#define WL_INFO(fmt, args...) \
|
||||
do { \
|
||||
if (brcmf_dbg_level & WL_DBG_INFO) { \
|
||||
if (net_ratelimit()) { \
|
||||
printk(KERN_ERR "INFO @%s : " fmt, \
|
||||
__func__, ##args); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define WL_TRACE(fmt, args...) \
|
||||
do { \
|
||||
if (brcmf_dbg_level & WL_DBG_TRACE) { \
|
||||
if (net_ratelimit()) { \
|
||||
printk(KERN_ERR "TRACE @%s : " fmt, \
|
||||
__func__, ##args); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define WL_SCAN(fmt, args...) \
|
||||
do { \
|
||||
if (brcmf_dbg_level & WL_DBG_SCAN) { \
|
||||
if (net_ratelimit()) { \
|
||||
printk(KERN_ERR "SCAN @%s : " fmt, \
|
||||
__func__, ##args); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define WL_CONN(fmt, args...) \
|
||||
do { \
|
||||
if (brcmf_dbg_level & WL_DBG_CONN) { \
|
||||
if (net_ratelimit()) { \
|
||||
printk(KERN_ERR "CONN @%s : " fmt, \
|
||||
__func__, ##args); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else /* (defined BCMDBG) */
|
||||
#define WL_INFO(fmt, args...)
|
||||
#define WL_TRACE(fmt, args...)
|
||||
#define WL_SCAN(fmt, args...)
|
||||
#define WL_CONN(fmt, args...)
|
||||
#endif /* (defined BCMDBG) */
|
||||
|
||||
#define WL_NUM_SCAN_MAX 1
|
||||
#define WL_NUM_PMKIDS_MAX MAXPMKID /* will be used
|
||||
* for 2.6.33 kernel
|
||||
* or later
|
||||
*/
|
||||
#define WL_SCAN_BUF_MAX (1024 * 8)
|
||||
#define WL_TLV_INFO_MAX 1024
|
||||
#define WL_BSS_INFO_MAX 2048
|
||||
#define WL_ASSOC_INFO_MAX 512 /*
|
||||
* needs to grab assoc info from dongle to
|
||||
* report it to cfg80211 through "connect"
|
||||
* event
|
||||
*/
|
||||
#define WL_DCMD_LEN_MAX 1024
|
||||
#define WL_EXTRA_BUF_MAX 2048
|
||||
#define WL_ISCAN_BUF_MAX 2048 /*
|
||||
* the buf length can be BRCMF_DCMD_MAXLEN
|
||||
* to reduce iteration
|
||||
*/
|
||||
#define WL_ISCAN_TIMER_INTERVAL_MS 3000
|
||||
#define WL_SCAN_ERSULTS_LAST (BRCMF_SCAN_RESULTS_NO_MEM+1)
|
||||
#define WL_AP_MAX 256 /* virtually unlimitted as long
|
||||
* as kernel memory allows
|
||||
*/
|
||||
|
||||
#define WL_ROAM_TRIGGER_LEVEL -75
|
||||
#define WL_ROAM_DELTA 20
|
||||
#define WL_BEACON_TIMEOUT 3
|
||||
|
||||
#define WL_SCAN_CHANNEL_TIME 40
|
||||
#define WL_SCAN_UNASSOC_TIME 40
|
||||
#define WL_SCAN_PASSIVE_TIME 120
|
||||
|
||||
/* dongle status */
|
||||
enum wl_status {
|
||||
WL_STATUS_READY,
|
||||
WL_STATUS_SCANNING,
|
||||
WL_STATUS_SCAN_ABORTING,
|
||||
WL_STATUS_CONNECTING,
|
||||
WL_STATUS_CONNECTED
|
||||
};
|
||||
|
||||
/* wi-fi mode */
|
||||
enum wl_mode {
|
||||
WL_MODE_BSS,
|
||||
WL_MODE_IBSS,
|
||||
WL_MODE_AP
|
||||
};
|
||||
|
||||
/* dongle profile list */
|
||||
enum wl_prof_list {
|
||||
WL_PROF_MODE,
|
||||
WL_PROF_SSID,
|
||||
WL_PROF_SEC,
|
||||
WL_PROF_IBSS,
|
||||
WL_PROF_BAND,
|
||||
WL_PROF_BSSID,
|
||||
WL_PROF_ACT,
|
||||
WL_PROF_BEACONINT,
|
||||
WL_PROF_DTIMPERIOD
|
||||
};
|
||||
|
||||
/* dongle iscan state */
|
||||
enum wl_iscan_state {
|
||||
WL_ISCAN_STATE_IDLE,
|
||||
WL_ISCAN_STATE_SCANING
|
||||
};
|
||||
|
||||
/* dongle configuration */
|
||||
struct brcmf_cfg80211_conf {
|
||||
u32 mode; /* adhoc , infrastructure or ap */
|
||||
u32 frag_threshold;
|
||||
u32 rts_threshold;
|
||||
u32 retry_short;
|
||||
u32 retry_long;
|
||||
s32 tx_power;
|
||||
struct ieee80211_channel channel;
|
||||
};
|
||||
|
||||
/* cfg80211 main event loop */
|
||||
struct brcmf_cfg80211_event_loop {
|
||||
s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_priv *cfg_priv,
|
||||
struct net_device *ndev,
|
||||
const struct brcmf_event_msg *e,
|
||||
void *data);
|
||||
};
|
||||
|
||||
/* representing interface of cfg80211 plane */
|
||||
struct brcmf_cfg80211_iface {
|
||||
struct brcmf_cfg80211_priv *cfg_priv;
|
||||
};
|
||||
|
||||
struct brcmf_cfg80211_dev {
|
||||
void *driver_data; /* to store cfg80211 object information */
|
||||
};
|
||||
|
||||
/* basic structure of scan request */
|
||||
struct brcmf_cfg80211_scan_req {
|
||||
struct brcmf_ssid_le ssid_le;
|
||||
};
|
||||
|
||||
/* basic structure of information element */
|
||||
struct brcmf_cfg80211_ie {
|
||||
u16 offset;
|
||||
u8 buf[WL_TLV_INFO_MAX];
|
||||
};
|
||||
|
||||
/* event queue for cfg80211 main event */
|
||||
struct brcmf_cfg80211_event_q {
|
||||
struct list_head evt_q_list;
|
||||
u32 etype;
|
||||
struct brcmf_event_msg emsg;
|
||||
s8 edata[1];
|
||||
};
|
||||
|
||||
/* security information with currently associated ap */
|
||||
struct brcmf_cfg80211_security {
|
||||
u32 wpa_versions;
|
||||
u32 auth_type;
|
||||
u32 cipher_pairwise;
|
||||
u32 cipher_group;
|
||||
u32 wpa_auth;
|
||||
};
|
||||
|
||||
/* ibss information for currently joined ibss network */
|
||||
struct brcmf_cfg80211_ibss {
|
||||
u8 beacon_interval; /* in millisecond */
|
||||
u8 atim; /* in millisecond */
|
||||
s8 join_only;
|
||||
u8 band;
|
||||
u8 channel;
|
||||
};
|
||||
|
||||
/* dongle profile */
|
||||
struct brcmf_cfg80211_profile {
|
||||
u32 mode;
|
||||
struct brcmf_ssid ssid;
|
||||
u8 bssid[ETH_ALEN];
|
||||
u16 beacon_interval;
|
||||
u8 dtim_period;
|
||||
struct brcmf_cfg80211_security sec;
|
||||
struct brcmf_cfg80211_ibss ibss;
|
||||
s32 band;
|
||||
};
|
||||
|
||||
/* dongle iscan event loop */
|
||||
struct brcmf_cfg80211_iscan_eloop {
|
||||
s32 (*handler[WL_SCAN_ERSULTS_LAST])
|
||||
(struct brcmf_cfg80211_priv *cfg_priv);
|
||||
};
|
||||
|
||||
/* dongle iscan controller */
|
||||
struct brcmf_cfg80211_iscan_ctrl {
|
||||
struct net_device *ndev;
|
||||
struct timer_list timer;
|
||||
u32 timer_ms;
|
||||
u32 timer_on;
|
||||
s32 state;
|
||||
struct work_struct work;
|
||||
struct brcmf_cfg80211_iscan_eloop el;
|
||||
void *data;
|
||||
s8 dcmd_buf[BRCMF_DCMD_SMLEN];
|
||||
s8 scan_buf[WL_ISCAN_BUF_MAX];
|
||||
};
|
||||
|
||||
/* association inform */
|
||||
struct brcmf_cfg80211_connect_info {
|
||||
u8 *req_ie;
|
||||
s32 req_ie_len;
|
||||
u8 *resp_ie;
|
||||
s32 resp_ie_len;
|
||||
};
|
||||
|
||||
/* assoc ie length */
|
||||
struct brcmf_cfg80211_assoc_ielen_le {
|
||||
__le32 req_len;
|
||||
__le32 resp_len;
|
||||
};
|
||||
|
||||
/* wpa2 pmk list */
|
||||
struct brcmf_cfg80211_pmk_list {
|
||||
struct pmkid_list pmkids;
|
||||
struct pmkid foo[MAXPMKID - 1];
|
||||
};
|
||||
|
||||
/* dongle private data of cfg80211 interface */
|
||||
struct brcmf_cfg80211_priv {
|
||||
struct wireless_dev *wdev; /* representing wl cfg80211 device */
|
||||
struct brcmf_cfg80211_conf *conf; /* dongle configuration */
|
||||
struct cfg80211_scan_request *scan_request; /* scan request
|
||||
object */
|
||||
struct brcmf_cfg80211_event_loop el; /* main event loop */
|
||||
struct list_head evt_q_list; /* used for event queue */
|
||||
spinlock_t evt_q_lock; /* for event queue synchronization */
|
||||
struct mutex usr_sync; /* maily for dongle up/down synchronization */
|
||||
struct brcmf_scan_results *bss_list; /* bss_list holding scanned
|
||||
ap information */
|
||||
struct brcmf_scan_results *scan_results;
|
||||
struct brcmf_cfg80211_scan_req *scan_req_int; /* scan request object
|
||||
for internal purpose */
|
||||
struct wl_cfg80211_bss_info *bss_info; /* bss information for
|
||||
cfg80211 layer */
|
||||
struct brcmf_cfg80211_ie ie; /* information element object for
|
||||
internal purpose */
|
||||
struct brcmf_cfg80211_profile *profile; /* holding dongle profile */
|
||||
struct brcmf_cfg80211_iscan_ctrl *iscan; /* iscan controller */
|
||||
struct brcmf_cfg80211_connect_info conn_info; /* association info */
|
||||
struct brcmf_cfg80211_pmk_list *pmk_list; /* wpa2 pmk list */
|
||||
struct work_struct event_work; /* event handler work struct */
|
||||
unsigned long status; /* current dongle status */
|
||||
void *pub;
|
||||
u32 channel; /* current channel */
|
||||
bool iscan_on; /* iscan on/off switch */
|
||||
bool iscan_kickstart; /* indicate iscan already started */
|
||||
bool active_scan; /* current scan mode */
|
||||
bool ibss_starter; /* indicates this sta is ibss starter */
|
||||
bool link_up; /* link/connection up flag */
|
||||
bool pwr_save; /* indicate whether dongle to support
|
||||
power save mode */
|
||||
bool dongle_up; /* indicate whether dongle up or not */
|
||||
bool roam_on; /* on/off switch for dongle self-roaming */
|
||||
bool scan_tried; /* indicates if first scan attempted */
|
||||
u8 *dcmd_buf; /* dcmd buffer */
|
||||
u8 *extra_buf; /* maily to grab assoc information */
|
||||
struct dentry *debugfsdir;
|
||||
u8 ci[0] __aligned(NETDEV_ALIGN);
|
||||
};
|
||||
|
||||
static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_priv *w)
|
||||
{
|
||||
return w->wdev->wiphy;
|
||||
}
|
||||
|
||||
static inline struct brcmf_cfg80211_priv *wiphy_to_cfg(struct wiphy *w)
|
||||
{
|
||||
return (struct brcmf_cfg80211_priv *)(wiphy_priv(w));
|
||||
}
|
||||
|
||||
static inline struct brcmf_cfg80211_priv *wdev_to_cfg(struct wireless_dev *wd)
|
||||
{
|
||||
return (struct brcmf_cfg80211_priv *)(wdev_priv(wd));
|
||||
}
|
||||
|
||||
static inline struct net_device *cfg_to_ndev(struct brcmf_cfg80211_priv *cfg)
|
||||
{
|
||||
return cfg->wdev->netdev;
|
||||
}
|
||||
|
||||
static inline struct brcmf_cfg80211_priv *ndev_to_cfg(struct net_device *ndev)
|
||||
{
|
||||
return wdev_to_cfg(ndev->ieee80211_ptr);
|
||||
}
|
||||
|
||||
#define iscan_to_cfg(i) ((struct brcmf_cfg80211_priv *)(i->data))
|
||||
#define cfg_to_iscan(w) (w->iscan)
|
||||
|
||||
static inline struct
|
||||
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);
|
||||
extern void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg);
|
||||
|
||||
/* event handler from dongle */
|
||||
extern void brcmf_cfg80211_event(struct net_device *ndev,
|
||||
const struct brcmf_event_msg *e, void *data);
|
||||
extern s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev);
|
||||
extern s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev);
|
||||
|
||||
#endif /* _wl_cfg80211_h_ */
|
51
drivers/net/wireless/brcm80211/brcmsmac/Makefile
Normal file
51
drivers/net/wireless/brcm80211/brcmsmac/Makefile
Normal file
@ -0,0 +1,51 @@
|
||||
#
|
||||
# Makefile fragment for Broadcom 802.11n Networking Device Driver
|
||||
#
|
||||
# Copyright (c) 2010 Broadcom Corporation
|
||||
#
|
||||
# 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.
|
||||
|
||||
ccflags-y := \
|
||||
-D__CHECK_ENDIAN__ \
|
||||
-Idrivers/net/wireless/brcm80211/brcmsmac \
|
||||
-Idrivers/net/wireless/brcm80211/brcmsmac/phy \
|
||||
-Idrivers/net/wireless/brcm80211/include
|
||||
|
||||
BRCMSMAC_OFILES := \
|
||||
mac80211_if.o \
|
||||
ucode_loader.o \
|
||||
ampdu.o \
|
||||
antsel.o \
|
||||
channel.o \
|
||||
main.o \
|
||||
phy_shim.o \
|
||||
pmu.o \
|
||||
rate.o \
|
||||
stf.o \
|
||||
aiutils.o \
|
||||
phy/phy_cmn.o \
|
||||
phy/phy_lcn.o \
|
||||
phy/phy_n.o \
|
||||
phy/phytbl_lcn.o \
|
||||
phy/phytbl_n.o \
|
||||
phy/phy_qmath.o \
|
||||
otp.o \
|
||||
srom.o \
|
||||
dma.o \
|
||||
nicpci.o \
|
||||
brcms_trace_events.o
|
||||
|
||||
MODULEPFX := brcmsmac
|
||||
|
||||
obj-$(CONFIG_BRCMSMAC) += $(MODULEPFX).o
|
||||
$(MODULEPFX)-objs = $(BRCMSMAC_OFILES)
|
2079
drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
Normal file
2079
drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
Normal file
File diff suppressed because it is too large
Load Diff
378
drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
Normal file
378
drivers/net/wireless/brcm80211/brcmsmac/aiutils.h
Normal file
@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Broadcom Corporation
|
||||
*
|
||||
* 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 _BRCM_AIUTILS_H_
|
||||
#define _BRCM_AIUTILS_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/*
|
||||
* SOC Interconnect Address Map.
|
||||
* All regions may not exist on all chips.
|
||||
*/
|
||||
/* each core gets 4Kbytes for registers */
|
||||
#define SI_CORE_SIZE 0x1000
|
||||
/*
|
||||
* Max cores (this is arbitrary, for software
|
||||
* convenience and could be changed if we
|
||||
* make any larger chips
|
||||
*/
|
||||
#define SI_MAXCORES 16
|
||||
|
||||
/* Client Mode sb2pcitranslation2 size in bytes */
|
||||
#define SI_PCI_DMA_SZ 0x40000000
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
#define SI_CLK_CTL_ST 0x1e0 /* clock control and status */
|
||||
|
||||
/* clk_ctl_st register */
|
||||
#define CCS_FORCEALP 0x00000001 /* force ALP request */
|
||||
#define CCS_FORCEHT 0x00000002 /* force HT request */
|
||||
#define CCS_FORCEILP 0x00000004 /* force ILP request */
|
||||
#define CCS_ALPAREQ 0x00000008 /* ALP Avail Request */
|
||||
#define CCS_HTAREQ 0x00000010 /* HT Avail Request */
|
||||
#define CCS_FORCEHWREQOFF 0x00000020 /* Force HW Clock Request Off */
|
||||
#define CCS_ERSRC_REQ_MASK 0x00000700 /* external resource requests */
|
||||
#define CCS_ERSRC_REQ_SHIFT 8
|
||||
#define CCS_ALPAVAIL 0x00010000 /* ALP is available */
|
||||
#define CCS_HTAVAIL 0x00020000 /* HT is available */
|
||||
#define CCS_BP_ON_APL 0x00040000 /* RO: running on ALP clock */
|
||||
#define CCS_BP_ON_HT 0x00080000 /* RO: running on HT clock */
|
||||
#define CCS_ERSRC_STS_MASK 0x07000000 /* external resource status */
|
||||
#define CCS_ERSRC_STS_SHIFT 24
|
||||
|
||||
/* HT avail in chipc and pcmcia on 4328a0 */
|
||||
#define CCS0_HTAVAIL 0x00010000
|
||||
/* ALP avail in chipc and pcmcia on 4328a0 */
|
||||
#define CCS0_ALPAVAIL 0x00020000
|
||||
|
||||
/* Not really related to SOC Interconnect, but a couple of software
|
||||
* conventions for the use the flash space:
|
||||
*/
|
||||
|
||||
/* Minumum amount of flash we support */
|
||||
#define FLASH_MIN 0x00020000 /* Minimum flash size */
|
||||
|
||||
#define CC_SROM_OTP 0x800 /* SROM/OTP address space */
|
||||
|
||||
/* gpiotimerval */
|
||||
#define GPIO_ONTIME_SHIFT 16
|
||||
|
||||
/* Fields in clkdiv */
|
||||
#define CLKD_OTP 0x000f0000
|
||||
#define CLKD_OTP_SHIFT 16
|
||||
|
||||
/* Package IDs */
|
||||
#define BCM4717_PKG_ID 9 /* 4717 package id */
|
||||
#define BCM4718_PKG_ID 10 /* 4718 package id */
|
||||
#define BCM43224_FAB_SMIC 0xa /* the chip is manufactured by SMIC */
|
||||
|
||||
/* these are router chips */
|
||||
#define BCM4716_CHIP_ID 0x4716 /* 4716 chipcommon chipid */
|
||||
#define BCM47162_CHIP_ID 47162 /* 47162 chipcommon chipid */
|
||||
#define BCM4748_CHIP_ID 0x4748 /* 4716 chipcommon chipid (OTP, RBBU) */
|
||||
|
||||
/* dynamic clock control defines */
|
||||
#define LPOMINFREQ 25000 /* low power oscillator min */
|
||||
#define LPOMAXFREQ 43000 /* low power oscillator max */
|
||||
#define XTALMINFREQ 19800000 /* 20 MHz - 1% */
|
||||
#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */
|
||||
#define PCIMINFREQ 25000000 /* 25 MHz */
|
||||
#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */
|
||||
|
||||
#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */
|
||||
#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */
|
||||
|
||||
/* clkctl xtal what flags */
|
||||
#define XTAL 0x1 /* primary crystal oscillator (2050) */
|
||||
#define PLL 0x2 /* main chip pll */
|
||||
|
||||
/* clkctl clk mode */
|
||||
#define CLK_FAST 0 /* force fast (pll) clock */
|
||||
#define CLK_DYNAMIC 2 /* enable dynamic clock control */
|
||||
|
||||
/* GPIO usage priorities */
|
||||
#define GPIO_DRV_PRIORITY 0 /* Driver */
|
||||
#define GPIO_APP_PRIORITY 1 /* Application */
|
||||
#define GPIO_HI_PRIORITY 2 /* Highest priority. Ignore GPIO
|
||||
* reservation
|
||||
*/
|
||||
|
||||
/* GPIO pull up/down */
|
||||
#define GPIO_PULLUP 0
|
||||
#define GPIO_PULLDN 1
|
||||
|
||||
/* GPIO event regtype */
|
||||
#define GPIO_REGEVT 0 /* GPIO register event */
|
||||
#define GPIO_REGEVT_INTMSK 1 /* GPIO register event int mask */
|
||||
#define GPIO_REGEVT_INTPOL 2 /* GPIO register event int polarity */
|
||||
|
||||
/* device path */
|
||||
#define SI_DEVPATH_BUFSZ 16 /* min buffer size in bytes */
|
||||
|
||||
/* SI routine enumeration: to be used by update function with multiple hooks */
|
||||
#define SI_DOATTACH 1
|
||||
#define SI_PCIDOWN 2
|
||||
#define SI_PCIUP 3
|
||||
|
||||
/*
|
||||
* Data structure to export all chip specific common variables
|
||||
* public (read-only) portion of aiutils handle returned by si_attach()
|
||||
*/
|
||||
struct si_pub {
|
||||
uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */
|
||||
uint buscorerev; /* buscore rev */
|
||||
uint buscoreidx; /* buscore index */
|
||||
int ccrev; /* chip common core rev */
|
||||
u32 cccaps; /* chip common capabilities */
|
||||
u32 cccaps_ext; /* chip common capabilities extension */
|
||||
int pmurev; /* pmu core rev */
|
||||
u32 pmucaps; /* pmu capabilities */
|
||||
uint boardtype; /* board type */
|
||||
uint boardvendor; /* board vendor */
|
||||
uint boardflags; /* board flags */
|
||||
uint boardflags2; /* board flags2 */
|
||||
uint chip; /* chip number */
|
||||
uint chiprev; /* chip revision */
|
||||
uint chippkg; /* chip package option */
|
||||
u32 chipst; /* chip status */
|
||||
bool issim; /* chip is in simulation or emulation */
|
||||
uint socirev; /* SOC interconnect rev */
|
||||
bool pci_pr32414;
|
||||
|
||||
};
|
||||
|
||||
struct pci_dev;
|
||||
|
||||
struct gpioh_item {
|
||||
void *arg;
|
||||
bool level;
|
||||
void (*handler) (u32 stat, void *arg);
|
||||
u32 event;
|
||||
struct gpioh_item *next;
|
||||
};
|
||||
|
||||
/* misc si info needed by some of the routines */
|
||||
struct si_info {
|
||||
struct si_pub pub; /* back plane public state (must be first) */
|
||||
struct pci_dev *pbus; /* handle to pci bus */
|
||||
uint dev_coreid; /* the core provides driver functions */
|
||||
void *intr_arg; /* interrupt callback function arg */
|
||||
u32 (*intrsoff_fn) (void *intr_arg); /* turns chip interrupts off */
|
||||
/* restore chip interrupts */
|
||||
void (*intrsrestore_fn) (void *intr_arg, u32 arg);
|
||||
/* check if interrupts are enabled */
|
||||
bool (*intrsenabled_fn) (void *intr_arg);
|
||||
|
||||
struct pcicore_info *pch; /* PCI/E core handle */
|
||||
|
||||
struct list_head var_list; /* list of srom variables */
|
||||
|
||||
void __iomem *curmap; /* current regs va */
|
||||
void __iomem *regs[SI_MAXCORES]; /* other regs va */
|
||||
|
||||
uint curidx; /* current core index */
|
||||
uint numcores; /* # discovered cores */
|
||||
uint coreid[SI_MAXCORES]; /* id of each core */
|
||||
u32 coresba[SI_MAXCORES]; /* backplane address of each core */
|
||||
void *regs2[SI_MAXCORES]; /* 2nd virtual address per core (usbh20) */
|
||||
u32 coresba2[SI_MAXCORES]; /* 2nd phys address per core (usbh20) */
|
||||
u32 coresba_size[SI_MAXCORES]; /* backplane address space size */
|
||||
u32 coresba2_size[SI_MAXCORES]; /* second address space size */
|
||||
|
||||
void *curwrap; /* current wrapper va */
|
||||
void *wrappers[SI_MAXCORES]; /* other cores wrapper va */
|
||||
u32 wrapba[SI_MAXCORES]; /* address of controlling wrapper */
|
||||
|
||||
u32 cia[SI_MAXCORES]; /* erom cia entry for each core */
|
||||
u32 cib[SI_MAXCORES]; /* erom cia entry for each core */
|
||||
u32 oob_router; /* oob router registers for axi */
|
||||
};
|
||||
|
||||
/*
|
||||
* Many of the routines below take an 'sih' handle as their first arg.
|
||||
* Allocate this by calling si_attach(). Free it by calling si_detach().
|
||||
* At any one time, the sih is logically focused on one particular si core
|
||||
* (the "current core").
|
||||
* Use si_setcore() or si_setcoreidx() to change the association to another core
|
||||
*/
|
||||
|
||||
|
||||
/* AMBA Interconnect exported externs */
|
||||
extern uint ai_flag(struct si_pub *sih);
|
||||
extern void ai_setint(struct si_pub *sih, int siflag);
|
||||
extern uint ai_coreidx(struct si_pub *sih);
|
||||
extern uint ai_corevendor(struct si_pub *sih);
|
||||
extern uint ai_corerev(struct si_pub *sih);
|
||||
extern bool ai_iscoreup(struct si_pub *sih);
|
||||
extern u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern void ai_core_cflags_wo(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask,
|
||||
uint val);
|
||||
extern void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits);
|
||||
extern void ai_core_disable(struct si_pub *sih, u32 bits);
|
||||
extern int ai_numaddrspaces(struct si_pub *sih);
|
||||
extern u32 ai_addrspace(struct si_pub *sih, uint asidx);
|
||||
extern u32 ai_addrspacesize(struct si_pub *sih, uint asidx);
|
||||
extern void ai_write_wrap_reg(struct si_pub *sih, u32 offset, u32 val);
|
||||
|
||||
/* === exported functions === */
|
||||
extern struct si_pub *ai_attach(void __iomem *regs, struct pci_dev *sdh);
|
||||
extern void ai_detach(struct si_pub *sih);
|
||||
extern uint ai_coreid(struct si_pub *sih);
|
||||
extern uint ai_corerev(struct si_pub *sih);
|
||||
extern uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask,
|
||||
uint val);
|
||||
extern void ai_write_wrapperreg(struct si_pub *sih, u32 offset, u32 val);
|
||||
extern u32 ai_core_cflags(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val);
|
||||
extern bool ai_iscoreup(struct si_pub *sih);
|
||||
extern uint ai_findcoreidx(struct si_pub *sih, uint coreid, uint coreunit);
|
||||
extern void __iomem *ai_setcoreidx(struct si_pub *sih, uint coreidx);
|
||||
extern void __iomem *ai_setcore(struct si_pub *sih, uint coreid, uint coreunit);
|
||||
extern void __iomem *ai_switch_core(struct si_pub *sih, uint coreid,
|
||||
uint *origidx, uint *intr_val);
|
||||
extern void ai_restore_core(struct si_pub *sih, uint coreid, uint intr_val);
|
||||
extern void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits);
|
||||
extern void ai_core_disable(struct si_pub *sih, u32 bits);
|
||||
extern u32 ai_alp_clock(struct si_pub *sih);
|
||||
extern u32 ai_ilp_clock(struct si_pub *sih);
|
||||
extern void ai_pci_setup(struct si_pub *sih, uint coremask);
|
||||
extern void ai_setint(struct si_pub *sih, int siflag);
|
||||
extern bool ai_backplane64(struct si_pub *sih);
|
||||
extern void ai_register_intr_callback(struct si_pub *sih, void *intrsoff_fn,
|
||||
void *intrsrestore_fn,
|
||||
void *intrsenabled_fn, void *intr_arg);
|
||||
extern void ai_deregister_intr_callback(struct si_pub *sih);
|
||||
extern void ai_clkctl_init(struct si_pub *sih);
|
||||
extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih);
|
||||
extern bool ai_clkctl_cc(struct si_pub *sih, uint mode);
|
||||
extern int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on);
|
||||
extern bool ai_deviceremoved(struct si_pub *sih);
|
||||
extern u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val,
|
||||
u8 priority);
|
||||
|
||||
/* OTP status */
|
||||
extern bool ai_is_otp_disabled(struct si_pub *sih);
|
||||
|
||||
/* SPROM availability */
|
||||
extern bool ai_is_sprom_available(struct si_pub *sih);
|
||||
|
||||
/*
|
||||
* Build device path. Path size must be >= SI_DEVPATH_BUFSZ.
|
||||
* The returned path is NULL terminated and has trailing '/'.
|
||||
* Return 0 on success, nonzero otherwise.
|
||||
*/
|
||||
extern int ai_devpath(struct si_pub *sih, char *path, int size);
|
||||
|
||||
extern void ai_pci_sleep(struct si_pub *sih);
|
||||
extern void ai_pci_down(struct si_pub *sih);
|
||||
extern void ai_pci_up(struct si_pub *sih);
|
||||
extern int ai_pci_fixcfg(struct si_pub *sih);
|
||||
|
||||
extern void ai_chipcontrl_epa4331(struct si_pub *sih, bool on);
|
||||
/* Enable Ex-PA for 4313 */
|
||||
extern void ai_epa_4313war(struct si_pub *sih);
|
||||
|
||||
#endif /* _BRCM_AIUTILS_H_ */
|
1241
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
Normal file
1241
drivers/net/wireless/brcm80211/brcmsmac/ampdu.c
Normal file
File diff suppressed because it is too large
Load Diff
30
drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
Normal file
30
drivers/net/wireless/brcm80211/brcmsmac/ampdu.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 _BRCM_AMPDU_H_
|
||||
#define _BRCM_AMPDU_H_
|
||||
|
||||
extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu);
|
||||
extern int brcms_c_sendampdu(struct ampdu_info *ampdu,
|
||||
struct brcms_txq_info *qi,
|
||||
struct sk_buff **aggp, int prec);
|
||||
extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
|
||||
struct sk_buff *p, struct tx_status *txs);
|
||||
extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu);
|
||||
|
||||
#endif /* _BRCM_AMPDU_H_ */
|
307
drivers/net/wireless/brcm80211/brcmsmac/antsel.c
Normal file
307
drivers/net/wireless/brcm80211/brcmsmac/antsel.c
Normal file
@ -0,0 +1,307 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 <linux/slab.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "main.h"
|
||||
#include "phy_shim.h"
|
||||
#include "antsel.h"
|
||||
|
||||
#define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */
|
||||
#define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */
|
||||
#define ANT_SELCFG_TX_UNICAST 0 /* unicast tx antenna configuration */
|
||||
#define ANT_SELCFG_RX_UNICAST 1 /* unicast rx antenna configuration */
|
||||
#define ANT_SELCFG_TX_DEF 2 /* default tx antenna configuration */
|
||||
#define ANT_SELCFG_RX_DEF 3 /* default rx antenna configuration */
|
||||
|
||||
/* useful macros */
|
||||
#define BRCMS_ANTSEL_11N_0(ant) ((((ant) & ANT_SELCFG_MASK) >> 4) & 0xf)
|
||||
#define BRCMS_ANTSEL_11N_1(ant) (((ant) & ANT_SELCFG_MASK) & 0xf)
|
||||
#define BRCMS_ANTIDX_11N(ant) (((BRCMS_ANTSEL_11N_0(ant)) << 2) +\
|
||||
(BRCMS_ANTSEL_11N_1(ant)))
|
||||
#define BRCMS_ANT_ISAUTO_11N(ant) (((ant) & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO)
|
||||
#define BRCMS_ANTSEL_11N(ant) ((ant) & ANT_SELCFG_MASK)
|
||||
|
||||
/* antenna switch */
|
||||
/* defines for no boardlevel antenna diversity */
|
||||
#define ANT_SELCFG_DEF_2x2 0x01 /* default antenna configuration */
|
||||
|
||||
/* 2x3 antdiv defines and tables for GPIO communication */
|
||||
#define ANT_SELCFG_NUM_2x3 3
|
||||
#define ANT_SELCFG_DEF_2x3 0x01 /* default antenna configuration */
|
||||
|
||||
/* 2x4 antdiv rev4 defines and tables for GPIO communication */
|
||||
#define ANT_SELCFG_NUM_2x4 4
|
||||
#define ANT_SELCFG_DEF_2x4 0x02 /* default antenna configuration */
|
||||
|
||||
static const u16 mimo_2x4_div_antselpat_tbl[] = {
|
||||
0, 0, 0x9, 0xa, /* ant0: 0 ant1: 2,3 */
|
||||
0, 0, 0x5, 0x6, /* ant0: 1 ant1: 2,3 */
|
||||
0, 0, 0, 0, /* n.a. */
|
||||
0, 0, 0, 0 /* n.a. */
|
||||
};
|
||||
|
||||
static const u8 mimo_2x4_div_antselid_tbl[16] = {
|
||||
0, 0, 0, 0, 0, 2, 3, 0,
|
||||
0, 0, 1, 0, 0, 0, 0, 0 /* pat to antselid */
|
||||
};
|
||||
|
||||
static const u16 mimo_2x3_div_antselpat_tbl[] = {
|
||||
16, 0, 1, 16, /* ant0: 0 ant1: 1,2 */
|
||||
16, 16, 16, 16, /* n.a. */
|
||||
16, 2, 16, 16, /* ant0: 2 ant1: 1 */
|
||||
16, 16, 16, 16 /* n.a. */
|
||||
};
|
||||
|
||||
static const u8 mimo_2x3_div_antselid_tbl[16] = {
|
||||
0, 1, 2, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */
|
||||
};
|
||||
|
||||
/* boardlevel antenna selection: init antenna selection structure */
|
||||
static void
|
||||
brcms_c_antsel_init_cfg(struct antsel_info *asi, struct brcms_antselcfg *antsel,
|
||||
bool auto_sel)
|
||||
{
|
||||
if (asi->antsel_type == ANTSEL_2x3) {
|
||||
u8 antcfg_def = ANT_SELCFG_DEF_2x3 |
|
||||
((asi->antsel_avail && auto_sel) ? ANT_SELCFG_AUTO : 0);
|
||||
antsel->ant_config[ANT_SELCFG_TX_DEF] = antcfg_def;
|
||||
antsel->ant_config[ANT_SELCFG_TX_UNICAST] = antcfg_def;
|
||||
antsel->ant_config[ANT_SELCFG_RX_DEF] = antcfg_def;
|
||||
antsel->ant_config[ANT_SELCFG_RX_UNICAST] = antcfg_def;
|
||||
antsel->num_antcfg = ANT_SELCFG_NUM_2x3;
|
||||
|
||||
} else if (asi->antsel_type == ANTSEL_2x4) {
|
||||
|
||||
antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x4;
|
||||
antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x4;
|
||||
antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x4;
|
||||
antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x4;
|
||||
antsel->num_antcfg = ANT_SELCFG_NUM_2x4;
|
||||
|
||||
} else { /* no antenna selection available */
|
||||
|
||||
antsel->ant_config[ANT_SELCFG_TX_DEF] = ANT_SELCFG_DEF_2x2;
|
||||
antsel->ant_config[ANT_SELCFG_TX_UNICAST] = ANT_SELCFG_DEF_2x2;
|
||||
antsel->ant_config[ANT_SELCFG_RX_DEF] = ANT_SELCFG_DEF_2x2;
|
||||
antsel->ant_config[ANT_SELCFG_RX_UNICAST] = ANT_SELCFG_DEF_2x2;
|
||||
antsel->num_antcfg = 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc)
|
||||
{
|
||||
struct antsel_info *asi;
|
||||
struct si_pub *sih = wlc->hw->sih;
|
||||
|
||||
asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC);
|
||||
if (!asi)
|
||||
return NULL;
|
||||
|
||||
asi->wlc = wlc;
|
||||
asi->pub = wlc->pub;
|
||||
asi->antsel_type = ANTSEL_NA;
|
||||
asi->antsel_avail = false;
|
||||
asi->antsel_antswitch = (u8) getintvar(sih, BRCMS_SROM_ANTSWITCH);
|
||||
|
||||
if ((asi->pub->sromrev >= 4) && (asi->antsel_antswitch != 0)) {
|
||||
switch (asi->antsel_antswitch) {
|
||||
case ANTSWITCH_TYPE_1:
|
||||
case ANTSWITCH_TYPE_2:
|
||||
case ANTSWITCH_TYPE_3:
|
||||
/* 4321/2 board with 2x3 switch logic */
|
||||
asi->antsel_type = ANTSEL_2x3;
|
||||
/* Antenna selection availability */
|
||||
if (((u16) getintvar(sih, BRCMS_SROM_AA2G) == 7) ||
|
||||
((u16) getintvar(sih, BRCMS_SROM_AA5G) == 7)) {
|
||||
asi->antsel_avail = true;
|
||||
} else if (
|
||||
(u16) getintvar(sih, BRCMS_SROM_AA2G) == 3 ||
|
||||
(u16) getintvar(sih, BRCMS_SROM_AA5G) == 3) {
|
||||
asi->antsel_avail = false;
|
||||
} else {
|
||||
asi->antsel_avail = false;
|
||||
wiphy_err(wlc->wiphy, "antsel_attach: 2o3 "
|
||||
"board cfg invalid\n");
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if ((asi->pub->sromrev == 4) &&
|
||||
((u16) getintvar(sih, BRCMS_SROM_AA2G) == 7) &&
|
||||
((u16) getintvar(sih, BRCMS_SROM_AA5G) == 0)) {
|
||||
/* hack to match old 4321CB2 cards with 2of3 antenna switch */
|
||||
asi->antsel_type = ANTSEL_2x3;
|
||||
asi->antsel_avail = true;
|
||||
} else if (asi->pub->boardflags2 & BFL2_2X4_DIV) {
|
||||
asi->antsel_type = ANTSEL_2x4;
|
||||
asi->antsel_avail = true;
|
||||
}
|
||||
|
||||
/* Set the antenna selection type for the low driver */
|
||||
brcms_b_antsel_type_set(wlc->hw, asi->antsel_type);
|
||||
|
||||
/* Init (auto/manual) antenna selection */
|
||||
brcms_c_antsel_init_cfg(asi, &asi->antcfg_11n, true);
|
||||
brcms_c_antsel_init_cfg(asi, &asi->antcfg_cur, true);
|
||||
|
||||
return asi;
|
||||
}
|
||||
|
||||
void brcms_c_antsel_detach(struct antsel_info *asi)
|
||||
{
|
||||
kfree(asi);
|
||||
}
|
||||
|
||||
/*
|
||||
* boardlevel antenna selection:
|
||||
* convert ant_cfg to mimo_antsel (ucode interface)
|
||||
*/
|
||||
static u16 brcms_c_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg)
|
||||
{
|
||||
u8 idx = BRCMS_ANTIDX_11N(BRCMS_ANTSEL_11N(ant_cfg));
|
||||
u16 mimo_antsel = 0;
|
||||
|
||||
if (asi->antsel_type == ANTSEL_2x4) {
|
||||
/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
|
||||
mimo_antsel = (mimo_2x4_div_antselpat_tbl[idx] & 0xf);
|
||||
return mimo_antsel;
|
||||
|
||||
} else if (asi->antsel_type == ANTSEL_2x3) {
|
||||
/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
|
||||
mimo_antsel = (mimo_2x3_div_antselpat_tbl[idx] & 0xf);
|
||||
return mimo_antsel;
|
||||
}
|
||||
|
||||
return mimo_antsel;
|
||||
}
|
||||
|
||||
/* boardlevel antenna selection: ucode interface control */
|
||||
static int brcms_c_antsel_cfgupd(struct antsel_info *asi,
|
||||
struct brcms_antselcfg *antsel)
|
||||
{
|
||||
struct brcms_c_info *wlc = asi->wlc;
|
||||
u8 ant_cfg;
|
||||
u16 mimo_antsel;
|
||||
|
||||
/* 1) Update TX antconfig for all frames that are not unicast data
|
||||
* (aka default TX)
|
||||
*/
|
||||
ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF];
|
||||
mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
|
||||
brcms_b_write_shm(wlc->hw, M_MIMO_ANTSEL_TXDFLT, mimo_antsel);
|
||||
/*
|
||||
* Update driver stats for currently selected
|
||||
* default tx/rx antenna config
|
||||
*/
|
||||
asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg;
|
||||
|
||||
/* 2) Update RX antconfig for all frames that are not unicast data
|
||||
* (aka default RX)
|
||||
*/
|
||||
ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF];
|
||||
mimo_antsel = brcms_c_antsel_antcfg2antsel(asi, ant_cfg);
|
||||
brcms_b_write_shm(wlc->hw, M_MIMO_ANTSEL_RXDFLT, mimo_antsel);
|
||||
/*
|
||||
* Update driver stats for currently selected
|
||||
* default tx/rx antenna config
|
||||
*/
|
||||
asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void brcms_c_antsel_init(struct antsel_info *asi)
|
||||
{
|
||||
if ((asi->antsel_type == ANTSEL_2x3) ||
|
||||
(asi->antsel_type == ANTSEL_2x4))
|
||||
brcms_c_antsel_cfgupd(asi, &asi->antcfg_11n);
|
||||
}
|
||||
|
||||
/* boardlevel antenna selection: convert id to ant_cfg */
|
||||
static u8 brcms_c_antsel_id2antcfg(struct antsel_info *asi, u8 id)
|
||||
{
|
||||
u8 antcfg = ANT_SELCFG_DEF_2x2;
|
||||
|
||||
if (asi->antsel_type == ANTSEL_2x4) {
|
||||
/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
|
||||
antcfg = (((id & 0x2) << 3) | ((id & 0x1) + 2));
|
||||
return antcfg;
|
||||
|
||||
} else if (asi->antsel_type == ANTSEL_2x3) {
|
||||
/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
|
||||
antcfg = (((id & 0x02) << 4) | ((id & 0x1) + 1));
|
||||
return antcfg;
|
||||
}
|
||||
|
||||
return antcfg;
|
||||
}
|
||||
|
||||
void
|
||||
brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel,
|
||||
u8 antselid, u8 fbantselid, u8 *antcfg,
|
||||
u8 *fbantcfg)
|
||||
{
|
||||
u8 ant;
|
||||
|
||||
/* if use default, assign it and return */
|
||||
if (usedef) {
|
||||
*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_DEF];
|
||||
*fbantcfg = *antcfg;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sel) {
|
||||
*antcfg = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
|
||||
*fbantcfg = *antcfg;
|
||||
|
||||
} else {
|
||||
ant = asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
|
||||
if ((ant & ANT_SELCFG_AUTO) == ANT_SELCFG_AUTO) {
|
||||
*antcfg = brcms_c_antsel_id2antcfg(asi, antselid);
|
||||
*fbantcfg = brcms_c_antsel_id2antcfg(asi, fbantselid);
|
||||
} else {
|
||||
*antcfg =
|
||||
asi->antcfg_11n.ant_config[ANT_SELCFG_TX_UNICAST];
|
||||
*fbantcfg = *antcfg;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */
|
||||
u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel)
|
||||
{
|
||||
u8 antselid = 0;
|
||||
|
||||
if (asi->antsel_type == ANTSEL_2x4) {
|
||||
/* 2x4 antenna diversity board, 4 cfgs: 0-2 0-3 1-2 1-3 */
|
||||
antselid = mimo_2x4_div_antselid_tbl[(antsel & 0xf)];
|
||||
return antselid;
|
||||
|
||||
} else if (asi->antsel_type == ANTSEL_2x3) {
|
||||
/* 2x3 antenna selection, 3 cfgs: 0-1 0-2 2-1 */
|
||||
antselid = mimo_2x3_div_antselid_tbl[(antsel & 0xf)];
|
||||
return antselid;
|
||||
}
|
||||
|
||||
return antselid;
|
||||
}
|
29
drivers/net/wireless/brcm80211/brcmsmac/antsel.h
Normal file
29
drivers/net/wireless/brcm80211/brcmsmac/antsel.h
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 _BRCM_ANTSEL_H_
|
||||
#define _BRCM_ANTSEL_H_
|
||||
|
||||
extern struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_antsel_detach(struct antsel_info *asi);
|
||||
extern void brcms_c_antsel_init(struct antsel_info *asi);
|
||||
extern void brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef,
|
||||
bool sel,
|
||||
u8 id, u8 fbid, u8 *antcfg,
|
||||
u8 *fbantcfg);
|
||||
extern u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel);
|
||||
|
||||
#endif /* _BRCM_ANTSEL_H_ */
|
23
drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c
Normal file
23
drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.c
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Broadcom Corporation
|
||||
*
|
||||
* 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 <linux/module.h> /* bug in tracepoint.h, it should include this */
|
||||
|
||||
#ifndef __CHECKER__
|
||||
#include "mac80211_if.h"
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include "brcms_trace_events.h"
|
||||
#endif
|
92
drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
Normal file
92
drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#undef TRACE_SYSTEM
|
||||
#define TRACE_SYSTEM brcmsmac
|
||||
|
||||
#if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||
|
||||
#define __TRACE_BRCMSMAC_H
|
||||
|
||||
#include <linux/tracepoint.h>
|
||||
#include "mac80211_if.h"
|
||||
|
||||
#ifndef CONFIG_BRCMDBG
|
||||
#undef TRACE_EVENT
|
||||
#define TRACE_EVENT(name, proto, ...) \
|
||||
static inline void trace_ ## name(proto) {}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We define a tracepoint, its arguments, its printk format and its
|
||||
* 'fast binary record' layout.
|
||||
*/
|
||||
TRACE_EVENT(brcms_timer,
|
||||
/* TPPROTO is the prototype of the function called by this tracepoint */
|
||||
TP_PROTO(struct brcms_timer *t),
|
||||
/*
|
||||
* TPARGS(firstarg, p) are the parameters names, same as found in the
|
||||
* prototype.
|
||||
*/
|
||||
TP_ARGS(t),
|
||||
/*
|
||||
* Fast binary tracing: define the trace record via TP_STRUCT__entry().
|
||||
* You can think about it like a regular C structure local variable
|
||||
* definition.
|
||||
*/
|
||||
TP_STRUCT__entry(
|
||||
__field(uint, ms)
|
||||
__field(uint, set)
|
||||
__field(uint, periodic)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->ms = t->ms;
|
||||
__entry->set = t->set;
|
||||
__entry->periodic = t->periodic;
|
||||
),
|
||||
TP_printk(
|
||||
"ms=%u set=%u periodic=%u",
|
||||
__entry->ms, __entry->set, __entry->periodic
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(brcms_dpc,
|
||||
TP_PROTO(unsigned long data),
|
||||
TP_ARGS(data),
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned long, data)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->data = data;
|
||||
),
|
||||
TP_printk(
|
||||
"data=%p",
|
||||
(void *)__entry->data
|
||||
)
|
||||
);
|
||||
|
||||
#endif /* __TRACE_BRCMSMAC_H */
|
||||
|
||||
#ifdef CONFIG_BRCMDBG
|
||||
|
||||
#undef TRACE_INCLUDE_PATH
|
||||
#define TRACE_INCLUDE_PATH .
|
||||
#undef TRACE_INCLUDE_FILE
|
||||
#define TRACE_INCLUDE_FILE brcms_trace_events
|
||||
|
||||
#include <trace/define_trace.h>
|
||||
|
||||
#endif /* CONFIG_BRCMDBG */
|
1591
drivers/net/wireless/brcm80211/brcmsmac/channel.c
Normal file
1591
drivers/net/wireless/brcm80211/brcmsmac/channel.c
Normal file
File diff suppressed because it is too large
Load Diff
53
drivers/net/wireless/brcm80211/brcmsmac/channel.h
Normal file
53
drivers/net/wireless/brcm80211/brcmsmac/channel.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 _BRCM_CHANNEL_H_
|
||||
#define _BRCM_CHANNEL_H_
|
||||
|
||||
/* conversion for phy txpwr calculations that use .25 dB units */
|
||||
#define BRCMS_TXPWR_DB_FACTOR 4
|
||||
|
||||
/* bits for locale_info flags */
|
||||
#define BRCMS_PEAK_CONDUCTED 0x00 /* Peak for locals */
|
||||
#define BRCMS_EIRP 0x01 /* Flag for EIRP */
|
||||
#define BRCMS_DFS_TPC 0x02 /* Flag for DFS TPC */
|
||||
#define BRCMS_NO_OFDM 0x04 /* Flag for No OFDM */
|
||||
#define BRCMS_NO_40MHZ 0x08 /* Flag for No MIMO 40MHz */
|
||||
#define BRCMS_NO_MIMO 0x10 /* Flag for No MIMO, 20 or 40 MHz */
|
||||
#define BRCMS_RADAR_TYPE_EU 0x20 /* Flag for EU */
|
||||
#define BRCMS_DFS_FCC BRCMS_DFS_TPC /* Flag for DFS FCC */
|
||||
|
||||
#define BRCMS_DFS_EU (BRCMS_DFS_TPC | BRCMS_RADAR_TYPE_EU) /* Flag for DFS EU */
|
||||
|
||||
extern struct brcms_cm_info *
|
||||
brcms_c_channel_mgr_attach(struct brcms_c_info *wlc);
|
||||
|
||||
extern void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm);
|
||||
|
||||
extern u8 brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm,
|
||||
uint bandunit);
|
||||
|
||||
extern bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm,
|
||||
u16 chspec);
|
||||
|
||||
extern void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm,
|
||||
u16 chanspec,
|
||||
struct txpwr_limits *txpwr);
|
||||
extern void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm,
|
||||
u16 chanspec,
|
||||
u8 local_constraint_qdbm);
|
||||
|
||||
#endif /* _WLC_CHANNEL_H */
|
1898
drivers/net/wireless/brcm80211/brcmsmac/d11.h
Normal file
1898
drivers/net/wireless/brcm80211/brcmsmac/d11.h
Normal file
File diff suppressed because it is too large
Load Diff
1425
drivers/net/wireless/brcm80211/brcmsmac/dma.c
Normal file
1425
drivers/net/wireless/brcm80211/brcmsmac/dma.c
Normal file
File diff suppressed because it is too large
Load Diff
120
drivers/net/wireless/brcm80211/brcmsmac/dma.h
Normal file
120
drivers/net/wireless/brcm80211/brcmsmac/dma.h
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 _BRCM_DMA_H_
|
||||
#define _BRCM_DMA_H_
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include "types.h" /* forward structure declarations */
|
||||
|
||||
/* map/unmap direction */
|
||||
#define DMA_TX 1 /* TX direction for DMA */
|
||||
#define DMA_RX 2 /* RX direction for DMA */
|
||||
|
||||
/* DMA structure:
|
||||
* support two DMA engines: 32 bits address or 64 bit addressing
|
||||
* basic DMA register set is per channel(transmit or receive)
|
||||
* a pair of channels is defined for convenience
|
||||
*/
|
||||
|
||||
/* 32 bits addressing */
|
||||
|
||||
struct dma32diag { /* diag access */
|
||||
u32 fifoaddr; /* diag address */
|
||||
u32 fifodatalow; /* low 32bits of data */
|
||||
u32 fifodatahigh; /* high 32bits of data */
|
||||
u32 pad; /* reserved */
|
||||
};
|
||||
|
||||
/* 64 bits addressing */
|
||||
|
||||
/* dma registers per channel(xmt or rcv) */
|
||||
struct dma64regs {
|
||||
u32 control; /* enable, et al */
|
||||
u32 ptr; /* last descriptor posted to chip */
|
||||
u32 addrlow; /* desc ring base address low 32-bits (8K aligned) */
|
||||
u32 addrhigh; /* desc ring base address bits 63:32 (8K aligned) */
|
||||
u32 status0; /* current descriptor, xmt state */
|
||||
u32 status1; /* active descriptor, xmt error */
|
||||
};
|
||||
|
||||
/* range param for dma_getnexttxp() and dma_txreclaim */
|
||||
enum txd_range {
|
||||
DMA_RANGE_ALL = 1,
|
||||
DMA_RANGE_TRANSMITTED,
|
||||
DMA_RANGE_TRANSFERED
|
||||
};
|
||||
|
||||
/*
|
||||
* Exported data structure (read-only)
|
||||
*/
|
||||
/* export structure */
|
||||
struct dma_pub {
|
||||
uint txavail; /* # free tx descriptors */
|
||||
uint dmactrlflags; /* dma control flags */
|
||||
|
||||
/* rx error counters */
|
||||
uint rxgiants; /* rx giant frames */
|
||||
uint rxnobuf; /* rx out of dma descriptors */
|
||||
/* tx error counters */
|
||||
uint txnobuf; /* tx out of dma descriptors */
|
||||
};
|
||||
|
||||
extern struct dma_pub *dma_attach(char *name, struct si_pub *sih,
|
||||
void __iomem *dmaregstx, void __iomem *dmaregsrx,
|
||||
uint ntxd, uint nrxd,
|
||||
uint rxbufsize, int rxextheadroom,
|
||||
uint nrxpost, uint rxoffset, uint *msg_level);
|
||||
|
||||
void dma_rxinit(struct dma_pub *pub);
|
||||
struct sk_buff *dma_rx(struct dma_pub *pub);
|
||||
bool dma_rxfill(struct dma_pub *pub);
|
||||
bool dma_rxreset(struct dma_pub *pub);
|
||||
bool dma_txreset(struct dma_pub *pub);
|
||||
void dma_txinit(struct dma_pub *pub);
|
||||
int dma_txfast(struct dma_pub *pub, struct sk_buff *p0, bool commit);
|
||||
void dma_txsuspend(struct dma_pub *pub);
|
||||
bool dma_txsuspended(struct dma_pub *pub);
|
||||
void dma_txresume(struct dma_pub *pub);
|
||||
void dma_txreclaim(struct dma_pub *pub, enum txd_range range);
|
||||
void dma_rxreclaim(struct dma_pub *pub);
|
||||
void dma_detach(struct dma_pub *pub);
|
||||
unsigned long dma_getvar(struct dma_pub *pub, const char *name);
|
||||
struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range);
|
||||
void dma_counterreset(struct dma_pub *pub);
|
||||
|
||||
void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
|
||||
(void *pkt, void *arg_a), void *arg_a);
|
||||
|
||||
/*
|
||||
* DMA(Bug) on bcm47xx chips seems to declare that the packet is ready, but
|
||||
* the packet length is not updated yet (by DMA) on the expected time.
|
||||
* Workaround is to hold processor till DMA updates the length, and stay off
|
||||
* the bus to allow DMA update the length in buffer
|
||||
*/
|
||||
static inline void dma_spin_for_len(uint len, struct sk_buff *head)
|
||||
{
|
||||
#if defined(CONFIG_BCM47XX)
|
||||
if (!len) {
|
||||
while (!(len = *(u16 *) KSEG1ADDR(head->data)))
|
||||
udelay(1);
|
||||
|
||||
*(u16 *) (head->data) = cpu_to_le16((u16) len);
|
||||
}
|
||||
#endif /* defined(CONFIG_BCM47XX) */
|
||||
}
|
||||
|
||||
#endif /* _BRCM_DMA_H_ */
|
1696
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
Normal file
1696
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
Normal file
File diff suppressed because it is too large
Load Diff
108
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
Normal file
108
drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 _BRCM_MAC80211_IF_H_
|
||||
#define _BRCM_MAC80211_IF_H_
|
||||
|
||||
#include <linux/timer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include "ucode_loader.h"
|
||||
/*
|
||||
* Starting index for 5G rates in the
|
||||
* legacy rate table.
|
||||
*/
|
||||
#define BRCMS_LEGACY_5G_RATE_OFFSET 4
|
||||
|
||||
/* softmac ioctl definitions */
|
||||
#define BRCMS_SET_SHORTSLOT_OVERRIDE 146
|
||||
|
||||
struct brcms_timer {
|
||||
struct delayed_work dly_wrk;
|
||||
struct brcms_info *wl;
|
||||
void (*fn) (void *); /* function called upon expiration */
|
||||
void *arg; /* fixed argument provided to called function */
|
||||
uint ms;
|
||||
bool periodic;
|
||||
bool set; /* indicates if timer is active */
|
||||
struct brcms_timer *next; /* for freeing on unload */
|
||||
#ifdef BCMDBG
|
||||
char *name; /* Description of the timer */
|
||||
#endif
|
||||
};
|
||||
|
||||
struct brcms_if {
|
||||
uint subunit; /* WDS/BSS unit */
|
||||
struct pci_dev *pci_dev;
|
||||
};
|
||||
|
||||
#define MAX_FW_IMAGES 4
|
||||
struct brcms_firmware {
|
||||
u32 fw_cnt;
|
||||
const struct firmware *fw_bin[MAX_FW_IMAGES];
|
||||
const struct firmware *fw_hdr[MAX_FW_IMAGES];
|
||||
u32 hdr_num_entries[MAX_FW_IMAGES];
|
||||
};
|
||||
|
||||
struct brcms_info {
|
||||
struct brcms_pub *pub; /* pointer to public wlc state */
|
||||
struct brcms_c_info *wlc; /* pointer to private common data */
|
||||
u32 magic;
|
||||
|
||||
int irq;
|
||||
|
||||
spinlock_t lock; /* per-device perimeter lock */
|
||||
spinlock_t isr_lock; /* per-device ISR synchronization lock */
|
||||
|
||||
/* regsva for unmap in brcms_free() */
|
||||
void __iomem *regsva; /* opaque chip registers virtual address */
|
||||
|
||||
/* timer related fields */
|
||||
atomic_t callbacks; /* # outstanding callback functions */
|
||||
struct brcms_timer *timers; /* timer cleanup queue */
|
||||
|
||||
struct tasklet_struct tasklet; /* dpc tasklet */
|
||||
bool resched; /* dpc needs to be and is rescheduled */
|
||||
struct brcms_firmware fw;
|
||||
struct wiphy *wiphy;
|
||||
struct brcms_ucode ucode;
|
||||
};
|
||||
|
||||
/* misc callbacks */
|
||||
extern void brcms_init(struct brcms_info *wl);
|
||||
extern uint brcms_reset(struct brcms_info *wl);
|
||||
extern void brcms_intrson(struct brcms_info *wl);
|
||||
extern u32 brcms_intrsoff(struct brcms_info *wl);
|
||||
extern void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask);
|
||||
extern int brcms_up(struct brcms_info *wl);
|
||||
extern void brcms_down(struct brcms_info *wl);
|
||||
extern void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
|
||||
bool state, int prio);
|
||||
extern bool brcms_rfkill_set_hw_state(struct brcms_info *wl);
|
||||
|
||||
/* timer functions */
|
||||
extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
|
||||
void (*fn) (void *arg), void *arg,
|
||||
const char *name);
|
||||
extern void brcms_free_timer(struct brcms_timer *timer);
|
||||
extern void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic);
|
||||
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);
|
||||
|
||||
#endif /* _BRCM_MAC80211_IF_H_ */
|
8775
drivers/net/wireless/brcm80211/brcmsmac/main.c
Normal file
8775
drivers/net/wireless/brcm80211/brcmsmac/main.c
Normal file
File diff suppressed because it is too large
Load Diff
735
drivers/net/wireless/brcm80211/brcmsmac/main.h
Normal file
735
drivers/net/wireless/brcm80211/brcmsmac/main.h
Normal file
@ -0,0 +1,735 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 _BRCM_MAIN_H_
|
||||
#define _BRCM_MAIN_H_
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
|
||||
#include <brcmu_utils.h>
|
||||
#include "types.h"
|
||||
#include "d11.h"
|
||||
#include "scb.h"
|
||||
|
||||
#define INVCHANNEL 255 /* invalid channel */
|
||||
|
||||
/* max # brcms_c_module_register() calls */
|
||||
#define BRCMS_MAXMODULES 22
|
||||
|
||||
#define SEQNUM_SHIFT 4
|
||||
#define SEQNUM_MAX 0x1000
|
||||
|
||||
#define NTXRATE 64 /* # tx MPDUs rate is reported for */
|
||||
|
||||
/* Maximum wait time for a MAC suspend */
|
||||
/* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */
|
||||
#define BRCMS_MAX_MAC_SUSPEND 83000
|
||||
|
||||
/* responses for probe requests older that this are tossed, zero to disable */
|
||||
#define BRCMS_PRB_RESP_TIMEOUT 0 /* Disable probe response timeout */
|
||||
|
||||
/* transmit buffer max headroom for protocol headers */
|
||||
#define TXOFF (D11_TXH_LEN + D11_PHY_HDR_LEN)
|
||||
|
||||
#define AC_COUNT 4
|
||||
|
||||
/* Macros for doing definition and get/set of bitfields
|
||||
* Usage example, e.g. a three-bit field (bits 4-6):
|
||||
* #define <NAME>_M BITFIELD_MASK(3)
|
||||
* #define <NAME>_S 4
|
||||
* ...
|
||||
* regval = R_REG(osh, ®s->regfoo);
|
||||
* field = GFIELD(regval, <NAME>);
|
||||
* regval = SFIELD(regval, <NAME>, 1);
|
||||
* W_REG(osh, ®s->regfoo, regval);
|
||||
*/
|
||||
#define BITFIELD_MASK(width) \
|
||||
(((unsigned)1 << (width)) - 1)
|
||||
#define GFIELD(val, field) \
|
||||
(((val) >> field ## _S) & field ## _M)
|
||||
#define SFIELD(val, field, bits) \
|
||||
(((val) & (~(field ## _M << field ## _S))) | \
|
||||
((unsigned)(bits) << field ## _S))
|
||||
|
||||
#define SW_TIMER_MAC_STAT_UPD 30 /* periodic MAC stats update */
|
||||
|
||||
/* max # supported core revisions (0 .. MAXCOREREV - 1) */
|
||||
#define MAXCOREREV 28
|
||||
|
||||
/* Double check that unsupported cores are not enabled */
|
||||
#if CONF_MSK(D11CONF, 0x4f) || CONF_GE(D11CONF, MAXCOREREV)
|
||||
#error "Configuration for D11CONF includes unsupported versions."
|
||||
#endif /* Bad versions */
|
||||
|
||||
/* values for shortslot_override */
|
||||
#define BRCMS_SHORTSLOT_AUTO -1 /* Driver will manage Shortslot setting */
|
||||
#define BRCMS_SHORTSLOT_OFF 0 /* Turn off short slot */
|
||||
#define BRCMS_SHORTSLOT_ON 1 /* Turn on short slot */
|
||||
|
||||
/* value for short/long and mixmode/greenfield preamble */
|
||||
#define BRCMS_LONG_PREAMBLE (0)
|
||||
#define BRCMS_SHORT_PREAMBLE (1 << 0)
|
||||
#define BRCMS_GF_PREAMBLE (1 << 1)
|
||||
#define BRCMS_MM_PREAMBLE (1 << 2)
|
||||
#define BRCMS_IS_MIMO_PREAMBLE(_pre) (((_pre) == BRCMS_GF_PREAMBLE) || \
|
||||
((_pre) == BRCMS_MM_PREAMBLE))
|
||||
|
||||
/* TxFrameID */
|
||||
/* seq and frag bits: SEQNUM_SHIFT, FRAGNUM_MASK (802.11.h) */
|
||||
/* rate epoch bits: TXFID_RATE_SHIFT, TXFID_RATE_MASK ((wlc_rate.c) */
|
||||
#define TXFID_QUEUE_MASK 0x0007 /* Bits 0-2 */
|
||||
#define TXFID_SEQ_MASK 0x7FE0 /* Bits 5-15 */
|
||||
#define TXFID_SEQ_SHIFT 5 /* Number of bit shifts */
|
||||
#define TXFID_RATE_PROBE_MASK 0x8000 /* Bit 15 for rate probe */
|
||||
#define TXFID_RATE_MASK 0x0018 /* Mask for bits 3 and 4 */
|
||||
#define TXFID_RATE_SHIFT 3 /* Shift 3 bits for rate mask */
|
||||
|
||||
/* promote boardrev */
|
||||
#define BOARDREV_PROMOTABLE 0xFF /* from */
|
||||
#define BOARDREV_PROMOTED 1 /* to */
|
||||
|
||||
#define DATA_BLOCK_TX_SUPR (1 << 4)
|
||||
|
||||
/* 802.1D Priority to TX FIFO number for wme */
|
||||
extern const u8 prio2fifo[];
|
||||
|
||||
/* Ucode MCTL_WAKE override bits */
|
||||
#define BRCMS_WAKE_OVERRIDE_CLKCTL 0x01
|
||||
#define BRCMS_WAKE_OVERRIDE_PHYREG 0x02
|
||||
#define BRCMS_WAKE_OVERRIDE_MACSUSPEND 0x04
|
||||
#define BRCMS_WAKE_OVERRIDE_TXFIFO 0x08
|
||||
#define BRCMS_WAKE_OVERRIDE_FORCEFAST 0x10
|
||||
|
||||
/* stuff pulled in from wlc.c */
|
||||
|
||||
/* Interrupt bit error summary. Don't include I_RU: we refill DMA at other
|
||||
* times; and if we run out, constant I_RU interrupts may cause lockup. We
|
||||
* will still get error counts from rx0ovfl.
|
||||
*/
|
||||
#define I_ERRORS (I_PC | I_PD | I_DE | I_RO | I_XU)
|
||||
/* default software intmasks */
|
||||
#define DEF_RXINTMASK (I_RI) /* enable rx int on rxfifo only */
|
||||
#define DEF_MACINTMASK (MI_TXSTOP | MI_TBTT | MI_ATIMWINEND | MI_PMQ | \
|
||||
MI_PHYTXERR | MI_DMAINT | MI_TFS | MI_BG_NOISE | \
|
||||
MI_CCA | MI_TO | MI_GP0 | MI_RFDISABLE | MI_PWRUP)
|
||||
|
||||
#define MAXTXPKTS 6 /* max # pkts pending */
|
||||
|
||||
/* frameburst */
|
||||
#define MAXTXFRAMEBURST 8 /* vanilla xpress mode: max frames/burst */
|
||||
#define MAXFRAMEBURST_TXOP 10000 /* Frameburst TXOP in usec */
|
||||
|
||||
#define NFIFO 6 /* # tx/rx fifopairs */
|
||||
|
||||
/* PLL requests */
|
||||
|
||||
/* pll is shared on old chips */
|
||||
#define BRCMS_PLLREQ_SHARED 0x1
|
||||
/* hold pll for radio monitor register checking */
|
||||
#define BRCMS_PLLREQ_RADIO_MON 0x2
|
||||
/* hold/release pll for some short operation */
|
||||
#define BRCMS_PLLREQ_FLIP 0x4
|
||||
|
||||
#define CHANNEL_BANDUNIT(wlc, ch) \
|
||||
(((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX)
|
||||
|
||||
#define OTHERBANDUNIT(wlc) \
|
||||
((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX))
|
||||
|
||||
/*
|
||||
* 802.11 protection information
|
||||
*
|
||||
* _g: use g spec protection, driver internal.
|
||||
* g_override: override for use of g spec protection.
|
||||
* gmode_user: user config gmode, operating band->gmode is different.
|
||||
* overlap: Overlap BSS/IBSS protection for both 11g and 11n.
|
||||
* nmode_user: user config nmode, operating pub->nmode is different.
|
||||
* n_cfg: use OFDM protection on MIMO frames.
|
||||
* n_cfg_override: override for use of N protection.
|
||||
* nongf: non-GF present protection.
|
||||
* nongf_override: override for use of GF protection.
|
||||
* n_pam_override: override for preamble: MM or GF.
|
||||
* n_obss: indicated OBSS Non-HT STA present.
|
||||
*/
|
||||
struct brcms_protection {
|
||||
bool _g;
|
||||
s8 g_override;
|
||||
u8 gmode_user;
|
||||
s8 overlap;
|
||||
s8 nmode_user;
|
||||
s8 n_cfg;
|
||||
s8 n_cfg_override;
|
||||
bool nongf;
|
||||
s8 nongf_override;
|
||||
s8 n_pam_override;
|
||||
bool n_obss;
|
||||
};
|
||||
|
||||
/*
|
||||
* anything affecting the single/dual streams/antenna operation
|
||||
*
|
||||
* hw_txchain: HW txchain bitmap cfg.
|
||||
* txchain: txchain bitmap being used.
|
||||
* txstreams: number of txchains being used.
|
||||
* hw_rxchain: HW rxchain bitmap cfg.
|
||||
* rxchain: rxchain bitmap being used.
|
||||
* rxstreams: number of rxchains being used.
|
||||
* ant_rx_ovr: rx antenna override.
|
||||
* txant: userTx antenna setting.
|
||||
* phytxant: phyTx antenna setting in txheader.
|
||||
* ss_opmode: singlestream Operational mode, 0:siso; 1:cdd.
|
||||
* ss_algosel_auto: if true, use wlc->stf->ss_algo_channel;
|
||||
* else use wlc->band->stf->ss_mode_band.
|
||||
* ss_algo_channel: ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC.
|
||||
* rxchain_restore_delay: delay time to restore default rxchain.
|
||||
* ldpc: AUTO/ON/OFF ldpc cap supported.
|
||||
* txcore[MAX_STREAMS_SUPPORTED + 1]: bitmap of selected core for each Nsts.
|
||||
* spatial_policy:
|
||||
*/
|
||||
struct brcms_stf {
|
||||
u8 hw_txchain;
|
||||
u8 txchain;
|
||||
u8 txstreams;
|
||||
u8 hw_rxchain;
|
||||
u8 rxchain;
|
||||
u8 rxstreams;
|
||||
u8 ant_rx_ovr;
|
||||
s8 txant;
|
||||
u16 phytxant;
|
||||
u8 ss_opmode;
|
||||
bool ss_algosel_auto;
|
||||
u16 ss_algo_channel;
|
||||
u8 rxchain_restore_delay;
|
||||
s8 ldpc;
|
||||
u8 txcore[MAX_STREAMS_SUPPORTED + 1];
|
||||
s8 spatial_policy;
|
||||
};
|
||||
|
||||
#define BRCMS_STF_SS_STBC_TX(wlc, scb) \
|
||||
(((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) \
|
||||
|| (((scb)->flags & SCB_STBCCAP) && \
|
||||
(wlc)->band->band_stf_stbc_tx == AUTO && \
|
||||
isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC))))
|
||||
|
||||
#define BRCMS_STBC_CAP_PHY(wlc) (BRCMS_ISNPHY(wlc->band) && \
|
||||
NREV_GE(wlc->band->phyrev, 3))
|
||||
|
||||
#define BRCMS_SGI_CAP_PHY(wlc) ((BRCMS_ISNPHY(wlc->band) && \
|
||||
NREV_GE(wlc->band->phyrev, 3)) || \
|
||||
BRCMS_ISLCNPHY(wlc->band))
|
||||
|
||||
#define BRCMS_CHAN_PHYTYPE(x) (((x) & RXS_CHAN_PHYTYPE_MASK) \
|
||||
>> RXS_CHAN_PHYTYPE_SHIFT)
|
||||
#define BRCMS_CHAN_CHANNEL(x) (((x) & RXS_CHAN_ID_MASK) \
|
||||
>> RXS_CHAN_ID_SHIFT)
|
||||
|
||||
/*
|
||||
* core state (mac)
|
||||
*/
|
||||
struct brcms_core {
|
||||
uint coreidx; /* # sb enumerated core */
|
||||
|
||||
/* fifo */
|
||||
uint *txavail[NFIFO]; /* # tx descriptors available */
|
||||
s16 txpktpend[NFIFO]; /* tx admission control */
|
||||
|
||||
struct macstat *macstat_snapshot; /* mac hw prev read values */
|
||||
};
|
||||
|
||||
/*
|
||||
* band state (phy+ana+radio)
|
||||
*/
|
||||
struct brcms_band {
|
||||
int bandtype; /* BRCM_BAND_2G, BRCM_BAND_5G */
|
||||
uint bandunit; /* bandstate[] index */
|
||||
|
||||
u16 phytype; /* phytype */
|
||||
u16 phyrev;
|
||||
u16 radioid;
|
||||
u16 radiorev;
|
||||
struct brcms_phy_pub *pi; /* pointer to phy specific information */
|
||||
bool abgphy_encore;
|
||||
|
||||
u8 gmode; /* currently active gmode */
|
||||
|
||||
struct scb *hwrs_scb; /* permanent scb for hw rateset */
|
||||
|
||||
/* band-specific copy of default_bss.rateset */
|
||||
struct brcms_c_rateset defrateset;
|
||||
|
||||
u8 band_stf_ss_mode; /* Configured STF type, 0:siso; 1:cdd */
|
||||
s8 band_stf_stbc_tx; /* STBC TX 0:off; 1:force on; -1:auto */
|
||||
/* rates supported by chip (phy-specific) */
|
||||
struct brcms_c_rateset hw_rateset;
|
||||
u8 basic_rate[BRCM_MAXRATE + 1]; /* basic rates indexed by rate */
|
||||
bool mimo_cap_40; /* 40 MHz cap enabled on this band */
|
||||
s8 antgain; /* antenna gain from srom */
|
||||
|
||||
u16 CWmin; /* minimum size of contention window, in unit of aSlotTime */
|
||||
u16 CWmax; /* maximum size of contention window, in unit of aSlotTime */
|
||||
struct ieee80211_supported_band band;
|
||||
};
|
||||
|
||||
/* module control blocks */
|
||||
struct modulecb {
|
||||
/* module name : NULL indicates empty array member */
|
||||
char name[32];
|
||||
/* handle passed when handler 'doiovar' is called */
|
||||
struct brcms_info *hdl;
|
||||
|
||||
int (*down_fn)(void *handle); /* down handler. Note: the int returned
|
||||
* by the down function is a count of the
|
||||
* number of timers that could not be
|
||||
* freed.
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
struct brcms_hw_band {
|
||||
int bandtype; /* BRCM_BAND_2G, BRCM_BAND_5G */
|
||||
uint bandunit; /* bandstate[] index */
|
||||
u16 mhfs[MHFMAX]; /* MHF array shadow */
|
||||
u8 bandhw_stf_ss_mode; /* HW configured STF type, 0:siso; 1:cdd */
|
||||
u16 CWmin;
|
||||
u16 CWmax;
|
||||
u32 core_flags;
|
||||
|
||||
u16 phytype; /* phytype */
|
||||
u16 phyrev;
|
||||
u16 radioid;
|
||||
u16 radiorev;
|
||||
struct brcms_phy_pub *pi; /* pointer to phy specific information */
|
||||
bool abgphy_encore;
|
||||
};
|
||||
|
||||
struct brcms_hardware {
|
||||
bool _piomode; /* true if pio mode */
|
||||
struct brcms_c_info *wlc;
|
||||
|
||||
/* fifo */
|
||||
struct dma_pub *di[NFIFO]; /* dma handles, per fifo */
|
||||
|
||||
uint unit; /* device instance number */
|
||||
|
||||
/* version info */
|
||||
u16 vendorid; /* PCI vendor id */
|
||||
u16 deviceid; /* PCI device id */
|
||||
uint corerev; /* core revision */
|
||||
u8 sromrev; /* version # of the srom */
|
||||
u16 boardrev; /* version # of particular board */
|
||||
u32 boardflags; /* Board specific flags from srom */
|
||||
u32 boardflags2; /* More board flags if sromrev >= 4 */
|
||||
u32 machwcap; /* MAC capabilities */
|
||||
u32 machwcap_backup; /* backup of machwcap */
|
||||
|
||||
struct si_pub *sih; /* SI handle (cookie for siutils calls) */
|
||||
struct d11regs __iomem *regs; /* pointer to device registers */
|
||||
struct phy_shim_info *physhim; /* phy shim layer handler */
|
||||
struct shared_phy *phy_sh; /* pointer to shared phy state */
|
||||
struct brcms_hw_band *band;/* pointer to active per-band state */
|
||||
/* band state per phy/radio */
|
||||
struct brcms_hw_band *bandstate[MAXBANDS];
|
||||
u16 bmac_phytxant; /* cache of high phytxant state */
|
||||
bool shortslot; /* currently using 11g ShortSlot timing */
|
||||
u16 SRL; /* 802.11 dot11ShortRetryLimit */
|
||||
u16 LRL; /* 802.11 dot11LongRetryLimit */
|
||||
u16 SFBL; /* Short Frame Rate Fallback Limit */
|
||||
u16 LFBL; /* Long Frame Rate Fallback Limit */
|
||||
|
||||
bool up; /* d11 hardware up and running */
|
||||
uint now; /* # elapsed seconds */
|
||||
uint _nbands; /* # bands supported */
|
||||
u16 chanspec; /* bmac chanspec shadow */
|
||||
|
||||
uint *txavail[NFIFO]; /* # tx descriptors available */
|
||||
const u16 *xmtfifo_sz; /* fifo size in 256B for each xmt fifo */
|
||||
|
||||
u32 pllreq; /* pll requests to keep PLL on */
|
||||
|
||||
u8 suspended_fifos; /* Which TX fifo to remain awake for */
|
||||
u32 maccontrol; /* Cached value of maccontrol */
|
||||
uint mac_suspend_depth; /* current depth of mac_suspend levels */
|
||||
u32 wake_override; /* bit flags to force MAC to WAKE mode */
|
||||
u32 mute_override; /* Prevent ucode from sending beacons */
|
||||
u8 etheraddr[ETH_ALEN]; /* currently configured ethernet address */
|
||||
bool noreset; /* true= do not reset hw, used by WLC_OUT */
|
||||
bool forcefastclk; /* true if h/w is forcing to use fast clk */
|
||||
bool clk; /* core is out of reset and has clock */
|
||||
bool sbclk; /* sb has clock */
|
||||
bool phyclk; /* phy is out of reset and has clock */
|
||||
|
||||
bool ucode_loaded; /* true after ucode downloaded */
|
||||
|
||||
|
||||
u8 hw_stf_ss_opmode; /* STF single stream operation mode */
|
||||
u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic
|
||||
* 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
|
||||
*/
|
||||
u32 antsel_avail; /*
|
||||
* put struct antsel_info here if more info is
|
||||
* needed
|
||||
*/
|
||||
};
|
||||
|
||||
/* TX Queue information
|
||||
*
|
||||
* Each flow of traffic out of the device has a TX Queue with independent
|
||||
* flow control. Several interfaces may be associated with a single TX Queue
|
||||
* if they belong to the same flow of traffic from the device. For multi-channel
|
||||
* operation there are independent TX Queues for each channel.
|
||||
*/
|
||||
struct brcms_txq_info {
|
||||
struct brcms_txq_info *next;
|
||||
struct pktq q;
|
||||
uint stopped; /* tx flow control bits */
|
||||
};
|
||||
|
||||
/*
|
||||
* Principal common driver data structure.
|
||||
*
|
||||
* pub: pointer to driver public state.
|
||||
* wl: pointer to specific private state.
|
||||
* regs: pointer to device registers.
|
||||
* hw: HW related state.
|
||||
* clkreq_override: setting for clkreq for PCIE : Auto, 0, 1.
|
||||
* fastpwrup_dly: time in us needed to bring up d11 fast clock.
|
||||
* macintstatus: bit channel between isr and dpc.
|
||||
* macintmask: sw runtime master macintmask value.
|
||||
* defmacintmask: default "on" macintmask value.
|
||||
* clk: core is out of reset and has clock.
|
||||
* core: pointer to active io core.
|
||||
* band: pointer to active per-band state.
|
||||
* corestate: per-core state (one per hw core).
|
||||
* bandstate: per-band state (one per phy/radio).
|
||||
* qvalid: DirFrmQValid and BcMcFrmQValid.
|
||||
* ampdu: ampdu module handler.
|
||||
* asi: antsel module handler.
|
||||
* cmi: channel manager module handler.
|
||||
* vendorid: PCI vendor id.
|
||||
* deviceid: PCI device id.
|
||||
* ucode_rev: microcode revision.
|
||||
* machwcap: MAC capabilities, BMAC shadow.
|
||||
* perm_etheraddr: original sprom local ethernet address.
|
||||
* bandlocked: disable auto multi-band switching.
|
||||
* 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.
|
||||
* bcnmisc_monitor: bcns promisc mode override for monitor.
|
||||
* _rifs: enable per-packet rifs.
|
||||
* bcn_li_bcn: beacon listen interval in # beacons.
|
||||
* bcn_li_dtim: beacon listen interval in # dtims.
|
||||
* WDarmed: watchdog timer is armed.
|
||||
* WDlast: last time wlc_watchdog() was called.
|
||||
* edcf_txop[AC_COUNT]: current txop for each ac.
|
||||
* wme_retries: per-AC retry limits.
|
||||
* tx_prec_map: Precedence map based on HW FIFO space.
|
||||
* fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME.
|
||||
* bsscfg: set of BSS configurations, idx 0 is default and always valid.
|
||||
* cfg: the primary bsscfg (can be AP or STA).
|
||||
* tx_queues: common TX Queue list.
|
||||
* modulecb:
|
||||
* mimoft: SIGN or 11N.
|
||||
* cck_40txbw: 11N, cck tx b/w override when in 40MHZ mode.
|
||||
* ofdm_40txbw: 11N, ofdm tx b/w override when in 40MHZ mode.
|
||||
* mimo_40txbw: 11N, mimo tx b/w override when in 40MHZ mode.
|
||||
* default_bss: configured BSS parameters.
|
||||
* mc_fid_counter: BC/MC FIFO frame ID counter.
|
||||
* country_default: saved country for leaving 802.11d auto-country mode.
|
||||
* autocountry_default: initial country for 802.11d auto-country mode.
|
||||
* prb_resp_timeout: do not send prb resp if request older
|
||||
* than this, 0 = disable.
|
||||
* home_chanspec: shared home chanspec.
|
||||
* chanspec: target operational channel.
|
||||
* usr_fragthresh: user configured fragmentation threshold.
|
||||
* fragthresh[NFIFO]: per-fifo fragmentation thresholds.
|
||||
* RTSThresh: 802.11 dot11RTSThreshold.
|
||||
* SRL: 802.11 dot11ShortRetryLimit.
|
||||
* LRL: 802.11 dot11LongRetryLimit.
|
||||
* SFBL: Short Frame Rate Fallback Limit.
|
||||
* LFBL: Long Frame Rate Fallback Limit.
|
||||
* shortslot: currently using 11g ShortSlot timing.
|
||||
* shortslot_override: 11g ShortSlot override.
|
||||
* include_legacy_erp: include Legacy ERP info elt ID 47 as well as g ID 42.
|
||||
* PLCPHdr_override: 802.11b Preamble Type override.
|
||||
* stf:
|
||||
* bcn_rspec: save bcn ratespec purpose.
|
||||
* tempsense_lasttime;
|
||||
* tx_duty_cycle_ofdm: maximum allowed duty cycle for OFDM.
|
||||
* tx_duty_cycle_cck: maximum allowed duty cycle for CCK.
|
||||
* pkt_queue: txq for transmit packets.
|
||||
* wiphy:
|
||||
* pri_scb: primary Station Control Block
|
||||
*/
|
||||
struct brcms_c_info {
|
||||
struct brcms_pub *pub;
|
||||
struct brcms_info *wl;
|
||||
struct d11regs __iomem *regs;
|
||||
struct brcms_hardware *hw;
|
||||
|
||||
/* clock */
|
||||
u16 fastpwrup_dly;
|
||||
|
||||
/* interrupt */
|
||||
u32 macintstatus;
|
||||
u32 macintmask;
|
||||
u32 defmacintmask;
|
||||
|
||||
bool clk;
|
||||
|
||||
/* multiband */
|
||||
struct brcms_core *core;
|
||||
struct brcms_band *band;
|
||||
struct brcms_core *corestate;
|
||||
struct brcms_band *bandstate[MAXBANDS];
|
||||
|
||||
/* packet queue */
|
||||
uint qvalid;
|
||||
|
||||
struct ampdu_info *ampdu;
|
||||
struct antsel_info *asi;
|
||||
struct brcms_cm_info *cmi;
|
||||
|
||||
u16 vendorid;
|
||||
u16 deviceid;
|
||||
uint ucode_rev;
|
||||
|
||||
u8 perm_etheraddr[ETH_ALEN];
|
||||
|
||||
bool bandlocked;
|
||||
bool bandinit_pending;
|
||||
|
||||
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;
|
||||
|
||||
/* promiscuous */
|
||||
bool monitor;
|
||||
bool bcnmisc_monitor;
|
||||
|
||||
/* driver feature */
|
||||
bool _rifs;
|
||||
|
||||
/* AP-STA synchronization, power save */
|
||||
u8 bcn_li_bcn;
|
||||
u8 bcn_li_dtim;
|
||||
|
||||
bool WDarmed;
|
||||
u32 WDlast;
|
||||
|
||||
/* WME */
|
||||
u16 edcf_txop[AC_COUNT];
|
||||
|
||||
u16 wme_retries[AC_COUNT];
|
||||
u16 tx_prec_map;
|
||||
u16 fifo2prec_map[NFIFO];
|
||||
|
||||
struct brcms_bss_cfg *bsscfg;
|
||||
|
||||
/* tx queue */
|
||||
struct brcms_txq_info *tx_queues;
|
||||
|
||||
struct modulecb *modulecb;
|
||||
|
||||
u8 mimoft;
|
||||
s8 cck_40txbw;
|
||||
s8 ofdm_40txbw;
|
||||
s8 mimo_40txbw;
|
||||
|
||||
struct brcms_bss_info *default_bss;
|
||||
|
||||
u16 mc_fid_counter;
|
||||
|
||||
char country_default[BRCM_CNTRY_BUF_SZ];
|
||||
char autocountry_default[BRCM_CNTRY_BUF_SZ];
|
||||
u16 prb_resp_timeout;
|
||||
|
||||
u16 home_chanspec;
|
||||
|
||||
/* PHY parameters */
|
||||
u16 chanspec;
|
||||
u16 usr_fragthresh;
|
||||
u16 fragthresh[NFIFO];
|
||||
u16 RTSThresh;
|
||||
u16 SRL;
|
||||
u16 LRL;
|
||||
u16 SFBL;
|
||||
u16 LFBL;
|
||||
|
||||
/* network config */
|
||||
bool shortslot;
|
||||
s8 shortslot_override;
|
||||
bool include_legacy_erp;
|
||||
|
||||
struct brcms_protection *protection;
|
||||
s8 PLCPHdr_override;
|
||||
|
||||
struct brcms_stf *stf;
|
||||
|
||||
u32 bcn_rspec;
|
||||
|
||||
uint tempsense_lasttime;
|
||||
|
||||
u16 tx_duty_cycle_ofdm;
|
||||
u16 tx_duty_cycle_cck;
|
||||
|
||||
struct brcms_txq_info *pkt_queue;
|
||||
struct wiphy *wiphy;
|
||||
struct scb pri_scb;
|
||||
};
|
||||
|
||||
/* antsel module specific state */
|
||||
struct antsel_info {
|
||||
struct brcms_c_info *wlc; /* pointer to main wlc structure */
|
||||
struct brcms_pub *pub; /* pointer to public fn */
|
||||
u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic
|
||||
* 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board
|
||||
*/
|
||||
u8 antsel_antswitch; /* board level antenna switch type */
|
||||
bool antsel_avail; /* Ant selection availability (SROM based) */
|
||||
struct brcms_antselcfg antcfg_11n; /* antenna configuration */
|
||||
struct brcms_antselcfg antcfg_cur; /* current antenna config (auto) */
|
||||
};
|
||||
|
||||
/*
|
||||
* BSS configuration state
|
||||
*
|
||||
* wlc: wlc to which this bsscfg belongs to.
|
||||
* up: is this configuration up operational
|
||||
* enable: is this configuration enabled
|
||||
* associated: is BSS in ASSOCIATED state
|
||||
* BSS: infraustructure or adhoc
|
||||
* SSID_len: the length of SSID
|
||||
* SSID: SSID string
|
||||
*
|
||||
*
|
||||
* BSSID: BSSID (associated)
|
||||
* cur_etheraddr: h/w address
|
||||
* flags: BSSCFG flags; see below
|
||||
*
|
||||
* current_bss: BSS parms in ASSOCIATED state
|
||||
*
|
||||
*
|
||||
* ID: 'unique' ID of this bsscfg, assigned at bsscfg allocation
|
||||
*/
|
||||
struct brcms_bss_cfg {
|
||||
struct brcms_c_info *wlc;
|
||||
bool up;
|
||||
bool enable;
|
||||
bool associated;
|
||||
bool BSS;
|
||||
u8 SSID_len;
|
||||
u8 SSID[IEEE80211_MAX_SSID_LEN];
|
||||
u8 BSSID[ETH_ALEN];
|
||||
u8 cur_etheraddr[ETH_ALEN];
|
||||
struct brcms_bss_info *current_bss;
|
||||
};
|
||||
|
||||
extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo,
|
||||
struct sk_buff *p,
|
||||
bool commit, s8 txpktpend);
|
||||
extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo,
|
||||
s8 txpktpend);
|
||||
extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb,
|
||||
struct sk_buff *sdu, uint prec);
|
||||
extern void brcms_c_print_txstatus(struct tx_status *txs);
|
||||
extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
|
||||
uint *blocks);
|
||||
|
||||
#if defined(BCMDBG)
|
||||
extern void brcms_c_print_txdesc(struct d11txh *txh);
|
||||
#else
|
||||
#define brcms_c_print_txdesc(a)
|
||||
#endif
|
||||
|
||||
extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config);
|
||||
extern void brcms_c_mac_bcn_promisc_change(struct brcms_c_info *wlc,
|
||||
bool promisc);
|
||||
extern void brcms_c_send_q(struct brcms_c_info *wlc);
|
||||
extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu,
|
||||
uint *fifo);
|
||||
extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec,
|
||||
uint mac_len);
|
||||
extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc,
|
||||
u32 rspec,
|
||||
bool use_rspec, u16 mimo_ctlchbw);
|
||||
extern u16 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only,
|
||||
u32 rts_rate,
|
||||
u32 frame_rate,
|
||||
u8 rts_preamble_type,
|
||||
u8 frame_preamble_type, uint frame_len,
|
||||
bool ba);
|
||||
extern void brcms_c_inval_dma_pkts(struct brcms_hardware *hw,
|
||||
struct ieee80211_sta *sta,
|
||||
void (*dma_callback_fn));
|
||||
extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend);
|
||||
extern int brcms_c_set_nmode(struct brcms_c_info *wlc);
|
||||
extern void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc,
|
||||
u32 bcn_rate);
|
||||
extern void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw,
|
||||
u8 antsel_type);
|
||||
extern void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw,
|
||||
u16 chanspec,
|
||||
bool mute, struct txpwr_limits *txpwr);
|
||||
extern void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset,
|
||||
u16 v);
|
||||
extern u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset);
|
||||
extern void brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask,
|
||||
u16 val, int bands);
|
||||
extern void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags);
|
||||
extern void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val);
|
||||
extern void brcms_b_phy_reset(struct brcms_hardware *wlc_hw);
|
||||
extern void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw);
|
||||
extern void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw);
|
||||
extern void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw,
|
||||
u32 override_bit);
|
||||
extern void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw,
|
||||
u32 override_bit);
|
||||
extern void brcms_b_write_template_ram(struct brcms_hardware *wlc_hw,
|
||||
int offset, int len, void *buf);
|
||||
extern u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate);
|
||||
extern void brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw,
|
||||
uint offset, const void *buf, int len,
|
||||
u32 sel);
|
||||
extern void brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset,
|
||||
void *buf, int len, u32 sel);
|
||||
extern void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode);
|
||||
extern u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw);
|
||||
extern void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk);
|
||||
extern void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk);
|
||||
extern void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on);
|
||||
extern void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant);
|
||||
extern void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw,
|
||||
u8 stf_mode);
|
||||
extern void brcms_c_init_scb(struct scb *scb);
|
||||
|
||||
#endif /* _BRCM_MAIN_H_ */
|
835
drivers/net/wireless/brcm80211/brcmsmac/nicpci.c
Normal file
835
drivers/net/wireless/brcm80211/brcmsmac/nicpci.c
Normal file
@ -0,0 +1,835 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <defs.h>
|
||||
#include <soc.h>
|
||||
#include <chipcommon.h>
|
||||
#include "aiutils.h"
|
||||
#include "pub.h"
|
||||
#include "nicpci.h"
|
||||
|
||||
/* SPROM offsets */
|
||||
#define SRSH_ASPM_OFFSET 4 /* word 4 */
|
||||
#define SRSH_ASPM_ENB 0x18 /* bit 3, 4 */
|
||||
#define SRSH_ASPM_L1_ENB 0x10 /* bit 4 */
|
||||
#define SRSH_ASPM_L0s_ENB 0x8 /* bit 3 */
|
||||
|
||||
#define SRSH_PCIE_MISC_CONFIG 5 /* word 5 */
|
||||
#define SRSH_L23READY_EXIT_NOPERST 0x8000 /* bit 15 */
|
||||
#define SRSH_CLKREQ_OFFSET_REV5 20 /* word 20 for srom rev <= 5 */
|
||||
#define SRSH_CLKREQ_ENB 0x0800 /* bit 11 */
|
||||
#define SRSH_BD_OFFSET 6 /* word 6 */
|
||||
|
||||
/* chipcontrol */
|
||||
#define CHIPCTRL_4321_PLL_DOWN 0x800000/* serdes PLL down override */
|
||||
|
||||
/* MDIO control */
|
||||
#define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */
|
||||
#define MDIOCTL_DIVISOR_VAL 0x2
|
||||
#define MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */
|
||||
#define MDIOCTL_ACCESS_DONE 0x100 /* Transaction complete */
|
||||
|
||||
/* MDIO Data */
|
||||
#define MDIODATA_MASK 0x0000ffff /* data 2 bytes */
|
||||
#define MDIODATA_TA 0x00020000 /* Turnaround */
|
||||
|
||||
#define MDIODATA_REGADDR_SHF 18 /* Regaddr shift */
|
||||
#define MDIODATA_REGADDR_MASK 0x007c0000 /* Regaddr Mask */
|
||||
#define MDIODATA_DEVADDR_SHF 23 /* Physmedia devaddr shift */
|
||||
#define MDIODATA_DEVADDR_MASK 0x0f800000
|
||||
/* Physmedia devaddr Mask */
|
||||
|
||||
/* MDIO Data for older revisions < 10 */
|
||||
#define MDIODATA_REGADDR_SHF_OLD 18 /* Regaddr shift */
|
||||
#define MDIODATA_REGADDR_MASK_OLD 0x003c0000
|
||||
/* Regaddr Mask */
|
||||
#define MDIODATA_DEVADDR_SHF_OLD 22 /* Physmedia devaddr shift */
|
||||
#define MDIODATA_DEVADDR_MASK_OLD 0x0fc00000
|
||||
/* Physmedia devaddr Mask */
|
||||
|
||||
/* Transactions flags */
|
||||
#define MDIODATA_WRITE 0x10000000
|
||||
#define MDIODATA_READ 0x20000000
|
||||
#define MDIODATA_START 0x40000000
|
||||
|
||||
#define MDIODATA_DEV_ADDR 0x0 /* dev address for serdes */
|
||||
#define MDIODATA_BLK_ADDR 0x1F /* blk address for serdes */
|
||||
|
||||
/* serdes regs (rev < 10) */
|
||||
#define MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */
|
||||
#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */
|
||||
#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */
|
||||
|
||||
/* SERDES RX registers */
|
||||
#define SERDES_RX_CTRL 1 /* Rx cntrl */
|
||||
#define SERDES_RX_TIMER1 2 /* Rx Timer1 */
|
||||
#define SERDES_RX_CDR 6 /* CDR */
|
||||
#define SERDES_RX_CDRBW 7 /* CDR BW */
|
||||
/* SERDES RX control register */
|
||||
#define SERDES_RX_CTRL_FORCE 0x80 /* rxpolarity_force */
|
||||
#define SERDES_RX_CTRL_POLARITY 0x40 /* rxpolarity_value */
|
||||
|
||||
/* SERDES PLL registers */
|
||||
#define SERDES_PLL_CTRL 1 /* PLL control reg */
|
||||
#define PLL_CTRL_FREQDET_EN 0x4000 /* bit 14 is FREQDET on */
|
||||
|
||||
/* Linkcontrol reg offset in PCIE Cap */
|
||||
#define PCIE_CAP_LINKCTRL_OFFSET 16 /* offset in pcie cap */
|
||||
#define PCIE_CAP_LCREG_ASPML0s 0x01 /* ASPM L0s in linkctrl */
|
||||
#define PCIE_CAP_LCREG_ASPML1 0x02 /* ASPM L1 in linkctrl */
|
||||
#define PCIE_CLKREQ_ENAB 0x100 /* CLKREQ Enab in linkctrl */
|
||||
|
||||
#define PCIE_ASPM_ENAB 3 /* ASPM L0s & L1 in linkctrl */
|
||||
#define PCIE_ASPM_L1_ENAB 2 /* ASPM L0s & L1 in linkctrl */
|
||||
#define PCIE_ASPM_L0s_ENAB 1 /* ASPM L0s & L1 in linkctrl */
|
||||
#define PCIE_ASPM_DISAB 0 /* ASPM L0s & L1 in linkctrl */
|
||||
|
||||
/* Power management threshold */
|
||||
#define PCIE_L1THRESHOLDTIME_MASK 0xFF00 /* bits 8 - 15 */
|
||||
#define PCIE_L1THRESHOLDTIME_SHIFT 8 /* PCIE_L1THRESHOLDTIME_SHIFT */
|
||||
#define PCIE_L1THRESHOLD_WARVAL 0x72 /* WAR value */
|
||||
#define PCIE_ASPMTIMER_EXTEND 0x01000000
|
||||
/* > rev7:
|
||||
* enable extend ASPM timer
|
||||
*/
|
||||
|
||||
/* different register spaces to access thru pcie indirect access */
|
||||
#define PCIE_CONFIGREGS 1 /* Access to config space */
|
||||
#define PCIE_PCIEREGS 2 /* Access to pcie registers */
|
||||
|
||||
/* PCIE protocol PHY diagnostic registers */
|
||||
#define PCIE_PLP_STATUSREG 0x204 /* Status */
|
||||
|
||||
/* Status reg PCIE_PLP_STATUSREG */
|
||||
#define PCIE_PLP_POLARITYINV_STAT 0x10
|
||||
|
||||
/* PCIE protocol DLLP diagnostic registers */
|
||||
#define PCIE_DLLP_LCREG 0x100 /* Link Control */
|
||||
#define PCIE_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */
|
||||
|
||||
/* PCIE protocol TLP diagnostic registers */
|
||||
#define PCIE_TLP_WORKAROUNDSREG 0x004 /* TLP Workarounds */
|
||||
|
||||
/* Sonics to PCI translation types */
|
||||
#define SBTOPCI_PREF 0x4 /* prefetch enable */
|
||||
#define SBTOPCI_BURST 0x8 /* burst enable */
|
||||
#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */
|
||||
|
||||
#define PCI_CLKRUN_DSBL 0x8000 /* Bit 15 forceClkrun */
|
||||
|
||||
/* PCI core index in SROM shadow area */
|
||||
#define SRSH_PI_OFFSET 0 /* first word */
|
||||
#define SRSH_PI_MASK 0xf000 /* bit 15:12 */
|
||||
#define SRSH_PI_SHIFT 12 /* bit 15:12 */
|
||||
|
||||
/* Sonics side: PCI core and host control registers */
|
||||
struct sbpciregs {
|
||||
u32 control; /* PCI control */
|
||||
u32 PAD[3];
|
||||
u32 arbcontrol; /* PCI arbiter control */
|
||||
u32 clkrun; /* Clkrun Control (>=rev11) */
|
||||
u32 PAD[2];
|
||||
u32 intstatus; /* Interrupt status */
|
||||
u32 intmask; /* Interrupt mask */
|
||||
u32 sbtopcimailbox; /* Sonics to PCI mailbox */
|
||||
u32 PAD[9];
|
||||
u32 bcastaddr; /* Sonics broadcast address */
|
||||
u32 bcastdata; /* Sonics broadcast data */
|
||||
u32 PAD[2];
|
||||
u32 gpioin; /* ro: gpio input (>=rev2) */
|
||||
u32 gpioout; /* rw: gpio output (>=rev2) */
|
||||
u32 gpioouten; /* rw: gpio output enable (>= rev2) */
|
||||
u32 gpiocontrol; /* rw: gpio control (>= rev2) */
|
||||
u32 PAD[36];
|
||||
u32 sbtopci0; /* Sonics to PCI translation 0 */
|
||||
u32 sbtopci1; /* Sonics to PCI translation 1 */
|
||||
u32 sbtopci2; /* Sonics to PCI translation 2 */
|
||||
u32 PAD[189];
|
||||
u32 pcicfg[4][64]; /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */
|
||||
u16 sprom[36]; /* SPROM shadow Area */
|
||||
u32 PAD[46];
|
||||
};
|
||||
|
||||
/* SB side: PCIE core and host control registers */
|
||||
struct sbpcieregs {
|
||||
u32 control; /* host mode only */
|
||||
u32 PAD[2];
|
||||
u32 biststatus; /* bist Status: 0x00C */
|
||||
u32 gpiosel; /* PCIE gpio sel: 0x010 */
|
||||
u32 gpioouten; /* PCIE gpio outen: 0x14 */
|
||||
u32 PAD[2];
|
||||
u32 intstatus; /* Interrupt status: 0x20 */
|
||||
u32 intmask; /* Interrupt mask: 0x24 */
|
||||
u32 sbtopcimailbox; /* sb to pcie mailbox: 0x028 */
|
||||
u32 PAD[53];
|
||||
u32 sbtopcie0; /* sb to pcie translation 0: 0x100 */
|
||||
u32 sbtopcie1; /* sb to pcie translation 1: 0x104 */
|
||||
u32 sbtopcie2; /* sb to pcie translation 2: 0x108 */
|
||||
u32 PAD[5];
|
||||
|
||||
/* pcie core supports in direct access to config space */
|
||||
u32 configaddr; /* pcie config space access: Address field: 0x120 */
|
||||
u32 configdata; /* pcie config space access: Data field: 0x124 */
|
||||
|
||||
/* mdio access to serdes */
|
||||
u32 mdiocontrol; /* controls the mdio access: 0x128 */
|
||||
u32 mdiodata; /* Data to the mdio access: 0x12c */
|
||||
|
||||
/* pcie protocol phy/dllp/tlp register indirect access mechanism */
|
||||
u32 pcieindaddr; /* indirect access to
|
||||
* the internal register: 0x130
|
||||
*/
|
||||
u32 pcieinddata; /* Data to/from the internal regsiter: 0x134 */
|
||||
|
||||
u32 clkreqenctrl; /* >= rev 6, Clkreq rdma control : 0x138 */
|
||||
u32 PAD[177];
|
||||
u32 pciecfg[4][64]; /* 0x400 - 0x7FF, PCIE Cfg Space */
|
||||
u16 sprom[64]; /* SPROM shadow Area */
|
||||
};
|
||||
|
||||
struct pcicore_info {
|
||||
union {
|
||||
struct sbpcieregs __iomem *pcieregs;
|
||||
struct sbpciregs __iomem *pciregs;
|
||||
} regs; /* Memory mapped register to the core */
|
||||
|
||||
struct si_pub *sih; /* System interconnect handle */
|
||||
struct pci_dev *dev;
|
||||
u8 pciecap_lcreg_offset;/* PCIE capability LCreg offset
|
||||
* in the config space
|
||||
*/
|
||||
bool pcie_pr42767;
|
||||
u8 pcie_polarity;
|
||||
u8 pcie_war_aspm_ovr; /* Override ASPM/Clkreq settings */
|
||||
|
||||
u8 pmecap_offset; /* PM Capability offset in the config space */
|
||||
bool pmecap; /* Capable of generating PME */
|
||||
};
|
||||
|
||||
#define PCIE_ASPM(sih) \
|
||||
(((sih)->buscoretype == PCIE_CORE_ID) && \
|
||||
(((sih)->buscorerev >= 3) && \
|
||||
((sih)->buscorerev <= 5)))
|
||||
|
||||
|
||||
/* delay needed between the mdio control/ mdiodata register data access */
|
||||
static void pr28829_delay(void)
|
||||
{
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
/* Initialize the PCI core.
|
||||
* It's caller's responsibility to make sure that this is done only once
|
||||
*/
|
||||
struct pcicore_info *pcicore_init(struct si_pub *sih, struct pci_dev *pdev,
|
||||
void __iomem *regs)
|
||||
{
|
||||
struct pcicore_info *pi;
|
||||
|
||||
/* alloc struct pcicore_info */
|
||||
pi = kzalloc(sizeof(struct pcicore_info), GFP_ATOMIC);
|
||||
if (pi == NULL)
|
||||
return NULL;
|
||||
|
||||
pi->sih = sih;
|
||||
pi->dev = pdev;
|
||||
|
||||
if (sih->buscoretype == PCIE_CORE_ID) {
|
||||
u8 cap_ptr;
|
||||
pi->regs.pcieregs = regs;
|
||||
cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_EXP,
|
||||
NULL, NULL);
|
||||
pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
|
||||
} else
|
||||
pi->regs.pciregs = regs;
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
void pcicore_deinit(struct pcicore_info *pch)
|
||||
{
|
||||
kfree(pch);
|
||||
}
|
||||
|
||||
/* return cap_offset if requested capability exists in the PCI config space */
|
||||
/* Note that it's caller's responsibility to make sure it's a pci bus */
|
||||
u8
|
||||
pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id,
|
||||
unsigned char *buf, u32 *buflen)
|
||||
{
|
||||
u8 cap_id;
|
||||
u8 cap_ptr = 0;
|
||||
u32 bufsize;
|
||||
u8 byte_val;
|
||||
|
||||
/* check for Header type 0 */
|
||||
pci_read_config_byte(dev, PCI_HEADER_TYPE, &byte_val);
|
||||
if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
|
||||
goto end;
|
||||
|
||||
/* check if the capability pointer field exists */
|
||||
pci_read_config_byte(dev, PCI_STATUS, &byte_val);
|
||||
if (!(byte_val & PCI_STATUS_CAP_LIST))
|
||||
goto end;
|
||||
|
||||
pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &cap_ptr);
|
||||
/* check if the capability pointer is 0x00 */
|
||||
if (cap_ptr == 0x00)
|
||||
goto end;
|
||||
|
||||
/* loop thru the capability list
|
||||
* and see if the pcie capability exists
|
||||
*/
|
||||
|
||||
pci_read_config_byte(dev, cap_ptr, &cap_id);
|
||||
|
||||
while (cap_id != req_cap_id) {
|
||||
pci_read_config_byte(dev, cap_ptr + 1, &cap_ptr);
|
||||
if (cap_ptr == 0x00)
|
||||
break;
|
||||
pci_read_config_byte(dev, cap_ptr, &cap_id);
|
||||
}
|
||||
if (cap_id != req_cap_id)
|
||||
goto end;
|
||||
|
||||
/* found the caller requested capability */
|
||||
if (buf != NULL && buflen != NULL) {
|
||||
u8 cap_data;
|
||||
|
||||
bufsize = *buflen;
|
||||
if (!bufsize)
|
||||
goto end;
|
||||
*buflen = 0;
|
||||
/* copy the capability data excluding cap ID and next ptr */
|
||||
cap_data = cap_ptr + 2;
|
||||
if ((bufsize + cap_data) > PCI_SZPCR)
|
||||
bufsize = PCI_SZPCR - cap_data;
|
||||
*buflen = bufsize;
|
||||
while (bufsize--) {
|
||||
pci_read_config_byte(dev, cap_data, buf);
|
||||
cap_data++;
|
||||
buf++;
|
||||
}
|
||||
}
|
||||
end:
|
||||
return cap_ptr;
|
||||
}
|
||||
|
||||
/* ***** Register Access API */
|
||||
static uint
|
||||
pcie_readreg(struct sbpcieregs __iomem *pcieregs, uint addrtype, uint offset)
|
||||
{
|
||||
uint retval = 0xFFFFFFFF;
|
||||
|
||||
switch (addrtype) {
|
||||
case PCIE_CONFIGREGS:
|
||||
W_REG(&pcieregs->configaddr, offset);
|
||||
(void)R_REG((&pcieregs->configaddr));
|
||||
retval = R_REG(&pcieregs->configdata);
|
||||
break;
|
||||
case PCIE_PCIEREGS:
|
||||
W_REG(&pcieregs->pcieindaddr, offset);
|
||||
(void)R_REG(&pcieregs->pcieindaddr);
|
||||
retval = R_REG(&pcieregs->pcieinddata);
|
||||
break;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static uint pcie_writereg(struct sbpcieregs __iomem *pcieregs, uint addrtype,
|
||||
uint offset, uint val)
|
||||
{
|
||||
switch (addrtype) {
|
||||
case PCIE_CONFIGREGS:
|
||||
W_REG((&pcieregs->configaddr), offset);
|
||||
W_REG((&pcieregs->configdata), val);
|
||||
break;
|
||||
case PCIE_PCIEREGS:
|
||||
W_REG((&pcieregs->pcieindaddr), offset);
|
||||
W_REG((&pcieregs->pcieinddata), val);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk)
|
||||
{
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
uint mdiodata, i = 0;
|
||||
uint pcie_serdes_spinwait = 200;
|
||||
|
||||
mdiodata = (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
|
||||
(MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
|
||||
(MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) |
|
||||
(blk << 4));
|
||||
W_REG(&pcieregs->mdiodata, mdiodata);
|
||||
|
||||
pr28829_delay();
|
||||
/* retry till the transaction is complete */
|
||||
while (i < pcie_serdes_spinwait) {
|
||||
if (R_REG(&pcieregs->mdiocontrol) & MDIOCTL_ACCESS_DONE)
|
||||
break;
|
||||
|
||||
udelay(1000);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i >= pcie_serdes_spinwait)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
pcie_mdioop(struct pcicore_info *pi, uint physmedia, uint regaddr, bool write,
|
||||
uint *val)
|
||||
{
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
uint mdiodata;
|
||||
uint i = 0;
|
||||
uint pcie_serdes_spinwait = 10;
|
||||
|
||||
/* enable mdio access to SERDES */
|
||||
W_REG(&pcieregs->mdiocontrol, MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
|
||||
|
||||
if (pi->sih->buscorerev >= 10) {
|
||||
/* new serdes is slower in rw,
|
||||
* using two layers of reg address mapping
|
||||
*/
|
||||
if (!pcie_mdiosetblock(pi, physmedia))
|
||||
return 1;
|
||||
mdiodata = ((MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
|
||||
(regaddr << MDIODATA_REGADDR_SHF));
|
||||
pcie_serdes_spinwait *= 20;
|
||||
} else {
|
||||
mdiodata = ((physmedia << MDIODATA_DEVADDR_SHF_OLD) |
|
||||
(regaddr << MDIODATA_REGADDR_SHF_OLD));
|
||||
}
|
||||
|
||||
if (!write)
|
||||
mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
|
||||
else
|
||||
mdiodata |= (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA |
|
||||
*val);
|
||||
|
||||
W_REG(&pcieregs->mdiodata, mdiodata);
|
||||
|
||||
pr28829_delay();
|
||||
|
||||
/* retry till the transaction is complete */
|
||||
while (i < pcie_serdes_spinwait) {
|
||||
if (R_REG(&pcieregs->mdiocontrol) & MDIOCTL_ACCESS_DONE) {
|
||||
if (!write) {
|
||||
pr28829_delay();
|
||||
*val = (R_REG(&pcieregs->mdiodata) &
|
||||
MDIODATA_MASK);
|
||||
}
|
||||
/* Disable mdio access to SERDES */
|
||||
W_REG(&pcieregs->mdiocontrol, 0);
|
||||
return 0;
|
||||
}
|
||||
udelay(1000);
|
||||
i++;
|
||||
}
|
||||
|
||||
/* Timed out. Disable mdio access to SERDES. */
|
||||
W_REG(&pcieregs->mdiocontrol, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* use the mdio interface to read from mdio slaves */
|
||||
static int
|
||||
pcie_mdioread(struct pcicore_info *pi, uint physmedia, uint regaddr,
|
||||
uint *regval)
|
||||
{
|
||||
return pcie_mdioop(pi, physmedia, regaddr, false, regval);
|
||||
}
|
||||
|
||||
/* use the mdio interface to write to mdio slaves */
|
||||
static int
|
||||
pcie_mdiowrite(struct pcicore_info *pi, uint physmedia, uint regaddr, uint val)
|
||||
{
|
||||
return pcie_mdioop(pi, physmedia, regaddr, true, &val);
|
||||
}
|
||||
|
||||
/* ***** Support functions ***** */
|
||||
static u8 pcie_clkreq(struct pcicore_info *pi, u32 mask, u32 val)
|
||||
{
|
||||
u32 reg_val;
|
||||
u8 offset;
|
||||
|
||||
offset = pi->pciecap_lcreg_offset;
|
||||
if (!offset)
|
||||
return 0;
|
||||
|
||||
pci_read_config_dword(pi->dev, offset, ®_val);
|
||||
/* set operation */
|
||||
if (mask) {
|
||||
if (val)
|
||||
reg_val |= PCIE_CLKREQ_ENAB;
|
||||
else
|
||||
reg_val &= ~PCIE_CLKREQ_ENAB;
|
||||
pci_write_config_dword(pi->dev, offset, reg_val);
|
||||
pci_read_config_dword(pi->dev, offset, ®_val);
|
||||
}
|
||||
if (reg_val & PCIE_CLKREQ_ENAB)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pcie_extendL1timer(struct pcicore_info *pi, bool extend)
|
||||
{
|
||||
u32 w;
|
||||
struct si_pub *sih = pi->sih;
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
|
||||
if (sih->buscoretype != PCIE_CORE_ID || sih->buscorerev < 7)
|
||||
return;
|
||||
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
|
||||
if (extend)
|
||||
w |= PCIE_ASPMTIMER_EXTEND;
|
||||
else
|
||||
w &= ~PCIE_ASPMTIMER_EXTEND;
|
||||
pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
|
||||
}
|
||||
|
||||
/* centralized clkreq control policy */
|
||||
static void pcie_clkreq_upd(struct pcicore_info *pi, uint state)
|
||||
{
|
||||
struct si_pub *sih = pi->sih;
|
||||
|
||||
switch (state) {
|
||||
case SI_DOATTACH:
|
||||
if (PCIE_ASPM(sih))
|
||||
pcie_clkreq(pi, 1, 0);
|
||||
break;
|
||||
case SI_PCIDOWN:
|
||||
if (sih->buscorerev == 6) { /* turn on serdes PLL down */
|
||||
ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, chipcontrol_addr),
|
||||
~0, 0);
|
||||
ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, chipcontrol_data),
|
||||
~0x40, 0);
|
||||
} else if (pi->pcie_pr42767) {
|
||||
pcie_clkreq(pi, 1, 1);
|
||||
}
|
||||
break;
|
||||
case SI_PCIUP:
|
||||
if (sih->buscorerev == 6) { /* turn off serdes PLL down */
|
||||
ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, chipcontrol_addr),
|
||||
~0, 0);
|
||||
ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, chipcontrol_data),
|
||||
~0x40, 0x40);
|
||||
} else if (PCIE_ASPM(sih)) { /* disable clkreq */
|
||||
pcie_clkreq(pi, 1, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* ***** PCI core WARs ***** */
|
||||
/* Done only once at attach time */
|
||||
static void pcie_war_polarity(struct pcicore_info *pi)
|
||||
{
|
||||
u32 w;
|
||||
|
||||
if (pi->pcie_polarity != 0)
|
||||
return;
|
||||
|
||||
w = pcie_readreg(pi->regs.pcieregs, PCIE_PCIEREGS, PCIE_PLP_STATUSREG);
|
||||
|
||||
/* Detect the current polarity at attach and force that polarity and
|
||||
* disable changing the polarity
|
||||
*/
|
||||
if ((w & PCIE_PLP_POLARITYINV_STAT) == 0)
|
||||
pi->pcie_polarity = SERDES_RX_CTRL_FORCE;
|
||||
else
|
||||
pi->pcie_polarity = (SERDES_RX_CTRL_FORCE |
|
||||
SERDES_RX_CTRL_POLARITY);
|
||||
}
|
||||
|
||||
/* enable ASPM and CLKREQ if srom doesn't have it */
|
||||
/* Needs to happen when update to shadow SROM is needed
|
||||
* : Coming out of 'standby'/'hibernate'
|
||||
* : If pcie_war_aspm_ovr state changed
|
||||
*/
|
||||
static void pcie_war_aspm_clkreq(struct pcicore_info *pi)
|
||||
{
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
struct si_pub *sih = pi->sih;
|
||||
u16 val16;
|
||||
u16 __iomem *reg16;
|
||||
u32 w;
|
||||
|
||||
if (!PCIE_ASPM(sih))
|
||||
return;
|
||||
|
||||
/* bypass this on QT or VSIM */
|
||||
reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET];
|
||||
val16 = R_REG(reg16);
|
||||
|
||||
val16 &= ~SRSH_ASPM_ENB;
|
||||
if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB)
|
||||
val16 |= SRSH_ASPM_ENB;
|
||||
else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB)
|
||||
val16 |= SRSH_ASPM_L1_ENB;
|
||||
else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB)
|
||||
val16 |= SRSH_ASPM_L0s_ENB;
|
||||
|
||||
W_REG(reg16, val16);
|
||||
|
||||
pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
|
||||
w &= ~PCIE_ASPM_ENAB;
|
||||
w |= pi->pcie_war_aspm_ovr;
|
||||
pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
|
||||
|
||||
reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV5];
|
||||
val16 = R_REG(reg16);
|
||||
|
||||
if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) {
|
||||
val16 |= SRSH_CLKREQ_ENB;
|
||||
pi->pcie_pr42767 = true;
|
||||
} else
|
||||
val16 &= ~SRSH_CLKREQ_ENB;
|
||||
|
||||
W_REG(reg16, val16);
|
||||
}
|
||||
|
||||
/* Apply the polarity determined at the start */
|
||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
|
||||
static void pcie_war_serdes(struct pcicore_info *pi)
|
||||
{
|
||||
u32 w = 0;
|
||||
|
||||
if (pi->pcie_polarity != 0)
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CTRL,
|
||||
pi->pcie_polarity);
|
||||
|
||||
pcie_mdioread(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w);
|
||||
if (w & PLL_CTRL_FREQDET_EN) {
|
||||
w &= ~PLL_CTRL_FREQDET_EN;
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
|
||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
|
||||
static void pcie_misc_config_fixup(struct pcicore_info *pi)
|
||||
{
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
u16 val16;
|
||||
u16 __iomem *reg16;
|
||||
|
||||
reg16 = &pcieregs->sprom[SRSH_PCIE_MISC_CONFIG];
|
||||
val16 = R_REG(reg16);
|
||||
|
||||
if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) {
|
||||
val16 |= SRSH_L23READY_EXIT_NOPERST;
|
||||
W_REG(reg16, val16);
|
||||
}
|
||||
}
|
||||
|
||||
/* quick hack for testing */
|
||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
|
||||
static void pcie_war_noplldown(struct pcicore_info *pi)
|
||||
{
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
u16 __iomem *reg16;
|
||||
|
||||
/* turn off serdes PLL down */
|
||||
ai_corereg(pi->sih, SI_CC_IDX, offsetof(struct chipcregs, chipcontrol),
|
||||
CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN);
|
||||
|
||||
/* clear srom shadow backdoor */
|
||||
reg16 = &pcieregs->sprom[SRSH_BD_OFFSET];
|
||||
W_REG(reg16, 0);
|
||||
}
|
||||
|
||||
/* Needs to happen when coming out of 'standby'/'hibernate' */
|
||||
static void pcie_war_pci_setup(struct pcicore_info *pi)
|
||||
{
|
||||
struct si_pub *sih = pi->sih;
|
||||
struct sbpcieregs __iomem *pcieregs = pi->regs.pcieregs;
|
||||
u32 w;
|
||||
|
||||
if (sih->buscorerev == 0 || sih->buscorerev == 1) {
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
|
||||
PCIE_TLP_WORKAROUNDSREG);
|
||||
w |= 0x8;
|
||||
pcie_writereg(pcieregs, PCIE_PCIEREGS,
|
||||
PCIE_TLP_WORKAROUNDSREG, w);
|
||||
}
|
||||
|
||||
if (sih->buscorerev == 1) {
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
|
||||
w |= 0x40;
|
||||
pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
|
||||
}
|
||||
|
||||
if (sih->buscorerev == 0) {
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
|
||||
pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
|
||||
} else if (PCIE_ASPM(sih)) {
|
||||
/* Change the L1 threshold for better performance */
|
||||
w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
|
||||
PCIE_DLLP_PMTHRESHREG);
|
||||
w &= ~PCIE_L1THRESHOLDTIME_MASK;
|
||||
w |= PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT;
|
||||
pcie_writereg(pcieregs, PCIE_PCIEREGS,
|
||||
PCIE_DLLP_PMTHRESHREG, w);
|
||||
|
||||
pcie_war_serdes(pi);
|
||||
|
||||
pcie_war_aspm_clkreq(pi);
|
||||
} else if (pi->sih->buscorerev == 7)
|
||||
pcie_war_noplldown(pi);
|
||||
|
||||
/* Note that the fix is actually in the SROM,
|
||||
* that's why this is open-ended
|
||||
*/
|
||||
if (pi->sih->buscorerev >= 6)
|
||||
pcie_misc_config_fixup(pi);
|
||||
}
|
||||
|
||||
/* ***** Functions called during driver state changes ***** */
|
||||
void pcicore_attach(struct pcicore_info *pi, int state)
|
||||
{
|
||||
struct si_pub *sih = pi->sih;
|
||||
u32 bfl2 = (u32)getintvar(sih, BRCMS_SROM_BOARDFLAGS2);
|
||||
|
||||
/* Determine if this board needs override */
|
||||
if (PCIE_ASPM(sih)) {
|
||||
if (bfl2 & BFL2_PCIEWAR_OVR)
|
||||
pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB;
|
||||
else
|
||||
pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB;
|
||||
}
|
||||
|
||||
/* These need to happen in this order only */
|
||||
pcie_war_polarity(pi);
|
||||
|
||||
pcie_war_serdes(pi);
|
||||
|
||||
pcie_war_aspm_clkreq(pi);
|
||||
|
||||
pcie_clkreq_upd(pi, state);
|
||||
|
||||
}
|
||||
|
||||
void pcicore_hwup(struct pcicore_info *pi)
|
||||
{
|
||||
if (!pi || pi->sih->buscoretype != PCIE_CORE_ID)
|
||||
return;
|
||||
|
||||
pcie_war_pci_setup(pi);
|
||||
}
|
||||
|
||||
void pcicore_up(struct pcicore_info *pi, int state)
|
||||
{
|
||||
if (!pi || pi->sih->buscoretype != PCIE_CORE_ID)
|
||||
return;
|
||||
|
||||
/* Restore L1 timer for better performance */
|
||||
pcie_extendL1timer(pi, true);
|
||||
|
||||
pcie_clkreq_upd(pi, state);
|
||||
}
|
||||
|
||||
/* When the device is going to enter D3 state
|
||||
* (or the system is going to enter S3/S4 states)
|
||||
*/
|
||||
void pcicore_sleep(struct pcicore_info *pi)
|
||||
{
|
||||
u32 w;
|
||||
|
||||
if (!pi || !PCIE_ASPM(pi->sih))
|
||||
return;
|
||||
|
||||
pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
|
||||
w &= ~PCIE_CAP_LCREG_ASPML1;
|
||||
pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
|
||||
|
||||
pi->pcie_pr42767 = false;
|
||||
}
|
||||
|
||||
void pcicore_down(struct pcicore_info *pi, int state)
|
||||
{
|
||||
if (!pi || pi->sih->buscoretype != PCIE_CORE_ID)
|
||||
return;
|
||||
|
||||
pcie_clkreq_upd(pi, state);
|
||||
|
||||
/* Reduce L1 timer for better power savings */
|
||||
pcie_extendL1timer(pi, false);
|
||||
}
|
||||
|
||||
/* precondition: current core is sii->buscoretype */
|
||||
static void pcicore_fixcfg(struct pcicore_info *pi, u16 __iomem *reg16)
|
||||
{
|
||||
struct si_info *sii = (struct si_info *)(pi->sih);
|
||||
u16 val16;
|
||||
uint pciidx;
|
||||
|
||||
pciidx = ai_coreidx(&sii->pub);
|
||||
val16 = R_REG(reg16);
|
||||
if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16)pciidx) {
|
||||
val16 = (u16)(pciidx << SRSH_PI_SHIFT) |
|
||||
(val16 & ~SRSH_PI_MASK);
|
||||
W_REG(reg16, val16);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pcicore_fixcfg_pci(struct pcicore_info *pi, struct sbpciregs __iomem *pciregs)
|
||||
{
|
||||
pcicore_fixcfg(pi, &pciregs->sprom[SRSH_PI_OFFSET]);
|
||||
}
|
||||
|
||||
void pcicore_fixcfg_pcie(struct pcicore_info *pi,
|
||||
struct sbpcieregs __iomem *pcieregs)
|
||||
{
|
||||
pcicore_fixcfg(pi, &pcieregs->sprom[SRSH_PI_OFFSET]);
|
||||
}
|
||||
|
||||
/* precondition: current core is pci core */
|
||||
void
|
||||
pcicore_pci_setup(struct pcicore_info *pi, struct sbpciregs __iomem *pciregs)
|
||||
{
|
||||
u32 w;
|
||||
|
||||
OR_REG(&pciregs->sbtopci2, SBTOPCI_PREF | SBTOPCI_BURST);
|
||||
|
||||
if (((struct si_info *)(pi->sih))->pub.buscorerev >= 11) {
|
||||
OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI);
|
||||
w = R_REG(&pciregs->clkrun);
|
||||
W_REG(&pciregs->clkrun, w | PCI_CLKRUN_DSBL);
|
||||
w = R_REG(&pciregs->clkrun);
|
||||
}
|
||||
}
|
82
drivers/net/wireless/brcm80211/brcmsmac/nicpci.h
Normal file
82
drivers/net/wireless/brcm80211/brcmsmac/nicpci.h
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 _BRCM_NICPCI_H_
|
||||
#define _BRCM_NICPCI_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/* PCI configuration address space size */
|
||||
#define PCI_SZPCR 256
|
||||
|
||||
/* Brcm PCI configuration registers */
|
||||
/* backplane address space accessed by BAR0 */
|
||||
#define PCI_BAR0_WIN 0x80
|
||||
/* sprom property control */
|
||||
#define PCI_SPROM_CONTROL 0x88
|
||||
/* mask of PCI and other cores interrupts */
|
||||
#define PCI_INT_MASK 0x94
|
||||
/* backplane core interrupt mask bits offset */
|
||||
#define PCI_SBIM_SHIFT 8
|
||||
/* backplane address space accessed by second 4KB of BAR0 */
|
||||
#define PCI_BAR0_WIN2 0xac
|
||||
/* pci config space gpio input (>=rev3) */
|
||||
#define PCI_GPIO_IN 0xb0
|
||||
/* pci config space gpio output (>=rev3) */
|
||||
#define PCI_GPIO_OUT 0xb4
|
||||
/* pci config space gpio output enable (>=rev3) */
|
||||
#define PCI_GPIO_OUTEN 0xb8
|
||||
|
||||
/* bar0 + 4K accesses external sprom */
|
||||
#define PCI_BAR0_SPROM_OFFSET (4 * 1024)
|
||||
/* bar0 + 6K accesses pci core registers */
|
||||
#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024)
|
||||
/*
|
||||
* pci core SB registers are at the end of the
|
||||
* 8KB window, so their address is the "regular"
|
||||
* address plus 4K
|
||||
*/
|
||||
#define PCI_BAR0_PCISBR_OFFSET (4 * 1024)
|
||||
/* bar0 window size Match with corerev 13 */
|
||||
#define PCI_BAR0_WINSZ (16 * 1024)
|
||||
/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */
|
||||
/* bar0 + 8K accesses pci/pcie core registers */
|
||||
#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024)
|
||||
/* bar0 + 12K accesses chipc core registers */
|
||||
#define PCI_16KB0_CCREGS_OFFSET (12 * 1024)
|
||||
|
||||
struct sbpciregs;
|
||||
struct sbpcieregs;
|
||||
|
||||
extern struct pcicore_info *pcicore_init(struct si_pub *sih,
|
||||
struct pci_dev *pdev,
|
||||
void __iomem *regs);
|
||||
extern void pcicore_deinit(struct pcicore_info *pch);
|
||||
extern void pcicore_attach(struct pcicore_info *pch, int state);
|
||||
extern void pcicore_hwup(struct pcicore_info *pch);
|
||||
extern void pcicore_up(struct pcicore_info *pch, int state);
|
||||
extern void pcicore_sleep(struct pcicore_info *pch);
|
||||
extern void pcicore_down(struct pcicore_info *pch, int state);
|
||||
extern u8 pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id,
|
||||
unsigned char *buf, u32 *buflen);
|
||||
extern void pcicore_fixcfg_pci(struct pcicore_info *pch,
|
||||
struct sbpciregs __iomem *pciregs);
|
||||
extern void pcicore_fixcfg_pcie(struct pcicore_info *pch,
|
||||
struct sbpcieregs __iomem *pciregs);
|
||||
extern void pcicore_pci_setup(struct pcicore_info *pch,
|
||||
struct sbpciregs __iomem *pciregs);
|
||||
|
||||
#endif /* _BRCM_NICPCI_H_ */
|
426
drivers/net/wireless/brcm80211/brcmsmac/otp.c
Normal file
426
drivers/net/wireless/brcm80211/brcmsmac/otp.c
Normal file
@ -0,0 +1,426 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 <linux/io.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include <brcm_hw_ids.h>
|
||||
#include <chipcommon.h>
|
||||
#include "aiutils.h"
|
||||
#include "otp.h"
|
||||
|
||||
#define OTPS_GUP_MASK 0x00000f00
|
||||
#define OTPS_GUP_SHIFT 8
|
||||
/* h/w subregion is programmed */
|
||||
#define OTPS_GUP_HW 0x00000100
|
||||
/* s/w subregion is programmed */
|
||||
#define OTPS_GUP_SW 0x00000200
|
||||
/* chipid/pkgopt subregion is programmed */
|
||||
#define OTPS_GUP_CI 0x00000400
|
||||
/* fuse subregion is programmed */
|
||||
#define OTPS_GUP_FUSE 0x00000800
|
||||
|
||||
/* Fields in otpprog in rev >= 21 */
|
||||
#define OTPP_COL_MASK 0x000000ff
|
||||
#define OTPP_COL_SHIFT 0
|
||||
#define OTPP_ROW_MASK 0x0000ff00
|
||||
#define OTPP_ROW_SHIFT 8
|
||||
#define OTPP_OC_MASK 0x0f000000
|
||||
#define OTPP_OC_SHIFT 24
|
||||
#define OTPP_READERR 0x10000000
|
||||
#define OTPP_VALUE_MASK 0x20000000
|
||||
#define OTPP_VALUE_SHIFT 29
|
||||
#define OTPP_START_BUSY 0x80000000
|
||||
#define OTPP_READ 0x40000000
|
||||
|
||||
/* Opcodes for OTPP_OC field */
|
||||
#define OTPPOC_READ 0
|
||||
#define OTPPOC_BIT_PROG 1
|
||||
#define OTPPOC_VERIFY 3
|
||||
#define OTPPOC_INIT 4
|
||||
#define OTPPOC_SET 5
|
||||
#define OTPPOC_RESET 6
|
||||
#define OTPPOC_OCST 7
|
||||
#define OTPPOC_ROW_LOCK 8
|
||||
#define OTPPOC_PRESCN_TEST 9
|
||||
|
||||
#define OTPTYPE_IPX(ccrev) ((ccrev) == 21 || (ccrev) >= 23)
|
||||
|
||||
#define OTPP_TRIES 10000000 /* # of tries for OTPP */
|
||||
|
||||
#define MAXNUMRDES 9 /* Maximum OTP redundancy entries */
|
||||
|
||||
/* Fixed size subregions sizes in words */
|
||||
#define OTPGU_CI_SZ 2
|
||||
|
||||
struct otpinfo;
|
||||
|
||||
/* OTP function struct */
|
||||
struct otp_fn_s {
|
||||
int (*init)(struct si_pub *sih, struct otpinfo *oi);
|
||||
int (*read_region)(struct otpinfo *oi, int region, u16 *data,
|
||||
uint *wlen);
|
||||
};
|
||||
|
||||
struct otpinfo {
|
||||
uint ccrev; /* chipc revision */
|
||||
const struct otp_fn_s *fn; /* OTP functions */
|
||||
struct si_pub *sih; /* Saved sb handle */
|
||||
|
||||
/* IPX OTP section */
|
||||
u16 wsize; /* Size of otp in words */
|
||||
u16 rows; /* Geometry */
|
||||
u16 cols; /* Geometry */
|
||||
u32 status; /* Flag bits (lock/prog/rv).
|
||||
* (Reflected only when OTP is power cycled)
|
||||
*/
|
||||
u16 hwbase; /* hardware subregion offset */
|
||||
u16 hwlim; /* hardware subregion boundary */
|
||||
u16 swbase; /* software subregion offset */
|
||||
u16 swlim; /* software subregion boundary */
|
||||
u16 fbase; /* fuse subregion offset */
|
||||
u16 flim; /* fuse subregion boundary */
|
||||
int otpgu_base; /* offset to General Use Region */
|
||||
};
|
||||
|
||||
/* OTP layout */
|
||||
/* CC revs 21, 24 and 27 OTP General Use Region word offset */
|
||||
#define REVA4_OTPGU_BASE 12
|
||||
|
||||
/* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */
|
||||
#define REVB8_OTPGU_BASE 20
|
||||
|
||||
/* CC rev 36 OTP General Use Region word offset */
|
||||
#define REV36_OTPGU_BASE 12
|
||||
|
||||
/* Subregion word offsets in General Use region */
|
||||
#define OTPGU_HSB_OFF 0
|
||||
#define OTPGU_SFB_OFF 1
|
||||
#define OTPGU_CI_OFF 2
|
||||
#define OTPGU_P_OFF 3
|
||||
#define OTPGU_SROM_OFF 4
|
||||
|
||||
/* Flag bit offsets in General Use region */
|
||||
#define OTPGU_HWP_OFF 60
|
||||
#define OTPGU_SWP_OFF 61
|
||||
#define OTPGU_CIP_OFF 62
|
||||
#define OTPGU_FUSEP_OFF 63
|
||||
#define OTPGU_CIP_MSK 0x4000
|
||||
#define OTPGU_P_MSK 0xf000
|
||||
#define OTPGU_P_SHIFT (OTPGU_HWP_OFF % 16)
|
||||
|
||||
/* OTP Size */
|
||||
#define OTP_SZ_FU_324 ((roundup(324, 8))/8) /* 324 bits */
|
||||
#define OTP_SZ_FU_288 (288/8) /* 288 bits */
|
||||
#define OTP_SZ_FU_216 (216/8) /* 216 bits */
|
||||
#define OTP_SZ_FU_72 (72/8) /* 72 bits */
|
||||
#define OTP_SZ_CHECKSUM (16/8) /* 16 bits */
|
||||
#define OTP4315_SWREG_SZ 178 /* 178 bytes */
|
||||
#define OTP_SZ_FU_144 (144/8) /* 144 bits */
|
||||
|
||||
static u16
|
||||
ipxotp_otpr(struct otpinfo *oi, struct chipcregs __iomem *cc, uint wn)
|
||||
{
|
||||
return R_REG(&cc->sromotp[wn]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate max HW/SW region byte size by subtracting fuse region
|
||||
* and checksum size, osizew is oi->wsize (OTP size - GU size) in words
|
||||
*/
|
||||
static int ipxotp_max_rgnsz(struct si_pub *sih, int osizew)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (sih->chip) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
|
||||
break;
|
||||
case BCM4313_CHIP_ID:
|
||||
ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
|
||||
break;
|
||||
default:
|
||||
break; /* Don't know about this chip */
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void _ipxotp_init(struct otpinfo *oi, struct chipcregs __iomem *cc)
|
||||
{
|
||||
uint k;
|
||||
u32 otpp, st;
|
||||
|
||||
/*
|
||||
* record word offset of General Use Region
|
||||
* for various chipcommon revs
|
||||
*/
|
||||
if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24
|
||||
|| oi->sih->ccrev == 27) {
|
||||
oi->otpgu_base = REVA4_OTPGU_BASE;
|
||||
} else if (oi->sih->ccrev == 36) {
|
||||
/*
|
||||
* OTP size greater than equal to 2KB (128 words),
|
||||
* otpgu_base is similar to rev23
|
||||
*/
|
||||
if (oi->wsize >= 128)
|
||||
oi->otpgu_base = REVB8_OTPGU_BASE;
|
||||
else
|
||||
oi->otpgu_base = REV36_OTPGU_BASE;
|
||||
} else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) {
|
||||
oi->otpgu_base = REVB8_OTPGU_BASE;
|
||||
}
|
||||
|
||||
/* First issue an init command so the status is up to date */
|
||||
otpp =
|
||||
OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK);
|
||||
|
||||
W_REG(&cc->otpprog, otpp);
|
||||
for (k = 0;
|
||||
((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
|
||||
&& (k < OTPP_TRIES); k++)
|
||||
;
|
||||
if (k >= OTPP_TRIES)
|
||||
return;
|
||||
|
||||
/* Read OTP lock bits and subregion programmed indication bits */
|
||||
oi->status = R_REG(&cc->otpstatus);
|
||||
|
||||
if ((oi->sih->chip == BCM43224_CHIP_ID)
|
||||
|| (oi->sih->chip == BCM43225_CHIP_ID)) {
|
||||
u32 p_bits;
|
||||
p_bits =
|
||||
(ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) &
|
||||
OTPGU_P_MSK)
|
||||
>> OTPGU_P_SHIFT;
|
||||
oi->status |= (p_bits << OTPS_GUP_SHIFT);
|
||||
}
|
||||
|
||||
/*
|
||||
* h/w region base and fuse region limit are fixed to
|
||||
* the top and the bottom of the general use region.
|
||||
* Everything else can be flexible.
|
||||
*/
|
||||
oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF;
|
||||
oi->hwlim = oi->wsize;
|
||||
if (oi->status & OTPS_GUP_HW) {
|
||||
oi->hwlim =
|
||||
ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
|
||||
oi->swbase = oi->hwlim;
|
||||
} else
|
||||
oi->swbase = oi->hwbase;
|
||||
|
||||
/* subtract fuse and checksum from beginning */
|
||||
oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2;
|
||||
|
||||
if (oi->status & OTPS_GUP_SW) {
|
||||
oi->swlim =
|
||||
ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
|
||||
oi->fbase = oi->swlim;
|
||||
} else
|
||||
oi->fbase = oi->swbase;
|
||||
|
||||
oi->flim = oi->wsize;
|
||||
}
|
||||
|
||||
static int ipxotp_init(struct si_pub *sih, struct otpinfo *oi)
|
||||
{
|
||||
uint idx;
|
||||
struct chipcregs __iomem *cc;
|
||||
|
||||
/* Make sure we're running IPX OTP */
|
||||
if (!OTPTYPE_IPX(sih->ccrev))
|
||||
return -EBADE;
|
||||
|
||||
/* Make sure OTP is not disabled */
|
||||
if (ai_is_otp_disabled(sih))
|
||||
return -EBADE;
|
||||
|
||||
/* Check for otp size */
|
||||
switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
|
||||
case 0:
|
||||
/* Nothing there */
|
||||
return -EBADE;
|
||||
case 1: /* 32x64 */
|
||||
oi->rows = 32;
|
||||
oi->cols = 64;
|
||||
oi->wsize = 128;
|
||||
break;
|
||||
case 2: /* 64x64 */
|
||||
oi->rows = 64;
|
||||
oi->cols = 64;
|
||||
oi->wsize = 256;
|
||||
break;
|
||||
case 5: /* 96x64 */
|
||||
oi->rows = 96;
|
||||
oi->cols = 64;
|
||||
oi->wsize = 384;
|
||||
break;
|
||||
case 7: /* 16x64 *//* 1024 bits */
|
||||
oi->rows = 16;
|
||||
oi->cols = 64;
|
||||
oi->wsize = 64;
|
||||
break;
|
||||
default:
|
||||
/* Don't know the geometry */
|
||||
return -EBADE;
|
||||
}
|
||||
|
||||
/* Retrieve OTP region info */
|
||||
idx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
_ipxotp_init(oi, cc);
|
||||
|
||||
ai_setcoreidx(sih, idx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ipxotp_read_region(struct otpinfo *oi, int region, u16 *data, uint *wlen)
|
||||
{
|
||||
uint idx;
|
||||
struct chipcregs __iomem *cc;
|
||||
uint base, i, sz;
|
||||
|
||||
/* Validate region selection */
|
||||
switch (region) {
|
||||
case OTP_HW_RGN:
|
||||
sz = (uint) oi->hwlim - oi->hwbase;
|
||||
if (!(oi->status & OTPS_GUP_HW)) {
|
||||
*wlen = sz;
|
||||
return -ENODATA;
|
||||
}
|
||||
if (*wlen < sz) {
|
||||
*wlen = sz;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
base = oi->hwbase;
|
||||
break;
|
||||
case OTP_SW_RGN:
|
||||
sz = ((uint) oi->swlim - oi->swbase);
|
||||
if (!(oi->status & OTPS_GUP_SW)) {
|
||||
*wlen = sz;
|
||||
return -ENODATA;
|
||||
}
|
||||
if (*wlen < sz) {
|
||||
*wlen = sz;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
base = oi->swbase;
|
||||
break;
|
||||
case OTP_CI_RGN:
|
||||
sz = OTPGU_CI_SZ;
|
||||
if (!(oi->status & OTPS_GUP_CI)) {
|
||||
*wlen = sz;
|
||||
return -ENODATA;
|
||||
}
|
||||
if (*wlen < sz) {
|
||||
*wlen = sz;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
base = oi->otpgu_base + OTPGU_CI_OFF;
|
||||
break;
|
||||
case OTP_FUSE_RGN:
|
||||
sz = (uint) oi->flim - oi->fbase;
|
||||
if (!(oi->status & OTPS_GUP_FUSE)) {
|
||||
*wlen = sz;
|
||||
return -ENODATA;
|
||||
}
|
||||
if (*wlen < sz) {
|
||||
*wlen = sz;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
base = oi->fbase;
|
||||
break;
|
||||
case OTP_ALL_RGN:
|
||||
sz = ((uint) oi->flim - oi->hwbase);
|
||||
if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) {
|
||||
*wlen = sz;
|
||||
return -ENODATA;
|
||||
}
|
||||
if (*wlen < sz) {
|
||||
*wlen = sz;
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
base = oi->hwbase;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
idx = ai_coreidx(oi->sih);
|
||||
cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
|
||||
|
||||
/* Read the data */
|
||||
for (i = 0; i < sz; i++)
|
||||
data[i] = ipxotp_otpr(oi, cc, base + i);
|
||||
|
||||
ai_setcoreidx(oi->sih, idx);
|
||||
*wlen = sz;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct otp_fn_s ipxotp_fn = {
|
||||
(int (*)(struct si_pub *, struct otpinfo *)) ipxotp_init,
|
||||
(int (*)(struct otpinfo *, int, u16 *, uint *)) ipxotp_read_region,
|
||||
};
|
||||
|
||||
static int otp_init(struct si_pub *sih, struct otpinfo *oi)
|
||||
{
|
||||
|
||||
int ret;
|
||||
|
||||
memset(oi, 0, sizeof(struct otpinfo));
|
||||
|
||||
oi->ccrev = sih->ccrev;
|
||||
|
||||
if (OTPTYPE_IPX(oi->ccrev))
|
||||
oi->fn = &ipxotp_fn;
|
||||
|
||||
if (oi->fn == NULL)
|
||||
return -EBADE;
|
||||
|
||||
oi->sih = sih;
|
||||
|
||||
ret = (oi->fn->init) (sih, oi);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
otp_read_region(struct si_pub *sih, int region, u16 *data, uint *wlen) {
|
||||
struct otpinfo otpinfo;
|
||||
struct otpinfo *oi = &otpinfo;
|
||||
int err = 0;
|
||||
|
||||
if (ai_is_otp_disabled(sih)) {
|
||||
err = -EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = otp_init(sih, oi);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = ((oi)->fn->read_region)(oi, region, data, wlen);
|
||||
|
||||
out:
|
||||
return err;
|
||||
}
|
36
drivers/net/wireless/brcm80211/brcmsmac/otp.h
Normal file
36
drivers/net/wireless/brcm80211/brcmsmac/otp.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 _BRCM_OTP_H_
|
||||
#define _BRCM_OTP_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
/* OTP regions */
|
||||
#define OTP_HW_RGN 1
|
||||
#define OTP_SW_RGN 2
|
||||
#define OTP_CI_RGN 4
|
||||
#define OTP_FUSE_RGN 8
|
||||
/* From h/w region to end of OTP including checksum */
|
||||
#define OTP_ALL_RGN 0xf
|
||||
|
||||
/* OTP Size */
|
||||
#define OTP_SZ_MAX (6144/8) /* maximum bytes in one CIS */
|
||||
|
||||
extern int otp_read_region(struct si_pub *sih, int region, u16 *data,
|
||||
uint *wlen);
|
||||
|
||||
#endif /* _BRCM_OTP_H_ */
|
2988
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
Normal file
2988
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
Normal file
File diff suppressed because it is too large
Load Diff
301
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h
Normal file
301
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h
Normal file
@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* phy_hal.h: functionality exported from the phy to higher layers
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_PHY_HAL_H_
|
||||
#define _BRCM_PHY_HAL_H_
|
||||
|
||||
#include <brcmu_utils.h>
|
||||
#include <brcmu_wifi.h>
|
||||
#include <phy_shim.h>
|
||||
|
||||
#define IDCODE_VER_MASK 0x0000000f
|
||||
#define IDCODE_VER_SHIFT 0
|
||||
#define IDCODE_MFG_MASK 0x00000fff
|
||||
#define IDCODE_MFG_SHIFT 0
|
||||
#define IDCODE_ID_MASK 0x0ffff000
|
||||
#define IDCODE_ID_SHIFT 12
|
||||
#define IDCODE_REV_MASK 0xf0000000
|
||||
#define IDCODE_REV_SHIFT 28
|
||||
|
||||
#define NORADIO_ID 0xe4f5
|
||||
#define NORADIO_IDCODE 0x4e4f5246
|
||||
|
||||
#define BCM2055_ID 0x2055
|
||||
#define BCM2055_IDCODE 0x02055000
|
||||
#define BCM2055A0_IDCODE 0x1205517f
|
||||
|
||||
#define BCM2056_ID 0x2056
|
||||
#define BCM2056_IDCODE 0x02056000
|
||||
#define BCM2056A0_IDCODE 0x1205617f
|
||||
|
||||
#define BCM2057_ID 0x2057
|
||||
#define BCM2057_IDCODE 0x02057000
|
||||
#define BCM2057A0_IDCODE 0x1205717f
|
||||
|
||||
#define BCM2064_ID 0x2064
|
||||
#define BCM2064_IDCODE 0x02064000
|
||||
#define BCM2064A0_IDCODE 0x0206417f
|
||||
|
||||
#define PHY_TPC_HW_OFF false
|
||||
#define PHY_TPC_HW_ON true
|
||||
|
||||
#define PHY_PERICAL_DRIVERUP 1
|
||||
#define PHY_PERICAL_WATCHDOG 2
|
||||
#define PHY_PERICAL_PHYINIT 3
|
||||
#define PHY_PERICAL_JOIN_BSS 4
|
||||
#define PHY_PERICAL_START_IBSS 5
|
||||
#define PHY_PERICAL_UP_BSS 6
|
||||
#define PHY_PERICAL_CHAN 7
|
||||
#define PHY_FULLCAL 8
|
||||
|
||||
#define PHY_PERICAL_DISABLE 0
|
||||
#define PHY_PERICAL_SPHASE 1
|
||||
#define PHY_PERICAL_MPHASE 2
|
||||
#define PHY_PERICAL_MANUAL 3
|
||||
|
||||
#define PHY_HOLD_FOR_ASSOC 1
|
||||
#define PHY_HOLD_FOR_SCAN 2
|
||||
#define PHY_HOLD_FOR_RM 4
|
||||
#define PHY_HOLD_FOR_PLT 8
|
||||
#define PHY_HOLD_FOR_MUTE 16
|
||||
#define PHY_HOLD_FOR_NOT_ASSOC 0x20
|
||||
|
||||
#define PHY_MUTE_FOR_PREISM 1
|
||||
#define PHY_MUTE_ALL 0xffffffff
|
||||
|
||||
#define PHY_NOISE_FIXED_VAL (-95)
|
||||
#define PHY_NOISE_FIXED_VAL_NPHY (-92)
|
||||
#define PHY_NOISE_FIXED_VAL_LCNPHY (-92)
|
||||
|
||||
#define PHY_MODE_CAL 0x0002
|
||||
#define PHY_MODE_NOISEM 0x0004
|
||||
|
||||
#define BRCMS_TXPWR_DB_FACTOR 4
|
||||
|
||||
/* a large TX Power as an init value to factor out of min() calculations,
|
||||
* keep low enough to fit in an s8, units are .25 dBm
|
||||
*/
|
||||
#define BRCMS_TXPWR_MAX (127) /* ~32 dBm = 1,500 mW */
|
||||
|
||||
#define BRCMS_NUM_RATES_CCK 4
|
||||
#define BRCMS_NUM_RATES_OFDM 8
|
||||
#define BRCMS_NUM_RATES_MCS_1_STREAM 8
|
||||
#define BRCMS_NUM_RATES_MCS_2_STREAM 8
|
||||
#define BRCMS_NUM_RATES_MCS_3_STREAM 8
|
||||
#define BRCMS_NUM_RATES_MCS_4_STREAM 8
|
||||
|
||||
#define BRCMS_RSSI_INVALID 0 /* invalid RSSI value */
|
||||
|
||||
struct d11regs;
|
||||
struct phy_shim_info;
|
||||
|
||||
struct txpwr_limits {
|
||||
u8 cck[BRCMS_NUM_RATES_CCK];
|
||||
u8 ofdm[BRCMS_NUM_RATES_OFDM];
|
||||
|
||||
u8 ofdm_cdd[BRCMS_NUM_RATES_OFDM];
|
||||
|
||||
u8 ofdm_40_siso[BRCMS_NUM_RATES_OFDM];
|
||||
u8 ofdm_40_cdd[BRCMS_NUM_RATES_OFDM];
|
||||
|
||||
u8 mcs_20_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_20_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_20_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_20_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
|
||||
|
||||
u8 mcs_40_siso[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_40_cdd[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_40_stbc[BRCMS_NUM_RATES_MCS_1_STREAM];
|
||||
u8 mcs_40_mimo[BRCMS_NUM_RATES_MCS_2_STREAM];
|
||||
u8 mcs32;
|
||||
};
|
||||
|
||||
struct tx_power {
|
||||
u32 flags;
|
||||
u16 chanspec; /* txpwr report for this channel */
|
||||
u16 local_chanspec; /* channel on which we are associated */
|
||||
u8 local_max; /* local max according to the AP */
|
||||
u8 local_constraint; /* local constraint according to the AP */
|
||||
s8 antgain[2]; /* Ant gain for each band - from SROM */
|
||||
u8 rf_cores; /* count of RF Cores being reported */
|
||||
u8 est_Pout[4]; /* Latest tx power out estimate per RF chain */
|
||||
u8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain
|
||||
* without adjustment */
|
||||
u8 est_Pout_cck; /* Latest CCK tx power out estimate */
|
||||
u8 tx_power_max[4]; /* Maximum target power among all rates */
|
||||
/* Index of the rate with the max target power */
|
||||
u8 tx_power_max_rate_ind[4];
|
||||
/* User limit */
|
||||
u8 user_limit[WL_TX_POWER_RATES];
|
||||
/* Regulatory power limit */
|
||||
u8 reg_limit[WL_TX_POWER_RATES];
|
||||
/* Max power board can support (SROM) */
|
||||
u8 board_limit[WL_TX_POWER_RATES];
|
||||
/* Latest target power */
|
||||
u8 target[WL_TX_POWER_RATES];
|
||||
};
|
||||
|
||||
struct tx_inst_power {
|
||||
u8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */
|
||||
u8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */
|
||||
};
|
||||
|
||||
struct brcms_chanvec {
|
||||
u8 vec[MAXCHANNEL / NBBY];
|
||||
};
|
||||
|
||||
struct shared_phy_params {
|
||||
struct si_pub *sih;
|
||||
struct phy_shim_info *physhim;
|
||||
uint unit;
|
||||
uint corerev;
|
||||
uint buscorerev;
|
||||
u16 vid;
|
||||
u16 did;
|
||||
uint chip;
|
||||
uint chiprev;
|
||||
uint chippkg;
|
||||
uint sromrev;
|
||||
uint boardtype;
|
||||
uint boardrev;
|
||||
uint boardvendor;
|
||||
u32 boardflags;
|
||||
u32 boardflags2;
|
||||
};
|
||||
|
||||
|
||||
extern struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp);
|
||||
extern struct brcms_phy_pub *wlc_phy_attach(struct shared_phy *sh,
|
||||
struct d11regs __iomem *regs,
|
||||
int bandtype, struct wiphy *wiphy);
|
||||
extern void wlc_phy_detach(struct brcms_phy_pub *ppi);
|
||||
|
||||
extern bool wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype,
|
||||
u16 *phyrev, u16 *radioid,
|
||||
u16 *radiover);
|
||||
extern bool wlc_phy_get_encore(struct brcms_phy_pub *pih);
|
||||
extern u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih);
|
||||
|
||||
extern void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *ppi, bool newstate);
|
||||
extern void wlc_phy_hw_state_upd(struct brcms_phy_pub *ppi, bool newstate);
|
||||
extern void wlc_phy_init(struct brcms_phy_pub *ppi, u16 chanspec);
|
||||
extern void wlc_phy_watchdog(struct brcms_phy_pub *ppi);
|
||||
extern int wlc_phy_down(struct brcms_phy_pub *ppi);
|
||||
extern u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih);
|
||||
extern void wlc_phy_cal_init(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init);
|
||||
|
||||
extern void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi,
|
||||
u16 chanspec);
|
||||
extern u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi,
|
||||
u16 newch);
|
||||
extern u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw);
|
||||
|
||||
extern int wlc_phy_rssi_compute(struct brcms_phy_pub *pih,
|
||||
struct d11rxhdr *rxh);
|
||||
extern void wlc_phy_por_inform(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_noise_sample_intr(struct brcms_phy_pub *ppi);
|
||||
extern bool wlc_phy_bist_check_phy(struct brcms_phy_pub *ppi);
|
||||
|
||||
extern void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag);
|
||||
|
||||
extern void wlc_phy_switch_radio(struct brcms_phy_pub *ppi, bool on);
|
||||
extern void wlc_phy_anacore(struct brcms_phy_pub *ppi, bool on);
|
||||
|
||||
|
||||
extern void wlc_phy_BSSinit(struct brcms_phy_pub *ppi, bool bonlyap, int rssi);
|
||||
|
||||
extern void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi,
|
||||
bool wide_filter);
|
||||
extern void wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band,
|
||||
struct brcms_chanvec *channels);
|
||||
extern u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi,
|
||||
uint band);
|
||||
|
||||
extern void wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint chan,
|
||||
u8 *_min_, u8 *_max_, int rate);
|
||||
extern void wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi,
|
||||
uint chan, u8 *_max_, u8 *_min_);
|
||||
extern void wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi,
|
||||
uint band, s32 *, s32 *, u32 *);
|
||||
extern void wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi,
|
||||
struct txpwr_limits *,
|
||||
u16 chanspec);
|
||||
extern int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm,
|
||||
bool *override);
|
||||
extern int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm,
|
||||
bool override);
|
||||
extern void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
|
||||
struct txpwr_limits *);
|
||||
extern bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi,
|
||||
bool hwpwrctrl);
|
||||
extern u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi);
|
||||
extern u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi);
|
||||
extern bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *pih);
|
||||
|
||||
extern void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain,
|
||||
u8 rxchain);
|
||||
extern void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain,
|
||||
u8 rxchain);
|
||||
extern void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain,
|
||||
u8 *rxchain);
|
||||
extern u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih);
|
||||
extern s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih,
|
||||
u16 chanspec);
|
||||
extern void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool val);
|
||||
|
||||
extern void wlc_phy_cal_perical(struct brcms_phy_pub *ppi, u8 reason);
|
||||
extern void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock);
|
||||
extern void wlc_phy_cal_papd_recal(struct brcms_phy_pub *ppi);
|
||||
|
||||
extern void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val);
|
||||
extern void wlc_phy_clear_tssi(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_hold_upd(struct brcms_phy_pub *ppi, u32 id, bool val);
|
||||
extern void wlc_phy_mute_upd(struct brcms_phy_pub *ppi, bool val, u32 flags);
|
||||
|
||||
extern void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type);
|
||||
|
||||
extern void wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi,
|
||||
struct tx_power *power, uint channel);
|
||||
|
||||
extern void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal);
|
||||
extern bool wlc_phy_test_ison(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi,
|
||||
u8 txpwr_percent);
|
||||
extern void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war);
|
||||
extern void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih,
|
||||
bool bf_preempt);
|
||||
extern void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap);
|
||||
|
||||
extern void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end);
|
||||
|
||||
extern void wlc_phy_freqtrack_start(struct brcms_phy_pub *ppi);
|
||||
extern void wlc_phy_freqtrack_end(struct brcms_phy_pub *ppi);
|
||||
|
||||
extern const u8 *wlc_phy_get_ofdm_rate_lookup(void);
|
||||
|
||||
extern s8 wlc_phy_get_tx_power_offset_by_mcs(struct brcms_phy_pub *ppi,
|
||||
u8 mcs_offset);
|
||||
extern s8 wlc_phy_get_tx_power_offset(struct brcms_phy_pub *ppi, u8 tbl_offset);
|
||||
#endif /* _BRCM_PHY_HAL_H_ */
|
1169
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
Normal file
1169
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h
Normal file
File diff suppressed because it is too large
Load Diff
5154
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
Normal file
5154
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
Normal file
File diff suppressed because it is too large
Load Diff
121
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h
Normal file
121
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 _BRCM_PHY_LCN_H_
|
||||
#define _BRCM_PHY_LCN_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
struct brcms_phy_lcnphy {
|
||||
int lcnphy_txrf_sp_9_override;
|
||||
u8 lcnphy_full_cal_channel;
|
||||
u8 lcnphy_cal_counter;
|
||||
u16 lcnphy_cal_temper;
|
||||
bool lcnphy_recal;
|
||||
|
||||
u8 lcnphy_rc_cap;
|
||||
u32 lcnphy_mcs20_po;
|
||||
|
||||
u8 lcnphy_tr_isolation_mid;
|
||||
u8 lcnphy_tr_isolation_low;
|
||||
u8 lcnphy_tr_isolation_hi;
|
||||
|
||||
u8 lcnphy_bx_arch;
|
||||
u8 lcnphy_rx_power_offset;
|
||||
u8 lcnphy_rssi_vf;
|
||||
u8 lcnphy_rssi_vc;
|
||||
u8 lcnphy_rssi_gs;
|
||||
u8 lcnphy_tssi_val;
|
||||
u8 lcnphy_rssi_vf_lowtemp;
|
||||
u8 lcnphy_rssi_vc_lowtemp;
|
||||
u8 lcnphy_rssi_gs_lowtemp;
|
||||
|
||||
u8 lcnphy_rssi_vf_hightemp;
|
||||
u8 lcnphy_rssi_vc_hightemp;
|
||||
u8 lcnphy_rssi_gs_hightemp;
|
||||
|
||||
s16 lcnphy_pa0b0;
|
||||
s16 lcnphy_pa0b1;
|
||||
s16 lcnphy_pa0b2;
|
||||
|
||||
u16 lcnphy_rawtempsense;
|
||||
u8 lcnphy_measPower;
|
||||
u8 lcnphy_tempsense_slope;
|
||||
u8 lcnphy_freqoffset_corr;
|
||||
u8 lcnphy_tempsense_option;
|
||||
u8 lcnphy_tempcorrx;
|
||||
bool lcnphy_iqcal_swp_dis;
|
||||
bool lcnphy_hw_iqcal_en;
|
||||
uint lcnphy_bandedge_corr;
|
||||
bool lcnphy_spurmod;
|
||||
u16 lcnphy_tssi_tx_cnt;
|
||||
u16 lcnphy_tssi_idx;
|
||||
u16 lcnphy_tssi_npt;
|
||||
|
||||
u16 lcnphy_target_tx_freq;
|
||||
s8 lcnphy_tx_power_idx_override;
|
||||
u16 lcnphy_noise_samples;
|
||||
|
||||
u32 lcnphy_papdRxGnIdx;
|
||||
u32 lcnphy_papd_rxGnCtrl_init;
|
||||
|
||||
u32 lcnphy_gain_idx_14_lowword;
|
||||
u32 lcnphy_gain_idx_14_hiword;
|
||||
u32 lcnphy_gain_idx_27_lowword;
|
||||
u32 lcnphy_gain_idx_27_hiword;
|
||||
s16 lcnphy_ofdmgainidxtableoffset;
|
||||
s16 lcnphy_dsssgainidxtableoffset;
|
||||
u32 lcnphy_tr_R_gain_val;
|
||||
u32 lcnphy_tr_T_gain_val;
|
||||
s8 lcnphy_input_pwr_offset_db;
|
||||
u16 lcnphy_Med_Low_Gain_db;
|
||||
u16 lcnphy_Very_Low_Gain_db;
|
||||
s8 lcnphy_lastsensed_temperature;
|
||||
s8 lcnphy_pkteng_rssi_slope;
|
||||
u8 lcnphy_saved_tx_user_target[TXP_NUM_RATES];
|
||||
u8 lcnphy_volt_winner;
|
||||
u8 lcnphy_volt_low;
|
||||
u8 lcnphy_54_48_36_24mbps_backoff;
|
||||
u8 lcnphy_11n_backoff;
|
||||
u8 lcnphy_lowerofdm;
|
||||
u8 lcnphy_cck;
|
||||
u8 lcnphy_psat_2pt3_detected;
|
||||
s32 lcnphy_lowest_Re_div_Im;
|
||||
s8 lcnphy_final_papd_cal_idx;
|
||||
u16 lcnphy_extstxctrl4;
|
||||
u16 lcnphy_extstxctrl0;
|
||||
u16 lcnphy_extstxctrl1;
|
||||
s16 lcnphy_cck_dig_filt_type;
|
||||
s16 lcnphy_ofdm_dig_filt_type;
|
||||
struct lcnphy_cal_results lcnphy_cal_results;
|
||||
|
||||
u8 lcnphy_psat_pwr;
|
||||
u8 lcnphy_psat_indx;
|
||||
s32 lcnphy_min_phase;
|
||||
u8 lcnphy_final_idx;
|
||||
u8 lcnphy_start_idx;
|
||||
u8 lcnphy_current_index;
|
||||
u16 lcnphy_logen_buf_1;
|
||||
u16 lcnphy_local_ovr_2;
|
||||
u16 lcnphy_local_oval_6;
|
||||
u16 lcnphy_local_oval_5;
|
||||
u16 lcnphy_logen_mixer_1;
|
||||
|
||||
u8 lcnphy_aci_stat;
|
||||
uint lcnphy_aci_start_time;
|
||||
s8 lcnphy_tx_power_offset[TXP_NUM_RATES];
|
||||
};
|
||||
#endif /* _BRCM_PHY_LCN_H_ */
|
28876
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
Normal file
28876
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
Normal file
File diff suppressed because it is too large
Load Diff
308
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c
Normal file
308
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.c
Normal file
@ -0,0 +1,308 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 "phy_qmath.h"
|
||||
|
||||
/*
|
||||
* Description: This function make 16 bit unsigned multiplication.
|
||||
* To fit the output into 16 bits the 32 bit multiplication result is right
|
||||
* shifted by 16 bits.
|
||||
*/
|
||||
u16 qm_mulu16(u16 op1, u16 op2)
|
||||
{
|
||||
return (u16) (((u32) op1 * (u32) op2) >> 16);
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function make 16 bit multiplication and return the result
|
||||
* in 16 bits. To fit the multiplication result into 16 bits the multiplication
|
||||
* result is right shifted by 15 bits. Right shifting 15 bits instead of 16 bits
|
||||
* is done to remove the extra sign bit formed due to the multiplication.
|
||||
* When both the 16bit inputs are 0x8000 then the output is saturated to
|
||||
* 0x7fffffff.
|
||||
*/
|
||||
s16 qm_muls16(s16 op1, s16 op2)
|
||||
{
|
||||
s32 result;
|
||||
if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000)
|
||||
result = 0x7fffffff;
|
||||
else
|
||||
result = ((s32) (op1) * (s32) (op2));
|
||||
|
||||
return (s16) (result >> 15);
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function add two 32 bit numbers and return the 32bit
|
||||
* result. If the result overflow 32 bits, the output will be saturated to
|
||||
* 32bits.
|
||||
*/
|
||||
s32 qm_add32(s32 op1, s32 op2)
|
||||
{
|
||||
s32 result;
|
||||
result = op1 + op2;
|
||||
if (op1 < 0 && op2 < 0 && result > 0)
|
||||
result = 0x80000000;
|
||||
else if (op1 > 0 && op2 > 0 && result < 0)
|
||||
result = 0x7fffffff;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function add two 16 bit numbers and return the 16bit
|
||||
* result. If the result overflow 16 bits, the output will be saturated to
|
||||
* 16bits.
|
||||
*/
|
||||
s16 qm_add16(s16 op1, s16 op2)
|
||||
{
|
||||
s16 result;
|
||||
s32 temp = (s32) op1 + (s32) op2;
|
||||
if (temp > (s32) 0x7fff)
|
||||
result = (s16) 0x7fff;
|
||||
else if (temp < (s32) 0xffff8000)
|
||||
result = (s16) 0xffff8000;
|
||||
else
|
||||
result = (s16) temp;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function make 16 bit subtraction and return the 16bit
|
||||
* result. If the result overflow 16 bits, the output will be saturated to
|
||||
* 16bits.
|
||||
*/
|
||||
s16 qm_sub16(s16 op1, s16 op2)
|
||||
{
|
||||
s16 result;
|
||||
s32 temp = (s32) op1 - (s32) op2;
|
||||
if (temp > (s32) 0x7fff)
|
||||
result = (s16) 0x7fff;
|
||||
else if (temp < (s32) 0xffff8000)
|
||||
result = (s16) 0xffff8000;
|
||||
else
|
||||
result = (s16) temp;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function make a 32 bit saturated left shift when the
|
||||
* specified shift is +ve. This function will make a 32 bit right shift when
|
||||
* the specified shift is -ve. This function return the result after shifting
|
||||
* operation.
|
||||
*/
|
||||
s32 qm_shl32(s32 op, int shift)
|
||||
{
|
||||
int i;
|
||||
s32 result;
|
||||
result = op;
|
||||
if (shift > 31)
|
||||
shift = 31;
|
||||
else if (shift < -31)
|
||||
shift = -31;
|
||||
if (shift >= 0) {
|
||||
for (i = 0; i < shift; i++)
|
||||
result = qm_add32(result, result);
|
||||
} else {
|
||||
result = result >> (-shift);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function make a 16 bit saturated left shift when the
|
||||
* specified shift is +ve. This function will make a 16 bit right shift when
|
||||
* the specified shift is -ve. This function return the result after shifting
|
||||
* operation.
|
||||
*/
|
||||
s16 qm_shl16(s16 op, int shift)
|
||||
{
|
||||
int i;
|
||||
s16 result;
|
||||
result = op;
|
||||
if (shift > 15)
|
||||
shift = 15;
|
||||
else if (shift < -15)
|
||||
shift = -15;
|
||||
if (shift > 0) {
|
||||
for (i = 0; i < shift; i++)
|
||||
result = qm_add16(result, result);
|
||||
} else {
|
||||
result = result >> (-shift);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function make a 16 bit right shift when shift is +ve.
|
||||
* This function make a 16 bit saturated left shift when shift is -ve. This
|
||||
* function return the result of the shift operation.
|
||||
*/
|
||||
s16 qm_shr16(s16 op, int shift)
|
||||
{
|
||||
return qm_shl16(op, -shift);
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: This function return the number of redundant sign bits in a
|
||||
* 32 bit number. Example: qm_norm32(0x00000080) = 23
|
||||
*/
|
||||
s16 qm_norm32(s32 op)
|
||||
{
|
||||
u16 u16extraSignBits;
|
||||
if (op == 0) {
|
||||
return 31;
|
||||
} else {
|
||||
u16extraSignBits = 0;
|
||||
while ((op >> 31) == (op >> 30)) {
|
||||
u16extraSignBits++;
|
||||
op = op << 1;
|
||||
}
|
||||
}
|
||||
return u16extraSignBits;
|
||||
}
|
||||
|
||||
/* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */
|
||||
static const s16 log_table[] = {
|
||||
0,
|
||||
1455,
|
||||
2866,
|
||||
4236,
|
||||
5568,
|
||||
6863,
|
||||
8124,
|
||||
9352,
|
||||
10549,
|
||||
11716,
|
||||
12855,
|
||||
13968,
|
||||
15055,
|
||||
16117,
|
||||
17156,
|
||||
18173,
|
||||
19168,
|
||||
20143,
|
||||
21098,
|
||||
22034,
|
||||
22952,
|
||||
23852,
|
||||
24736,
|
||||
25604,
|
||||
26455,
|
||||
27292,
|
||||
28114,
|
||||
28922,
|
||||
29717,
|
||||
30498,
|
||||
31267,
|
||||
32024
|
||||
};
|
||||
|
||||
#define LOG_TABLE_SIZE 32 /* log_table size */
|
||||
#define LOG2_LOG_TABLE_SIZE 5 /* log2(log_table size) */
|
||||
#define Q_LOG_TABLE 15 /* qformat of log_table */
|
||||
#define LOG10_2 19728 /* log10(2) in q.16 */
|
||||
|
||||
/*
|
||||
* Description:
|
||||
* This routine takes the input number N and its q format qN and compute
|
||||
* the log10(N). This routine first normalizes the input no N. Then N is in
|
||||
* mag*(2^x) format. mag is any number in the range 2^30-(2^31 - 1).
|
||||
* Then log2(mag * 2^x) = log2(mag) + x is computed. From that
|
||||
* log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed.
|
||||
* This routine looks the log2 value in the table considering
|
||||
* LOG2_LOG_TABLE_SIZE+1 MSBs. As the MSB is always 1, only next
|
||||
* LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup. Next 16 MSBs are used
|
||||
* for interpolation.
|
||||
* Inputs:
|
||||
* N - number to which log10 has to be found.
|
||||
* qN - q format of N
|
||||
* log10N - address where log10(N) will be written.
|
||||
* qLog10N - address where log10N qformat will be written.
|
||||
* Note/Problem:
|
||||
* For accurate results input should be in normalized or near normalized form.
|
||||
*/
|
||||
void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N)
|
||||
{
|
||||
s16 s16norm, s16tableIndex, s16errorApproximation;
|
||||
u16 u16offset;
|
||||
s32 s32log;
|
||||
|
||||
/* normalize the N. */
|
||||
s16norm = qm_norm32(N);
|
||||
N = N << s16norm;
|
||||
|
||||
/* The qformat of N after normalization.
|
||||
* -30 is added to treat the no as between 1.0 to 2.0
|
||||
* i.e. after adding the -30 to the qformat the decimal point will be
|
||||
* just rigtht of the MSB. (i.e. after sign bit and 1st MSB). i.e.
|
||||
* at the right side of 30th bit.
|
||||
*/
|
||||
qN = qN + s16norm - 30;
|
||||
|
||||
/* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the
|
||||
* MSB */
|
||||
s16tableIndex = (s16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE)));
|
||||
|
||||
/* remove the MSB. the MSB is always 1 after normalization. */
|
||||
s16tableIndex =
|
||||
s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1);
|
||||
|
||||
/* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */
|
||||
N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1);
|
||||
|
||||
/* take the offset as the 16 MSBS after table index.
|
||||
*/
|
||||
u16offset = (u16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16)));
|
||||
|
||||
/* look the log value in the table. */
|
||||
s32log = log_table[s16tableIndex]; /* q.15 format */
|
||||
|
||||
/* interpolate using the offset. q.15 format. */
|
||||
s16errorApproximation = (s16) qm_mulu16(u16offset,
|
||||
(u16) (log_table[s16tableIndex + 1] -
|
||||
log_table[s16tableIndex]));
|
||||
|
||||
/* q.15 format */
|
||||
s32log = qm_add16((s16) s32log, s16errorApproximation);
|
||||
|
||||
/* adjust for the qformat of the N as
|
||||
* log2(mag * 2^x) = log2(mag) + x
|
||||
*/
|
||||
s32log = qm_add32(s32log, ((s32) -qN) << 15); /* q.15 format */
|
||||
|
||||
/* normalize the result. */
|
||||
s16norm = qm_norm32(s32log);
|
||||
|
||||
/* bring all the important bits into lower 16 bits */
|
||||
/* q.15+s16norm-16 format */
|
||||
s32log = qm_shl32(s32log, s16norm - 16);
|
||||
|
||||
/* compute the log10(N) by multiplying log2(N) with log10(2).
|
||||
* as log10(mag * 2^x) = log2(mag * 2^x) * log10(2)
|
||||
* log10N in q.15+s16norm-16+1 (LOG10_2 is in q.16)
|
||||
*/
|
||||
*log10N = qm_muls16((s16) s32log, (s16) LOG10_2);
|
||||
|
||||
/* write the q format of the result. */
|
||||
*qLog10N = 15 + s16norm - 16 + 1;
|
||||
|
||||
return;
|
||||
}
|
42
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h
Normal file
42
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_qmath.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 _BRCM_QMATH_H_
|
||||
#define _BRCM_QMATH_H_
|
||||
|
||||
#include <types.h>
|
||||
|
||||
u16 qm_mulu16(u16 op1, u16 op2);
|
||||
|
||||
s16 qm_muls16(s16 op1, s16 op2);
|
||||
|
||||
s32 qm_add32(s32 op1, s32 op2);
|
||||
|
||||
s16 qm_add16(s16 op1, s16 op2);
|
||||
|
||||
s16 qm_sub16(s16 op1, s16 op2);
|
||||
|
||||
s32 qm_shl32(s32 op, int shift);
|
||||
|
||||
s16 qm_shl16(s16 op, int shift);
|
||||
|
||||
s16 qm_shr16(s16 op, int shift);
|
||||
|
||||
s16 qm_norm32(s32 op);
|
||||
|
||||
void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N);
|
||||
|
||||
#endif /* #ifndef _BRCM_QMATH_H_ */
|
1533
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h
Normal file
1533
drivers/net/wireless/brcm80211/brcmsmac/phy/phy_radio.h
Normal file
File diff suppressed because it is too large
Load Diff
167
drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h
Normal file
167
drivers/net/wireless/brcm80211/brcmsmac/phy/phyreg_n.h
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define NPHY_TBL_ID_GAIN1 0
|
||||
#define NPHY_TBL_ID_GAIN2 1
|
||||
#define NPHY_TBL_ID_GAINBITS1 2
|
||||
#define NPHY_TBL_ID_GAINBITS2 3
|
||||
#define NPHY_TBL_ID_GAINLIMIT 4
|
||||
#define NPHY_TBL_ID_WRSSIGainLimit 5
|
||||
#define NPHY_TBL_ID_RFSEQ 7
|
||||
#define NPHY_TBL_ID_AFECTRL 8
|
||||
#define NPHY_TBL_ID_ANTSWCTRLLUT 9
|
||||
#define NPHY_TBL_ID_IQLOCAL 15
|
||||
#define NPHY_TBL_ID_NOISEVAR 16
|
||||
#define NPHY_TBL_ID_SAMPLEPLAY 17
|
||||
#define NPHY_TBL_ID_CORE1TXPWRCTL 26
|
||||
#define NPHY_TBL_ID_CORE2TXPWRCTL 27
|
||||
#define NPHY_TBL_ID_CMPMETRICDATAWEIGHTTBL 30
|
||||
|
||||
#define NPHY_TBL_ID_EPSILONTBL0 31
|
||||
#define NPHY_TBL_ID_SCALARTBL0 32
|
||||
#define NPHY_TBL_ID_EPSILONTBL1 33
|
||||
#define NPHY_TBL_ID_SCALARTBL1 34
|
||||
|
||||
#define NPHY_TO_BPHY_OFF 0xc00
|
||||
|
||||
#define NPHY_BandControl_currentBand 0x0001
|
||||
#define RFCC_CHIP0_PU 0x0400
|
||||
#define RFCC_POR_FORCE 0x0040
|
||||
#define RFCC_OE_POR_FORCE 0x0080
|
||||
#define NPHY_RfctrlIntc_override_OFF 0
|
||||
#define NPHY_RfctrlIntc_override_TRSW 1
|
||||
#define NPHY_RfctrlIntc_override_PA 2
|
||||
#define NPHY_RfctrlIntc_override_EXT_LNA_PU 3
|
||||
#define NPHY_RfctrlIntc_override_EXT_LNA_GAIN 4
|
||||
#define RIFS_ENABLE 0x80
|
||||
#define BPHY_BAND_SEL_UP20 0x10
|
||||
#define NPHY_MLenable 0x02
|
||||
|
||||
#define NPHY_RfseqMode_CoreActv_override 0x0001
|
||||
#define NPHY_RfseqMode_Trigger_override 0x0002
|
||||
#define NPHY_RfseqCoreActv_TxRxChain0 (0x11)
|
||||
#define NPHY_RfseqCoreActv_TxRxChain1 (0x22)
|
||||
|
||||
#define NPHY_RfseqTrigger_rx2tx 0x0001
|
||||
#define NPHY_RfseqTrigger_tx2rx 0x0002
|
||||
#define NPHY_RfseqTrigger_updategainh 0x0004
|
||||
#define NPHY_RfseqTrigger_updategainl 0x0008
|
||||
#define NPHY_RfseqTrigger_updategainu 0x0010
|
||||
#define NPHY_RfseqTrigger_reset2rx 0x0020
|
||||
#define NPHY_RfseqStatus_rx2tx 0x0001
|
||||
#define NPHY_RfseqStatus_tx2rx 0x0002
|
||||
#define NPHY_RfseqStatus_updategainh 0x0004
|
||||
#define NPHY_RfseqStatus_updategainl 0x0008
|
||||
#define NPHY_RfseqStatus_updategainu 0x0010
|
||||
#define NPHY_RfseqStatus_reset2rx 0x0020
|
||||
#define NPHY_ClassifierCtrl_cck_en 0x1
|
||||
#define NPHY_ClassifierCtrl_ofdm_en 0x2
|
||||
#define NPHY_ClassifierCtrl_waited_en 0x4
|
||||
#define NPHY_IQFlip_ADC1 0x0001
|
||||
#define NPHY_IQFlip_ADC2 0x0010
|
||||
#define NPHY_sampleCmd_STOP 0x0002
|
||||
|
||||
#define RX_GF_OR_MM 0x0004
|
||||
#define RX_GF_MM_AUTO 0x0100
|
||||
|
||||
#define NPHY_iqloCalCmdGctl_IQLO_CAL_EN 0x8000
|
||||
|
||||
#define NPHY_IqestCmd_iqstart 0x1
|
||||
#define NPHY_IqestCmd_iqMode 0x2
|
||||
|
||||
#define NPHY_TxPwrCtrlCmd_pwrIndex_init 0x40
|
||||
#define NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 0x19
|
||||
|
||||
#define PRIM_SEL_UP20 0x8000
|
||||
|
||||
#define NPHY_RFSEQ_RX2TX 0x0
|
||||
#define NPHY_RFSEQ_TX2RX 0x1
|
||||
#define NPHY_RFSEQ_RESET2RX 0x2
|
||||
#define NPHY_RFSEQ_UPDATEGAINH 0x3
|
||||
#define NPHY_RFSEQ_UPDATEGAINL 0x4
|
||||
#define NPHY_RFSEQ_UPDATEGAINU 0x5
|
||||
|
||||
#define NPHY_RFSEQ_CMD_NOP 0x0
|
||||
#define NPHY_RFSEQ_CMD_RXG_FBW 0x1
|
||||
#define NPHY_RFSEQ_CMD_TR_SWITCH 0x2
|
||||
#define NPHY_RFSEQ_CMD_EXT_PA 0x3
|
||||
#define NPHY_RFSEQ_CMD_RXPD_TXPD 0x4
|
||||
#define NPHY_RFSEQ_CMD_TX_GAIN 0x5
|
||||
#define NPHY_RFSEQ_CMD_RX_GAIN 0x6
|
||||
#define NPHY_RFSEQ_CMD_SET_HPF_BW 0x7
|
||||
#define NPHY_RFSEQ_CMD_CLR_HIQ_DIS 0x8
|
||||
#define NPHY_RFSEQ_CMD_END 0xf
|
||||
|
||||
#define NPHY_REV3_RFSEQ_CMD_NOP 0x0
|
||||
#define NPHY_REV3_RFSEQ_CMD_RXG_FBW 0x1
|
||||
#define NPHY_REV3_RFSEQ_CMD_TR_SWITCH 0x2
|
||||
#define NPHY_REV3_RFSEQ_CMD_INT_PA_PU 0x3
|
||||
#define NPHY_REV3_RFSEQ_CMD_EXT_PA 0x4
|
||||
#define NPHY_REV3_RFSEQ_CMD_RXPD_TXPD 0x5
|
||||
#define NPHY_REV3_RFSEQ_CMD_TX_GAIN 0x6
|
||||
#define NPHY_REV3_RFSEQ_CMD_RX_GAIN 0x7
|
||||
#define NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS 0x8
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_HPF_H_HPC 0x9
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_LPF_H_HPC 0xa
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_HPF_M_HPC 0xb
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_LPF_M_HPC 0xc
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_HPF_L_HPC 0xd
|
||||
#define NPHY_REV3_RFSEQ_CMD_SET_LPF_L_HPC 0xe
|
||||
#define NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS 0xf
|
||||
#define NPHY_REV3_RFSEQ_CMD_END 0x1f
|
||||
|
||||
#define NPHY_RSSI_SEL_W1 0x0
|
||||
#define NPHY_RSSI_SEL_W2 0x1
|
||||
#define NPHY_RSSI_SEL_NB 0x2
|
||||
#define NPHY_RSSI_SEL_IQ 0x3
|
||||
#define NPHY_RSSI_SEL_TSSI_2G 0x4
|
||||
#define NPHY_RSSI_SEL_TSSI_5G 0x5
|
||||
#define NPHY_RSSI_SEL_TBD 0x6
|
||||
|
||||
#define NPHY_RAIL_I 0x0
|
||||
#define NPHY_RAIL_Q 0x1
|
||||
|
||||
#define NPHY_FORCESIG_DECODEGATEDCLKS 0x8
|
||||
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_rxrf_pu 0x0
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_rx_pu 0x1
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_tx_pu 0x2
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_rxgain 0x3
|
||||
#define NPHY_REV7_RfctrlOverride_cmd_txgain 0x4
|
||||
|
||||
#define NPHY_REV7_RXGAINCODE_RFMXGAIN_MASK 0x000ff
|
||||
#define NPHY_REV7_RXGAINCODE_LPFGAIN_MASK 0x0ff00
|
||||
#define NPHY_REV7_RXGAINCODE_DVGAGAIN_MASK 0xf0000
|
||||
|
||||
#define NPHY_REV7_TXGAINCODE_TGAIN_MASK 0x7fff
|
||||
#define NPHY_REV7_TXGAINCODE_LPFGAIN_MASK 0x8000
|
||||
#define NPHY_REV7_TXGAINCODE_BIQ0GAIN_SHIFT 14
|
||||
|
||||
#define NPHY_REV7_RFCTRLOVERRIDE_ID0 0x0
|
||||
#define NPHY_REV7_RFCTRLOVERRIDE_ID1 0x1
|
||||
#define NPHY_REV7_RFCTRLOVERRIDE_ID2 0x2
|
||||
|
||||
#define NPHY_IqestIqAccLo(core) ((core == 0) ? 0x12c : 0x134)
|
||||
|
||||
#define NPHY_IqestIqAccHi(core) ((core == 0) ? 0x12d : 0x135)
|
||||
|
||||
#define NPHY_IqestipwrAccLo(core) ((core == 0) ? 0x12e : 0x136)
|
||||
|
||||
#define NPHY_IqestipwrAccHi(core) ((core == 0) ? 0x12f : 0x137)
|
||||
|
||||
#define NPHY_IqestqpwrAccLo(core) ((core == 0) ? 0x130 : 0x138)
|
||||
|
||||
#define NPHY_IqestqpwrAccHi(core) ((core == 0) ? 0x131 : 0x139)
|
3250
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
Normal file
3250
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
Normal file
File diff suppressed because it is too large
Load Diff
54
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
Normal file
54
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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 <types.h>
|
||||
#include "phy_int.h"
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_rev0[];
|
||||
extern const u32 dot11lcnphytbl_rx_gain_info_sz_rev0;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_epa_combo;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa;
|
||||
extern const struct phytbl_info dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250;
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_info_rev0[];
|
||||
extern const u32 dot11lcnphytbl_info_sz_rev0;
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_2G_rev2[];
|
||||
extern const u32 dot11lcnphytbl_rx_gain_info_2G_rev2_sz;
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_5G_rev2[];
|
||||
extern const u32 dot11lcnphytbl_rx_gain_info_5G_rev2_sz;
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_2G_rev2[];
|
||||
|
||||
extern const struct phytbl_info dot11lcnphytbl_rx_gain_info_extlna_5G_rev2[];
|
||||
|
||||
struct lcnphy_tx_gain_tbl_entry {
|
||||
unsigned char gm;
|
||||
unsigned char pga;
|
||||
unsigned char pad;
|
||||
unsigned char dac;
|
||||
unsigned char bb_mult;
|
||||
};
|
||||
|
||||
extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[];
|
||||
|
||||
extern const struct
|
||||
lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[];
|
||||
|
||||
extern const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[];
|
10630
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c
Normal file
10630
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.c
Normal file
File diff suppressed because it is too large
Load Diff
50
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h
Normal file
50
drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_n.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define ANT_SWCTRL_TBL_REV3_IDX (0)
|
||||
|
||||
#include <types.h>
|
||||
#include "phy_int.h"
|
||||
|
||||
extern const struct phytbl_info mimophytbl_info_rev0[],
|
||||
mimophytbl_info_rev0_volatile[];
|
||||
|
||||
extern const u32 mimophytbl_info_sz_rev0,
|
||||
mimophytbl_info_sz_rev0_volatile;
|
||||
|
||||
extern const struct phytbl_info mimophytbl_info_rev3[],
|
||||
mimophytbl_info_rev3_volatile[],
|
||||
mimophytbl_info_rev3_volatile1[],
|
||||
mimophytbl_info_rev3_volatile2[],
|
||||
mimophytbl_info_rev3_volatile3[];
|
||||
|
||||
extern const u32 mimophytbl_info_sz_rev3,
|
||||
mimophytbl_info_sz_rev3_volatile,
|
||||
mimophytbl_info_sz_rev3_volatile1,
|
||||
mimophytbl_info_sz_rev3_volatile2,
|
||||
mimophytbl_info_sz_rev3_volatile3;
|
||||
|
||||
extern const u32 noise_var_tbl_rev3[];
|
||||
|
||||
extern const struct phytbl_info mimophytbl_info_rev7[];
|
||||
|
||||
extern const u32 mimophytbl_info_sz_rev7;
|
||||
|
||||
extern const u32 noise_var_tbl_rev7[];
|
||||
|
||||
extern const struct phytbl_info mimophytbl_info_rev16[];
|
||||
|
||||
extern const u32 mimophytbl_info_sz_rev16;
|
225
drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
Normal file
225
drivers/net/wireless/brcm80211/brcmsmac/phy_shim.c
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is "two-way" interface, acting as the SHIM layer between driver
|
||||
* and PHY layer. The driver can optionally call this translation layer
|
||||
* to do some preprocessing, then reach PHY. On the PHY->driver direction,
|
||||
* all calls go through this layer since PHY doesn't have access to the
|
||||
* driver's brcms_hardware pointer.
|
||||
*/
|
||||
#include <linux/slab.h>
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "main.h"
|
||||
#include "mac80211_if.h"
|
||||
#include "phy_shim.h"
|
||||
|
||||
/* PHY SHIM module specific state */
|
||||
struct phy_shim_info {
|
||||
struct brcms_hardware *wlc_hw; /* pointer to main wlc_hw structure */
|
||||
struct brcms_c_info *wlc; /* pointer to main wlc structure */
|
||||
struct brcms_info *wl; /* pointer to os-specific private state */
|
||||
};
|
||||
|
||||
struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
|
||||
struct brcms_info *wl,
|
||||
struct brcms_c_info *wlc) {
|
||||
struct phy_shim_info *physhim = NULL;
|
||||
|
||||
physhim = kzalloc(sizeof(struct phy_shim_info), GFP_ATOMIC);
|
||||
if (!physhim)
|
||||
return NULL;
|
||||
|
||||
physhim->wlc_hw = wlc_hw;
|
||||
physhim->wlc = wlc;
|
||||
physhim->wl = wl;
|
||||
|
||||
return physhim;
|
||||
}
|
||||
|
||||
void wlc_phy_shim_detach(struct phy_shim_info *physhim)
|
||||
{
|
||||
kfree(physhim);
|
||||
}
|
||||
|
||||
struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
|
||||
void (*fn)(struct brcms_phy *pi),
|
||||
void *arg, const char *name)
|
||||
{
|
||||
return (struct wlapi_timer *)
|
||||
brcms_init_timer(physhim->wl, (void (*)(void *))fn,
|
||||
arg, name);
|
||||
}
|
||||
|
||||
void wlapi_free_timer(struct wlapi_timer *t)
|
||||
{
|
||||
brcms_free_timer((struct brcms_timer *)t);
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic)
|
||||
{
|
||||
brcms_add_timer((struct brcms_timer *)t, ms, periodic);
|
||||
}
|
||||
|
||||
bool wlapi_del_timer(struct wlapi_timer *t)
|
||||
{
|
||||
return brcms_del_timer((struct brcms_timer *)t);
|
||||
}
|
||||
|
||||
void wlapi_intrson(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_intrson(physhim->wl);
|
||||
}
|
||||
|
||||
u32 wlapi_intrsoff(struct phy_shim_info *physhim)
|
||||
{
|
||||
return brcms_intrsoff(physhim->wl);
|
||||
}
|
||||
|
||||
void wlapi_intrsrestore(struct phy_shim_info *physhim, u32 macintmask)
|
||||
{
|
||||
brcms_intrsrestore(physhim->wl, macintmask);
|
||||
}
|
||||
|
||||
void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset, u16 v)
|
||||
{
|
||||
brcms_b_write_shm(physhim->wlc_hw, offset, v);
|
||||
}
|
||||
|
||||
u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset)
|
||||
{
|
||||
return brcms_b_read_shm(physhim->wlc_hw, offset);
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx, u16 mask,
|
||||
u16 val, int bands)
|
||||
{
|
||||
brcms_b_mhf(physhim->wlc_hw, idx, mask, val, bands);
|
||||
}
|
||||
|
||||
void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags)
|
||||
{
|
||||
brcms_b_corereset(physhim->wlc_hw, flags);
|
||||
}
|
||||
|
||||
void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_c_suspend_mac_and_wait(physhim->wlc);
|
||||
}
|
||||
|
||||
void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode)
|
||||
{
|
||||
brcms_b_switch_macfreq(physhim->wlc_hw, spurmode);
|
||||
}
|
||||
|
||||
void wlapi_enable_mac(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_c_enable_mac(physhim->wlc);
|
||||
}
|
||||
|
||||
void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask, u32 val)
|
||||
{
|
||||
brcms_b_mctrl(physhim->wlc_hw, mask, val);
|
||||
}
|
||||
|
||||
void wlapi_bmac_phy_reset(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_b_phy_reset(physhim->wlc_hw);
|
||||
}
|
||||
|
||||
void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw)
|
||||
{
|
||||
brcms_b_bw_set(physhim->wlc_hw, bw);
|
||||
}
|
||||
|
||||
u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim)
|
||||
{
|
||||
return brcms_b_get_txant(physhim->wlc_hw);
|
||||
}
|
||||
|
||||
void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk)
|
||||
{
|
||||
brcms_b_phyclk_fgc(physhim->wlc_hw, clk);
|
||||
}
|
||||
|
||||
void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk)
|
||||
{
|
||||
brcms_b_macphyclk_set(physhim->wlc_hw, clk);
|
||||
}
|
||||
|
||||
void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on)
|
||||
{
|
||||
brcms_b_core_phypll_ctl(physhim->wlc_hw, on);
|
||||
}
|
||||
|
||||
void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_b_core_phypll_reset(physhim->wlc_hw);
|
||||
}
|
||||
|
||||
void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_c_ucode_wake_override_set(physhim->wlc_hw,
|
||||
BRCMS_WAKE_OVERRIDE_PHYREG);
|
||||
}
|
||||
|
||||
void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *physhim)
|
||||
{
|
||||
brcms_c_ucode_wake_override_clear(physhim->wlc_hw,
|
||||
BRCMS_WAKE_OVERRIDE_PHYREG);
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int offset,
|
||||
int len, void *buf)
|
||||
{
|
||||
brcms_b_write_template_ram(physhim->wlc_hw, offset, len, buf);
|
||||
}
|
||||
|
||||
u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim, u8 rate)
|
||||
{
|
||||
return brcms_b_rate_shm_offset(physhim->wlc_hw, rate);
|
||||
}
|
||||
|
||||
void wlapi_ucode_sample_init(struct phy_shim_info *physhim)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint offset, void *buf,
|
||||
int len, u32 sel)
|
||||
{
|
||||
brcms_b_copyfrom_objmem(physhim->wlc_hw, offset, buf, len, sel);
|
||||
}
|
||||
|
||||
void
|
||||
wlapi_copyto_objmem(struct phy_shim_info *physhim, uint offset, const void *buf,
|
||||
int l, u32 sel)
|
||||
{
|
||||
brcms_b_copyto_objmem(physhim->wlc_hw, offset, buf, l, sel);
|
||||
}
|
||||
|
||||
char *wlapi_getvar(struct phy_shim_info *physhim, enum brcms_srom_id id)
|
||||
{
|
||||
return getvar(physhim->wlc_hw->sih, id);
|
||||
}
|
||||
int wlapi_getintvar(struct phy_shim_info *physhim, enum brcms_srom_id id)
|
||||
{
|
||||
return getintvar(physhim->wlc_hw->sih, id);
|
||||
}
|
182
drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
Normal file
182
drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* phy_shim.h: stuff defined in phy_shim.c and included only by the phy
|
||||
*/
|
||||
|
||||
#ifndef _BRCM_PHY_SHIM_H_
|
||||
#define _BRCM_PHY_SHIM_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#define RADAR_TYPE_NONE 0 /* Radar type None */
|
||||
#define RADAR_TYPE_ETSI_1 1 /* ETSI 1 Radar type */
|
||||
#define RADAR_TYPE_ETSI_2 2 /* ETSI 2 Radar type */
|
||||
#define RADAR_TYPE_ETSI_3 3 /* ETSI 3 Radar type */
|
||||
#define RADAR_TYPE_ITU_E 4 /* ITU E Radar type */
|
||||
#define RADAR_TYPE_ITU_K 5 /* ITU K Radar type */
|
||||
#define RADAR_TYPE_UNCLASSIFIED 6 /* Unclassified Radar type */
|
||||
#define RADAR_TYPE_BIN5 7 /* long pulse radar type */
|
||||
#define RADAR_TYPE_STG2 8 /* staggered-2 radar */
|
||||
#define RADAR_TYPE_STG3 9 /* staggered-3 radar */
|
||||
#define RADAR_TYPE_FRA 10 /* French radar */
|
||||
|
||||
/* French radar pulse widths */
|
||||
#define FRA_T1_20MHZ 52770
|
||||
#define FRA_T2_20MHZ 61538
|
||||
#define FRA_T3_20MHZ 66002
|
||||
#define FRA_T1_40MHZ 105541
|
||||
#define FRA_T2_40MHZ 123077
|
||||
#define FRA_T3_40MHZ 132004
|
||||
#define FRA_ERR_20MHZ 60
|
||||
#define FRA_ERR_40MHZ 120
|
||||
|
||||
#define ANTSEL_NA 0 /* No boardlevel selection available */
|
||||
#define ANTSEL_2x4 1 /* 2x4 boardlevel selection available */
|
||||
#define ANTSEL_2x3 2 /* 2x3 CB2 boardlevel selection available */
|
||||
|
||||
/* Rx Antenna diversity control values */
|
||||
#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */
|
||||
#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */
|
||||
#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */
|
||||
#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */
|
||||
#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */
|
||||
#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */
|
||||
|
||||
#define WL_ANT_RX_MAX 2 /* max 2 receive antennas */
|
||||
#define WL_ANT_HT_RX_MAX 3 /* max 3 receive antennas/cores */
|
||||
#define WL_ANT_IDX_1 0 /* antenna index 1 */
|
||||
#define WL_ANT_IDX_2 1 /* antenna index 2 */
|
||||
|
||||
/* values for n_preamble_type */
|
||||
#define BRCMS_N_PREAMBLE_MIXEDMODE 0
|
||||
#define BRCMS_N_PREAMBLE_GF 1
|
||||
#define BRCMS_N_PREAMBLE_GF_BRCM 2
|
||||
|
||||
#define WL_TX_POWER_RATES_LEGACY 45
|
||||
#define WL_TX_POWER_MCS20_FIRST 12
|
||||
#define WL_TX_POWER_MCS20_NUM 16
|
||||
#define WL_TX_POWER_MCS40_FIRST 28
|
||||
#define WL_TX_POWER_MCS40_NUM 17
|
||||
|
||||
|
||||
#define WL_TX_POWER_RATES 101
|
||||
#define WL_TX_POWER_CCK_FIRST 0
|
||||
#define WL_TX_POWER_CCK_NUM 4
|
||||
/* Index for first 20MHz OFDM SISO rate */
|
||||
#define WL_TX_POWER_OFDM_FIRST 4
|
||||
/* Index for first 20MHz OFDM CDD rate */
|
||||
#define WL_TX_POWER_OFDM20_CDD_FIRST 12
|
||||
/* Index for first 40MHz OFDM SISO rate */
|
||||
#define WL_TX_POWER_OFDM40_SISO_FIRST 52
|
||||
/* Index for first 40MHz OFDM CDD rate */
|
||||
#define WL_TX_POWER_OFDM40_CDD_FIRST 60
|
||||
#define WL_TX_POWER_OFDM_NUM 8
|
||||
/* Index for first 20MHz MCS SISO rate */
|
||||
#define WL_TX_POWER_MCS20_SISO_FIRST 20
|
||||
/* Index for first 20MHz MCS CDD rate */
|
||||
#define WL_TX_POWER_MCS20_CDD_FIRST 28
|
||||
/* Index for first 20MHz MCS STBC rate */
|
||||
#define WL_TX_POWER_MCS20_STBC_FIRST 36
|
||||
/* Index for first 20MHz MCS SDM rate */
|
||||
#define WL_TX_POWER_MCS20_SDM_FIRST 44
|
||||
/* Index for first 40MHz MCS SISO rate */
|
||||
#define WL_TX_POWER_MCS40_SISO_FIRST 68
|
||||
/* Index for first 40MHz MCS CDD rate */
|
||||
#define WL_TX_POWER_MCS40_CDD_FIRST 76
|
||||
/* Index for first 40MHz MCS STBC rate */
|
||||
#define WL_TX_POWER_MCS40_STBC_FIRST 84
|
||||
/* Index for first 40MHz MCS SDM rate */
|
||||
#define WL_TX_POWER_MCS40_SDM_FIRST 92
|
||||
#define WL_TX_POWER_MCS_1_STREAM_NUM 8
|
||||
#define WL_TX_POWER_MCS_2_STREAM_NUM 8
|
||||
/* Index for 40MHz rate MCS 32 */
|
||||
#define WL_TX_POWER_MCS_32 100
|
||||
#define WL_TX_POWER_MCS_32_NUM 1
|
||||
|
||||
/* sslpnphy specifics */
|
||||
/* Index for first 20MHz MCS SISO rate */
|
||||
#define WL_TX_POWER_MCS20_SISO_FIRST_SSN 12
|
||||
|
||||
/* struct tx_power::flags bits */
|
||||
#define WL_TX_POWER_F_ENABLED 1
|
||||
#define WL_TX_POWER_F_HW 2
|
||||
#define WL_TX_POWER_F_MIMO 4
|
||||
#define WL_TX_POWER_F_SISO 8
|
||||
|
||||
/* values to force tx/rx chain */
|
||||
#define BRCMS_N_TXRX_CHAIN0 0
|
||||
#define BRCMS_N_TXRX_CHAIN1 1
|
||||
|
||||
struct brcms_phy;
|
||||
|
||||
extern struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw,
|
||||
struct brcms_info *wl,
|
||||
struct brcms_c_info *wlc);
|
||||
extern void wlc_phy_shim_detach(struct phy_shim_info *physhim);
|
||||
|
||||
/* PHY to WL utility functions */
|
||||
extern struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim,
|
||||
void (*fn) (struct brcms_phy *pi),
|
||||
void *arg, const char *name);
|
||||
extern void wlapi_free_timer(struct wlapi_timer *t);
|
||||
extern void wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic);
|
||||
extern bool wlapi_del_timer(struct wlapi_timer *t);
|
||||
extern void wlapi_intrson(struct phy_shim_info *physhim);
|
||||
extern u32 wlapi_intrsoff(struct phy_shim_info *physhim);
|
||||
extern void wlapi_intrsrestore(struct phy_shim_info *physhim,
|
||||
u32 macintmask);
|
||||
|
||||
extern void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset,
|
||||
u16 v);
|
||||
extern u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset);
|
||||
extern void wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx,
|
||||
u16 mask, u16 val, int bands);
|
||||
extern void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags);
|
||||
extern void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim);
|
||||
extern void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode);
|
||||
extern void wlapi_enable_mac(struct phy_shim_info *physhim);
|
||||
extern void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask,
|
||||
u32 val);
|
||||
extern void wlapi_bmac_phy_reset(struct phy_shim_info *physhim);
|
||||
extern void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw);
|
||||
extern void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk);
|
||||
extern void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk);
|
||||
extern void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on);
|
||||
extern void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim);
|
||||
extern void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *
|
||||
physhim);
|
||||
extern void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *
|
||||
physhim);
|
||||
extern void wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int o,
|
||||
int len, void *buf);
|
||||
extern u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim,
|
||||
u8 rate);
|
||||
extern void wlapi_ucode_sample_init(struct phy_shim_info *physhim);
|
||||
extern void wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint,
|
||||
void *buf, int, u32 sel);
|
||||
extern void wlapi_copyto_objmem(struct phy_shim_info *physhim, uint,
|
||||
const void *buf, int, u32);
|
||||
|
||||
extern void wlapi_high_update_phy_mode(struct phy_shim_info *physhim,
|
||||
u32 phy_mode);
|
||||
extern u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim);
|
||||
extern char *wlapi_getvar(struct phy_shim_info *physhim, enum brcms_srom_id id);
|
||||
extern int wlapi_getintvar(struct phy_shim_info *physhim,
|
||||
enum brcms_srom_id id);
|
||||
|
||||
#endif /* _BRCM_PHY_SHIM_H_ */
|
458
drivers/net/wireless/brcm80211/brcmsmac/pmu.c
Normal file
458
drivers/net/wireless/brcm80211/brcmsmac/pmu.c
Normal file
@ -0,0 +1,458 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Broadcom Corporation
|
||||
*
|
||||
* 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 <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <brcm_hw_ids.h>
|
||||
#include <chipcommon.h>
|
||||
#include <brcmu_utils.h>
|
||||
#include "pub.h"
|
||||
#include "aiutils.h"
|
||||
#include "pmu.h"
|
||||
|
||||
/*
|
||||
* external LPO crystal frequency
|
||||
*/
|
||||
#define EXT_ILP_HZ 32768
|
||||
|
||||
/*
|
||||
* Duration for ILP clock frequency measurment in milliseconds
|
||||
*
|
||||
* remark: 1000 must be an integer multiple of this duration
|
||||
*/
|
||||
#define ILP_CALC_DUR 10
|
||||
|
||||
/* Fields in pmucontrol */
|
||||
#define PCTL_ILP_DIV_MASK 0xffff0000
|
||||
#define PCTL_ILP_DIV_SHIFT 16
|
||||
#define PCTL_PLL_PLLCTL_UPD 0x00000400 /* rev 2 */
|
||||
#define PCTL_NOILP_ON_WAIT 0x00000200 /* rev 1 */
|
||||
#define PCTL_HT_REQ_EN 0x00000100
|
||||
#define PCTL_ALP_REQ_EN 0x00000080
|
||||
#define PCTL_XTALFREQ_MASK 0x0000007c
|
||||
#define PCTL_XTALFREQ_SHIFT 2
|
||||
#define PCTL_ILP_DIV_EN 0x00000002
|
||||
#define PCTL_LPO_SEL 0x00000001
|
||||
|
||||
/* ILP clock */
|
||||
#define ILP_CLOCK 32000
|
||||
|
||||
/* ALP clock on pre-PMU chips */
|
||||
#define ALP_CLOCK 20000000
|
||||
|
||||
/* pmustatus */
|
||||
#define PST_EXTLPOAVAIL 0x0100
|
||||
#define PST_WDRESET 0x0080
|
||||
#define PST_INTPEND 0x0040
|
||||
#define PST_SBCLKST 0x0030
|
||||
#define PST_SBCLKST_ILP 0x0010
|
||||
#define PST_SBCLKST_ALP 0x0020
|
||||
#define PST_SBCLKST_HT 0x0030
|
||||
#define PST_ALPAVAIL 0x0008
|
||||
#define PST_HTAVAIL 0x0004
|
||||
#define PST_RESINIT 0x0003
|
||||
|
||||
/* PMU resource bit position */
|
||||
#define PMURES_BIT(bit) (1 << (bit))
|
||||
|
||||
/* PMU corerev and chip specific PLL controls.
|
||||
* PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary
|
||||
* number to differentiate different PLLs controlled by the same PMU rev.
|
||||
*/
|
||||
/* pllcontrol registers:
|
||||
* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>,
|
||||
* p1div, p2div, _bypass_sdmod
|
||||
*/
|
||||
#define PMU1_PLL0_PLLCTL0 0
|
||||
#define PMU1_PLL0_PLLCTL1 1
|
||||
#define PMU1_PLL0_PLLCTL2 2
|
||||
#define PMU1_PLL0_PLLCTL3 3
|
||||
#define PMU1_PLL0_PLLCTL4 4
|
||||
#define PMU1_PLL0_PLLCTL5 5
|
||||
|
||||
/* pmu XtalFreqRatio */
|
||||
#define PMU_XTALFREQ_REG_ILPCTR_MASK 0x00001FFF
|
||||
#define PMU_XTALFREQ_REG_MEASURE_MASK 0x80000000
|
||||
#define PMU_XTALFREQ_REG_MEASURE_SHIFT 31
|
||||
|
||||
/* 4313 resources */
|
||||
#define RES4313_BB_PU_RSRC 0
|
||||
#define RES4313_ILP_REQ_RSRC 1
|
||||
#define RES4313_XTAL_PU_RSRC 2
|
||||
#define RES4313_ALP_AVAIL_RSRC 3
|
||||
#define RES4313_RADIO_PU_RSRC 4
|
||||
#define RES4313_BG_PU_RSRC 5
|
||||
#define RES4313_VREG1P4_PU_RSRC 6
|
||||
#define RES4313_AFE_PWRSW_RSRC 7
|
||||
#define RES4313_RX_PWRSW_RSRC 8
|
||||
#define RES4313_TX_PWRSW_RSRC 9
|
||||
#define RES4313_BB_PWRSW_RSRC 10
|
||||
#define RES4313_SYNTH_PWRSW_RSRC 11
|
||||
#define RES4313_MISC_PWRSW_RSRC 12
|
||||
#define RES4313_BB_PLL_PWRSW_RSRC 13
|
||||
#define RES4313_HT_AVAIL_RSRC 14
|
||||
#define RES4313_MACPHY_CLK_AVAIL_RSRC 15
|
||||
|
||||
/* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
|
||||
static void si_pmu_res_masks(struct si_pub *sih, u32 * pmin, u32 * pmax)
|
||||
{
|
||||
u32 min_mask = 0, max_mask = 0;
|
||||
uint rsrcs;
|
||||
|
||||
/* # resources */
|
||||
rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
|
||||
|
||||
/* determine min/max rsrc masks */
|
||||
switch (sih->chip) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
/* ??? */
|
||||
break;
|
||||
|
||||
case BCM4313_CHIP_ID:
|
||||
min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
|
||||
PMURES_BIT(RES4313_XTAL_PU_RSRC) |
|
||||
PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
|
||||
PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
|
||||
max_mask = 0xffff;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
*pmin = min_mask;
|
||||
*pmax = max_mask;
|
||||
}
|
||||
|
||||
static void
|
||||
si_pmu_spuravoid_pllupdate(struct si_pub *sih, struct chipcregs __iomem *cc,
|
||||
u8 spuravoid)
|
||||
{
|
||||
u32 tmp = 0;
|
||||
|
||||
switch (sih->chip) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
if (spuravoid == 1) {
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
|
||||
W_REG(&cc->pllcontrol_data, 0x11500010);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
|
||||
W_REG(&cc->pllcontrol_data, 0x000C0C06);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
|
||||
W_REG(&cc->pllcontrol_data, 0x0F600a08);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
|
||||
W_REG(&cc->pllcontrol_data, 0x00000000);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
|
||||
W_REG(&cc->pllcontrol_data, 0x2001E920);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
|
||||
W_REG(&cc->pllcontrol_data, 0x88888815);
|
||||
} else {
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
|
||||
W_REG(&cc->pllcontrol_data, 0x11100010);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
|
||||
W_REG(&cc->pllcontrol_data, 0x000c0c06);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
|
||||
W_REG(&cc->pllcontrol_data, 0x03000a08);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
|
||||
W_REG(&cc->pllcontrol_data, 0x00000000);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
|
||||
W_REG(&cc->pllcontrol_data, 0x200005c0);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
|
||||
W_REG(&cc->pllcontrol_data, 0x88888815);
|
||||
}
|
||||
tmp = 1 << 10;
|
||||
break;
|
||||
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
|
||||
W_REG(&cc->pllcontrol_data, 0x11100008);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
|
||||
W_REG(&cc->pllcontrol_data, 0x0c000c06);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
|
||||
W_REG(&cc->pllcontrol_data, 0x03000a08);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
|
||||
W_REG(&cc->pllcontrol_data, 0x00000000);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
|
||||
W_REG(&cc->pllcontrol_data, 0x200005c0);
|
||||
W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
|
||||
W_REG(&cc->pllcontrol_data, 0x88888855);
|
||||
|
||||
tmp = 1 << 10;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* bail out */
|
||||
return;
|
||||
}
|
||||
|
||||
tmp |= R_REG(&cc->pmucontrol);
|
||||
W_REG(&cc->pmucontrol, tmp);
|
||||
}
|
||||
|
||||
u16 si_pmu_fast_pwrup_delay(struct si_pub *sih)
|
||||
{
|
||||
uint delay = PMU_MAX_TRANSITION_DLY;
|
||||
|
||||
switch (sih->chip) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
case BCM4313_CHIP_ID:
|
||||
delay = 3700;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return (u16) delay;
|
||||
}
|
||||
|
||||
void si_pmu_sprom_enable(struct si_pub *sih, bool enable)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
/* Read/write a chipcontrol reg */
|
||||
u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
|
||||
{
|
||||
ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, chipcontrol_addr),
|
||||
~0, reg);
|
||||
return ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, chipcontrol_data), mask,
|
||||
val);
|
||||
}
|
||||
|
||||
/* Read/write a regcontrol reg */
|
||||
u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
|
||||
{
|
||||
ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, regcontrol_addr),
|
||||
~0, reg);
|
||||
return ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, regcontrol_data), mask,
|
||||
val);
|
||||
}
|
||||
|
||||
/* Read/write a pllcontrol reg */
|
||||
u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val)
|
||||
{
|
||||
ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, pllcontrol_addr),
|
||||
~0, reg);
|
||||
return ai_corereg(sih, SI_CC_IDX,
|
||||
offsetof(struct chipcregs, pllcontrol_data), mask,
|
||||
val);
|
||||
}
|
||||
|
||||
/* PMU PLL update */
|
||||
void si_pmu_pllupd(struct si_pub *sih)
|
||||
{
|
||||
ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, pmucontrol),
|
||||
PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
|
||||
}
|
||||
|
||||
/* query alp/xtal clock frequency */
|
||||
u32 si_pmu_alp_clock(struct si_pub *sih)
|
||||
{
|
||||
u32 clock = ALP_CLOCK;
|
||||
|
||||
/* bail out with default */
|
||||
if (!(sih->cccaps & CC_CAP_PMU))
|
||||
return clock;
|
||||
|
||||
switch (sih->chip) {
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
case BCM4313_CHIP_ID:
|
||||
/* always 20Mhz */
|
||||
clock = 20000 * 1000;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return clock;
|
||||
}
|
||||
|
||||
void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx, intr_val;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
cc = (struct chipcregs __iomem *)
|
||||
ai_switch_core(sih, CC_CORE_ID, &origidx, &intr_val);
|
||||
|
||||
/* update the pll changes */
|
||||
si_pmu_spuravoid_pllupdate(sih, cc, spuravoid);
|
||||
|
||||
/* Return to original core */
|
||||
ai_restore_core(sih, origidx, intr_val);
|
||||
}
|
||||
|
||||
/* initialize PMU */
|
||||
void si_pmu_init(struct si_pub *sih)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
if (sih->pmurev == 1)
|
||||
AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
|
||||
else if (sih->pmurev >= 2)
|
||||
OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT);
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
/* initialize PMU chip controls and other chip level stuff */
|
||||
void si_pmu_chip_init(struct si_pub *sih)
|
||||
{
|
||||
uint origidx;
|
||||
|
||||
/* Gate off SPROM clock and chip select signals */
|
||||
si_pmu_sprom_enable(sih, false);
|
||||
|
||||
/* Remember original core */
|
||||
origidx = ai_coreidx(sih);
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
/* initialize PMU switch/regulators */
|
||||
void si_pmu_swreg_init(struct si_pub *sih)
|
||||
{
|
||||
}
|
||||
|
||||
/* initialize PLL */
|
||||
void si_pmu_pll_init(struct si_pub *sih, uint xtalfreq)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
switch (sih->chip) {
|
||||
case BCM4313_CHIP_ID:
|
||||
case BCM43224_CHIP_ID:
|
||||
case BCM43225_CHIP_ID:
|
||||
/* ??? */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
/* initialize PMU resources */
|
||||
void si_pmu_res_init(struct si_pub *sih)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx;
|
||||
u32 min_mask = 0, max_mask = 0;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
/* Determine min/max rsrc masks */
|
||||
si_pmu_res_masks(sih, &min_mask, &max_mask);
|
||||
|
||||
/* It is required to program max_mask first and then min_mask */
|
||||
|
||||
/* Program max resource mask */
|
||||
|
||||
if (max_mask)
|
||||
W_REG(&cc->max_res_mask, max_mask);
|
||||
|
||||
/* Program min resource mask */
|
||||
|
||||
if (min_mask)
|
||||
W_REG(&cc->min_res_mask, min_mask);
|
||||
|
||||
/* Add some delay; allow resources to come up and settle. */
|
||||
mdelay(2);
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
}
|
||||
|
||||
u32 si_pmu_measure_alpclk(struct si_pub *sih)
|
||||
{
|
||||
struct chipcregs __iomem *cc;
|
||||
uint origidx;
|
||||
u32 alp_khz;
|
||||
|
||||
if (sih->pmurev < 10)
|
||||
return 0;
|
||||
|
||||
/* Remember original core before switch to chipc */
|
||||
origidx = ai_coreidx(sih);
|
||||
cc = ai_setcoreidx(sih, SI_CC_IDX);
|
||||
|
||||
if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) {
|
||||
u32 ilp_ctr, alp_hz;
|
||||
|
||||
/*
|
||||
* Enable the reg to measure the freq,
|
||||
* in case it was disabled before
|
||||
*/
|
||||
W_REG(&cc->pmu_xtalfreq,
|
||||
1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
|
||||
|
||||
/* Delay for well over 4 ILP clocks */
|
||||
udelay(1000);
|
||||
|
||||
/* Read the latched number of ALP ticks per 4 ILP ticks */
|
||||
ilp_ctr =
|
||||
R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;
|
||||
|
||||
/*
|
||||
* Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
|
||||
* bit to save power
|
||||
*/
|
||||
W_REG(&cc->pmu_xtalfreq, 0);
|
||||
|
||||
/* Calculate ALP frequency */
|
||||
alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
|
||||
|
||||
/*
|
||||
* Round to nearest 100KHz, and at
|
||||
* the same time convert to KHz
|
||||
*/
|
||||
alp_khz = (alp_hz + 50000) / 100000 * 100;
|
||||
} else
|
||||
alp_khz = 0;
|
||||
|
||||
/* Return to original core */
|
||||
ai_setcoreidx(sih, origidx);
|
||||
|
||||
return alp_khz;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user