提交 820ae8a8 编写于 作者: D David S. Miller

Merge branch 'for-davem' of...

Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
......@@ -110,6 +110,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
{ USB_DEVICE(0x0409, 0x0249) },
/* AVM FRITZ!WLAN USB Stick N 2.4 */
{ USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY },
/* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */
{ USB_DEVICE(0x1668, 0x1200) },
/* terminate */
{}
......
......@@ -1932,12 +1932,6 @@ ath5k_tasklet_rx(unsigned long data)
sc->stats.rx_all_count++;
if (unlikely(rs.rs_more)) {
ATH5K_WARN(sc, "unsupported jumbo\n");
sc->stats.rxerr_jumbo++;
goto next;
}
if (unlikely(rs.rs_status)) {
if (rs.rs_status & AR5K_RXERR_CRC)
sc->stats.rxerr_crc++;
......@@ -1977,6 +1971,12 @@ ath5k_tasklet_rx(unsigned long data)
sc->opmode != NL80211_IFTYPE_MONITOR)
goto next;
}
if (unlikely(rs.rs_more)) {
sc->stats.rxerr_jumbo++;
goto next;
}
accept:
next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr);
......
......@@ -38,6 +38,9 @@
#define AR_SWITCH_TABLE_ALL (0xfff)
#define AR_SWITCH_TABLE_ALL_S (0)
#define LE16(x) __constant_cpu_to_le16(x)
#define LE32(x) __constant_cpu_to_le32(x)
static const struct ar9300_eeprom ar9300_default = {
.eepromVersion = 2,
.templateVersion = 2,
......@@ -45,7 +48,7 @@ static const struct ar9300_eeprom ar9300_default = {
.custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
.baseEepHeader = {
.regDmn = {0, 0x1f},
.regDmn = { LE16(0), LE16(0x1f) },
.txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
.opCapFlags = {
.opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
......@@ -76,15 +79,15 @@ static const struct ar9300_eeprom ar9300_default = {
.modalHeader2G = {
/* ar9300_modal_eep_header 2g */
/* 4 idle,t1,t2,b(4 bits per setting) */
.antCtrlCommon = 0x110,
.antCtrlCommon = LE32(0x110),
/* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
.antCtrlCommon2 = 0x22222,
.antCtrlCommon2 = LE32(0x22222),
/*
* antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
* rx1, rx12, b (2 bits each)
*/
.antCtrlChain = {0x150, 0x150, 0x150},
.antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
/*
* xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
......@@ -287,12 +290,12 @@ static const struct ar9300_eeprom ar9300_default = {
},
.modalHeader5G = {
/* 4 idle,t1,t2,b (4 bits per setting) */
.antCtrlCommon = 0x110,
.antCtrlCommon = LE32(0x110),
/* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
.antCtrlCommon2 = 0x22222,
.antCtrlCommon2 = LE32(0x22222),
/* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
.antCtrlChain = {
0x000, 0x000, 0x000,
LE16(0x000), LE16(0x000), LE16(0x000),
},
/* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
.xatten1DB = {0, 0, 0},
......@@ -620,9 +623,9 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
case EEP_MAC_MSW:
return eep->macAddr[4] << 8 | eep->macAddr[5];
case EEP_REG_0:
return pBase->regDmn[0];
return le16_to_cpu(pBase->regDmn[0]);
case EEP_REG_1:
return pBase->regDmn[1];
return le16_to_cpu(pBase->regDmn[1]);
case EEP_OP_CAP:
return pBase->deviceCap;
case EEP_OP_MODE:
......@@ -640,93 +643,80 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
/* Bit 4 is internal regulator flag */
return (pBase->featureEnable & 0x10) >> 4;
case EEP_SWREG:
return pBase->swreg;
return le32_to_cpu(pBase->swreg);
default:
return 0;
}
}
#ifdef __BIG_ENDIAN
static void ar9300_swap_eeprom(struct ar9300_eeprom *eep)
static bool ar9300_eeprom_read_byte(struct ath_common *common, int address,
u8 *buffer)
{
u32 dword;
u16 word;
int i;
word = swab16(eep->baseEepHeader.regDmn[0]);
eep->baseEepHeader.regDmn[0] = word;
word = swab16(eep->baseEepHeader.regDmn[1]);
eep->baseEepHeader.regDmn[1] = word;
dword = swab32(eep->baseEepHeader.swreg);
eep->baseEepHeader.swreg = dword;
u16 val;
dword = swab32(eep->modalHeader2G.antCtrlCommon);
eep->modalHeader2G.antCtrlCommon = dword;
if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
return false;
dword = swab32(eep->modalHeader2G.antCtrlCommon2);
eep->modalHeader2G.antCtrlCommon2 = dword;
*buffer = (val >> (8 * (address % 2))) & 0xff;
return true;
}
dword = swab32(eep->modalHeader5G.antCtrlCommon);
eep->modalHeader5G.antCtrlCommon = dword;
static bool ar9300_eeprom_read_word(struct ath_common *common, int address,
u8 *buffer)
{
u16 val;
dword = swab32(eep->modalHeader5G.antCtrlCommon2);
eep->modalHeader5G.antCtrlCommon2 = dword;
if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
return false;
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
word = swab16(eep->modalHeader2G.antCtrlChain[i]);
eep->modalHeader2G.antCtrlChain[i] = word;
buffer[0] = val >> 8;
buffer[1] = val & 0xff;
word = swab16(eep->modalHeader5G.antCtrlChain[i]);
eep->modalHeader5G.antCtrlChain[i] = word;
}
return true;
}
#endif
static bool ar9300_hw_read_eeprom(struct ath_hw *ah,
long address, u8 *buffer, int many)
static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
int count)
{
int i;
u8 value[2];
unsigned long eepAddr;
unsigned long byteAddr;
u16 *svalue;
struct ath_common *common = ath9k_hw_common(ah);
int i;
if ((address < 0) || ((address + many) > AR9300_EEPROM_SIZE - 1)) {
if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
ath_print(common, ATH_DBG_EEPROM,
"eeprom address not in range\n");
return false;
}
for (i = 0; i < many; i++) {
eepAddr = (u16) (address + i) / 2;
byteAddr = (u16) (address + i) % 2;
svalue = (u16 *) value;
if (!ath9k_hw_nvram_read(common, eepAddr, svalue)) {
ath_print(common, ATH_DBG_EEPROM,
"unable to read eeprom region\n");
return false;
}
*svalue = le16_to_cpu(*svalue);
buffer[i] = value[byteAddr];
/*
* Since we're reading the bytes in reverse order from a little-endian
* word stream, an even address means we only use the lower half of
* the 16-bit word at that address
*/
if (address % 2 == 0) {
if (!ar9300_eeprom_read_byte(common, address--, buffer++))
goto error;
count--;
}
return true;
}
for (i = 0; i < count / 2; i++) {
if (!ar9300_eeprom_read_word(common, address, buffer))
goto error;
static bool ar9300_read_eeprom(struct ath_hw *ah,
int address, u8 *buffer, int many)
{
int it;
address -= 2;
buffer += 2;
}
if (count % 2)
if (!ar9300_eeprom_read_byte(common, address, buffer))
goto error;
for (it = 0; it < many; it++)
if (!ar9300_hw_read_eeprom(ah,
(address - it),
(buffer + it), 1))
return false;
return true;
error:
ath_print(common, ATH_DBG_EEPROM,
"unable to read eeprom region at offset %d\n", address);
return false;
}
static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
......@@ -927,30 +917,13 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
*/
static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
{
u8 *mptr = NULL;
int mdata_size;
u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
mptr = (u8 *) &ah->eeprom.ar9300_eep;
mdata_size = sizeof(struct ar9300_eeprom);
if (ar9300_eeprom_restore_internal(ah, mptr,
sizeof(struct ar9300_eeprom)) < 0)
return false;
if (mptr && mdata_size > 0) {
/* At this point, mptr points to the eeprom data structure
* in it's "default" state. If this is big endian, swap the
* data structures back to "little endian"
*/
/* First swap, default to Little Endian */
#ifdef __BIG_ENDIAN
ar9300_swap_eeprom((struct ar9300_eeprom *)mptr);
#endif
if (ar9300_eeprom_restore_internal(ah, mptr, mdata_size) >= 0)
return true;
/* Second Swap, back to Big Endian */
#ifdef __BIG_ENDIAN
ar9300_swap_eeprom((struct ar9300_eeprom *)mptr);
#endif
}
return false;
return true;
}
/* XXX: review hardware docs */
......@@ -998,21 +971,25 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
{
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
__le32 val;
if (is2ghz)
return eep->modalHeader2G.antCtrlCommon;
val = eep->modalHeader2G.antCtrlCommon;
else
return eep->modalHeader5G.antCtrlCommon;
val = eep->modalHeader5G.antCtrlCommon;
return le32_to_cpu(val);
}
static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
{
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
__le32 val;
if (is2ghz)
return eep->modalHeader2G.antCtrlCommon2;
val = eep->modalHeader2G.antCtrlCommon2;
else
return eep->modalHeader5G.antCtrlCommon2;
val = eep->modalHeader5G.antCtrlCommon2;
return le32_to_cpu(val);
}
static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
......@@ -1020,15 +997,16 @@ static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
bool is2ghz)
{
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
__le16 val = 0;
if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
if (is2ghz)
return eep->modalHeader2G.antCtrlChain[chain];
val = eep->modalHeader2G.antCtrlChain[chain];
else
return eep->modalHeader5G.antCtrlChain[chain];
val = eep->modalHeader5G.antCtrlChain[chain];
}
return 0;
return le16_to_cpu(val);
}
static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
......
......@@ -169,7 +169,7 @@ enum CompressAlgorithm {
};
struct ar9300_base_eep_hdr {
u16 regDmn[2];
__le16 regDmn[2];
/* 4 bits tx and 4 bits rx */
u8 txrxMask;
struct eepFlags opCapFlags;
......@@ -199,16 +199,16 @@ struct ar9300_base_eep_hdr {
u8 rxBandSelectGpio;
u8 txrxgain;
/* SW controlled internal regulator fields */
u32 swreg;
__le32 swreg;
} __packed;
struct ar9300_modal_eep_header {
/* 4 idle, t1, t2, b (4 bits per setting) */
u32 antCtrlCommon;
__le32 antCtrlCommon;
/* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
u32 antCtrlCommon2;
__le32 antCtrlCommon2;
/* 6 idle, t, r, rx1, rx12, b (2 bits each) */
u16 antCtrlChain[AR9300_MAX_CHAINS];
__le16 antCtrlChain[AR9300_MAX_CHAINS];
/* 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
u8 xatten1DB[AR9300_MAX_CHAINS];
/* 3 xatten1_margin for merlin (0xa20c/b20c 16:12 */
......
......@@ -25,8 +25,11 @@ static const u32 ar9300_2p0_radio_postamble[][5] = {
{0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800},
{0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20},
{0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
{0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
{0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
{0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
{0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000},
{0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
};
static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p0[][5] = {
......@@ -97,13 +100,13 @@ static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p0[][5] = {
{0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
{0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
{0x00016048, 0x60001a61, 0x60001a61, 0x60001a61, 0x60001a61},
{0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
{0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
{0x00016448, 0x60001a61, 0x60001a61, 0x60001a61, 0x60001a61},
{0x00016448, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
{0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
{0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
{0x00016848, 0x60001a61, 0x60001a61, 0x60001a61, 0x60001a61},
{0x00016848, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
};
......@@ -129,7 +132,7 @@ static const u32 ar9300_2p0_radio_core[][2] = {
{0x00016040, 0x7f80fff8},
{0x0001604c, 0x76d005b5},
{0x00016050, 0x556cf031},
{0x00016054, 0x43449440},
{0x00016054, 0x13449440},
{0x00016058, 0x0c51c92c},
{0x0001605c, 0x3db7fffc},
{0x00016060, 0xfffffffc},
......@@ -152,12 +155,11 @@ static const u32 ar9300_2p0_radio_core[][2] = {
{0x00016100, 0x3fffbe01},
{0x00016104, 0xfff80000},
{0x00016108, 0x00080010},
{0x00016140, 0x10804008},
{0x00016144, 0x02084080},
{0x00016148, 0x00000000},
{0x00016280, 0x058a0001},
{0x00016284, 0x3d840208},
{0x00016288, 0x01a20408},
{0x00016288, 0x05a20408},
{0x0001628c, 0x00038c07},
{0x00016290, 0x40000004},
{0x00016294, 0x458aa14f},
......@@ -190,7 +192,7 @@ static const u32 ar9300_2p0_radio_core[][2] = {
{0x00016440, 0x7f80fff8},
{0x0001644c, 0x76d005b5},
{0x00016450, 0x556cf031},
{0x00016454, 0x43449440},
{0x00016454, 0x13449440},
{0x00016458, 0x0c51c92c},
{0x0001645c, 0x3db7fffc},
{0x00016460, 0xfffffffc},
......@@ -199,7 +201,6 @@ static const u32 ar9300_2p0_radio_core[][2] = {
{0x00016500, 0x3fffbe01},
{0x00016504, 0xfff80000},
{0x00016508, 0x00080010},
{0x00016540, 0x10804008},
{0x00016544, 0x02084080},
{0x00016548, 0x00000000},
{0x00016780, 0x00000000},
......@@ -231,7 +232,7 @@ static const u32 ar9300_2p0_radio_core[][2] = {
{0x00016840, 0x7f80fff8},
{0x0001684c, 0x76d005b5},
{0x00016850, 0x556cf031},
{0x00016854, 0x43449440},
{0x00016854, 0x13449440},
{0x00016858, 0x0c51c92c},
{0x0001685c, 0x3db7fffc},
{0x00016860, 0xfffffffc},
......@@ -240,7 +241,6 @@ static const u32 ar9300_2p0_radio_core[][2] = {
{0x00016900, 0x3fffbe01},
{0x00016904, 0xfff80000},
{0x00016908, 0x00080010},
{0x00016940, 0x10804008},
{0x00016944, 0x02084080},
{0x00016948, 0x00000000},
{0x00016b80, 0x00000000},
......@@ -588,12 +588,12 @@ static const u32 ar9200_merlin_2p0_radio_core[][2] = {
static const u32 ar9300_2p0_baseband_postamble[][5] = {
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
{0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a800b},
{0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
{0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e},
{0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
{0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
{0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
{0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x00000b9c},
{0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
{0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044},
{0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
{0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
......@@ -604,8 +604,8 @@ static const u32 ar9300_2p0_baseband_postamble[][5] = {
{0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
{0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
{0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
{0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324},
{0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010},
{0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27},
{0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
{0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
{0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0},
{0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
......@@ -674,7 +674,7 @@ static const u32 ar9300_2p0_baseband_core[][2] = {
{0x00009d10, 0x01834061},
{0x00009d14, 0x00c0040b},
{0x00009d18, 0x00000000},
{0x00009e08, 0x0038233c},
{0x00009e08, 0x0038230c},
{0x00009e24, 0x990bb515},
{0x00009e28, 0x0c6f0000},
{0x00009e30, 0x06336f77},
......@@ -901,13 +901,13 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = {
{0x0000a5f8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
{0x0000a5fc, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
{0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
{0x00016048, 0xae481a61, 0xae481a61, 0xae481a61, 0xae481a61},
{0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
{0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
{0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
{0x00016448, 0xae481a61, 0xae481a61, 0xae481a61, 0xae481a61},
{0x00016448, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
{0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
{0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
{0x00016848, 0xae481a61, 0xae481a61, 0xae481a61, 0xae481a61},
{0x00016848, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
{0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
};
......@@ -979,13 +979,13 @@ static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = {
{0x0000a5f8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
{0x0000a5fc, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec},
{0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
{0x00016048, 0x8e481a61, 0x8e481a61, 0x8e481a61, 0x8e481a61},
{0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
{0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
{0x00016448, 0x8e481a61, 0x8e481a61, 0x8e481a61, 0x8e481a61},
{0x00016448, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
{0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
{0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
{0x00016848, 0x8e481a61, 0x8e481a61, 0x8e481a61, 0x8e481a61},
{0x00016848, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
};
......@@ -995,22 +995,22 @@ static const u32 ar9300Common_rx_gain_table_2p0[][2] = {
{0x0000a004, 0x00030002},
{0x0000a008, 0x00050004},
{0x0000a00c, 0x00810080},
{0x0000a010, 0x01800082},
{0x0000a014, 0x01820181},
{0x0000a018, 0x01840183},
{0x0000a01c, 0x01880185},
{0x0000a020, 0x018a0189},
{0x0000a024, 0x02850284},
{0x0000a028, 0x02890288},
{0x0000a02c, 0x028b028a},
{0x0000a030, 0x028d028c},
{0x0000a034, 0x02910290},
{0x0000a038, 0x02930292},
{0x0000a03c, 0x03910390},
{0x0000a040, 0x03930392},
{0x0000a044, 0x03950394},
{0x0000a048, 0x00000396},
{0x0000a04c, 0x00000000},
{0x0000a010, 0x00830082},
{0x0000a014, 0x01810180},
{0x0000a018, 0x01830182},
{0x0000a01c, 0x01850184},
{0x0000a020, 0x01890188},
{0x0000a024, 0x018b018a},
{0x0000a028, 0x018d018c},
{0x0000a02c, 0x01910190},
{0x0000a030, 0x01930192},
{0x0000a034, 0x01950194},
{0x0000a038, 0x038a0196},
{0x0000a03c, 0x038c038b},
{0x0000a040, 0x0390038d},
{0x0000a044, 0x03920391},
{0x0000a048, 0x03940393},
{0x0000a04c, 0x03960395},
{0x0000a050, 0x00000000},
{0x0000a054, 0x00000000},
{0x0000a058, 0x00000000},
......@@ -1023,14 +1023,14 @@ static const u32 ar9300Common_rx_gain_table_2p0[][2] = {
{0x0000a074, 0x00000000},
{0x0000a078, 0x00000000},
{0x0000a07c, 0x00000000},
{0x0000a080, 0x28282828},
{0x0000a084, 0x21212128},
{0x0000a088, 0x21212121},
{0x0000a08c, 0x1c1c1c21},
{0x0000a090, 0x1c1c1c1c},
{0x0000a094, 0x17171c1c},
{0x0000a098, 0x02020212},
{0x0000a09c, 0x02020202},
{0x0000a080, 0x22222229},
{0x0000a084, 0x1d1d1d1d},
{0x0000a088, 0x1d1d1d1d},
{0x0000a08c, 0x1d1d1d1d},
{0x0000a090, 0x171d1d1d},
{0x0000a094, 0x11111717},
{0x0000a098, 0x00030311},
{0x0000a09c, 0x00000000},
{0x0000a0a0, 0x00000000},
{0x0000a0a4, 0x00000000},
{0x0000a0a8, 0x00000000},
......@@ -1040,26 +1040,26 @@ static const u32 ar9300Common_rx_gain_table_2p0[][2] = {
{0x0000a0b8, 0x00000000},
{0x0000a0bc, 0x00000000},
{0x0000a0c0, 0x001f0000},
{0x0000a0c4, 0x011f0100},
{0x0000a0c8, 0x011d011e},
{0x0000a0cc, 0x011b011c},
{0x0000a0c4, 0x01000101},
{0x0000a0c8, 0x011e011f},
{0x0000a0cc, 0x011c011d},
{0x0000a0d0, 0x02030204},
{0x0000a0d4, 0x02010202},
{0x0000a0d8, 0x021f0200},
{0x0000a0dc, 0x021d021e},
{0x0000a0e0, 0x03010302},
{0x0000a0e4, 0x031f0300},
{0x0000a0e8, 0x0402031e},
{0x0000a0dc, 0x0302021e},
{0x0000a0e0, 0x03000301},
{0x0000a0e4, 0x031e031f},
{0x0000a0e8, 0x0402031d},
{0x0000a0ec, 0x04000401},
{0x0000a0f0, 0x041e041f},
{0x0000a0f4, 0x05010502},
{0x0000a0f8, 0x051f0500},
{0x0000a0fc, 0x0602051e},
{0x0000a100, 0x06000601},
{0x0000a104, 0x061e061f},
{0x0000a108, 0x0703061d},
{0x0000a10c, 0x07010702},
{0x0000a110, 0x00000700},
{0x0000a0f4, 0x0502041d},
{0x0000a0f8, 0x05000501},
{0x0000a0fc, 0x051e051f},
{0x0000a100, 0x06010602},
{0x0000a104, 0x061f0600},
{0x0000a108, 0x061d061e},
{0x0000a10c, 0x07020703},
{0x0000a110, 0x07000701},
{0x0000a114, 0x00000000},
{0x0000a118, 0x00000000},
{0x0000a11c, 0x00000000},
......@@ -1072,26 +1072,26 @@ static const u32 ar9300Common_rx_gain_table_2p0[][2] = {
{0x0000a138, 0x00000000},
{0x0000a13c, 0x00000000},
{0x0000a140, 0x001f0000},
{0x0000a144, 0x011f0100},
{0x0000a148, 0x011d011e},
{0x0000a14c, 0x011b011c},
{0x0000a144, 0x01000101},
{0x0000a148, 0x011e011f},
{0x0000a14c, 0x011c011d},
{0x0000a150, 0x02030204},
{0x0000a154, 0x02010202},
{0x0000a158, 0x021f0200},
{0x0000a15c, 0x021d021e},
{0x0000a160, 0x03010302},
{0x0000a164, 0x031f0300},
{0x0000a168, 0x0402031e},
{0x0000a15c, 0x0302021e},
{0x0000a160, 0x03000301},
{0x0000a164, 0x031e031f},
{0x0000a168, 0x0402031d},
{0x0000a16c, 0x04000401},
{0x0000a170, 0x041e041f},
{0x0000a174, 0x05010502},
{0x0000a178, 0x051f0500},
{0x0000a17c, 0x0602051e},
{0x0000a180, 0x06000601},
{0x0000a184, 0x061e061f},
{0x0000a188, 0x0703061d},
{0x0000a18c, 0x07010702},
{0x0000a190, 0x00000700},
{0x0000a174, 0x0502041d},
{0x0000a178, 0x05000501},
{0x0000a17c, 0x051e051f},
{0x0000a180, 0x06010602},
{0x0000a184, 0x061f0600},
{0x0000a188, 0x061d061e},
{0x0000a18c, 0x07020703},
{0x0000a190, 0x07000701},
{0x0000a194, 0x00000000},
{0x0000a198, 0x00000000},
{0x0000a19c, 0x00000000},
......@@ -1317,13 +1317,13 @@ static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p0[][5] = {
{0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
{0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
{0x00016048, 0x64001a61, 0x64001a61, 0x64001a61, 0x64001a61},
{0x00016048, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
{0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
{0x00016448, 0x64001a61, 0x64001a61, 0x64001a61, 0x64001a61},
{0x00016448, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
{0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
{0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
{0x00016848, 0x64001a61, 0x64001a61, 0x64001a61, 0x64001a61},
{0x00016848, 0x64000001, 0x64000001, 0x64000001, 0x64000001},
{0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
};
......@@ -1497,22 +1497,22 @@ static const u32 ar9300Common_wo_xlna_rx_gain_table_2p0[][2] = {
{0x0000a004, 0x00030002},
{0x0000a008, 0x00050004},
{0x0000a00c, 0x00810080},
{0x0000a010, 0x01800082},
{0x0000a014, 0x01820181},
{0x0000a018, 0x01840183},
{0x0000a01c, 0x01880185},
{0x0000a020, 0x018a0189},
{0x0000a024, 0x02850284},
{0x0000a028, 0x02890288},
{0x0000a02c, 0x03850384},
{0x0000a030, 0x03890388},
{0x0000a034, 0x038b038a},
{0x0000a038, 0x038d038c},
{0x0000a03c, 0x03910390},
{0x0000a040, 0x03930392},
{0x0000a044, 0x03950394},
{0x0000a048, 0x00000396},
{0x0000a04c, 0x00000000},
{0x0000a010, 0x00830082},
{0x0000a014, 0x01810180},
{0x0000a018, 0x01830182},
{0x0000a01c, 0x01850184},
{0x0000a020, 0x01890188},
{0x0000a024, 0x018b018a},
{0x0000a028, 0x018d018c},
{0x0000a02c, 0x03820190},
{0x0000a030, 0x03840383},
{0x0000a034, 0x03880385},
{0x0000a038, 0x038a0389},
{0x0000a03c, 0x038c038b},
{0x0000a040, 0x0390038d},
{0x0000a044, 0x03920391},
{0x0000a048, 0x03940393},
{0x0000a04c, 0x03960395},
{0x0000a050, 0x00000000},
{0x0000a054, 0x00000000},
{0x0000a058, 0x00000000},
......@@ -1525,15 +1525,15 @@ static const u32 ar9300Common_wo_xlna_rx_gain_table_2p0[][2] = {
{0x0000a074, 0x00000000},
{0x0000a078, 0x00000000},
{0x0000a07c, 0x00000000},
{0x0000a080, 0x28282828},
{0x0000a084, 0x28282828},
{0x0000a088, 0x28282828},
{0x0000a08c, 0x28282828},
{0x0000a090, 0x28282828},
{0x0000a094, 0x21212128},
{0x0000a098, 0x171c1c1c},
{0x0000a09c, 0x02020212},
{0x0000a0a0, 0x00000202},
{0x0000a080, 0x29292929},
{0x0000a084, 0x29292929},
{0x0000a088, 0x29292929},
{0x0000a08c, 0x29292929},
{0x0000a090, 0x22292929},
{0x0000a094, 0x1d1d2222},
{0x0000a098, 0x0c111117},
{0x0000a09c, 0x00030303},
{0x0000a0a0, 0x00000000},
{0x0000a0a4, 0x00000000},
{0x0000a0a8, 0x00000000},
{0x0000a0ac, 0x00000000},
......@@ -1542,26 +1542,26 @@ static const u32 ar9300Common_wo_xlna_rx_gain_table_2p0[][2] = {
{0x0000a0b8, 0x00000000},
{0x0000a0bc, 0x00000000},
{0x0000a0c0, 0x001f0000},
{0x0000a0c4, 0x011f0100},
{0x0000a0c8, 0x011d011e},
{0x0000a0cc, 0x011b011c},
{0x0000a0c4, 0x01000101},
{0x0000a0c8, 0x011e011f},
{0x0000a0cc, 0x011c011d},
{0x0000a0d0, 0x02030204},
{0x0000a0d4, 0x02010202},
{0x0000a0d8, 0x021f0200},
{0x0000a0dc, 0x021d021e},
{0x0000a0e0, 0x03010302},
{0x0000a0e4, 0x031f0300},
{0x0000a0e8, 0x0402031e},
{0x0000a0dc, 0x0302021e},
{0x0000a0e0, 0x03000301},
{0x0000a0e4, 0x031e031f},
{0x0000a0e8, 0x0402031d},
{0x0000a0ec, 0x04000401},
{0x0000a0f0, 0x041e041f},
{0x0000a0f4, 0x05010502},
{0x0000a0f8, 0x051f0500},
{0x0000a0fc, 0x0602051e},
{0x0000a100, 0x06000601},
{0x0000a104, 0x061e061f},
{0x0000a108, 0x0703061d},
{0x0000a10c, 0x07010702},
{0x0000a110, 0x00000700},
{0x0000a0f4, 0x0502041d},
{0x0000a0f8, 0x05000501},
{0x0000a0fc, 0x051e051f},
{0x0000a100, 0x06010602},
{0x0000a104, 0x061f0600},
{0x0000a108, 0x061d061e},
{0x0000a10c, 0x07020703},
{0x0000a110, 0x07000701},
{0x0000a114, 0x00000000},
{0x0000a118, 0x00000000},
{0x0000a11c, 0x00000000},
......@@ -1574,26 +1574,26 @@ static const u32 ar9300Common_wo_xlna_rx_gain_table_2p0[][2] = {
{0x0000a138, 0x00000000},
{0x0000a13c, 0x00000000},
{0x0000a140, 0x001f0000},
{0x0000a144, 0x011f0100},
{0x0000a148, 0x011d011e},
{0x0000a14c, 0x011b011c},
{0x0000a144, 0x01000101},
{0x0000a148, 0x011e011f},
{0x0000a14c, 0x011c011d},
{0x0000a150, 0x02030204},
{0x0000a154, 0x02010202},
{0x0000a158, 0x021f0200},
{0x0000a15c, 0x021d021e},
{0x0000a160, 0x03010302},
{0x0000a164, 0x031f0300},
{0x0000a168, 0x0402031e},
{0x0000a15c, 0x0302021e},
{0x0000a160, 0x03000301},
{0x0000a164, 0x031e031f},
{0x0000a168, 0x0402031d},
{0x0000a16c, 0x04000401},
{0x0000a170, 0x041e041f},
{0x0000a174, 0x05010502},
{0x0000a178, 0x051f0500},
{0x0000a17c, 0x0602051e},
{0x0000a180, 0x06000601},
{0x0000a184, 0x061e061f},
{0x0000a188, 0x0703061d},
{0x0000a18c, 0x07010702},
{0x0000a190, 0x00000700},
{0x0000a174, 0x0502041d},
{0x0000a178, 0x05000501},
{0x0000a17c, 0x051e051f},
{0x0000a180, 0x06010602},
{0x0000a184, 0x061f0600},
{0x0000a188, 0x061d061e},
{0x0000a18c, 0x07020703},
{0x0000a190, 0x07000701},
{0x0000a194, 0x00000000},
{0x0000a198, 0x00000000},
{0x0000a19c, 0x00000000},
......@@ -1620,7 +1620,7 @@ static const u32 ar9300Common_wo_xlna_rx_gain_table_2p0[][2] = {
{0x0000a1f0, 0x00000396},
{0x0000a1f4, 0x00000396},
{0x0000a1f8, 0x00000396},
{0x0000a1fc, 0x00000296},
{0x0000a1fc, 0x00000196},
{0x0000b000, 0x00010000},
{0x0000b004, 0x00030002},
{0x0000b008, 0x00050004},
......
......@@ -78,6 +78,90 @@ static const struct file_operations fops_debug = {
#define DMA_BUF_LEN 1024
static ssize_t read_file_tx_chainmask(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
char buf[32];
unsigned int len;
len = snprintf(buf, sizeof(buf), "0x%08x\n", common->tx_chainmask);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
static ssize_t write_file_tx_chainmask(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
unsigned long mask;
char buf[32];
ssize_t len;
len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len))
return -EINVAL;
buf[len] = '\0';
if (strict_strtoul(buf, 0, &mask))
return -EINVAL;
common->tx_chainmask = mask;
sc->sc_ah->caps.tx_chainmask = mask;
return count;
}
static const struct file_operations fops_tx_chainmask = {
.read = read_file_tx_chainmask,
.write = write_file_tx_chainmask,
.open = ath9k_debugfs_open,
.owner = THIS_MODULE
};
static ssize_t read_file_rx_chainmask(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
char buf[32];
unsigned int len;
len = snprintf(buf, sizeof(buf), "0x%08x\n", common->rx_chainmask);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
static ssize_t write_file_rx_chainmask(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
unsigned long mask;
char buf[32];
ssize_t len;
len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len))
return -EINVAL;
buf[len] = '\0';
if (strict_strtoul(buf, 0, &mask))
return -EINVAL;
common->rx_chainmask = mask;
sc->sc_ah->caps.rx_chainmask = mask;
return count;
}
static const struct file_operations fops_rx_chainmask = {
.read = read_file_rx_chainmask,
.write = write_file_rx_chainmask,
.open = ath9k_debugfs_open,
.owner = THIS_MODULE
};
static ssize_t read_file_dma(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
......@@ -711,6 +795,86 @@ static const struct file_operations fops_recv = {
.owner = THIS_MODULE
};
static ssize_t read_file_regidx(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
char buf[32];
unsigned int len;
len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.regidx);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
static ssize_t write_file_regidx(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
unsigned long regidx;
char buf[32];
ssize_t len;
len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len))
return -EINVAL;
buf[len] = '\0';
if (strict_strtoul(buf, 0, &regidx))
return -EINVAL;
sc->debug.regidx = regidx;
return count;
}
static const struct file_operations fops_regidx = {
.read = read_file_regidx,
.write = write_file_regidx,
.open = ath9k_debugfs_open,
.owner = THIS_MODULE
};
static ssize_t read_file_regval(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
struct ath_hw *ah = sc->sc_ah;
char buf[32];
unsigned int len;
u32 regval;
regval = REG_READ_D(ah, sc->debug.regidx);
len = snprintf(buf, sizeof(buf), "0x%08x\n", regval);
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
static ssize_t write_file_regval(struct file *file, const char __user *user_buf,
size_t count, loff_t *ppos)
{
struct ath_softc *sc = file->private_data;
struct ath_hw *ah = sc->sc_ah;
unsigned long regval;
char buf[32];
ssize_t len;
len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len))
return -EINVAL;
buf[len] = '\0';
if (strict_strtoul(buf, 0, &regval))
return -EINVAL;
REG_WRITE_D(ah, sc->debug.regidx, regval);
return count;
}
static const struct file_operations fops_regval = {
.read = read_file_regval,
.write = write_file_regval,
.open = ath9k_debugfs_open,
.owner = THIS_MODULE
};
int ath9k_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
......@@ -722,54 +886,55 @@ int ath9k_init_debug(struct ath_hw *ah)
sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
ath9k_debugfs_root);
if (!sc->debug.debugfs_phy)
goto err;
return -ENOMEM;
#ifdef CONFIG_ATH_DEBUG
sc->debug.debugfs_debug = debugfs_create_file("debug",
S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug);
if (!sc->debug.debugfs_debug)
if (!debugfs_create_file("debug", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, sc, &fops_debug))
goto err;
#endif
sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUSR,
sc->debug.debugfs_phy, sc, &fops_dma);
if (!sc->debug.debugfs_dma)
if (!debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy,
sc, &fops_dma))
goto err;
if (!debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy,
sc, &fops_interrupt))
goto err;
if (!debugfs_create_file("rcstat", S_IRUSR, sc->debug.debugfs_phy,
sc, &fops_rcstat))
goto err;
if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, sc, &fops_wiphy))
goto err;
if (!debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy,
sc, &fops_xmit))
goto err;
sc->debug.debugfs_interrupt = debugfs_create_file("interrupt",
S_IRUSR,
sc->debug.debugfs_phy,
sc, &fops_interrupt);
if (!sc->debug.debugfs_interrupt)
if (!debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy,
sc, &fops_recv))
goto err;
sc->debug.debugfs_rcstat = debugfs_create_file("rcstat",
S_IRUSR,
sc->debug.debugfs_phy,
sc, &fops_rcstat);
if (!sc->debug.debugfs_rcstat)
if (!debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, sc, &fops_rx_chainmask))
goto err;
sc->debug.debugfs_wiphy = debugfs_create_file(
"wiphy", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc,
&fops_wiphy);
if (!sc->debug.debugfs_wiphy)
if (!debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, sc, &fops_tx_chainmask))
goto err;
sc->debug.debugfs_xmit = debugfs_create_file("xmit",
S_IRUSR,
sc->debug.debugfs_phy,
sc, &fops_xmit);
if (!sc->debug.debugfs_xmit)
if (!debugfs_create_file("regidx", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, sc, &fops_regidx))
goto err;
sc->debug.debugfs_recv = debugfs_create_file("recv",
S_IRUSR,
sc->debug.debugfs_phy,
sc, &fops_recv);
if (!sc->debug.debugfs_recv)
if (!debugfs_create_file("regval", S_IRUSR | S_IWUSR,
sc->debug.debugfs_phy, sc, &fops_regval))
goto err;
sc->debug.regidx = 0;
return 0;
err:
ath9k_exit_debug(ah);
......@@ -781,14 +946,7 @@ void ath9k_exit_debug(struct ath_hw *ah)
struct ath_common *common = ath9k_hw_common(ah);
struct ath_softc *sc = (struct ath_softc *) common->priv;
debugfs_remove(sc->debug.debugfs_recv);
debugfs_remove(sc->debug.debugfs_xmit);
debugfs_remove(sc->debug.debugfs_wiphy);
debugfs_remove(sc->debug.debugfs_rcstat);
debugfs_remove(sc->debug.debugfs_interrupt);
debugfs_remove(sc->debug.debugfs_dma);
debugfs_remove(sc->debug.debugfs_debug);
debugfs_remove(sc->debug.debugfs_phy);
debugfs_remove_recursive(sc->debug.debugfs_phy);
}
int ath9k_debug_create_root(void)
......
......@@ -153,13 +153,7 @@ struct ath_stats {
struct ath9k_debug {
struct dentry *debugfs_phy;
struct dentry *debugfs_debug;
struct dentry *debugfs_dma;
struct dentry *debugfs_interrupt;
struct dentry *debugfs_rcstat;
struct dentry *debugfs_wiphy;
struct dentry *debugfs_xmit;
struct dentry *debugfs_recv;
u32 regidx;
struct ath_stats stats;
};
......
......@@ -735,6 +735,14 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
return -ENOMEM;
}
static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
{
usb_kill_anchored_urbs(&hif_dev->regout_submitted);
ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
}
static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
{
int transfer, err;
......@@ -794,14 +802,6 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev,
goto err_fw_req;
}
/* Download firmware */
ret = ath9k_hif_usb_download_fw(hif_dev);
if (ret) {
dev_err(&hif_dev->udev->dev,
"ath9k_htc: Firmware - %s download failed\n", fw_name);
goto err_fw_download;
}
/* Alloc URBs */
ret = ath9k_hif_usb_alloc_urbs(hif_dev);
if (ret) {
......@@ -810,25 +810,25 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev,
goto err_urb;
}
/* Download firmware */
ret = ath9k_hif_usb_download_fw(hif_dev);
if (ret) {
dev_err(&hif_dev->udev->dev,
"ath9k_htc: Firmware - %s download failed\n", fw_name);
goto err_fw_download;
}
return 0;
err_urb:
/* Nothing */
err_fw_download:
ath9k_hif_usb_dealloc_urbs(hif_dev);
err_urb:
release_firmware(hif_dev->firmware);
err_fw_req:
hif_dev->firmware = NULL;
return ret;
}
static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
{
usb_kill_anchored_urbs(&hif_dev->regout_submitted);
ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
}
static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev)
{
ath9k_hif_usb_dealloc_urbs(hif_dev);
......@@ -859,21 +859,21 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
#endif
usb_set_intfdata(interface, hif_dev);
hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb,
&hif_dev->udev->dev);
if (hif_dev->htc_handle == NULL) {
ret = -ENOMEM;
goto err_htc_hw_alloc;
}
ret = ath9k_hif_usb_dev_init(hif_dev, fw_name);
if (ret) {
ret = -EINVAL;
goto err_hif_init_usb;
}
hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev);
if (hif_dev->htc_handle == NULL) {
ret = -ENOMEM;
goto err_htc_hw_alloc;
}
ret = ath9k_htc_hw_init(&hif_usb, hif_dev->htc_handle, hif_dev,
&hif_dev->udev->dev, hif_dev->device_id,
ATH9K_HIF_USB);
ret = ath9k_htc_hw_init(hif_dev->htc_handle,
&hif_dev->udev->dev, hif_dev->device_id);
if (ret) {
ret = -EINVAL;
goto err_htc_hw_init;
......@@ -884,10 +884,10 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
return 0;
err_htc_hw_init:
ath9k_htc_hw_free(hif_dev->htc_handle);
err_htc_hw_alloc:
ath9k_hif_usb_dev_deinit(hif_dev);
err_hif_init_usb:
ath9k_htc_hw_free(hif_dev->htc_handle);
err_htc_hw_alloc:
usb_set_intfdata(interface, NULL);
kfree(hif_dev);
usb_put_dev(udev);
......
......@@ -81,6 +81,11 @@ static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
{
int time_left;
if (atomic_read(&priv->htc->tgt_ready) > 0) {
atomic_dec(&priv->htc->tgt_ready);
return 0;
}
/* Firmware can take up to 50ms to get ready, to be safe use 1 second */
time_left = wait_for_completion_timeout(&priv->htc->target_wait, HZ);
if (!time_left) {
......@@ -88,6 +93,8 @@ static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
return -ETIMEDOUT;
}
atomic_dec(&priv->htc->tgt_ready);
return 0;
}
......
......@@ -1452,6 +1452,8 @@ static void ath9k_htc_sta_notify(struct ieee80211_hw *hw,
struct ath9k_htc_priv *priv = hw->priv;
int ret;
mutex_lock(&priv->mutex);
switch (cmd) {
case STA_NOTIFY_ADD:
ret = ath9k_htc_add_station(priv, vif, sta);
......@@ -1464,6 +1466,8 @@ static void ath9k_htc_sta_notify(struct ieee80211_hw *hw,
default:
break;
}
mutex_unlock(&priv->mutex);
}
static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue,
......
......@@ -39,7 +39,7 @@ static struct htc_endpoint *get_next_avail_ep(struct htc_endpoint *endpoint)
{
enum htc_endpoint_id avail_epid;
for (avail_epid = ENDPOINT_MAX; avail_epid > ENDPOINT0; avail_epid--)
for (avail_epid = (ENDPOINT_MAX - 1); avail_epid > ENDPOINT0; avail_epid--)
if (endpoint[avail_epid].service_id == 0)
return &endpoint[avail_epid];
return NULL;
......@@ -95,6 +95,7 @@ static void htc_process_target_rdy(struct htc_target *target,
endpoint = &target->endpoint[ENDPOINT0];
endpoint->service_id = HTC_CTRL_RSVD_SVC;
endpoint->max_msglen = HTC_MAX_CONTROL_MESSAGE_LENGTH;
atomic_inc(&target->tgt_ready);
complete(&target->target_wait);
}
......@@ -116,7 +117,7 @@ static void htc_process_conn_rsp(struct htc_target *target,
max_msglen = be16_to_cpu(svc_rspmsg->max_msg_len);
endpoint = &target->endpoint[epid];
for (tepid = ENDPOINT_MAX; tepid > ENDPOINT0; tepid--) {
for (tepid = (ENDPOINT_MAX - 1); tepid > ENDPOINT0; tepid--) {
tmp_endpoint = &target->endpoint[tepid];
if (tmp_endpoint->service_id == service_id) {
tmp_endpoint->service_id = 0;
......@@ -124,7 +125,7 @@ static void htc_process_conn_rsp(struct htc_target *target,
}
}
if (!tmp_endpoint)
if (tepid == ENDPOINT0)
return;
endpoint->service_id = service_id;
......@@ -297,7 +298,7 @@ void htc_stop(struct htc_target *target)
enum htc_endpoint_id epid;
struct htc_endpoint *endpoint;
for (epid = ENDPOINT0; epid <= ENDPOINT_MAX; epid++) {
for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) {
endpoint = &target->endpoint[epid];
if (endpoint->service_id != 0)
target->hif->stop(target->hif_dev, endpoint->ul_pipeid);
......@@ -309,7 +310,7 @@ void htc_start(struct htc_target *target)
enum htc_endpoint_id epid;
struct htc_endpoint *endpoint;
for (epid = ENDPOINT0; epid <= ENDPOINT_MAX; epid++) {
for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) {
endpoint = &target->endpoint[epid];
if (endpoint->service_id != 0)
target->hif->start(target->hif_dev,
......@@ -425,29 +426,19 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,
}
}
struct htc_target *ath9k_htc_hw_alloc(void *hif_handle)
struct htc_target *ath9k_htc_hw_alloc(void *hif_handle,
struct ath9k_htc_hif *hif,
struct device *dev)
{
struct htc_endpoint *endpoint;
struct htc_target *target;
target = kzalloc(sizeof(struct htc_target), GFP_KERNEL);
if (!target)
if (!target) {
printk(KERN_ERR "Unable to allocate memory for"
"target device\n");
return target;
}
void ath9k_htc_hw_free(struct htc_target *htc)
{
kfree(htc);
}
int ath9k_htc_hw_init(struct ath9k_htc_hif *hif, struct htc_target *target,
void *hif_handle, struct device *dev, u16 devid,
enum ath9k_hif_transports transport)
{
struct htc_endpoint *endpoint;
int err = 0;
return NULL;
}
init_completion(&target->target_wait);
init_completion(&target->cmd_wait);
......@@ -461,8 +452,20 @@ int ath9k_htc_hw_init(struct ath9k_htc_hif *hif, struct htc_target *target,
endpoint->ul_pipeid = hif->control_ul_pipe;
endpoint->dl_pipeid = hif->control_dl_pipe;
err = ath9k_htc_probe_device(target, dev, devid);
if (err) {
atomic_set(&target->tgt_ready, 0);
return target;
}
void ath9k_htc_hw_free(struct htc_target *htc)
{
kfree(htc);
}
int ath9k_htc_hw_init(struct htc_target *target,
struct device *dev, u16 devid)
{
if (ath9k_htc_probe_device(target, dev, devid)) {
printk(KERN_ERR "Failed to initialize the device\n");
return -ENODEV;
}
......
......@@ -123,9 +123,6 @@ struct htc_endpoint {
#define HTC_CONTROL_BUFFER_SIZE \
(HTC_MAX_CONTROL_MESSAGE_LENGTH + sizeof(struct htc_frame_hdr))
#define NUM_CONTROL_BUFFERS 8
#define HST_ENDPOINT_MAX 8
struct htc_control_buf {
struct htc_packet htc_pkt;
u8 buf[HTC_CONTROL_BUFFER_SIZE];
......@@ -139,7 +136,7 @@ struct htc_target {
struct ath9k_htc_priv *drv_priv;
struct device *dev;
struct ath9k_htc_hif *hif;
struct htc_endpoint endpoint[HST_ENDPOINT_MAX];
struct htc_endpoint endpoint[ENDPOINT_MAX];
struct completion target_wait;
struct completion cmd_wait;
struct list_head list;
......@@ -147,6 +144,7 @@ struct htc_target {
u16 credits;
u16 credit_size;
u8 htc_flags;
atomic_t tgt_ready;
};
enum htc_msg_id {
......@@ -236,11 +234,12 @@ void ath9k_htc_rx_msg(struct htc_target *htc_handle,
void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
struct sk_buff *skb, bool txok);
struct htc_target *ath9k_htc_hw_alloc(void *hif_handle);
struct htc_target *ath9k_htc_hw_alloc(void *hif_handle,
struct ath9k_htc_hif *hif,
struct device *dev);
void ath9k_htc_hw_free(struct htc_target *htc);
int ath9k_htc_hw_init(struct ath9k_htc_hif *hif, struct htc_target *target,
void *hif_handle, struct device *dev, u16 devid,
enum ath9k_hif_transports transport);
int ath9k_htc_hw_init(struct htc_target *target,
struct device *dev, u16 devid);
void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug);
#endif /* HTC_HST_H */
......@@ -150,11 +150,9 @@ static bool ath_rx_edma_buf_link(struct ath_softc *sc,
static void ath_rx_addbuffer_edma(struct ath_softc *sc,
enum ath9k_rx_qtype qtype, int size)
{
struct ath_rx_edma *rx_edma;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
u32 nbuf = 0;
rx_edma = &sc->rx.rx_edma[qtype];
if (list_empty(&sc->rx.rxbuf)) {
ath_print(common, ATH_DBG_QUEUE, "No free rx buf available\n");
return;
......@@ -718,6 +716,7 @@ static bool ath_edma_get_buffers(struct ath_softc *sc,
__skb_unlink(skb, &rx_edma->rx_fifo);
list_add_tail(&bf->list, &sc->rx.rxbuf);
ath_rx_edma_buf_link(sc, qtype);
return true;
}
skb_queue_tail(&rx_edma->rx_buffers, skb);
......
......@@ -355,8 +355,7 @@ static struct hostap_bss_info *__hostap_add_bss(local_info_t *local, u8 *bssid,
list_del(&bss->list);
local->num_bss_info--;
} else {
bss = (struct hostap_bss_info *)
kmalloc(sizeof(*bss), GFP_ATOMIC);
bss = kmalloc(sizeof(*bss), GFP_ATOMIC);
if (bss == NULL)
return NULL;
}
......
......@@ -3039,8 +3039,7 @@ static int prism2_ioctl_priv_download(local_info_t *local, struct iw_point *p)
p->length > 1024 || !p->pointer)
return -EINVAL;
param = (struct prism2_download_param *)
kmalloc(p->length, GFP_KERNEL);
param = kmalloc(p->length, GFP_KERNEL);
if (param == NULL)
return -ENOMEM;
......
......@@ -212,7 +212,7 @@ static struct iwl_lib_ops iwl1000_lib = {
.temperature = iwlagn_temperature,
.set_ct_kill = iwl1000_set_ct_threshold,
},
.add_bcast_station = iwl_add_bcast_station,
.manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
......@@ -224,7 +224,6 @@ static struct iwl_lib_ops iwl1000_lib = {
};
static const struct iwl_ops iwl1000_ops = {
.ucode = &iwlagn_ucode,
.lib = &iwl1000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
......@@ -260,6 +259,9 @@ struct iwl_cfg iwl1000_bgn_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 128,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
struct iwl_cfg iwl1000_bg_cfg = {
......@@ -289,6 +291,9 @@ struct iwl_cfg iwl1000_bg_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 128,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
......@@ -391,6 +391,67 @@ static void iwl3945_accumulative_statistics(struct iwl_priv *priv,
}
#endif
/**
* iwl3945_good_plcp_health - checks for plcp error.
*
* When the plcp error is exceeding the thresholds, reset the radio
* to improve the throughput.
*/
static bool iwl3945_good_plcp_health(struct iwl_priv *priv,
struct iwl_rx_packet *pkt)
{
bool rc = true;
struct iwl3945_notif_statistics current_stat;
int combined_plcp_delta;
unsigned int plcp_msec;
unsigned long plcp_received_jiffies;
memcpy(&current_stat, pkt->u.raw, sizeof(struct
iwl3945_notif_statistics));
/*
* check for plcp_err and trigger radio reset if it exceeds
* the plcp error threshold plcp_delta.
*/
plcp_received_jiffies = jiffies;
plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
(long) priv->plcp_jiffies);
priv->plcp_jiffies = plcp_received_jiffies;
/*
* check to make sure plcp_msec is not 0 to prevent division
* by zero.
*/
if (plcp_msec) {
combined_plcp_delta =
(le32_to_cpu(current_stat.rx.ofdm.plcp_err) -
le32_to_cpu(priv->_3945.statistics.rx.ofdm.plcp_err));
if ((combined_plcp_delta > 0) &&
((combined_plcp_delta * 100) / plcp_msec) >
priv->cfg->plcp_delta_threshold) {
/*
* if plcp_err exceed the threshold, the following
* data is printed in csv format:
* Text: plcp_err exceeded %d,
* Received ofdm.plcp_err,
* Current ofdm.plcp_err,
* combined_plcp_delta,
* plcp_msec
*/
IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
"%u, %d, %u mSecs\n",
priv->cfg->plcp_delta_threshold,
le32_to_cpu(current_stat.rx.ofdm.plcp_err),
combined_plcp_delta, plcp_msec);
/*
* Reset the RF radio due to the high plcp
* error rate
*/
rc = false;
}
}
return rc;
}
void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
......@@ -402,6 +463,7 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
#ifdef CONFIG_IWLWIFI_DEBUG
iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw);
#endif
iwl_recover_from_statistics(priv, pkt);
memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics));
}
......@@ -885,7 +947,8 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]);
}
u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id,
u16 tx_rate, u8 flags)
{
unsigned long flags_spin;
struct iwl_station_entry *station;
......@@ -1715,6 +1778,11 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
int ref_temp;
int temperature = priv->temperature;
if (priv->disable_tx_power_cal ||
test_bit(STATUS_SCANNING, &priv->status)) {
/* do not perform tx power calibration */
return 0;
}
/* set up new Tx power info for each and every channel, 2.4 and 5.x */
for (i = 0; i < priv->channel_count; i++) {
ch_info = &priv->channel_info[i];
......@@ -1925,7 +1993,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
"configuration (%d).\n", rc);
return rc;
}
iwl_clear_ucode_stations(priv, false);
iwl_clear_ucode_stations(priv);
iwl_restore_stations(priv);
}
......@@ -1958,7 +2026,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
if (!new_assoc) {
iwl_clear_ucode_stations(priv, false);
iwl_clear_ucode_stations(priv);
iwl_restore_stations(priv);
}
......@@ -2391,6 +2459,30 @@ static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
return (u16)sizeof(struct iwl3945_addsta_cmd);
}
static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
struct ieee80211_vif *vif, bool add)
{
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
int ret;
if (add) {
ret = iwl_add_bssid_station(priv, vif->bss_conf.bssid, false,
&vif_priv->ibss_bssid_sta_id);
if (ret)
return ret;
iwl3945_sync_sta(priv, vif_priv->ibss_bssid_sta_id,
(priv->band == IEEE80211_BAND_5GHZ) ?
IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
CMD_ASYNC);
iwl3945_rate_scale_init(priv->hw, vif_priv->ibss_bssid_sta_id);
return 0;
}
return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
vif->bss_conf.bssid);
}
/**
* iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table
......@@ -2720,51 +2812,12 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
return 0;
}
#define IWL3945_UCODE_GET(item) \
static u32 iwl3945_ucode_get_##item(const struct iwl_ucode_header *ucode,\
u32 api_ver) \
{ \
return le32_to_cpu(ucode->u.v1.item); \
}
static u32 iwl3945_ucode_get_header_size(u32 api_ver)
{
return UCODE_HEADER_SIZE(1);
}
static u32 iwl3945_ucode_get_build(const struct iwl_ucode_header *ucode,
u32 api_ver)
{
return 0;
}
static u8 *iwl3945_ucode_get_data(const struct iwl_ucode_header *ucode,
u32 api_ver)
{
return (u8 *) ucode->u.v1.data;
}
IWL3945_UCODE_GET(inst_size);
IWL3945_UCODE_GET(data_size);
IWL3945_UCODE_GET(init_size);
IWL3945_UCODE_GET(init_data_size);
IWL3945_UCODE_GET(boot_size);
static struct iwl_hcmd_ops iwl3945_hcmd = {
.rxon_assoc = iwl3945_send_rxon_assoc,
.commit_rxon = iwl3945_commit_rxon,
.send_bt_config = iwl_send_bt_config,
};
static struct iwl_ucode_ops iwl3945_ucode = {
.get_header_size = iwl3945_ucode_get_header_size,
.get_build = iwl3945_ucode_get_build,
.get_inst_size = iwl3945_ucode_get_inst_size,
.get_data_size = iwl3945_ucode_get_data_size,
.get_init_size = iwl3945_ucode_get_init_size,
.get_init_data_size = iwl3945_ucode_get_init_data_size,
.get_boot_size = iwl3945_ucode_get_boot_size,
.get_data = iwl3945_ucode_get_data,
};
static struct iwl_lib_ops iwl3945_lib = {
.txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl3945_hw_txq_free_tfd,
......@@ -2798,7 +2851,8 @@ static struct iwl_lib_ops iwl3945_lib = {
.post_associate = iwl3945_post_associate,
.isr = iwl_isr_legacy,
.config_ap = iwl3945_config_ap,
.add_bcast_station = iwl3945_add_bcast_station,
.manage_ibss_station = iwl3945_manage_ibss_station,
.check_plcp_health = iwl3945_good_plcp_health,
.debugfs_ops = {
.rx_stats_read = iwl3945_ucode_rx_stats_read,
......@@ -2815,7 +2869,6 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
};
static const struct iwl_ops iwl3945_ops = {
.ucode = &iwl3945_ucode,
.lib = &iwl3945_lib,
.hcmd = &iwl3945_hcmd,
.utils = &iwl3945_hcmd_utils,
......@@ -2840,9 +2893,10 @@ static struct iwl_cfg iwl3945_bg_cfg = {
.ht_greenfield_support = false,
.led_compensation = 64,
.broken_powersave = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.tx_power_by_driver = true,
};
static struct iwl_cfg iwl3945_abg_cfg = {
......@@ -2860,9 +2914,10 @@ static struct iwl_cfg iwl3945_abg_cfg = {
.ht_greenfield_support = false,
.led_compensation = 64,
.broken_powersave = true,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.tx_power_by_driver = true,
};
DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {
......
......@@ -106,7 +106,12 @@ struct iwl3945_rs_sta {
};
/*
* The common struct MUST be first because it is shared between
* 3945 and agn!
*/
struct iwl3945_sta_priv {
struct iwl_station_priv_common common;
struct iwl3945_rs_sta rs_sta;
};
......@@ -211,13 +216,6 @@ extern int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
char **buf, bool display);
extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv);
/*
* Currently used by iwl-3945-rs... look at restructuring so that it doesn't
* call this... todo... fix that.
*/
extern u8 iwl3945_sync_station(struct iwl_priv *priv, int sta_id,
u16 tx_rate, u8 flags);
/******************************************************************************
*
* Functions implemented in iwl-[34]*.c which are forward declared here
......@@ -268,8 +266,10 @@ void iwl3945_reply_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
extern void iwl3945_disable_events(struct iwl_priv *priv);
extern int iwl4965_get_temperature(const struct iwl_priv *priv);
extern void iwl3945_post_associate(struct iwl_priv *priv);
extern void iwl3945_config_ap(struct iwl_priv *priv);
extern void iwl3945_post_associate(struct iwl_priv *priv,
struct ieee80211_vif *vif);
extern void iwl3945_config_ap(struct iwl_priv *priv,
struct ieee80211_vif *vif);
/**
* iwl3945_hw_find_station - Find station id for a given BSSID
......@@ -288,8 +288,6 @@ extern __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv);
extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv);
extern void iwl3945_reg_txpower_periodic(struct iwl_priv *priv);
extern int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv);
extern u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id,
u16 tx_rate, u8 flags);
extern const struct iwl_channel_info *iwl3945_get_channel_info(
const struct iwl_priv *priv, enum ieee80211_band band, u16 channel);
......@@ -297,7 +295,7 @@ extern const struct iwl_channel_info *iwl3945_get_channel_info(
extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate);
/* scanning */
void iwl3945_request_scan(struct iwl_priv *priv);
void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
/* Requires full declaration of iwl_priv before including */
#include "iwl-io.h"
......
......@@ -1953,6 +1953,60 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
return 0;
}
static u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
{
int i;
int start = 0;
int ret = IWL_INVALID_STATION;
unsigned long flags;
if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) ||
(priv->iw_mode == NL80211_IFTYPE_AP))
start = IWL_STA_ID;
if (is_broadcast_ether_addr(addr))
return priv->hw_params.bcast_sta_id;
spin_lock_irqsave(&priv->sta_lock, flags);
for (i = start; i < priv->hw_params.max_stations; i++)
if (priv->stations[i].used &&
(!compare_ether_addr(priv->stations[i].sta.sta.addr,
addr))) {
ret = i;
goto out;
}
IWL_DEBUG_ASSOC_LIMIT(priv, "can not find STA %pM total %d\n",
addr, priv->num_stations);
out:
/*
* It may be possible that more commands interacting with stations
* arrive before we completed processing the adding of
* station
*/
if (ret != IWL_INVALID_STATION &&
(!(priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) ||
((priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) &&
(priv->stations[ret].used & IWL_STA_UCODE_INPROGRESS)))) {
IWL_ERR(priv, "Requested station info for sta %d before ready.\n",
ret);
ret = IWL_INVALID_STATION;
}
spin_unlock_irqrestore(&priv->sta_lock, flags);
return ret;
}
static int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
{
if (priv->iw_mode == NL80211_IFTYPE_STATION) {
return IWL_AP_ID;
} else {
u8 *da = ieee80211_get_DA(hdr);
return iwl_find_station(priv, da);
}
}
/**
* iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response
*/
......@@ -2112,34 +2166,6 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
cancel_work_sync(&priv->txpower_work);
}
#define IWL4965_UCODE_GET(item) \
static u32 iwl4965_ucode_get_##item(const struct iwl_ucode_header *ucode,\
u32 api_ver) \
{ \
return le32_to_cpu(ucode->u.v1.item); \
}
static u32 iwl4965_ucode_get_header_size(u32 api_ver)
{
return UCODE_HEADER_SIZE(1);
}
static u32 iwl4965_ucode_get_build(const struct iwl_ucode_header *ucode,
u32 api_ver)
{
return 0;
}
static u8 *iwl4965_ucode_get_data(const struct iwl_ucode_header *ucode,
u32 api_ver)
{
return (u8 *) ucode->u.v1.data;
}
IWL4965_UCODE_GET(inst_size);
IWL4965_UCODE_GET(data_size);
IWL4965_UCODE_GET(init_size);
IWL4965_UCODE_GET(init_data_size);
IWL4965_UCODE_GET(boot_size);
static struct iwl_hcmd_ops iwl4965_hcmd = {
.rxon_assoc = iwl4965_send_rxon_assoc,
.commit_rxon = iwl_commit_rxon,
......@@ -2147,16 +2173,6 @@ static struct iwl_hcmd_ops iwl4965_hcmd = {
.send_bt_config = iwl_send_bt_config,
};
static struct iwl_ucode_ops iwl4965_ucode = {
.get_header_size = iwl4965_ucode_get_header_size,
.get_build = iwl4965_ucode_get_build,
.get_inst_size = iwl4965_ucode_get_inst_size,
.get_data_size = iwl4965_ucode_get_data_size,
.get_init_size = iwl4965_ucode_get_init_size,
.get_init_data_size = iwl4965_ucode_get_init_data_size,
.get_boot_size = iwl4965_ucode_get_boot_size,
.get_data = iwl4965_ucode_get_data,
};
static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
.get_hcmd_size = iwl4965_get_hcmd_size,
.build_addsta_hcmd = iwl4965_build_addsta_hcmd,
......@@ -2218,7 +2234,7 @@ static struct iwl_lib_ops iwl4965_lib = {
.temperature = iwl4965_temperature_calib,
.set_ct_kill = iwl4965_set_ct_threshold,
},
.add_bcast_station = iwl_add_bcast_station,
.manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
......@@ -2228,7 +2244,6 @@ static struct iwl_lib_ops iwl4965_lib = {
};
static const struct iwl_ops iwl4965_ops = {
.ucode = &iwl4965_ucode,
.lib = &iwl4965_lib,
.hcmd = &iwl4965_hcmd,
.utils = &iwl4965_hcmd_utils,
......@@ -2262,7 +2277,10 @@ struct iwl_cfg iwl4965_agn_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.temperature_kelvin = true,
.max_event_log_size = 512,
.tx_power_by_driver = true,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
/*
* Force use of chains B and C for scan RX on 5 GHz band
* because the device has off-channel reception on chain A.
......
......@@ -351,7 +351,7 @@ static struct iwl_lib_ops iwl5000_lib = {
.temperature = iwlagn_temperature,
.set_ct_kill = iwl5000_set_ct_threshold,
},
.add_bcast_station = iwl_add_bcast_station,
.manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
......@@ -413,7 +413,7 @@ static struct iwl_lib_ops iwl5150_lib = {
.temperature = iwl5150_temperature,
.set_ct_kill = iwl5150_set_ct_threshold,
},
.add_bcast_station = iwl_add_bcast_station,
.manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
......@@ -425,7 +425,6 @@ static struct iwl_lib_ops iwl5150_lib = {
};
static const struct iwl_ops iwl5000_ops = {
.ucode = &iwlagn_ucode,
.lib = &iwl5000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
......@@ -433,7 +432,6 @@ static const struct iwl_ops iwl5000_ops = {
};
static const struct iwl_ops iwl5150_ops = {
.ucode = &iwlagn_ucode,
.lib = &iwl5150_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
......@@ -466,6 +464,9 @@ struct iwl_cfg iwl5300_agn_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
struct iwl_cfg iwl5100_bgn_cfg = {
......@@ -494,6 +495,9 @@ struct iwl_cfg iwl5100_bgn_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
struct iwl_cfg iwl5100_abg_cfg = {
......@@ -520,6 +524,9 @@ struct iwl_cfg iwl5100_abg_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
struct iwl_cfg iwl5100_agn_cfg = {
......@@ -548,6 +555,9 @@ struct iwl_cfg iwl5100_agn_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
struct iwl_cfg iwl5350_agn_cfg = {
......@@ -576,6 +586,9 @@ struct iwl_cfg iwl5350_agn_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
struct iwl_cfg iwl5150_agn_cfg = {
......@@ -604,6 +617,9 @@ struct iwl_cfg iwl5150_agn_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
struct iwl_cfg iwl5150_abg_cfg = {
......@@ -630,6 +646,9 @@ struct iwl_cfg iwl5150_abg_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
......
......@@ -67,9 +67,10 @@
#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api)
#define IWL6000G2_FW_PRE "iwlwifi-6005-"
#define _IWL6000G2_MODULE_FIRMWARE(api) IWL6000G2_FW_PRE #api ".ucode"
#define IWL6000G2_MODULE_FIRMWARE(api) _IWL6000G2_MODULE_FIRMWARE(api)
#define IWL6000G2A_FW_PRE "iwlwifi-6000g2a-"
#define _IWL6000G2A_MODULE_FIRMWARE(api) IWL6000G2A_FW_PRE #api ".ucode"
#define IWL6000G2A_MODULE_FIRMWARE(api) _IWL6000G2A_MODULE_FIRMWARE(api)
static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
{
......@@ -316,7 +317,7 @@ static struct iwl_lib_ops iwl6000_lib = {
.temperature = iwlagn_temperature,
.set_ct_kill = iwl6000_set_ct_threshold,
},
.add_bcast_station = iwl_add_bcast_station,
.manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
......@@ -328,7 +329,6 @@ static struct iwl_lib_ops iwl6000_lib = {
};
static const struct iwl_ops iwl6000_ops = {
.ucode = &iwlagn_ucode,
.lib = &iwl6000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
......@@ -389,7 +389,7 @@ static struct iwl_lib_ops iwl6050_lib = {
.set_ct_kill = iwl6000_set_ct_threshold,
.set_calib_version = iwl6050_set_calib_version,
},
.add_bcast_station = iwl_add_bcast_station,
.manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
......@@ -401,19 +401,16 @@ static struct iwl_lib_ops iwl6050_lib = {
};
static const struct iwl_ops iwl6050_ops = {
.ucode = &iwlagn_ucode,
.lib = &iwl6050_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
.led = &iwlagn_led_ops,
};
/*
* "i": Internal configuration, use internal Power Amplifier
*/
struct iwl_cfg iwl6000g2_2agn_cfg = {
.name = "6000 Series 2x2 AGN Gen2",
.fw_name_pre = IWL6000G2_FW_PRE,
struct iwl_cfg iwl6000g2a_2agn_cfg = {
.name = "6000 Series 2x2 AGN Gen2a",
.fw_name_pre = IWL6000G2A_FW_PRE,
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
......@@ -442,9 +439,15 @@ struct iwl_cfg iwl6000g2_2agn_cfg = {
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.max_event_log_size = 512,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
/*
* "i": Internal configuration, use internal Power Amplifier
*/
struct iwl_cfg iwl6000i_2agn_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
.fw_name_pre = IWL6000_FW_PRE,
......@@ -477,6 +480,9 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
struct iwl_cfg iwl6000i_2abg_cfg = {
......@@ -509,6 +515,9 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
struct iwl_cfg iwl6000i_2bg_cfg = {
......@@ -541,6 +550,9 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
struct iwl_cfg iwl6050_2agn_cfg = {
......@@ -575,6 +587,9 @@ struct iwl_cfg iwl6050_2agn_cfg = {
.chain_noise_scale = 1500,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
struct iwl_cfg iwl6050_2abg_cfg = {
......@@ -607,6 +622,9 @@ struct iwl_cfg iwl6050_2abg_cfg = {
.chain_noise_scale = 1500,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
struct iwl_cfg iwl6000_3agn_cfg = {
......@@ -641,8 +659,11 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
.sensitivity_calib_by_driver = true,
.chain_noise_calib_by_driver = true,
};
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
MODULE_FIRMWARE(IWL6000G2_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
......@@ -709,6 +709,22 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file,
delta_tx->agg.rx_ba_rsp_cnt,
max_tx->agg.rx_ba_rsp_cnt);
if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
pos += scnprintf(buf + pos, bufsz - pos,
"tx power: (1/2 dB step)\n");
if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a)
pos += scnprintf(buf + pos, bufsz - pos,
"\tantenna A: 0x%X\n",
tx->tx_power.ant_a);
if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b)
pos += scnprintf(buf + pos, bufsz - pos,
"\tantenna B: 0x%X\n",
tx->tx_power.ant_b);
if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c)
pos += scnprintf(buf + pos, bufsz - pos,
"\tantenna C: 0x%X\n",
tx->tx_power.ant_c);
}
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
kfree(buf);
return ret;
......
......@@ -38,6 +38,7 @@
#include "iwl-helpers.h"
#include "iwl-agn-hw.h"
#include "iwl-agn.h"
#include "iwl-sta.h"
static inline u32 iwlagn_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
{
......@@ -1113,8 +1114,9 @@ void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
}
static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
enum ieee80211_band band,
struct iwl_scan_channel *scan_ch)
struct ieee80211_vif *vif,
enum ieee80211_band band,
struct iwl_scan_channel *scan_ch)
{
const struct ieee80211_supported_band *sband;
const struct iwl_channel_info *ch_info;
......@@ -1130,7 +1132,7 @@ static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
}
active_dwell = iwl_get_active_dwell_time(priv, band, 0);
passive_dwell = iwl_get_passive_dwell_time(priv, band);
passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);
if (passive_dwell <= active_dwell)
passive_dwell = active_dwell + 1;
......@@ -1179,6 +1181,7 @@ static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
}
static int iwl_get_channels_for_scan(struct iwl_priv *priv,
struct ieee80211_vif *vif,
enum ieee80211_band band,
u8 is_active, u8 n_probes,
struct iwl_scan_channel *scan_ch)
......@@ -1196,7 +1199,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
return 0;
active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
passive_dwell = iwl_get_passive_dwell_time(priv, band);
passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);
if (passive_dwell <= active_dwell)
passive_dwell = active_dwell + 1;
......@@ -1256,7 +1259,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
return added;
}
void iwlagn_request_scan(struct iwl_priv *priv)
void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
struct iwl_host_cmd cmd = {
.id = REPLY_SCAN_CMD,
......@@ -1342,7 +1345,7 @@ void iwlagn_request_scan(struct iwl_priv *priv)
IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
spin_lock_irqsave(&priv->lock, flags);
interval = priv->beacon_int;
interval = vif ? vif->bss_conf.beacon_int : 0;
spin_unlock_irqrestore(&priv->lock, flags);
scan->suspend_time = 0;
......@@ -1473,12 +1476,12 @@ void iwlagn_request_scan(struct iwl_priv *priv)
if (priv->is_internal_short_scan) {
scan->channel_count =
iwl_get_single_channel_for_scan(priv, band,
iwl_get_single_channel_for_scan(priv, vif, band,
(void *)&scan->data[le16_to_cpu(
scan->tx_cmd.len)]);
} else {
scan->channel_count =
iwl_get_channels_for_scan(priv, band,
iwl_get_channels_for_scan(priv, vif, band,
is_active, n_probes,
(void *)&scan->data[le16_to_cpu(
scan->tx_cmd.len)]);
......@@ -1513,3 +1516,15 @@ void iwlagn_request_scan(struct iwl_priv *priv)
/* inform mac80211 scan aborted */
queue_work(priv->workqueue, &priv->scan_completed);
}
int iwlagn_manage_ibss_station(struct iwl_priv *priv,
struct ieee80211_vif *vif, bool add)
{
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
if (add)
return iwl_add_bssid_station(priv, vif->bss_conf.bssid, true,
&vif_priv->ibss_bssid_sta_id);
return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
vif->bss_conf.bssid);
}
......@@ -566,11 +566,11 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
hdr_len = ieee80211_hdrlen(fc);
/* Find (or create) index into station table for destination station */
if (info->flags & IEEE80211_TX_CTL_INJECTED)
/* Find index into station table for destination station */
if (!info->control.sta)
sta_id = priv->hw_params.bcast_sta_id;
else
sta_id = iwl_get_sta_id(priv, hdr);
sta_id = iwl_sta_id(info->control.sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
......@@ -961,7 +961,8 @@ static int iwlagn_txq_ctx_activate_free(struct iwl_priv *priv)
return -1;
}
int iwlagn_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid, u16 *ssn)
{
int sta_id;
int tx_fifo;
......@@ -975,9 +976,9 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
return tx_fifo;
IWL_WARN(priv, "%s on ra = %pM tid = %d\n",
__func__, ra, tid);
__func__, sta->addr, tid);
sta_id = iwl_find_station(priv, ra);
sta_id = iwl_sta_id(sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_ERR(priv, "Start AGG on invalid station\n");
return -ENXIO;
......@@ -1011,7 +1012,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
if (tid_data->tfds_in_queue == 0) {
IWL_DEBUG_HT(priv, "HW queue is empty\n");
tid_data->agg.state = IWL_AGG_ON;
ieee80211_start_tx_ba_cb_irqsafe(priv->vif, ra, tid);
ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
} else {
IWL_DEBUG_HT(priv, "HW queue is NOT empty: %d packets in HW queue\n",
tid_data->tfds_in_queue);
......@@ -1020,23 +1021,19 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
return ret;
}
int iwlagn_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid)
{
int tx_fifo_id, txq_id, sta_id, ssn = -1;
struct iwl_tid_data *tid_data;
int write_ptr, read_ptr;
unsigned long flags;
if (!ra) {
IWL_ERR(priv, "ra = NULL\n");
return -EINVAL;
}
tx_fifo_id = get_fifo_from_tid(tid);
if (unlikely(tx_fifo_id < 0))
return tx_fifo_id;
sta_id = iwl_find_station(priv, ra);
sta_id = iwl_sta_id(sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
......@@ -1046,7 +1043,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
if (priv->stations[sta_id].tid[tid].agg.state ==
IWL_EMPTYING_HW_QUEUE_ADDBA) {
IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid);
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
return 0;
}
......@@ -1083,7 +1080,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
tx_fifo_id);
spin_unlock_irqrestore(&priv->lock, flags);
ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid);
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
return 0;
}
......
......@@ -52,6 +52,37 @@ static const s8 iwlagn_default_queue_to_tx_fifo[] = {
IWL_TX_FIFO_UNUSED,
};
static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
{COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
0, COEX_UNASSOC_IDLE_FLAGS},
{COEX_CU_UNASSOC_MANUAL_SCAN_RP, COEX_CU_UNASSOC_MANUAL_SCAN_WP,
0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
{COEX_CU_UNASSOC_AUTO_SCAN_RP, COEX_CU_UNASSOC_AUTO_SCAN_WP,
0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
{COEX_CU_CALIBRATION_RP, COEX_CU_CALIBRATION_WP,
0, COEX_CALIBRATION_FLAGS},
{COEX_CU_PERIODIC_CALIBRATION_RP, COEX_CU_PERIODIC_CALIBRATION_WP,
0, COEX_PERIODIC_CALIBRATION_FLAGS},
{COEX_CU_CONNECTION_ESTAB_RP, COEX_CU_CONNECTION_ESTAB_WP,
0, COEX_CONNECTION_ESTAB_FLAGS},
{COEX_CU_ASSOCIATED_IDLE_RP, COEX_CU_ASSOCIATED_IDLE_WP,
0, COEX_ASSOCIATED_IDLE_FLAGS},
{COEX_CU_ASSOC_MANUAL_SCAN_RP, COEX_CU_ASSOC_MANUAL_SCAN_WP,
0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
{COEX_CU_ASSOC_AUTO_SCAN_RP, COEX_CU_ASSOC_AUTO_SCAN_WP,
0, COEX_ASSOC_AUTO_SCAN_FLAGS},
{COEX_CU_ASSOC_ACTIVE_LEVEL_RP, COEX_CU_ASSOC_ACTIVE_LEVEL_WP,
0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
{COEX_CU_RF_ON_RP, COEX_CU_RF_ON_WP, 0, COEX_CU_RF_ON_FLAGS},
{COEX_CU_RF_OFF_RP, COEX_CU_RF_OFF_WP, 0, COEX_RF_OFF_FLAGS},
{COEX_CU_STAND_ALONE_DEBUG_RP, COEX_CU_STAND_ALONE_DEBUG_WP,
0, COEX_STAND_ALONE_DEBUG_FLAGS},
{COEX_CU_IPAN_ASSOC_LEVEL_RP, COEX_CU_IPAN_ASSOC_LEVEL_WP,
0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
{COEX_CU_RSRVD1_RP, COEX_CU_RSRVD1_WP, 0, COEX_RSRVD1_FLAGS},
{COEX_CU_RSRVD2_RP, COEX_CU_RSRVD2_WP, 0, COEX_RSRVD2_FLAGS}
};
/*
* ucode
*/
......@@ -151,55 +182,6 @@ int iwlagn_load_ucode(struct iwl_priv *priv)
return ret;
}
#define IWL_UCODE_GET(item) \
static u32 iwlagn_ucode_get_##item(const struct iwl_ucode_header *ucode,\
u32 api_ver) \
{ \
if (api_ver <= 2) \
return le32_to_cpu(ucode->u.v1.item); \
return le32_to_cpu(ucode->u.v2.item); \
}
static u32 iwlagn_ucode_get_header_size(u32 api_ver)
{
if (api_ver <= 2)
return UCODE_HEADER_SIZE(1);
return UCODE_HEADER_SIZE(2);
}
static u32 iwlagn_ucode_get_build(const struct iwl_ucode_header *ucode,
u32 api_ver)
{
if (api_ver <= 2)
return 0;
return le32_to_cpu(ucode->u.v2.build);
}
static u8 *iwlagn_ucode_get_data(const struct iwl_ucode_header *ucode,
u32 api_ver)
{
if (api_ver <= 2)
return (u8 *) ucode->u.v1.data;
return (u8 *) ucode->u.v2.data;
}
IWL_UCODE_GET(inst_size);
IWL_UCODE_GET(data_size);
IWL_UCODE_GET(init_size);
IWL_UCODE_GET(init_data_size);
IWL_UCODE_GET(boot_size);
struct iwl_ucode_ops iwlagn_ucode = {
.get_header_size = iwlagn_ucode_get_header_size,
.get_build = iwlagn_ucode_get_build,
.get_inst_size = iwlagn_ucode_get_inst_size,
.get_data_size = iwlagn_ucode_get_data_size,
.get_init_size = iwlagn_ucode_get_init_size,
.get_init_data_size = iwlagn_ucode_get_init_data_size,
.get_boot_size = iwlagn_ucode_get_boot_size,
.get_data = iwlagn_ucode_get_data,
};
/*
* Calibration
*/
......@@ -320,6 +302,33 @@ void iwlagn_init_alive_start(struct iwl_priv *priv)
queue_work(priv->workqueue, &priv->restart);
}
static int iwlagn_send_wimax_coex(struct iwl_priv *priv)
{
struct iwl_wimax_coex_cmd coex_cmd;
if (priv->cfg->support_wimax_coexist) {
/* UnMask wake up src at associated sleep */
coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
/* UnMask wake up src at unassociated sleep */
coex_cmd.flags |= COEX_FLAGS_UNASSOC_WA_UNMASK_MSK;
memcpy(coex_cmd.sta_prio, cu_priorities,
sizeof(struct iwl_wimax_coex_event_entry) *
COEX_NUM_OF_EVENTS);
/* enabling the coexistence feature */
coex_cmd.flags |= COEX_FLAGS_COEX_ENABLE_MSK;
/* enabling the priorities tables */
coex_cmd.flags |= COEX_FLAGS_STA_TABLE_VALID_MSK;
} else {
/* coexistence is disabled */
memset(&coex_cmd, 0, sizeof(coex_cmd));
}
return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD,
sizeof(coex_cmd), &coex_cmd);
}
int iwlagn_alive_notify(struct iwl_priv *priv)
{
u32 a;
......@@ -407,7 +416,7 @@ int iwlagn_alive_notify(struct iwl_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags);
iwl_send_wimax_coex(priv);
iwlagn_send_wimax_coex(priv);
iwlagn_set_Xtal_calib(priv);
iwl_send_calib_results(priv);
......
......@@ -66,7 +66,6 @@
#include "iwl-dev.h"
extern struct iwl_mod_params iwlagn_mod_params;
extern struct iwl_ucode_ops iwlagn_ucode;
extern struct iwl_hcmd_ops iwlagn_hcmd;
extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
......@@ -136,9 +135,10 @@ void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
struct ieee80211_tx_info *info);
int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
int iwlagn_tx_agg_start(struct iwl_priv *priv,
const u8 *ra, u16 tid, u16 *ssn);
int iwlagn_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid, u16 *ssn);
int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid);
int iwlagn_txq_check_empty(struct iwl_priv *priv,
int sta_id, u8 tid, int txq_id);
void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
......@@ -172,6 +172,10 @@ static inline bool iwl_is_tx_success(u32 status)
}
/* scan */
void iwlagn_request_scan(struct iwl_priv *priv);
void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
/* station mgmt */
int iwlagn_manage_ibss_station(struct iwl_priv *priv,
struct ieee80211_vif *vif, bool add);
#endif /* __iwl_agn_h__ */
......@@ -2668,7 +2668,6 @@ struct iwl_ssid_ie {
#define IWL_GOOD_CRC_TH_NEVER cpu_to_le16(0xffff)
#define IWL_MAX_SCAN_SIZE 1024
#define IWL_MAX_CMD_SIZE 4096
#define IWL_MAX_PROBE_REQUEST 200
/*
* REPLY_SCAN_CMD = 0x80 (command)
......@@ -3128,6 +3127,11 @@ struct statistics_tx {
__le32 cts_timeout_collision;
__le32 ack_or_ba_timeout_collision;
struct statistics_tx_non_phy_agg agg;
/*
* "tx_power" are optional parameters provided by uCode,
* 6000 series is the only device provide the information,
* Those are reserved fields for all the other devices
*/
struct statistics_tx_power tx_power;
__le32 reserved1;
} __attribute__ ((packed));
......
......@@ -68,37 +68,6 @@ static bool bt_coex_active = true;
module_param(bt_coex_active, bool, S_IRUGO);
MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist");
static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
{COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
0, COEX_UNASSOC_IDLE_FLAGS},
{COEX_CU_UNASSOC_MANUAL_SCAN_RP, COEX_CU_UNASSOC_MANUAL_SCAN_WP,
0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
{COEX_CU_UNASSOC_AUTO_SCAN_RP, COEX_CU_UNASSOC_AUTO_SCAN_WP,
0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
{COEX_CU_CALIBRATION_RP, COEX_CU_CALIBRATION_WP,
0, COEX_CALIBRATION_FLAGS},
{COEX_CU_PERIODIC_CALIBRATION_RP, COEX_CU_PERIODIC_CALIBRATION_WP,
0, COEX_PERIODIC_CALIBRATION_FLAGS},
{COEX_CU_CONNECTION_ESTAB_RP, COEX_CU_CONNECTION_ESTAB_WP,
0, COEX_CONNECTION_ESTAB_FLAGS},
{COEX_CU_ASSOCIATED_IDLE_RP, COEX_CU_ASSOCIATED_IDLE_WP,
0, COEX_ASSOCIATED_IDLE_FLAGS},
{COEX_CU_ASSOC_MANUAL_SCAN_RP, COEX_CU_ASSOC_MANUAL_SCAN_WP,
0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
{COEX_CU_ASSOC_AUTO_SCAN_RP, COEX_CU_ASSOC_AUTO_SCAN_WP,
0, COEX_ASSOC_AUTO_SCAN_FLAGS},
{COEX_CU_ASSOC_ACTIVE_LEVEL_RP, COEX_CU_ASSOC_ACTIVE_LEVEL_WP,
0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
{COEX_CU_RF_ON_RP, COEX_CU_RF_ON_WP, 0, COEX_CU_RF_ON_FLAGS},
{COEX_CU_RF_OFF_RP, COEX_CU_RF_OFF_WP, 0, COEX_RF_OFF_FLAGS},
{COEX_CU_STAND_ALONE_DEBUG_RP, COEX_CU_STAND_ALONE_DEBUG_WP,
0, COEX_STAND_ALONE_DEBUG_FLAGS},
{COEX_CU_IPAN_ASSOC_LEVEL_RP, COEX_CU_IPAN_ASSOC_LEVEL_WP,
0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
{COEX_CU_RSRVD1_RP, COEX_CU_RSRVD1_WP, 0, COEX_RSRVD1_FLAGS},
{COEX_CU_RSRVD2_RP, COEX_CU_RSRVD2_WP, 0, COEX_RSRVD2_FLAGS}
};
#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \
[IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
IWL_RATE_SISO_##s##M_PLCP, \
......@@ -512,7 +481,7 @@ static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
return new_val;
}
void iwl_setup_rxon_timing(struct iwl_priv *priv)
void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
u64 tsf;
s32 interval_tm, rem;
......@@ -526,15 +495,14 @@ void iwl_setup_rxon_timing(struct iwl_priv *priv)
priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval);
if (priv->iw_mode == NL80211_IFTYPE_STATION) {
beacon_int = priv->beacon_int;
priv->rxon_timing.atim_window = 0;
} else {
beacon_int = priv->vif->bss_conf.beacon_int;
beacon_int = vif->bss_conf.beacon_int;
if (vif->type == NL80211_IFTYPE_ADHOC) {
/* TODO: we need to get atim_window from upper stack
* for now we set to 0 */
priv->rxon_timing.atim_window = 0;
} else {
priv->rxon_timing.atim_window = 0;
}
beacon_int = iwl_adjust_beacon_interval(beacon_int,
......@@ -925,8 +893,9 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch)
}
EXPORT_SYMBOL(iwl_set_rxon_channel);
void iwl_set_flags_for_band(struct iwl_priv *priv,
enum ieee80211_band band)
static void iwl_set_flags_for_band(struct iwl_priv *priv,
enum ieee80211_band band,
struct ieee80211_vif *vif)
{
if (band == IEEE80211_BAND_5GHZ) {
priv->staging_rxon.flags &=
......@@ -935,12 +904,12 @@ void iwl_set_flags_for_band(struct iwl_priv *priv,
priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
} else {
/* Copied from iwl_post_associate() */
if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
if (vif && vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
if (vif && vif->type == NL80211_IFTYPE_ADHOC)
priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
......@@ -952,13 +921,18 @@ void iwl_set_flags_for_band(struct iwl_priv *priv,
/*
* initialize rxon structure with default values from eeprom
*/
void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
void iwl_connection_init_rx_config(struct iwl_priv *priv,
struct ieee80211_vif *vif)
{
const struct iwl_channel_info *ch_info;
enum nl80211_iftype type = NL80211_IFTYPE_STATION;
if (vif)
type = vif->type;
memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
switch (mode) {
switch (type) {
case NL80211_IFTYPE_AP:
priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
break;
......@@ -976,7 +950,7 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
break;
default:
IWL_ERR(priv, "Unsupported interface type %d\n", mode);
IWL_ERR(priv, "Unsupported interface type %d\n", type);
break;
}
......@@ -998,7 +972,7 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
priv->band = ch_info->band;
iwl_set_flags_for_band(priv, priv->band);
iwl_set_flags_for_band(priv, priv->band, vif);
priv->staging_rxon.ofdm_basic_rates =
(IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
......@@ -1099,6 +1073,9 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
/* Cancel currently queued command. */
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
IWL_ERR(priv, "Loaded firmware version: %s\n",
priv->hw->wiphy->fw_version);
priv->cfg->ops->lib->dump_nic_error_log(priv);
if (priv->cfg->ops->lib->dump_csr)
priv->cfg->ops->lib->dump_csr(priv);
......@@ -1285,41 +1262,33 @@ void iwl_configure_filter(struct ieee80211_hw *hw,
u64 multicast)
{
struct iwl_priv *priv = hw->priv;
__le32 *filter_flags = &priv->staging_rxon.filter_flags;
__le32 filter_or = 0, filter_nand = 0;
#define CHK(test, flag) do { \
if (*total_flags & (test)) \
filter_or |= (flag); \
else \
filter_nand |= (flag); \
} while (0)
IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n",
changed_flags, *total_flags);
if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))
*filter_flags |= RXON_FILTER_PROMISC_MSK;
else
*filter_flags &= ~RXON_FILTER_PROMISC_MSK;
}
if (changed_flags & FIF_ALLMULTI) {
if (*total_flags & FIF_ALLMULTI)
*filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
else
*filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
}
if (changed_flags & FIF_CONTROL) {
if (*total_flags & FIF_CONTROL)
*filter_flags |= RXON_FILTER_CTL2HOST_MSK;
else
*filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
}
if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
*filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
else
*filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
}
CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK);
CHK(FIF_ALLMULTI, RXON_FILTER_ACCEPT_GRP_MSK);
CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK);
CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK);
/* We avoid iwl_commit_rxon here to commit the new filter flags
* since mac80211 will call ieee80211_hw_config immediately.
* (mc_list is not supported at this time). Otherwise, we need to
* queue a background iwl_commit_rxon work.
*/
#undef CHK
mutex_lock(&priv->mutex);
priv->staging_rxon.filter_flags &= ~filter_nand;
priv->staging_rxon.filter_flags |= filter_or;
iwlcore_commit_rxon(priv);
mutex_unlock(&priv->mutex);
*total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
......@@ -1771,10 +1740,11 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
EXPORT_SYMBOL(iwl_mac_conf_tx);
static void iwl_ht_conf(struct iwl_priv *priv,
struct ieee80211_bss_conf *bss_conf)
struct ieee80211_vif *vif)
{
struct iwl_ht_config *ht_conf = &priv->current_ht_config;
struct ieee80211_sta *sta;
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
IWL_DEBUG_MAC80211(priv, "enter:\n");
......@@ -1788,10 +1758,10 @@ static void iwl_ht_conf(struct iwl_priv *priv,
ht_conf->single_chain_sufficient = false;
switch (priv->iw_mode) {
switch (vif->type) {
case NL80211_IFTYPE_STATION:
rcu_read_lock();
sta = ieee80211_find_sta(priv->vif, priv->bssid);
sta = ieee80211_find_sta(vif, bss_conf->bssid);
if (sta) {
struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
int maxstreams;
......@@ -1829,7 +1799,6 @@ static void iwl_ht_conf(struct iwl_priv *priv,
static inline void iwl_set_no_assoc(struct iwl_priv *priv)
{
priv->assoc_id = 0;
iwl_led_disassociate(priv);
/*
* inform the ucode that there is no longer an
......@@ -1857,14 +1826,12 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
if (changes & BSS_CHANGED_BEACON &&
priv->iw_mode == NL80211_IFTYPE_AP) {
if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
dev_kfree_skb(priv->ibss_beacon);
priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
}
if (changes & BSS_CHANGED_BEACON_INT) {
priv->beacon_int = bss_conf->beacon_int;
/* TODO: in AP mode, do something to make this take effect */
}
......@@ -1884,8 +1851,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
}
/* mac80211 only sets assoc when in STATION mode */
if (priv->iw_mode == NL80211_IFTYPE_ADHOC ||
bss_conf->assoc) {
if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
memcpy(priv->staging_rxon.bssid_addr,
bss_conf->bssid, ETH_ALEN);
......@@ -1903,7 +1869,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
* mac80211 decides to do both changes at once because
* it will invoke post_associate.
*/
if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
if (vif->type == NL80211_IFTYPE_ADHOC &&
changes & BSS_CHANGED_BEACON) {
struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
......@@ -1946,7 +1912,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
}
if (changes & BSS_CHANGED_HT) {
iwl_ht_conf(priv, bss_conf);
iwl_ht_conf(priv, vif);
if (priv->cfg->ops->hcmd->set_rxon_chain)
priv->cfg->ops->hcmd->set_rxon_chain(priv);
......@@ -1955,20 +1921,17 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
if (changes & BSS_CHANGED_ASSOC) {
IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
if (bss_conf->assoc) {
priv->assoc_id = bss_conf->aid;
priv->beacon_int = bss_conf->beacon_int;
priv->timestamp = bss_conf->timestamp;
priv->assoc_capability = bss_conf->assoc_capability;
iwl_led_associate(priv);
if (!iwl_is_rfkill(priv))
priv->cfg->ops->lib->post_associate(priv);
priv->cfg->ops->lib->post_associate(priv, vif);
} else
iwl_set_no_assoc(priv);
}
if (changes && iwl_is_associated(priv) && priv->assoc_id) {
if (changes && iwl_is_associated(priv) && bss_conf->aid) {
IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n",
changes);
ret = iwl_send_rxon_assoc(priv);
......@@ -1985,11 +1948,20 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
memcpy(priv->staging_rxon.bssid_addr,
bss_conf->bssid, ETH_ALEN);
memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
iwlcore_config_ap(priv);
iwlcore_config_ap(priv, vif);
} else
iwl_set_no_assoc(priv);
}
if (changes & BSS_CHANGED_IBSS) {
ret = priv->cfg->ops->lib->manage_ibss_station(priv, vif,
bss_conf->ibss_joined);
if (ret)
IWL_ERR(priv, "failed to %s IBSS station %pM\n",
bss_conf->ibss_joined ? "add" : "remove",
bss_conf->bssid);
}
mutex_unlock(&priv->mutex);
IWL_DEBUG_MAC80211(priv, "leave\n");
......@@ -2016,14 +1988,13 @@ int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
priv->ibss_beacon = skb;
priv->assoc_id = 0;
timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
priv->timestamp = le64_to_cpu(timestamp);
IWL_DEBUG_MAC80211(priv, "leave\n");
spin_unlock_irqrestore(&priv->lock, flags);
priv->cfg->ops->lib->post_associate(priv);
priv->cfg->ops->lib->post_associate(priv, priv->vif);
return 0;
}
......@@ -2031,7 +2002,7 @@ EXPORT_SYMBOL(iwl_mac_beacon_update);
static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
iwl_connection_init_rx_config(priv, vif->type);
iwl_connection_init_rx_config(priv, vif);
if (priv->cfg->ops->hcmd->set_rxon_chain)
priv->cfg->ops->hcmd->set_rxon_chain(priv);
......@@ -2071,9 +2042,6 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
if (err)
goto out_err;
/* Add the broadcast address so we can send broadcast frames */
priv->cfg->ops->lib->add_bcast_station(priv);
goto out;
out_err:
......@@ -2096,8 +2064,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
mutex_lock(&priv->mutex);
iwl_clear_ucode_stations(priv, true);
if (iwl_is_ready_rf(priv)) {
iwl_scan_cancel_timeout(priv, 100);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
......@@ -2203,7 +2169,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
iwl_set_rxon_channel(priv, conf->channel);
iwl_set_rxon_ht(priv, ht_conf);
iwl_set_flags_for_band(priv, conf->channel->band);
iwl_set_flags_for_band(priv, conf->channel->band, priv->vif);
spin_unlock_irqrestore(&priv->lock, flags);
if (iwl_is_associated(priv) &&
(le16_to_cpu(priv->active_rxon.channel) != ch) &&
......@@ -2286,8 +2252,6 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
spin_unlock_irqrestore(&priv->lock, flags);
spin_lock_irqsave(&priv->lock, flags);
priv->assoc_id = 0;
priv->assoc_capability = 0;
/* new association get rid of ibss beacon skb */
if (priv->ibss_beacon)
......@@ -2295,7 +2259,6 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
priv->ibss_beacon = NULL;
priv->beacon_int = priv->vif->bss_conf.beacon_int;
priv->timestamp = 0;
spin_unlock_irqrestore(&priv->lock, flags);
......@@ -2342,34 +2305,6 @@ void iwl_free_txq_mem(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_free_txq_mem);
int iwl_send_wimax_coex(struct iwl_priv *priv)
{
struct iwl_wimax_coex_cmd coex_cmd;
if (priv->cfg->support_wimax_coexist) {
/* UnMask wake up src at associated sleep */
coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
/* UnMask wake up src at unassociated sleep */
coex_cmd.flags |= COEX_FLAGS_UNASSOC_WA_UNMASK_MSK;
memcpy(coex_cmd.sta_prio, cu_priorities,
sizeof(struct iwl_wimax_coex_event_entry) *
COEX_NUM_OF_EVENTS);
/* enabling the coexistence feature */
coex_cmd.flags |= COEX_FLAGS_COEX_ENABLE_MSK;
/* enabling the priorities tables */
coex_cmd.flags |= COEX_FLAGS_STA_TABLE_VALID_MSK;
} else {
/* coexistence is disabled */
memset(&coex_cmd, 0, sizeof(coex_cmd));
}
return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD,
sizeof(coex_cmd), &coex_cmd);
}
EXPORT_SYMBOL(iwl_send_wimax_coex);
#ifdef CONFIG_IWLWIFI_DEBUGFS
#define IWL_TRAFFIC_DUMP_SIZE (IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES)
......
......@@ -106,7 +106,7 @@ struct iwl_hcmd_utils_ops {
__le32 *tx_flags);
int (*calc_rssi)(struct iwl_priv *priv,
struct iwl_rx_phy_res *rx_resp);
void (*request_scan)(struct iwl_priv *priv);
void (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
};
struct iwl_apm_ops {
......@@ -131,17 +131,6 @@ struct iwl_temp_ops {
void (*set_calib_version)(struct iwl_priv *priv);
};
struct iwl_ucode_ops {
u32 (*get_header_size)(u32);
u32 (*get_build)(const struct iwl_ucode_header *, u32);
u32 (*get_inst_size)(const struct iwl_ucode_header *, u32);
u32 (*get_data_size)(const struct iwl_ucode_header *, u32);
u32 (*get_init_size)(const struct iwl_ucode_header *, u32);
u32 (*get_init_data_size)(const struct iwl_ucode_header *, u32);
u32 (*get_boot_size)(const struct iwl_ucode_header *, u32);
u8 * (*get_data)(const struct iwl_ucode_header *, u32);
};
struct iwl_lib_ops {
/* set hw dependent parameters */
int (*set_hw_params)(struct iwl_priv *priv);
......@@ -191,8 +180,9 @@ struct iwl_lib_ops {
/* power */
int (*send_tx_power) (struct iwl_priv *priv);
void (*update_chain_flags)(struct iwl_priv *priv);
void (*post_associate) (struct iwl_priv *priv);
void (*config_ap) (struct iwl_priv *priv);
void (*post_associate)(struct iwl_priv *priv,
struct ieee80211_vif *vif);
void (*config_ap)(struct iwl_priv *priv, struct ieee80211_vif *vif);
irqreturn_t (*isr) (int irq, void *data);
/* eeprom operations (as defined in iwl-eeprom.h) */
......@@ -201,7 +191,8 @@ struct iwl_lib_ops {
/* temperature */
struct iwl_temp_ops temp_ops;
/* station management */
void (*add_bcast_station)(struct iwl_priv *priv);
int (*manage_ibss_station)(struct iwl_priv *priv,
struct ieee80211_vif *vif, bool add);
/* recover from tx queue stall */
void (*recover_from_tx_stall)(unsigned long data);
/* check for plcp health */
......@@ -220,7 +211,6 @@ struct iwl_led_ops {
};
struct iwl_ops {
const struct iwl_ucode_ops *ucode;
const struct iwl_lib_ops *lib;
const struct iwl_hcmd_ops *hcmd;
const struct iwl_hcmd_utils_ops *utils;
......@@ -257,6 +247,18 @@ struct iwl_mod_params {
* @support_wimax_coexist: support wimax/wifi co-exist
* @plcp_delta_threshold: plcp error rate threshold used to trigger
* radio tuning when there is a high receiving plcp error rate
* @chain_noise_scale: default chain noise scale used for gain computation
* @monitor_recover_period: default timer used to check stuck queues
* @temperature_kelvin: temperature report by uCode in kelvin
* @max_event_log_size: size of event log buffer size for ucode event logging
* @tx_power_by_driver: tx power calibration performed by driver
* instead of uCode
* @ucode_tracing: support ucode continuous tracing
* @sensitivity_calib_by_driver: driver has the capability to perform
* sensitivity calibration operation
* @chain_noise_calib_by_driver: driver has the capability to perform
* chain noise calibration operation
* @scan_antennas: available antenna for scan operation
*
* We enable the driver to be backward compatible wrt API version. The
* driver specifies which APIs it supports (with @ucode_api_max being the
......@@ -319,6 +321,10 @@ struct iwl_cfg {
u32 monitor_recover_period;
bool temperature_kelvin;
u32 max_event_log_size;
const bool tx_power_by_driver;
const bool ucode_tracing;
const bool sensitivity_calib_by_driver;
const bool chain_noise_calib_by_driver;
u8 scan_antennas[IEEE80211_NUM_BANDS];
};
......@@ -340,8 +346,8 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch);
void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf);
u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
struct ieee80211_sta_ht_cap *sta_ht_inf);
void iwl_set_flags_for_band(struct iwl_priv *priv, enum ieee80211_band band);
void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode);
void iwl_connection_init_rx_config(struct iwl_priv *priv,
struct ieee80211_vif *vif);
int iwl_set_decrypted_flag(struct iwl_priv *priv,
struct ieee80211_hdr *hdr,
u32 decrypt_res,
......@@ -351,7 +357,7 @@ void iwl_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *total_flags, u64 multicast);
int iwl_set_hw_params(struct iwl_priv *priv);
void iwl_post_associate(struct iwl_priv *priv);
void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif);
void iwl_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
......@@ -363,13 +369,12 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
void iwl_mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
int iwl_mac_config(struct ieee80211_hw *hw, u32 changed);
void iwl_config_ap(struct iwl_priv *priv);
void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif);
void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
int iwl_alloc_txq_mem(struct iwl_priv *priv);
void iwl_free_txq_mem(struct iwl_priv *priv);
void iwlcore_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
__le32 *tx_flags);
int iwl_send_wimax_coex(struct iwl_priv *priv);
#ifdef CONFIG_IWLWIFI_DEBUGFS
int iwl_alloc_traffic_mem(struct iwl_priv *priv);
void iwl_free_traffic_mem(struct iwl_priv *priv);
......@@ -448,6 +453,8 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
struct iwl_rx_packet *pkt);
bool iwl_good_ack_health(struct iwl_priv *priv,
struct iwl_rx_packet *pkt);
void iwl_recover_from_statistics(struct iwl_priv *priv,
struct iwl_rx_packet *pkt);
void iwl_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
void iwl_reply_statistics(struct iwl_priv *priv,
......@@ -515,6 +522,7 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
int iwl_mac_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_scan_request *req);
void iwl_bg_start_internal_scan(struct work_struct *work);
void iwl_internal_short_hw_scan(struct iwl_priv *priv);
int iwl_force_reset(struct iwl_priv *priv, int mode);
u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
......@@ -524,7 +532,8 @@ u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
enum ieee80211_band band,
u8 n_probes);
u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
enum ieee80211_band band);
enum ieee80211_band band,
struct ieee80211_vif *vif);
void iwl_bg_scan_check(struct work_struct *data);
void iwl_bg_abort_scan(struct work_struct *work);
void iwl_bg_scan_completed(struct work_struct *work);
......@@ -688,7 +697,7 @@ extern int iwl_send_lq_cmd(struct iwl_priv *priv,
void iwl_apm_stop(struct iwl_priv *priv);
int iwl_apm_init(struct iwl_priv *priv);
void iwl_setup_rxon_timing(struct iwl_priv *priv);
void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif);
static inline int iwl_send_rxon_assoc(struct iwl_priv *priv)
{
return priv->cfg->ops->hcmd->rxon_assoc(priv);
......@@ -697,9 +706,10 @@ static inline int iwlcore_commit_rxon(struct iwl_priv *priv)
{
return priv->cfg->ops->hcmd->commit_rxon(priv);
}
static inline void iwlcore_config_ap(struct iwl_priv *priv)
static inline void iwlcore_config_ap(struct iwl_priv *priv,
struct ieee80211_vif *vif)
{
priv->cfg->ops->lib->config_ap(priv);
priv->cfg->ops->lib->config_ap(priv, vif);
}
static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
struct iwl_priv *priv, enum ieee80211_band band)
......
......@@ -1220,46 +1220,6 @@ static ssize_t iwl_dbgfs_chain_noise_read(struct file *file,
return ret;
}
static ssize_t iwl_dbgfs_tx_power_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos) {
struct iwl_priv *priv = file->private_data;
char buf[128];
int pos = 0;
const size_t bufsz = sizeof(buf);
struct statistics_tx *tx;
if (!iwl_is_alive(priv))
pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
else {
tx = &priv->statistics.tx;
if (tx->tx_power.ant_a ||
tx->tx_power.ant_b ||
tx->tx_power.ant_c) {
pos += scnprintf(buf + pos, bufsz - pos,
"tx power: (1/2 dB step)\n");
if ((priv->cfg->valid_tx_ant & ANT_A) &&
tx->tx_power.ant_a)
pos += scnprintf(buf + pos, bufsz - pos,
"\tantenna A: 0x%X\n",
tx->tx_power.ant_a);
if ((priv->cfg->valid_tx_ant & ANT_B) &&
tx->tx_power.ant_b)
pos += scnprintf(buf + pos, bufsz - pos,
"\tantenna B: 0x%X\n",
tx->tx_power.ant_b);
if ((priv->cfg->valid_tx_ant & ANT_C) &&
tx->tx_power.ant_c)
pos += scnprintf(buf + pos, bufsz - pos,
"\tantenna C: 0x%X\n",
tx->tx_power.ant_c);
} else
pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
}
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
}
static ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
......@@ -1571,7 +1531,6 @@ DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
DEBUGFS_READ_FILE_OPS(ucode_general_stats);
DEBUGFS_READ_FILE_OPS(sensitivity);
DEBUGFS_READ_FILE_OPS(chain_noise);
DEBUGFS_READ_FILE_OPS(tx_power);
DEBUGFS_READ_FILE_OPS(power_save_status);
DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
......@@ -1618,8 +1577,11 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
if (!priv->cfg->broken_powersave) {
DEBUGFS_ADD_FILE(sleep_level_override, dir_data,
S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
}
DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
......@@ -1627,7 +1589,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(tx_power, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
......@@ -1640,18 +1601,21 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
if (priv->cfg->sensitivity_calib_by_driver)
DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
if (priv->cfg->chain_noise_calib_by_driver)
DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
if (priv->cfg->ucode_tracing)
DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
}
DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal);
DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
&priv->disable_chain_noise_cal);
if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
if (priv->cfg->sensitivity_calib_by_driver)
DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
&priv->disable_sens_cal);
if (priv->cfg->chain_noise_calib_by_driver)
DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
&priv->disable_chain_noise_cal);
if (priv->cfg->tx_power_by_driver)
DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
&priv->disable_tx_power_cal);
return 0;
......
......@@ -57,8 +57,8 @@ extern struct iwl_cfg iwl5100_bgn_cfg;
extern struct iwl_cfg iwl5100_abg_cfg;
extern struct iwl_cfg iwl5150_agn_cfg;
extern struct iwl_cfg iwl5150_abg_cfg;
extern struct iwl_cfg iwl6000g2a_2agn_cfg;
extern struct iwl_cfg iwl6000i_2agn_cfg;
extern struct iwl_cfg iwl6000g2_2agn_cfg;
extern struct iwl_cfg iwl6000i_2abg_cfg;
extern struct iwl_cfg iwl6000i_2bg_cfg;
extern struct iwl_cfg iwl6000_3agn_cfg;
......@@ -497,20 +497,38 @@ struct iwl_station_entry {
struct iwl_link_quality_cmd *lq;
};
struct iwl_station_priv_common {
u8 sta_id;
};
/*
* iwl_station_priv: Driver's private station information
*
* When mac80211 creates a station it reserves some space (hw->sta_data_size)
* in the structure for use by driver. This structure is places in that
* space.
*
* The common struct MUST be first because it is shared between
* 3945 and agn!
*/
struct iwl_station_priv {
struct iwl_station_priv_common common;
struct iwl_lq_sta lq_sta;
atomic_t pending_frames;
bool client;
bool asleep;
};
/**
* struct iwl_vif_priv - driver's private per-interface information
*
* When mac80211 allocates a virtual interface, it can allocate
* space for us to put data into.
*/
struct iwl_vif_priv {
u8 ibss_bssid_sta_id;
};
/* one for each uCode image (inst/data, boot/init/runtime) */
struct fw_desc {
void *v_addr; /* access by driver */
......@@ -518,7 +536,7 @@ struct fw_desc {
u32 len; /* bytes */
};
/* uCode file layout */
/* v1/v2 uCode file layout */
struct iwl_ucode_header {
__le32 ver; /* major/minor/API/serial */
union {
......@@ -541,7 +559,62 @@ struct iwl_ucode_header {
} v2;
} u;
};
#define UCODE_HEADER_SIZE(ver) ((ver) == 1 ? 24 : 28)
/*
* new TLV uCode file layout
*
* The new TLV file format contains TLVs, that each specify
* some piece of data. To facilitate "groups", for example
* different instruction image with different capabilities,
* bundled with the same init image, an alternative mechanism
* is provided:
* When the alternative field is 0, that means that the item
* is always valid. When it is non-zero, then it is only
* valid in conjunction with items of the same alternative,
* in which case the driver (user) selects one alternative
* to use.
*/
enum iwl_ucode_tlv_type {
IWL_UCODE_TLV_INVALID = 0, /* unused */
IWL_UCODE_TLV_INST = 1,
IWL_UCODE_TLV_DATA = 2,
IWL_UCODE_TLV_INIT = 3,
IWL_UCODE_TLV_INIT_DATA = 4,
IWL_UCODE_TLV_BOOT = 5,
IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */
};
struct iwl_ucode_tlv {
__le16 type; /* see above */
__le16 alternative; /* see comment */
__le32 length; /* not including type/length fields */
u8 data[0];
} __attribute__ ((packed));
#define IWL_TLV_UCODE_MAGIC 0x0a4c5749
struct iwl_tlv_ucode_header {
/*
* The TLV style ucode header is distinguished from
* the v1/v2 style header by first four bytes being
* zero, as such is an invalid combination of
* major/minor/API/serial versions.
*/
__le32 zero;
__le32 magic;
u8 human_readable[64];
__le32 ver; /* major/minor/API/serial */
__le32 build;
__le64 alternatives; /* bitmask of valid alternatives */
/*
* The data contained herein has a TLV layout,
* see above for the TLV header and types.
* Note that each TLV is padded to a length
* that is a multiple of 4 for alignment.
*/
u8 data[0];
};
struct iwl4965_ibss_seq {
u8 mac[ETH_ALEN];
......@@ -1155,8 +1228,7 @@ struct iwl_priv {
#endif
/* context information */
u8 bssid[ETH_ALEN];
u16 rts_threshold;
u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */
u8 mac_addr[ETH_ALEN];
/*station table variables */
......@@ -1189,7 +1261,6 @@ struct iwl_priv {
/* Last Rx'd beacon timestamp */
u64 timestamp;
u16 beacon_int;
struct ieee80211_vif *vif;
union {
......@@ -1242,6 +1313,8 @@ struct iwl_priv {
struct iwl_rx_phy_res last_phy_res;
bool last_phy_res_valid;
struct completion firmware_loading_complete;
} _agn;
#endif
};
......@@ -1249,10 +1322,6 @@ struct iwl_priv {
struct iwl_hw_params hw_params;
u32 inta_mask;
/* Current association information needed to configure the
* hardware */
u16 assoc_id;
u16 assoc_capability;
struct iwl_qos_info qos_data;
......
......@@ -590,9 +590,16 @@ int iwl_eeprom_init(struct iwl_priv *priv)
e[addr / 2] = cpu_to_le16(r >> 16);
}
}
IWL_DEBUG_INFO(priv, "NVM Type: %s, version: 0x%x\n",
(priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
? "OTP" : "EEPROM",
iwl_eeprom_query16(priv, EEPROM_VERSION));
ret = 0;
done:
priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv);
err:
if (ret)
iwl_eeprom_free(priv);
......
......@@ -318,10 +318,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
if (priv->vif)
dtimper = priv->hw->conf.ps_dtim_period;
else
dtimper = 1;
dtimper = priv->hw->conf.ps_dtim_period ?: 1;
if (priv->cfg->broken_powersave)
iwl_power_sleep_cam_cmd(priv, &cmd);
......
......@@ -398,7 +398,7 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
}
EXPORT_SYMBOL(iwl_good_plcp_health);
static void iwl_recover_from_statistics(struct iwl_priv *priv,
void iwl_recover_from_statistics(struct iwl_priv *priv,
struct iwl_rx_packet *pkt)
{
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
......@@ -413,9 +413,11 @@ static void iwl_recover_from_statistics(struct iwl_priv *priv,
*/
IWL_ERR(priv, "low ack count detected, "
"restart firmware\n");
iwl_force_reset(priv, IWL_FW_RESET);
if (!iwl_force_reset(priv, IWL_FW_RESET))
return;
}
} else if (priv->cfg->ops->lib->check_plcp_health) {
}
if (priv->cfg->ops->lib->check_plcp_health) {
if (!priv->cfg->ops->lib->check_plcp_health(
priv, pkt)) {
/*
......@@ -427,6 +429,7 @@ static void iwl_recover_from_statistics(struct iwl_priv *priv,
}
}
}
EXPORT_SYMBOL(iwl_recover_from_statistics);
void iwl_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
......
......@@ -265,7 +265,8 @@ inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
EXPORT_SYMBOL(iwl_get_active_dwell_time);
u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
enum ieee80211_band band)
enum ieee80211_band band,
struct ieee80211_vif *vif)
{
u16 passive = (band == IEEE80211_BAND_2GHZ) ?
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
......@@ -275,7 +276,7 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
/* If we're associated, we clamp the maximum passive
* dwell time to be 98% of the beacon interval (minus
* 2 * channel tune time) */
passive = priv->beacon_int;
passive = vif ? vif->bss_conf.beacon_int : 0;
if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)
passive = IWL_PASSIVE_DWELL_BASE;
passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
......@@ -295,7 +296,7 @@ void iwl_init_scan_params(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_init_scan_params);
static int iwl_scan_initiate(struct iwl_priv *priv)
static int iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
WARN_ON(!mutex_is_locked(&priv->mutex));
......@@ -307,7 +308,7 @@ static int iwl_scan_initiate(struct iwl_priv *priv)
if (WARN_ON(!priv->cfg->ops->utils->request_scan))
return -EOPNOTSUPP;
priv->cfg->ops->utils->request_scan(priv);
priv->cfg->ops->utils->request_scan(priv, vif);
return 0;
}
......@@ -348,7 +349,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
priv->scan_band = req->channels[0]->band;
priv->scan_request = req;
ret = iwl_scan_initiate(priv);
ret = iwl_scan_initiate(priv, vif);
IWL_DEBUG_MAC80211(priv, "leave\n");
......@@ -368,7 +369,7 @@ void iwl_internal_short_hw_scan(struct iwl_priv *priv)
queue_work(priv->workqueue, &priv->start_internal_scan);
}
static void iwl_bg_start_internal_scan(struct work_struct *work)
void iwl_bg_start_internal_scan(struct work_struct *work)
{
struct iwl_priv *priv =
container_of(work, struct iwl_priv, start_internal_scan);
......@@ -399,10 +400,11 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
if (WARN_ON(!priv->cfg->ops->utils->request_scan))
goto unlock;
priv->cfg->ops->utils->request_scan(priv);
priv->cfg->ops->utils->request_scan(priv, NULL);
unlock:
mutex_unlock(&priv->mutex);
}
EXPORT_SYMBOL(iwl_bg_start_internal_scan);
void iwl_bg_scan_check(struct work_struct *data)
{
......
......@@ -633,7 +633,8 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct txentry_desc *txdesc)
{
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
__le32 *txd = skbdesc->desc;
struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data;
__le32 *txd = entry_priv->desc;
u32 word;
/*
......@@ -657,15 +658,14 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
!test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W1_BURST,
test_bit(ENTRY_TXD_BURST, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W1_SD_LEN0,
rt2x00dev->ops->extra_tx_headroom);
rt2x00_set_field32(&word, TXD_W1_SD_LEN0, TXWI_DESC_SIZE);
rt2x00_set_field32(&word, TXD_W1_LAST_SEC0, 0);
rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0);
rt2x00_desc_write(txd, 1, word);
rt2x00_desc_read(txd, 2, &word);
rt2x00_set_field32(&word, TXD_W2_SD_PTR1,
skbdesc->skb_dma + rt2x00dev->ops->extra_tx_headroom);
skbdesc->skb_dma + TXWI_DESC_SIZE);
rt2x00_desc_write(txd, 2, word);
rt2x00_desc_read(txd, 3, &word);
......@@ -673,6 +673,12 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
!test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
rt2x00_set_field32(&word, TXD_W3_QSEL, 2);
rt2x00_desc_write(txd, 3, word);
/*
* Register descriptor details in skb frame descriptor.
*/
skbdesc->desc = txd;
skbdesc->desc_len = TXD_DESC_SIZE;
}
/*
......
......@@ -62,11 +62,14 @@
* the tx event which has either succeeded or failed. A frame
* with this type should also have been reported with as a
* %DUMP_FRAME_TX frame.
* @DUMP_FRAME_BEACON: This beacon frame is queued for transmission to the
* hardware.
*/
enum rt2x00_dump_type {
DUMP_FRAME_RXDONE = 1,
DUMP_FRAME_TX = 2,
DUMP_FRAME_TXDONE = 3,
DUMP_FRAME_BEACON = 4,
};
/**
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册