Merge branch 'master' of ssh://infradead/~/public_git/wireless-next into for-davem
This commit is contained in:
commit
b53d63ecce
14
MAINTAINERS
14
MAINTAINERS
@ -1246,6 +1246,14 @@ W: http://wireless.kernel.org/en/users/Drivers/ath5k
|
||||
S: Maintained
|
||||
F: drivers/net/wireless/ath/ath5k/
|
||||
|
||||
ATHEROS ATH6KL WIRELESS DRIVER
|
||||
M: Kalle Valo <kvalo@qca.qualcomm.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
W: http://wireless.kernel.org/en/users/Drivers/ath6kl
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath6kl.git
|
||||
S: Supported
|
||||
F: drivers/net/wireless/ath/ath6kl/
|
||||
|
||||
ATHEROS ATH9K WIRELESS DRIVER
|
||||
M: "Luis R. Rodriguez" <mcgrof@qca.qualcomm.com>
|
||||
M: Jouni Malinen <jouni@qca.qualcomm.com>
|
||||
@ -6145,12 +6153,6 @@ M: Jakub Schmidtke <sjakub@gmail.com>
|
||||
S: Odd Fixes
|
||||
F: drivers/staging/asus_oled/
|
||||
|
||||
STAGING - ATHEROS ATH6KL WIRELESS DRIVER
|
||||
M: Luis R. Rodriguez <mcgrof@gmail.com>
|
||||
M: Naveen Singh <nsingh@atheros.com>
|
||||
S: Odd Fixes
|
||||
F: drivers/staging/ath6kl/
|
||||
|
||||
STAGING - COMEDI
|
||||
M: Ian Abbott <abbotti@mev.co.uk>
|
||||
M: Mori Hess <fmhess@users.sourceforge.net>
|
||||
|
@ -133,6 +133,15 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
|
||||
v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
|
||||
*(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
|
||||
}
|
||||
|
||||
bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)];
|
||||
|
||||
bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)];
|
||||
bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)];
|
||||
bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)];
|
||||
bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)];
|
||||
|
||||
bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)];
|
||||
}
|
||||
|
||||
int bcma_sprom_get(struct bcma_bus *bus)
|
||||
|
@ -140,9 +140,6 @@ struct ath_common {
|
||||
u8 curbssid[ETH_ALEN];
|
||||
u8 bssidmask[ETH_ALEN];
|
||||
|
||||
u8 tx_chainmask;
|
||||
u8 rx_chainmask;
|
||||
|
||||
u32 rx_bufsize;
|
||||
|
||||
u32 keymax;
|
||||
|
@ -14,70 +14,71 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
static const u32 ar5416Modes[][6] = {
|
||||
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0},
|
||||
{0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0},
|
||||
{0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180},
|
||||
{0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008},
|
||||
{0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0},
|
||||
{0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf},
|
||||
{0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810},
|
||||
{0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a},
|
||||
{0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303},
|
||||
{0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200},
|
||||
{0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
|
||||
{0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001},
|
||||
{0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
|
||||
{0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007},
|
||||
{0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0},
|
||||
{0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68},
|
||||
{0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68},
|
||||
{0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68},
|
||||
{0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de, 0x6c48b0de},
|
||||
{0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e},
|
||||
{0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e},
|
||||
{0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18},
|
||||
{0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00},
|
||||
{0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190},
|
||||
{0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081},
|
||||
{0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0},
|
||||
{0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134},
|
||||
{0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b},
|
||||
{0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020},
|
||||
{0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80},
|
||||
{0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80},
|
||||
{0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80},
|
||||
{0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120},
|
||||
{0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00},
|
||||
{0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be},
|
||||
{0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77},
|
||||
{0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c},
|
||||
{0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8},
|
||||
{0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384},
|
||||
{0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880},
|
||||
{0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788},
|
||||
{0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120},
|
||||
{0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120},
|
||||
{0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120},
|
||||
{0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a},
|
||||
{0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000},
|
||||
{0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa},
|
||||
{0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000},
|
||||
{0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402},
|
||||
{0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06},
|
||||
{0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b},
|
||||
{0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b},
|
||||
{0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a},
|
||||
{0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf},
|
||||
{0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f},
|
||||
{0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f},
|
||||
{0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f},
|
||||
{0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
static const u32 ar5416Modes[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
|
||||
{0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
|
||||
{0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
|
||||
{0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000},
|
||||
{0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
|
||||
{0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab},
|
||||
{0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
|
||||
{0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
|
||||
{0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300},
|
||||
{0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200},
|
||||
{0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
|
||||
{0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001},
|
||||
{0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
|
||||
{0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007},
|
||||
{0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0},
|
||||
{0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68},
|
||||
{0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68},
|
||||
{0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68},
|
||||
{0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de},
|
||||
{0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e},
|
||||
{0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
|
||||
{0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18},
|
||||
{0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00},
|
||||
{0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190},
|
||||
{0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081},
|
||||
{0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
|
||||
{0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134},
|
||||
{0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b},
|
||||
{0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020},
|
||||
{0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80},
|
||||
{0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80},
|
||||
{0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80},
|
||||
{0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120},
|
||||
{0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00},
|
||||
{0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be},
|
||||
{0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77},
|
||||
{0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c},
|
||||
{0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8},
|
||||
{0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384},
|
||||
{0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880},
|
||||
{0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788},
|
||||
{0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120},
|
||||
{0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120},
|
||||
{0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120},
|
||||
{0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a},
|
||||
{0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
|
||||
{0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa},
|
||||
{0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000},
|
||||
{0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402},
|
||||
{0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06},
|
||||
{0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b},
|
||||
{0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b},
|
||||
{0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a},
|
||||
{0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf},
|
||||
{0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f},
|
||||
{0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f},
|
||||
{0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f},
|
||||
{0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000},
|
||||
{0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
};
|
||||
|
||||
static const u32 ar5416Common[][2] = {
|
||||
@ -668,6 +669,6 @@ static const u32 ar5416Addac[][2] = {
|
||||
{0x0000989c, 0x00000000},
|
||||
{0x0000989c, 0x00000000},
|
||||
{0x0000989c, 0x00000000},
|
||||
{0x000098cc, 0x00000000},
|
||||
{0x000098c4, 0x00000000},
|
||||
};
|
||||
|
||||
|
@ -14,73 +14,74 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
static const u32 ar5416Modes_9100[][6] = {
|
||||
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0},
|
||||
{0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0},
|
||||
{0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180},
|
||||
{0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008},
|
||||
{0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0},
|
||||
{0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf},
|
||||
{0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810},
|
||||
{0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a},
|
||||
{0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303},
|
||||
{0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200},
|
||||
{0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
|
||||
{0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001},
|
||||
{0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
|
||||
{0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007},
|
||||
{0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0},
|
||||
{0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68},
|
||||
{0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68},
|
||||
{0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68},
|
||||
{0x00009850, 0x6c48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6c48b0e2, 0x6c48b0e2},
|
||||
{0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e},
|
||||
{0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e},
|
||||
{0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18},
|
||||
{0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00},
|
||||
{0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0},
|
||||
{0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081},
|
||||
{0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0},
|
||||
{0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016},
|
||||
{0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d},
|
||||
{0x00009940, 0x00750604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204},
|
||||
{0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020},
|
||||
{0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e},
|
||||
{0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff},
|
||||
{0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0},
|
||||
{0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0},
|
||||
{0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0},
|
||||
{0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120},
|
||||
{0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00},
|
||||
{0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be},
|
||||
{0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77},
|
||||
{0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329},
|
||||
{0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8},
|
||||
{0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384},
|
||||
{0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880},
|
||||
{0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788},
|
||||
{0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120},
|
||||
{0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120},
|
||||
{0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120},
|
||||
{0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a},
|
||||
{0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000},
|
||||
{0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa},
|
||||
{0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000},
|
||||
{0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402},
|
||||
{0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06},
|
||||
{0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b},
|
||||
{0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b},
|
||||
{0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a},
|
||||
{0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf},
|
||||
{0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f},
|
||||
{0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f},
|
||||
{0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f},
|
||||
{0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
static const u32 ar5416Modes_9100[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
|
||||
{0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
|
||||
{0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
|
||||
{0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000},
|
||||
{0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
|
||||
{0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab},
|
||||
{0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
|
||||
{0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
|
||||
{0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300},
|
||||
{0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200},
|
||||
{0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
|
||||
{0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001},
|
||||
{0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
|
||||
{0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007},
|
||||
{0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
|
||||
{0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68},
|
||||
{0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68},
|
||||
{0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68},
|
||||
{0x00009850, 0x6c48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6c48b0e2},
|
||||
{0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e},
|
||||
{0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
|
||||
{0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20},
|
||||
{0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00},
|
||||
{0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0},
|
||||
{0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081},
|
||||
{0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
|
||||
{0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
|
||||
{0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d},
|
||||
{0x00009940, 0x00750604, 0x00754604, 0xfff81204, 0xfff81204},
|
||||
{0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020},
|
||||
{0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e},
|
||||
{0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff},
|
||||
{0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0},
|
||||
{0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0},
|
||||
{0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0},
|
||||
{0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120},
|
||||
{0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00},
|
||||
{0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be},
|
||||
{0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77},
|
||||
{0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329},
|
||||
{0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8},
|
||||
{0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384},
|
||||
{0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880},
|
||||
{0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788},
|
||||
{0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120},
|
||||
{0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120},
|
||||
{0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120},
|
||||
{0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a},
|
||||
{0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
|
||||
{0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa},
|
||||
{0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000},
|
||||
{0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402},
|
||||
{0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06},
|
||||
{0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b},
|
||||
{0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b},
|
||||
{0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a},
|
||||
{0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf},
|
||||
{0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f},
|
||||
{0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f},
|
||||
{0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f},
|
||||
{0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000},
|
||||
{0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
};
|
||||
|
||||
static const u32 ar5416Common_9100[][2] = {
|
||||
@ -666,71 +667,72 @@ static const u32 ar5416Addac_9100[][2] = {
|
||||
{0x000098cc, 0x00000000},
|
||||
};
|
||||
|
||||
static const u32 ar5416Modes_9160[][6] = {
|
||||
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0},
|
||||
{0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0},
|
||||
{0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180},
|
||||
{0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008},
|
||||
{0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0},
|
||||
{0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf},
|
||||
{0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810},
|
||||
{0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a},
|
||||
{0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303},
|
||||
{0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200},
|
||||
{0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
|
||||
{0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001},
|
||||
{0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
|
||||
{0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007},
|
||||
{0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0},
|
||||
{0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68},
|
||||
{0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68},
|
||||
{0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68},
|
||||
{0x00009850, 0x6c48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6c48b0e2, 0x6c48b0e2},
|
||||
{0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e},
|
||||
{0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e},
|
||||
{0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18},
|
||||
{0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00},
|
||||
{0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0},
|
||||
{0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081},
|
||||
{0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0},
|
||||
{0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016},
|
||||
{0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d},
|
||||
{0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020},
|
||||
{0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40},
|
||||
{0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40},
|
||||
{0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40},
|
||||
{0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120},
|
||||
{0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce},
|
||||
{0x000099bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00},
|
||||
{0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be},
|
||||
{0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77},
|
||||
{0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329},
|
||||
{0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8},
|
||||
{0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384},
|
||||
{0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880},
|
||||
{0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788},
|
||||
{0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120},
|
||||
{0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120},
|
||||
{0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120},
|
||||
{0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a},
|
||||
{0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000},
|
||||
{0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa},
|
||||
{0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000},
|
||||
{0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402},
|
||||
{0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06},
|
||||
{0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b},
|
||||
{0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b},
|
||||
{0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a},
|
||||
{0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf},
|
||||
{0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f},
|
||||
{0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f},
|
||||
{0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f},
|
||||
{0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
static const u32 ar5416Modes_9160[][5] = {
|
||||
/* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
|
||||
{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
|
||||
{0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
|
||||
{0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
|
||||
{0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000},
|
||||
{0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
|
||||
{0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab},
|
||||
{0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
|
||||
{0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
|
||||
{0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300},
|
||||
{0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200},
|
||||
{0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
|
||||
{0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001},
|
||||
{0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
|
||||
{0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007},
|
||||
{0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
|
||||
{0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68},
|
||||
{0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68},
|
||||
{0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68},
|
||||
{0x00009850, 0x6c48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6c48b0e2},
|
||||
{0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e},
|
||||
{0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
|
||||
{0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20},
|
||||
{0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00},
|
||||
{0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0},
|
||||
{0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081},
|
||||
{0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
|
||||
{0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
|
||||
{0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d},
|
||||
{0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020},
|
||||
{0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40},
|
||||
{0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40},
|
||||
{0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40},
|
||||
{0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120},
|
||||
{0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
|
||||
{0x000099bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00},
|
||||
{0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be},
|
||||
{0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77},
|
||||
{0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329},
|
||||
{0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8},
|
||||
{0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384},
|
||||
{0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880},
|
||||
{0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788},
|
||||
{0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120},
|
||||
{0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120},
|
||||
{0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120},
|
||||
{0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a},
|
||||
{0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
|
||||
{0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa},
|
||||
{0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000},
|
||||
{0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402},
|
||||
{0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06},
|
||||
{0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b},
|
||||
{0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b},
|
||||
{0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a},
|
||||
{0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf},
|
||||
{0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f},
|
||||
{0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f},
|
||||
{0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f},
|
||||
{0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000},
|
||||
{0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
{0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
|
||||
};
|
||||
|
||||
static const u32 ar5416Common_9160[][2] = {
|
||||
|
@ -30,7 +30,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9271(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271,
|
||||
ARRAY_SIZE(ar9271Modes_9271), 6);
|
||||
ARRAY_SIZE(ar9271Modes_9271), 5);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
|
||||
ARRAY_SIZE(ar9271Common_9271), 2);
|
||||
INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
|
||||
@ -41,21 +41,21 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
||||
ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2);
|
||||
INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
|
||||
ar9271Modes_9271_1_0_only,
|
||||
ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6);
|
||||
ARRAY_SIZE(ar9271Modes_9271_1_0_only), 5);
|
||||
INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg,
|
||||
ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 6);
|
||||
ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 5);
|
||||
INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
|
||||
ar9271Modes_high_power_tx_gain_9271,
|
||||
ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 6);
|
||||
ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 5);
|
||||
INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
|
||||
ar9271Modes_normal_power_tx_gain_9271,
|
||||
ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 6);
|
||||
ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 5);
|
||||
return;
|
||||
}
|
||||
|
||||
if (AR_SREV_9287_11_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
|
||||
ARRAY_SIZE(ar9287Modes_9287_1_1), 6);
|
||||
ARRAY_SIZE(ar9287Modes_9287_1_1), 5);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
|
||||
ARRAY_SIZE(ar9287Common_9287_1_1), 2);
|
||||
if (ah->config.pcie_clock_req)
|
||||
@ -71,7 +71,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
||||
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
|
||||
ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
|
||||
ARRAY_SIZE(ar9285Modes_9285_1_2), 5);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
|
||||
ARRAY_SIZE(ar9285Common_9285_1_2), 2);
|
||||
|
||||
@ -87,7 +87,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
||||
}
|
||||
} else if (AR_SREV_9280_20_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_9280_2), 6);
|
||||
ARRAY_SIZE(ar9280Modes_9280_2), 5);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
|
||||
ARRAY_SIZE(ar9280Common_9280_2), 2);
|
||||
|
||||
@ -105,7 +105,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
||||
ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
|
||||
} else if (AR_SREV_9160_10_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
|
||||
ARRAY_SIZE(ar5416Modes_9160), 6);
|
||||
ARRAY_SIZE(ar5416Modes_9160), 5);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
|
||||
ARRAY_SIZE(ar5416Common_9160), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
|
||||
@ -134,7 +134,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
||||
}
|
||||
} else if (AR_SREV_9100_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
|
||||
ARRAY_SIZE(ar5416Modes_9100), 6);
|
||||
ARRAY_SIZE(ar5416Modes_9100), 5);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
|
||||
ARRAY_SIZE(ar5416Common_9100), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
|
||||
@ -157,7 +157,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
||||
ARRAY_SIZE(ar5416Addac_9100), 2);
|
||||
} else {
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
|
||||
ARRAY_SIZE(ar5416Modes), 6);
|
||||
ARRAY_SIZE(ar5416Modes), 5);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
|
||||
ARRAY_SIZE(ar5416Common), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
|
||||
@ -207,19 +207,19 @@ static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah)
|
||||
if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9280Modes_backoff_13db_rxgain_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6);
|
||||
ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 5);
|
||||
else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9280Modes_backoff_23db_rxgain_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
|
||||
ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 5);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9280Modes_original_rxgain_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
|
||||
ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 5);
|
||||
} else {
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9280Modes_original_rxgain_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
|
||||
ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 5);
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,15 +234,15 @@ static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah)
|
||||
if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9280Modes_high_power_tx_gain_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
|
||||
ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 5);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9280Modes_original_tx_gain_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
|
||||
ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 5);
|
||||
} else {
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9280Modes_original_tx_gain_9280_2,
|
||||
ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
|
||||
ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 5);
|
||||
}
|
||||
}
|
||||
|
||||
@ -251,14 +251,14 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
|
||||
if (AR_SREV_9287_11_OR_LATER(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9287Modes_rx_gain_9287_1_1,
|
||||
ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6);
|
||||
ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 5);
|
||||
else if (AR_SREV_9280_20(ah))
|
||||
ar9280_20_hw_init_rxgain_ini(ah);
|
||||
|
||||
if (AR_SREV_9287_11_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9287Modes_tx_gain_9287_1_1,
|
||||
ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6);
|
||||
ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 5);
|
||||
} else if (AR_SREV_9280_20(ah)) {
|
||||
ar9280_20_hw_init_txgain_ini(ah);
|
||||
} else if (AR_SREV_9285_12_OR_LATER(ah)) {
|
||||
@ -270,24 +270,24 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9285Modes_XE2_0_high_power,
|
||||
ARRAY_SIZE(
|
||||
ar9285Modes_XE2_0_high_power), 6);
|
||||
ar9285Modes_XE2_0_high_power), 5);
|
||||
} else {
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9285Modes_high_power_tx_gain_9285_1_2,
|
||||
ARRAY_SIZE(
|
||||
ar9285Modes_high_power_tx_gain_9285_1_2), 6);
|
||||
ar9285Modes_high_power_tx_gain_9285_1_2), 5);
|
||||
}
|
||||
} else {
|
||||
if (AR_SREV_9285E_20(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9285Modes_XE2_0_normal_power,
|
||||
ARRAY_SIZE(
|
||||
ar9285Modes_XE2_0_normal_power), 6);
|
||||
ar9285Modes_XE2_0_normal_power), 5);
|
||||
} else {
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9285Modes_original_tx_gain_9285_1_2,
|
||||
ARRAY_SIZE(
|
||||
ar9285Modes_original_tx_gain_9285_1_2), 6);
|
||||
ar9285Modes_original_tx_gain_9285_1_2), 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -170,33 +170,104 @@ static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ar9002_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
|
||||
bool is_firstseg, bool is_lastseg,
|
||||
const void *ds0, dma_addr_t buf_addr,
|
||||
unsigned int qcu)
|
||||
static void
|
||||
ar9002_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
u32 ctl1, ctl6;
|
||||
|
||||
ads->ds_data = buf_addr;
|
||||
|
||||
if (is_firstseg) {
|
||||
ads->ds_ctl1 |= seglen | (is_lastseg ? 0 : AR_TxMore);
|
||||
} else if (is_lastseg) {
|
||||
ads->ds_ctl0 = 0;
|
||||
ads->ds_ctl1 = seglen;
|
||||
ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
|
||||
ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
|
||||
} else {
|
||||
ads->ds_ctl0 = 0;
|
||||
ads->ds_ctl1 = seglen | AR_TxMore;
|
||||
ads->ds_ctl2 = 0;
|
||||
ads->ds_ctl3 = 0;
|
||||
}
|
||||
ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
|
||||
ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
|
||||
ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
|
||||
ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
|
||||
ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
|
||||
|
||||
ACCESS_ONCE(ads->ds_link) = i->link;
|
||||
ACCESS_ONCE(ads->ds_data) = i->buf_addr[0];
|
||||
|
||||
ctl1 = i->buf_len[0] | (i->is_last ? 0 : AR_TxMore);
|
||||
ctl6 = SM(i->keytype, AR_EncrType);
|
||||
|
||||
if (AR_SREV_9285(ah)) {
|
||||
ads->ds_ctl8 = 0;
|
||||
ads->ds_ctl9 = 0;
|
||||
ads->ds_ctl10 = 0;
|
||||
ads->ds_ctl11 = 0;
|
||||
}
|
||||
|
||||
if ((i->is_first || i->is_last) &&
|
||||
i->aggr != AGGR_BUF_MIDDLE && i->aggr != AGGR_BUF_LAST) {
|
||||
ACCESS_ONCE(ads->ds_ctl2) = set11nTries(i->rates, 0)
|
||||
| set11nTries(i->rates, 1)
|
||||
| set11nTries(i->rates, 2)
|
||||
| set11nTries(i->rates, 3)
|
||||
| (i->dur_update ? AR_DurUpdateEna : 0)
|
||||
| SM(0, AR_BurstDur);
|
||||
|
||||
ACCESS_ONCE(ads->ds_ctl3) = set11nRate(i->rates, 0)
|
||||
| set11nRate(i->rates, 1)
|
||||
| set11nRate(i->rates, 2)
|
||||
| set11nRate(i->rates, 3);
|
||||
} else {
|
||||
ACCESS_ONCE(ads->ds_ctl2) = 0;
|
||||
ACCESS_ONCE(ads->ds_ctl3) = 0;
|
||||
}
|
||||
|
||||
if (!i->is_first) {
|
||||
ACCESS_ONCE(ads->ds_ctl0) = 0;
|
||||
ACCESS_ONCE(ads->ds_ctl1) = ctl1;
|
||||
ACCESS_ONCE(ads->ds_ctl6) = ctl6;
|
||||
return;
|
||||
}
|
||||
|
||||
ctl1 |= (i->keyix != ATH9K_TXKEYIX_INVALID ? SM(i->keyix, AR_DestIdx) : 0)
|
||||
| SM(i->type, AR_FrameType)
|
||||
| (i->flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
|
||||
| (i->flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
|
||||
| (i->flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
|
||||
|
||||
switch (i->aggr) {
|
||||
case AGGR_BUF_FIRST:
|
||||
ctl6 |= SM(i->aggr_len, AR_AggrLen);
|
||||
/* fall through */
|
||||
case AGGR_BUF_MIDDLE:
|
||||
ctl1 |= AR_IsAggr | AR_MoreAggr;
|
||||
ctl6 |= SM(i->ndelim, AR_PadDelim);
|
||||
break;
|
||||
case AGGR_BUF_LAST:
|
||||
ctl1 |= AR_IsAggr;
|
||||
break;
|
||||
case AGGR_BUF_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
ACCESS_ONCE(ads->ds_ctl0) = (i->pkt_len & AR_FrameLen)
|
||||
| (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
|
||||
| SM(i->txpower, AR_XmitPower)
|
||||
| (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
|
||||
| (i->flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
|
||||
| (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
|
||||
| (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
|
||||
| (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable :
|
||||
(i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0));
|
||||
|
||||
ACCESS_ONCE(ads->ds_ctl1) = ctl1;
|
||||
ACCESS_ONCE(ads->ds_ctl6) = ctl6;
|
||||
|
||||
if (i->aggr == AGGR_BUF_MIDDLE || i->aggr == AGGR_BUF_LAST)
|
||||
return;
|
||||
|
||||
ACCESS_ONCE(ads->ds_ctl4) = set11nPktDurRTSCTS(i->rates, 0)
|
||||
| set11nPktDurRTSCTS(i->rates, 1);
|
||||
|
||||
ACCESS_ONCE(ads->ds_ctl5) = set11nPktDurRTSCTS(i->rates, 2)
|
||||
| set11nPktDurRTSCTS(i->rates, 3);
|
||||
|
||||
ACCESS_ONCE(ads->ds_ctl7) = set11nRateFlags(i->rates, 0)
|
||||
| set11nRateFlags(i->rates, 1)
|
||||
| set11nRateFlags(i->rates, 2)
|
||||
| set11nRateFlags(i->rates, 3)
|
||||
| SM(i->rtscts_rate, AR_RTSCTSRate);
|
||||
}
|
||||
|
||||
static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
|
||||
@ -271,145 +342,6 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
|
||||
u32 pktLen, enum ath9k_pkt_type type,
|
||||
u32 txPower, u8 keyIx,
|
||||
enum ath9k_key_type keyType, u32 flags)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
if (txPower > 63)
|
||||
txPower = 63;
|
||||
|
||||
ads->ds_ctl0 = (pktLen & AR_FrameLen)
|
||||
| (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
|
||||
| SM(txPower, AR_XmitPower)
|
||||
| (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
|
||||
| (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
|
||||
| (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
|
||||
|
||||
ads->ds_ctl1 =
|
||||
(keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
|
||||
| SM(type, AR_FrameType)
|
||||
| (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
|
||||
| (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
|
||||
| (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
|
||||
|
||||
ads->ds_ctl6 = SM(keyType, AR_EncrType);
|
||||
|
||||
if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
|
||||
ads->ds_ctl8 = 0;
|
||||
ads->ds_ctl9 = 0;
|
||||
ads->ds_ctl10 = 0;
|
||||
ads->ds_ctl11 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void ar9002_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
if (val)
|
||||
ads->ds_ctl0 |= AR_ClrDestMask;
|
||||
else
|
||||
ads->ds_ctl0 &= ~AR_ClrDestMask;
|
||||
}
|
||||
|
||||
static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
|
||||
void *lastds,
|
||||
u32 durUpdateEn, u32 rtsctsRate,
|
||||
u32 rtsctsDuration,
|
||||
struct ath9k_11n_rate_series series[],
|
||||
u32 nseries, u32 flags)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
struct ar5416_desc *last_ads = AR5416DESC(lastds);
|
||||
u32 ds_ctl0;
|
||||
|
||||
if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
|
||||
ds_ctl0 = ads->ds_ctl0;
|
||||
|
||||
if (flags & ATH9K_TXDESC_RTSENA) {
|
||||
ds_ctl0 &= ~AR_CTSEnable;
|
||||
ds_ctl0 |= AR_RTSEnable;
|
||||
} else {
|
||||
ds_ctl0 &= ~AR_RTSEnable;
|
||||
ds_ctl0 |= AR_CTSEnable;
|
||||
}
|
||||
|
||||
ads->ds_ctl0 = ds_ctl0;
|
||||
} else {
|
||||
ads->ds_ctl0 =
|
||||
(ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
|
||||
}
|
||||
|
||||
ads->ds_ctl2 = set11nTries(series, 0)
|
||||
| set11nTries(series, 1)
|
||||
| set11nTries(series, 2)
|
||||
| set11nTries(series, 3)
|
||||
| (durUpdateEn ? AR_DurUpdateEna : 0)
|
||||
| SM(0, AR_BurstDur);
|
||||
|
||||
ads->ds_ctl3 = set11nRate(series, 0)
|
||||
| set11nRate(series, 1)
|
||||
| set11nRate(series, 2)
|
||||
| set11nRate(series, 3);
|
||||
|
||||
ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
|
||||
| set11nPktDurRTSCTS(series, 1);
|
||||
|
||||
ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
|
||||
| set11nPktDurRTSCTS(series, 3);
|
||||
|
||||
ads->ds_ctl7 = set11nRateFlags(series, 0)
|
||||
| set11nRateFlags(series, 1)
|
||||
| set11nRateFlags(series, 2)
|
||||
| set11nRateFlags(series, 3)
|
||||
| SM(rtsctsRate, AR_RTSCTSRate);
|
||||
last_ads->ds_ctl2 = ads->ds_ctl2;
|
||||
last_ads->ds_ctl3 = ads->ds_ctl3;
|
||||
}
|
||||
|
||||
static void ar9002_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
|
||||
u32 aggrLen)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
|
||||
ads->ds_ctl6 &= ~AR_AggrLen;
|
||||
ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
|
||||
}
|
||||
|
||||
static void ar9002_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
|
||||
u32 numDelims)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
unsigned int ctl6;
|
||||
|
||||
ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
|
||||
|
||||
ctl6 = ads->ds_ctl6;
|
||||
ctl6 &= ~AR_PadDelim;
|
||||
ctl6 |= SM(numDelims, AR_PadDelim);
|
||||
ads->ds_ctl6 = ctl6;
|
||||
}
|
||||
|
||||
static void ar9002_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
ads->ds_ctl1 |= AR_IsAggr;
|
||||
ads->ds_ctl1 &= ~AR_MoreAggr;
|
||||
ads->ds_ctl6 &= ~AR_PadDelim;
|
||||
}
|
||||
|
||||
static void ar9002_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
|
||||
}
|
||||
|
||||
void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
|
||||
u32 size, u32 flags)
|
||||
{
|
||||
@ -433,13 +365,6 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
|
||||
ops->rx_enable = ar9002_hw_rx_enable;
|
||||
ops->set_desc_link = ar9002_hw_set_desc_link;
|
||||
ops->get_isr = ar9002_hw_get_isr;
|
||||
ops->fill_txdesc = ar9002_hw_fill_txdesc;
|
||||
ops->set_txdesc = ar9002_set_txdesc;
|
||||
ops->proc_txdesc = ar9002_hw_proc_txdesc;
|
||||
ops->set11n_txdesc = ar9002_hw_set11n_txdesc;
|
||||
ops->set11n_ratescenario = ar9002_hw_set11n_ratescenario;
|
||||
ops->set11n_aggr_first = ar9002_hw_set11n_aggr_first;
|
||||
ops->set11n_aggr_middle = ar9002_hw_set11n_aggr_middle;
|
||||
ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last;
|
||||
ops->clr11n_aggr = ar9002_hw_clr11n_aggr;
|
||||
ops->set_clrdmask = ar9002_hw_set_clrdmask;
|
||||
}
|
||||
|
@ -615,11 +615,10 @@ static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
|
||||
{
|
||||
int mp_max = -64, max_idx = 0;
|
||||
int mp_min = 63, min_idx = 0;
|
||||
int mp_avg = 0, i, outlier_idx = 0;
|
||||
int mp_avg = 0, i, outlier_idx = 0, mp_count = 0;
|
||||
|
||||
/* find min/max mismatch across all calibrated gains */
|
||||
for (i = 0; i < nmeasurement; i++) {
|
||||
mp_avg += mp_coeff[i];
|
||||
if (mp_coeff[i] > mp_max) {
|
||||
mp_max = mp_coeff[i];
|
||||
max_idx = i;
|
||||
@ -632,10 +631,20 @@ static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
|
||||
/* find average (exclude max abs value) */
|
||||
for (i = 0; i < nmeasurement; i++) {
|
||||
if ((abs(mp_coeff[i]) < abs(mp_max)) ||
|
||||
(abs(mp_coeff[i]) < abs(mp_min)))
|
||||
(abs(mp_coeff[i]) < abs(mp_min))) {
|
||||
mp_avg += mp_coeff[i];
|
||||
mp_count++;
|
||||
}
|
||||
}
|
||||
mp_avg /= (nmeasurement - 1);
|
||||
|
||||
/*
|
||||
* finding mean magnitude/phase if possible, otherwise
|
||||
* just use the last value as the mean
|
||||
*/
|
||||
if (mp_count)
|
||||
mp_avg /= mp_count;
|
||||
else
|
||||
mp_avg = mp_coeff[nmeasurement - 1];
|
||||
|
||||
/* detect outlier */
|
||||
if (abs(mp_max - mp_min) > max_delta) {
|
||||
|
@ -22,25 +22,6 @@
|
||||
#define COMP_HDR_LEN 4
|
||||
#define COMP_CKSUM_LEN 2
|
||||
|
||||
#define AR_CH0_TOP (0x00016288)
|
||||
#define AR_CH0_TOP_XPABIASLVL (0x300)
|
||||
#define AR_CH0_TOP_XPABIASLVL_S (8)
|
||||
|
||||
#define AR_CH0_THERM (0x00016290)
|
||||
#define AR_CH0_THERM_XPABIASLVL_MSB 0x3
|
||||
#define AR_CH0_THERM_XPABIASLVL_MSB_S 0
|
||||
#define AR_CH0_THERM_XPASHORT2GND 0x4
|
||||
#define AR_CH0_THERM_XPASHORT2GND_S 2
|
||||
|
||||
#define AR_SWITCH_TABLE_COM_ALL (0xffff)
|
||||
#define AR_SWITCH_TABLE_COM_ALL_S (0)
|
||||
|
||||
#define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
|
||||
#define AR_SWITCH_TABLE_COM2_ALL_S (0)
|
||||
|
||||
#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)
|
||||
|
||||
@ -158,7 +139,7 @@ static const struct ar9300_eeprom ar9300_default = {
|
||||
.papdRateMaskHt20 = LE32(0x0cf0e0e0),
|
||||
.papdRateMaskHt40 = LE32(0x6cf0e0e0),
|
||||
.futureModal = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
},
|
||||
},
|
||||
.base_ext1 = {
|
||||
@ -360,7 +341,7 @@ static const struct ar9300_eeprom ar9300_default = {
|
||||
.papdRateMaskHt20 = LE32(0x0c80c080),
|
||||
.papdRateMaskHt40 = LE32(0x0080c080),
|
||||
.futureModal = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
},
|
||||
},
|
||||
.base_ext2 = {
|
||||
@ -735,7 +716,7 @@ static const struct ar9300_eeprom ar9300_x113 = {
|
||||
.papdRateMaskHt20 = LE32(0x0c80c080),
|
||||
.papdRateMaskHt40 = LE32(0x0080c080),
|
||||
.futureModal = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
},
|
||||
},
|
||||
.base_ext1 = {
|
||||
@ -937,7 +918,7 @@ static const struct ar9300_eeprom ar9300_x113 = {
|
||||
.papdRateMaskHt20 = LE32(0x0cf0e0e0),
|
||||
.papdRateMaskHt40 = LE32(0x6cf0e0e0),
|
||||
.futureModal = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
},
|
||||
},
|
||||
.base_ext2 = {
|
||||
@ -1313,7 +1294,7 @@ static const struct ar9300_eeprom ar9300_h112 = {
|
||||
.papdRateMaskHt20 = LE32(0x80c080),
|
||||
.papdRateMaskHt40 = LE32(0x80c080),
|
||||
.futureModal = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
},
|
||||
},
|
||||
.base_ext1 = {
|
||||
@ -1515,7 +1496,7 @@ static const struct ar9300_eeprom ar9300_h112 = {
|
||||
.papdRateMaskHt20 = LE32(0x0cf0e0e0),
|
||||
.papdRateMaskHt40 = LE32(0x6cf0e0e0),
|
||||
.futureModal = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
},
|
||||
},
|
||||
.base_ext2 = {
|
||||
@ -1891,7 +1872,7 @@ static const struct ar9300_eeprom ar9300_x112 = {
|
||||
.papdRateMaskHt20 = LE32(0x0c80c080),
|
||||
.papdRateMaskHt40 = LE32(0x0080c080),
|
||||
.futureModal = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
},
|
||||
},
|
||||
.base_ext1 = {
|
||||
@ -2093,7 +2074,7 @@ static const struct ar9300_eeprom ar9300_x112 = {
|
||||
.papdRateMaskHt20 = LE32(0x0cf0e0e0),
|
||||
.papdRateMaskHt40 = LE32(0x6cf0e0e0),
|
||||
.futureModal = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
},
|
||||
},
|
||||
.base_ext2 = {
|
||||
@ -2468,7 +2449,7 @@ static const struct ar9300_eeprom ar9300_h116 = {
|
||||
.papdRateMaskHt20 = LE32(0x0c80C080),
|
||||
.papdRateMaskHt40 = LE32(0x0080C080),
|
||||
.futureModal = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
},
|
||||
},
|
||||
.base_ext1 = {
|
||||
@ -2670,7 +2651,7 @@ static const struct ar9300_eeprom ar9300_h116 = {
|
||||
.papdRateMaskHt20 = LE32(0x0cf0e0e0),
|
||||
.papdRateMaskHt40 = LE32(0x6cf0e0e0),
|
||||
.futureModal = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
},
|
||||
},
|
||||
.base_ext2 = {
|
||||
@ -3573,6 +3554,8 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
|
||||
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah))
|
||||
REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
|
||||
else if (AR_SREV_9480(ah))
|
||||
REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
|
||||
else {
|
||||
REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
|
||||
REG_RMW_FIELD(ah, AR_CH0_THERM,
|
||||
@ -3583,6 +3566,19 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
|
||||
}
|
||||
}
|
||||
|
||||
static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is_2ghz)
|
||||
{
|
||||
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
|
||||
__le32 val;
|
||||
|
||||
if (is_2ghz)
|
||||
val = eep->modalHeader2G.switchcomspdt;
|
||||
else
|
||||
val = eep->modalHeader5G.switchcomspdt;
|
||||
return le32_to_cpu(val);
|
||||
}
|
||||
|
||||
|
||||
static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
|
||||
{
|
||||
struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
|
||||
@ -3637,7 +3633,36 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
|
||||
|
||||
u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
|
||||
if (AR_SREV_9480(ah)) {
|
||||
if (AR_SREV_9480_10(ah)) {
|
||||
value &= ~AR_SWITCH_TABLE_COM_SPDT;
|
||||
value |= 0x00100000;
|
||||
}
|
||||
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
|
||||
AR_SWITCH_TABLE_COM_AR9480_ALL, value);
|
||||
} else
|
||||
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM,
|
||||
AR_SWITCH_TABLE_COM_ALL, value);
|
||||
|
||||
|
||||
/*
|
||||
* AR9480 defines new switch table for BT/WLAN,
|
||||
* here's new field name in XXX.ref for both 2G and 5G.
|
||||
* Register: [GLB_CONTROL] GLB_CONTROL (@0x20044)
|
||||
* 15:12 R/W SWITCH_TABLE_COM_SPDT_WLAN_RX
|
||||
* SWITCH_TABLE_COM_SPDT_WLAN_RX
|
||||
*
|
||||
* 11:8 R/W SWITCH_TABLE_COM_SPDT_WLAN_TX
|
||||
* SWITCH_TABLE_COM_SPDT_WLAN_TX
|
||||
*
|
||||
* 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
|
||||
* SWITCH_TABLE_COM_SPDT_WLAN_IDLE
|
||||
*/
|
||||
if (AR_SREV_9480_20_OR_LATER(ah)) {
|
||||
value = ar9003_switch_com_spdt_get(ah, is2ghz);
|
||||
REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
|
||||
AR_SWITCH_TABLE_COM_SPDT_ALL, value);
|
||||
}
|
||||
|
||||
value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
|
||||
REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
|
||||
@ -3837,6 +3862,7 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
|
||||
{
|
||||
int internal_regulator =
|
||||
ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
|
||||
u32 reg_val;
|
||||
|
||||
if (internal_regulator) {
|
||||
if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
|
||||
@ -3881,13 +3907,16 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
|
||||
REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set);
|
||||
if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set))
|
||||
return;
|
||||
} else if (AR_SREV_9480(ah)) {
|
||||
reg_val = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
|
||||
REG_WRITE(ah, AR_PHY_PMU1, reg_val);
|
||||
} else {
|
||||
/* Internal regulator is ON. Write swreg register. */
|
||||
int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
|
||||
reg_val = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
|
||||
REG_WRITE(ah, AR_RTC_REG_CONTROL1,
|
||||
REG_READ(ah, AR_RTC_REG_CONTROL1) &
|
||||
(~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
|
||||
REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
|
||||
REG_WRITE(ah, AR_RTC_REG_CONTROL0, reg_val);
|
||||
/* Set REG_CONTROL1.SWREG_PROGRAM */
|
||||
REG_WRITE(ah, AR_RTC_REG_CONTROL1,
|
||||
REG_READ(ah,
|
||||
@ -3898,22 +3927,24 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
|
||||
if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) {
|
||||
REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0);
|
||||
while (REG_READ_FIELD(ah, AR_PHY_PMU2,
|
||||
AR_PHY_PMU2_PGM))
|
||||
AR_PHY_PMU2_PGM))
|
||||
udelay(10);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
|
||||
while (!REG_READ_FIELD(ah, AR_PHY_PMU1,
|
||||
AR_PHY_PMU1_PWD))
|
||||
AR_PHY_PMU1_PWD))
|
||||
udelay(10);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM, 0x1);
|
||||
while (!REG_READ_FIELD(ah, AR_PHY_PMU2,
|
||||
AR_PHY_PMU2_PGM))
|
||||
AR_PHY_PMU2_PGM))
|
||||
udelay(10);
|
||||
} else
|
||||
REG_WRITE(ah, AR_RTC_SLEEP_CLK,
|
||||
(REG_READ(ah,
|
||||
AR_RTC_SLEEP_CLK) |
|
||||
AR_RTC_FORCE_SWREG_PRD));
|
||||
} else if (AR_SREV_9480(ah))
|
||||
REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1);
|
||||
else {
|
||||
reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) |
|
||||
AR_RTC_FORCE_SWREG_PRD;
|
||||
REG_WRITE(ah, AR_RTC_SLEEP_CLK, reg_val);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -4493,6 +4524,12 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah,
|
||||
tempSlope = eep->modalHeader5G.tempSlope;
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
|
||||
|
||||
if (AR_SREV_9480_20(ah))
|
||||
REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
|
||||
AR_PHY_TPC_19_B1_ALPHA_THERM, tempSlope);
|
||||
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
|
||||
temperature[0]);
|
||||
|
||||
|
@ -233,7 +233,8 @@ struct ar9300_modal_eep_header {
|
||||
u8 thresh62;
|
||||
__le32 papdRateMaskHt20;
|
||||
__le32 papdRateMaskHt40;
|
||||
u8 futureModal[10];
|
||||
__le16 switchcomspdt;
|
||||
u8 futureModal[8];
|
||||
} __packed;
|
||||
|
||||
struct ar9300_cal_data_per_freq_op_loop {
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "ar9330_1p1_initvals.h"
|
||||
#include "ar9330_1p2_initvals.h"
|
||||
#include "ar9580_1p0_initvals.h"
|
||||
#include "ar9480_1p0_initvals.h"
|
||||
#include "ar9480_2p0_initvals.h"
|
||||
|
||||
/* General hardware code for the AR9003 hadware family */
|
||||
|
||||
@ -32,6 +34,14 @@
|
||||
*/
|
||||
static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
{
|
||||
#define PCIE_PLL_ON_CREQ_DIS_L1_2P0 \
|
||||
ar9480_pciephy_pll_on_clkreq_disable_L1_2p0
|
||||
|
||||
#define AR9480_BB_CTX_COEFJ(x) \
|
||||
ar9480_##x##_baseband_core_txfir_coeff_japan_2484
|
||||
|
||||
#define AR9480_BBC_TXIFR_COEFFJ \
|
||||
ar9480_2p0_baseband_core_txfir_coeff_japan_2484
|
||||
if (AR_SREV_9330_11(ah)) {
|
||||
/* mac */
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
|
||||
@ -254,6 +264,132 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
ar9485_1_1_pcie_phy_clkreq_disable_L1,
|
||||
ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
|
||||
2);
|
||||
} else if (AR_SREV_9480_10(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9480_1p0_mac_core,
|
||||
ARRAY_SIZE(ar9480_1p0_mac_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
|
||||
ar9480_1p0_mac_postamble,
|
||||
ARRAY_SIZE(ar9480_1p0_mac_postamble),
|
||||
5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
|
||||
ar9480_1p0_baseband_core,
|
||||
ARRAY_SIZE(ar9480_1p0_baseband_core),
|
||||
2);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
|
||||
ar9480_1p0_baseband_postamble,
|
||||
ARRAY_SIZE(ar9480_1p0_baseband_postamble), 5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
|
||||
ar9480_1p0_radio_core,
|
||||
ARRAY_SIZE(ar9480_1p0_radio_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
|
||||
ar9480_1p0_radio_postamble,
|
||||
ARRAY_SIZE(ar9480_1p0_radio_postamble), 5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
|
||||
ar9480_1p0_soc_preamble,
|
||||
ARRAY_SIZE(ar9480_1p0_soc_preamble), 2);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
|
||||
ar9480_1p0_soc_postamble,
|
||||
ARRAY_SIZE(ar9480_1p0_soc_postamble), 5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9480_common_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9480_common_rx_gain_table_1p0), 2);
|
||||
|
||||
/* Awake -> Sleep Setting */
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
ar9480_pcie_phy_clkreq_disable_L1_1p0,
|
||||
ARRAY_SIZE(ar9480_pcie_phy_clkreq_disable_L1_1p0),
|
||||
2);
|
||||
|
||||
/* Sleep -> Awake Setting */
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
|
||||
ar9480_pcie_phy_clkreq_disable_L1_1p0,
|
||||
ARRAY_SIZE(ar9480_pcie_phy_clkreq_disable_L1_1p0),
|
||||
2);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
ar9480_modes_fast_clock_1p0,
|
||||
ARRAY_SIZE(ar9480_modes_fast_clock_1p0), 3);
|
||||
INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
|
||||
AR9480_BB_CTX_COEFJ(1p0),
|
||||
ARRAY_SIZE(AR9480_BB_CTX_COEFJ(1p0)), 2);
|
||||
|
||||
} else if (AR_SREV_9480_20(ah)) {
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9480_2p0_mac_core,
|
||||
ARRAY_SIZE(ar9480_2p0_mac_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
|
||||
ar9480_2p0_mac_postamble,
|
||||
ARRAY_SIZE(ar9480_2p0_mac_postamble), 5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
|
||||
ar9480_2p0_baseband_core,
|
||||
ARRAY_SIZE(ar9480_2p0_baseband_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
|
||||
ar9480_2p0_baseband_postamble,
|
||||
ARRAY_SIZE(ar9480_2p0_baseband_postamble), 5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
|
||||
ar9480_2p0_radio_core,
|
||||
ARRAY_SIZE(ar9480_2p0_radio_core), 2);
|
||||
INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
|
||||
ar9480_2p0_radio_postamble,
|
||||
ARRAY_SIZE(ar9480_2p0_radio_postamble), 5);
|
||||
INIT_INI_ARRAY(&ah->ini_radio_post_sys2ant,
|
||||
ar9480_2p0_radio_postamble_sys2ant,
|
||||
ARRAY_SIZE(ar9480_2p0_radio_postamble_sys2ant),
|
||||
5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
|
||||
ar9480_2p0_soc_preamble,
|
||||
ARRAY_SIZE(ar9480_2p0_soc_preamble), 2);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
|
||||
INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
|
||||
ar9480_2p0_soc_postamble,
|
||||
ARRAY_SIZE(ar9480_2p0_soc_postamble), 5);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9480_common_rx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9480_common_rx_gain_table_2p0), 2);
|
||||
|
||||
INIT_INI_ARRAY(&ah->ini_BTCOEX_MAX_TXPWR,
|
||||
ar9480_2p0_BTCOEX_MAX_TXPWR_table,
|
||||
ARRAY_SIZE(ar9480_2p0_BTCOEX_MAX_TXPWR_table),
|
||||
2);
|
||||
|
||||
/* Awake -> Sleep Setting */
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdes,
|
||||
PCIE_PLL_ON_CREQ_DIS_L1_2P0,
|
||||
ARRAY_SIZE(PCIE_PLL_ON_CREQ_DIS_L1_2P0),
|
||||
2);
|
||||
/* Sleep -> Awake Setting */
|
||||
INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
|
||||
PCIE_PLL_ON_CREQ_DIS_L1_2P0,
|
||||
ARRAY_SIZE(PCIE_PLL_ON_CREQ_DIS_L1_2P0),
|
||||
2);
|
||||
|
||||
/* Fast clock modal settings */
|
||||
INIT_INI_ARRAY(&ah->iniModesAdditional,
|
||||
ar9480_modes_fast_clock_2p0,
|
||||
ARRAY_SIZE(ar9480_modes_fast_clock_2p0), 3);
|
||||
|
||||
INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
|
||||
AR9480_BB_CTX_COEFJ(2p0),
|
||||
ARRAY_SIZE(AR9480_BB_CTX_COEFJ(2p0)), 2);
|
||||
|
||||
INIT_INI_ARRAY(&ah->ini_japan2484, AR9480_BBC_TXIFR_COEFFJ,
|
||||
ARRAY_SIZE(AR9480_BBC_TXIFR_COEFFJ), 2);
|
||||
|
||||
} else if (AR_SREV_9580(ah)) {
|
||||
/* mac */
|
||||
INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
|
||||
@ -374,208 +510,293 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
|
||||
}
|
||||
}
|
||||
|
||||
static void ar9003_tx_gain_table_mode0(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_lowest_ob_db_tx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p2),
|
||||
5);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_lowest_ob_db_tx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p1),
|
||||
5);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9485_modes_lowest_ob_db_tx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
|
||||
5);
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9580_1p0_lowest_ob_db_tx_gain_table,
|
||||
ARRAY_SIZE(ar9580_1p0_lowest_ob_db_tx_gain_table),
|
||||
5);
|
||||
else if (AR_SREV_9480_10(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9480_modes_low_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9480_modes_low_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
else if (AR_SREV_9480_20(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9480_modes_low_ob_db_tx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9480_modes_low_ob_db_tx_gain_table_2p0),
|
||||
5);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
|
||||
ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
|
||||
5);
|
||||
}
|
||||
|
||||
static void ar9003_tx_gain_table_mode1(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_high_ob_db_tx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p2),
|
||||
5);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_high_ob_db_tx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p1),
|
||||
5);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9485Modes_high_ob_db_tx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
|
||||
5);
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9580_1p0_high_ob_db_tx_gain_table,
|
||||
ARRAY_SIZE(ar9580_1p0_high_ob_db_tx_gain_table),
|
||||
5);
|
||||
else if (AR_SREV_9480_10(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9480_modes_high_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9480_modes_high_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
else if (AR_SREV_9480_20(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9480_modes_high_ob_db_tx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9480_modes_high_ob_db_tx_gain_table_2p0),
|
||||
5);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9300Modes_high_ob_db_tx_gain_table_2p2,
|
||||
ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
|
||||
5);
|
||||
}
|
||||
|
||||
static void ar9003_tx_gain_table_mode2(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_low_ob_db_tx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p2),
|
||||
5);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_low_ob_db_tx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p1),
|
||||
5);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9485Modes_low_ob_db_tx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
|
||||
5);
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9580_1p0_low_ob_db_tx_gain_table,
|
||||
ARRAY_SIZE(ar9580_1p0_low_ob_db_tx_gain_table),
|
||||
5);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9300Modes_low_ob_db_tx_gain_table_2p2,
|
||||
ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
|
||||
5);
|
||||
}
|
||||
|
||||
static void ar9003_tx_gain_table_mode3(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_high_power_tx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p2),
|
||||
5);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_high_power_tx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p1),
|
||||
5);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9485Modes_high_power_tx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
|
||||
5);
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9580_1p0_high_power_tx_gain_table,
|
||||
ARRAY_SIZE(ar9580_1p0_high_power_tx_gain_table),
|
||||
5);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9300Modes_high_power_tx_gain_table_2p2,
|
||||
ARRAY_SIZE(ar9300Modes_high_power_tx_gain_table_2p2),
|
||||
5);
|
||||
}
|
||||
|
||||
static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
|
||||
{
|
||||
switch (ar9003_hw_get_tx_gain_idx(ah)) {
|
||||
case 0:
|
||||
default:
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_lowest_ob_db_tx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p2),
|
||||
5);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_lowest_ob_db_tx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p1),
|
||||
5);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9485_modes_lowest_ob_db_tx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
|
||||
5);
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9580_1p0_lowest_ob_db_tx_gain_table,
|
||||
ARRAY_SIZE(ar9580_1p0_lowest_ob_db_tx_gain_table),
|
||||
5);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
|
||||
ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
|
||||
5);
|
||||
ar9003_tx_gain_table_mode0(ah);
|
||||
break;
|
||||
case 1:
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_high_ob_db_tx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p2),
|
||||
5);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_high_ob_db_tx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p1),
|
||||
5);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9485Modes_high_ob_db_tx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
|
||||
5);
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9580_1p0_high_ob_db_tx_gain_table,
|
||||
ARRAY_SIZE(ar9580_1p0_high_ob_db_tx_gain_table),
|
||||
5);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9300Modes_high_ob_db_tx_gain_table_2p2,
|
||||
ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
|
||||
5);
|
||||
ar9003_tx_gain_table_mode1(ah);
|
||||
break;
|
||||
case 2:
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_low_ob_db_tx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p2),
|
||||
5);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_low_ob_db_tx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p1),
|
||||
5);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9485Modes_low_ob_db_tx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
|
||||
5);
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9580_1p0_low_ob_db_tx_gain_table,
|
||||
ARRAY_SIZE(ar9580_1p0_low_ob_db_tx_gain_table),
|
||||
5);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9300Modes_low_ob_db_tx_gain_table_2p2,
|
||||
ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
|
||||
5);
|
||||
ar9003_tx_gain_table_mode2(ah);
|
||||
break;
|
||||
case 3:
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_high_power_tx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p2),
|
||||
5);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9331_modes_high_power_tx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p1),
|
||||
5);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
|
||||
5);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9485Modes_high_power_tx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
|
||||
5);
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9580_1p0_high_power_tx_gain_table,
|
||||
ARRAY_SIZE(ar9580_1p0_high_power_tx_gain_table),
|
||||
5);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9300Modes_high_power_tx_gain_table_2p2,
|
||||
ARRAY_SIZE(ar9300Modes_high_power_tx_gain_table_2p2),
|
||||
5);
|
||||
ar9003_tx_gain_table_mode3(ah);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9331_common_rx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_common_rx_gain_1p2),
|
||||
2);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9331_common_rx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_common_rx_gain_1p1),
|
||||
2);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9340Common_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Common_rx_gain_table_1p0),
|
||||
2);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9485Common_wo_xlna_rx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
|
||||
2);
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9580_1p0_rx_gain_table,
|
||||
ARRAY_SIZE(ar9580_1p0_rx_gain_table),
|
||||
2);
|
||||
else if (AR_SREV_9480_10(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9480_common_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9480_common_rx_gain_table_1p0),
|
||||
2);
|
||||
else if (AR_SREV_9480_20(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9480_common_rx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9480_common_rx_gain_table_2p0),
|
||||
2);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9300Common_rx_gain_table_2p2,
|
||||
ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
|
||||
2);
|
||||
}
|
||||
|
||||
static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9331_common_wo_xlna_rx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p2),
|
||||
2);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9331_common_wo_xlna_rx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p1),
|
||||
2);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9340Common_wo_xlna_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
|
||||
2);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9485Common_wo_xlna_rx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
|
||||
2);
|
||||
else if (AR_SREV_9480_10(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9480_common_wo_xlna_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9480_common_wo_xlna_rx_gain_table_1p0),
|
||||
2);
|
||||
else if (AR_SREV_9480_20(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9480_common_wo_xlna_rx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9480_common_wo_xlna_rx_gain_table_2p0),
|
||||
2);
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9580_1p0_wo_xlna_rx_gain_table,
|
||||
ARRAY_SIZE(ar9580_1p0_wo_xlna_rx_gain_table),
|
||||
2);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9300Common_wo_xlna_rx_gain_table_2p2,
|
||||
ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
|
||||
2);
|
||||
}
|
||||
|
||||
static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9480_10(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9480_common_mixed_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9480_common_mixed_rx_gain_table_1p0), 2);
|
||||
else if (AR_SREV_9480_20(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9480_common_mixed_rx_gain_table_2p0,
|
||||
ARRAY_SIZE(ar9480_common_mixed_rx_gain_table_2p0), 2);
|
||||
}
|
||||
|
||||
static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
|
||||
{
|
||||
switch (ar9003_hw_get_rx_gain_idx(ah)) {
|
||||
case 0:
|
||||
default:
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9331_common_rx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_common_rx_gain_1p2),
|
||||
2);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9331_common_rx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_common_rx_gain_1p1),
|
||||
2);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9340Common_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Common_rx_gain_table_1p0),
|
||||
2);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9485Common_wo_xlna_rx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
|
||||
2);
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9580_1p0_rx_gain_table,
|
||||
ARRAY_SIZE(ar9580_1p0_rx_gain_table),
|
||||
2);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9300Common_rx_gain_table_2p2,
|
||||
ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
|
||||
2);
|
||||
ar9003_rx_gain_table_mode0(ah);
|
||||
break;
|
||||
case 1:
|
||||
if (AR_SREV_9330_12(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9331_common_wo_xlna_rx_gain_1p2,
|
||||
ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p2),
|
||||
2);
|
||||
else if (AR_SREV_9330_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9331_common_wo_xlna_rx_gain_1p1,
|
||||
ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p1),
|
||||
2);
|
||||
else if (AR_SREV_9340(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9340Common_wo_xlna_rx_gain_table_1p0,
|
||||
ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
|
||||
2);
|
||||
else if (AR_SREV_9485_11(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9485Common_wo_xlna_rx_gain_1_1,
|
||||
ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
|
||||
2);
|
||||
else if (AR_SREV_9580(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9580_1p0_wo_xlna_rx_gain_table,
|
||||
ARRAY_SIZE(ar9580_1p0_wo_xlna_rx_gain_table),
|
||||
2);
|
||||
else
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9300Common_wo_xlna_rx_gain_table_2p2,
|
||||
ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
|
||||
2);
|
||||
ar9003_rx_gain_table_mode1(ah);
|
||||
break;
|
||||
case 2:
|
||||
ar9003_rx_gain_table_mode2(ah);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,132 @@ static void ar9003_hw_rx_enable(struct ath_hw *hw)
|
||||
REG_WRITE(hw, AR_CR, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i)
|
||||
{
|
||||
struct ar9003_txc *ads = ds;
|
||||
int checksum = 0;
|
||||
u32 val, ctl12, ctl17;
|
||||
|
||||
val = (ATHEROS_VENDOR_ID << AR_DescId_S) |
|
||||
(1 << AR_TxRxDesc_S) |
|
||||
(1 << AR_CtrlStat_S) |
|
||||
(i->qcu << AR_TxQcuNum_S) | 0x17;
|
||||
|
||||
checksum += val;
|
||||
ACCESS_ONCE(ads->info) = val;
|
||||
|
||||
checksum += i->link;
|
||||
ACCESS_ONCE(ads->link) = i->link;
|
||||
|
||||
checksum += i->buf_addr[0];
|
||||
ACCESS_ONCE(ads->data0) = i->buf_addr[0];
|
||||
checksum += i->buf_addr[1];
|
||||
ACCESS_ONCE(ads->data1) = i->buf_addr[1];
|
||||
checksum += i->buf_addr[2];
|
||||
ACCESS_ONCE(ads->data2) = i->buf_addr[2];
|
||||
checksum += i->buf_addr[3];
|
||||
ACCESS_ONCE(ads->data3) = i->buf_addr[3];
|
||||
|
||||
checksum += (val = (i->buf_len[0] << AR_BufLen_S) & AR_BufLen);
|
||||
ACCESS_ONCE(ads->ctl3) = val;
|
||||
checksum += (val = (i->buf_len[1] << AR_BufLen_S) & AR_BufLen);
|
||||
ACCESS_ONCE(ads->ctl5) = val;
|
||||
checksum += (val = (i->buf_len[2] << AR_BufLen_S) & AR_BufLen);
|
||||
ACCESS_ONCE(ads->ctl7) = val;
|
||||
checksum += (val = (i->buf_len[3] << AR_BufLen_S) & AR_BufLen);
|
||||
ACCESS_ONCE(ads->ctl9) = val;
|
||||
|
||||
checksum = (u16) (((checksum & 0xffff) + (checksum >> 16)) & 0xffff);
|
||||
ACCESS_ONCE(ads->ctl10) = checksum;
|
||||
|
||||
if (i->is_first || i->is_last) {
|
||||
ACCESS_ONCE(ads->ctl13) = set11nTries(i->rates, 0)
|
||||
| set11nTries(i->rates, 1)
|
||||
| set11nTries(i->rates, 2)
|
||||
| set11nTries(i->rates, 3)
|
||||
| (i->dur_update ? AR_DurUpdateEna : 0)
|
||||
| SM(0, AR_BurstDur);
|
||||
|
||||
ACCESS_ONCE(ads->ctl14) = set11nRate(i->rates, 0)
|
||||
| set11nRate(i->rates, 1)
|
||||
| set11nRate(i->rates, 2)
|
||||
| set11nRate(i->rates, 3);
|
||||
} else {
|
||||
ACCESS_ONCE(ads->ctl13) = 0;
|
||||
ACCESS_ONCE(ads->ctl14) = 0;
|
||||
}
|
||||
|
||||
ads->ctl20 = 0;
|
||||
ads->ctl21 = 0;
|
||||
ads->ctl22 = 0;
|
||||
|
||||
ctl17 = SM(i->keytype, AR_EncrType);
|
||||
if (!i->is_first) {
|
||||
ACCESS_ONCE(ads->ctl11) = 0;
|
||||
ACCESS_ONCE(ads->ctl12) = i->is_last ? 0 : AR_TxMore;
|
||||
ACCESS_ONCE(ads->ctl15) = 0;
|
||||
ACCESS_ONCE(ads->ctl16) = 0;
|
||||
ACCESS_ONCE(ads->ctl17) = ctl17;
|
||||
ACCESS_ONCE(ads->ctl18) = 0;
|
||||
ACCESS_ONCE(ads->ctl19) = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
ACCESS_ONCE(ads->ctl11) = (i->pkt_len & AR_FrameLen)
|
||||
| (i->flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
|
||||
| SM(i->txpower, AR_XmitPower)
|
||||
| (i->flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
|
||||
| (i->keyix != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
|
||||
| (i->flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0)
|
||||
| (i->flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
|
||||
| (i->flags & ATH9K_TXDESC_RTSENA ? AR_RTSEnable :
|
||||
(i->flags & ATH9K_TXDESC_CTSENA ? AR_CTSEnable : 0));
|
||||
|
||||
ctl12 = (i->keyix != ATH9K_TXKEYIX_INVALID ?
|
||||
SM(i->keyix, AR_DestIdx) : 0)
|
||||
| SM(i->type, AR_FrameType)
|
||||
| (i->flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
|
||||
| (i->flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
|
||||
| (i->flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
|
||||
|
||||
ctl17 |= (i->flags & ATH9K_TXDESC_LDPC ? AR_LDPC : 0);
|
||||
switch (i->aggr) {
|
||||
case AGGR_BUF_FIRST:
|
||||
ctl17 |= SM(i->aggr_len, AR_AggrLen);
|
||||
/* fall through */
|
||||
case AGGR_BUF_MIDDLE:
|
||||
ctl12 |= AR_IsAggr | AR_MoreAggr;
|
||||
ctl17 |= SM(i->ndelim, AR_PadDelim);
|
||||
break;
|
||||
case AGGR_BUF_LAST:
|
||||
ctl12 |= AR_IsAggr;
|
||||
break;
|
||||
case AGGR_BUF_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
val = (i->flags & ATH9K_TXDESC_PAPRD) >> ATH9K_TXDESC_PAPRD_S;
|
||||
ctl12 |= SM(val, AR_PAPRDChainMask);
|
||||
|
||||
ACCESS_ONCE(ads->ctl12) = ctl12;
|
||||
ACCESS_ONCE(ads->ctl17) = ctl17;
|
||||
|
||||
ACCESS_ONCE(ads->ctl15) = set11nPktDurRTSCTS(i->rates, 0)
|
||||
| set11nPktDurRTSCTS(i->rates, 1);
|
||||
|
||||
ACCESS_ONCE(ads->ctl16) = set11nPktDurRTSCTS(i->rates, 2)
|
||||
| set11nPktDurRTSCTS(i->rates, 3);
|
||||
|
||||
ACCESS_ONCE(ads->ctl18) = set11nRateFlags(i->rates, 0)
|
||||
| set11nRateFlags(i->rates, 1)
|
||||
| set11nRateFlags(i->rates, 2)
|
||||
| set11nRateFlags(i->rates, 3)
|
||||
| SM(i->rtscts_rate, AR_RTSCTSRate);
|
||||
|
||||
ACCESS_ONCE(ads->ctl19) = AR_Not_Sounding;
|
||||
}
|
||||
|
||||
static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
|
||||
{
|
||||
int checksum;
|
||||
@ -185,47 +311,6 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ar9003_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen,
|
||||
bool is_firstseg, bool is_lastseg,
|
||||
const void *ds0, dma_addr_t buf_addr,
|
||||
unsigned int qcu)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
unsigned int descid = 0;
|
||||
|
||||
ads->info = (ATHEROS_VENDOR_ID << AR_DescId_S) |
|
||||
(1 << AR_TxRxDesc_S) |
|
||||
(1 << AR_CtrlStat_S) |
|
||||
(qcu << AR_TxQcuNum_S) | 0x17;
|
||||
|
||||
ads->data0 = buf_addr;
|
||||
ads->data1 = 0;
|
||||
ads->data2 = 0;
|
||||
ads->data3 = 0;
|
||||
|
||||
ads->ctl3 = (seglen << AR_BufLen_S);
|
||||
ads->ctl3 &= AR_BufLen;
|
||||
|
||||
/* Fill in pointer checksum and descriptor id */
|
||||
ads->ctl10 = ar9003_calc_ptr_chksum(ads);
|
||||
ads->ctl10 |= (descid << AR_TxDescId_S);
|
||||
|
||||
if (is_firstseg) {
|
||||
ads->ctl12 |= (is_lastseg ? 0 : AR_TxMore);
|
||||
} else if (is_lastseg) {
|
||||
ads->ctl11 = 0;
|
||||
ads->ctl12 = 0;
|
||||
ads->ctl13 = AR9003TXC_CONST(ds0)->ctl13;
|
||||
ads->ctl14 = AR9003TXC_CONST(ds0)->ctl14;
|
||||
} else {
|
||||
/* XXX Intermediate descriptor in a multi-descriptor frame.*/
|
||||
ads->ctl11 = 0;
|
||||
ads->ctl12 = AR_TxMore;
|
||||
ads->ctl13 = 0;
|
||||
ads->ctl14 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
|
||||
struct ath_tx_status *ts)
|
||||
{
|
||||
@ -310,161 +395,6 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
|
||||
u32 pktlen, enum ath9k_pkt_type type, u32 txpower,
|
||||
u8 keyIx, enum ath9k_key_type keyType, u32 flags)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
|
||||
if (txpower > ah->txpower_limit)
|
||||
txpower = ah->txpower_limit;
|
||||
|
||||
if (txpower > 63)
|
||||
txpower = 63;
|
||||
|
||||
ads->ctl11 = (pktlen & AR_FrameLen)
|
||||
| (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
|
||||
| SM(txpower, AR_XmitPower)
|
||||
| (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
|
||||
| (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
|
||||
| (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0);
|
||||
|
||||
ads->ctl12 =
|
||||
(keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
|
||||
| SM(type, AR_FrameType)
|
||||
| (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
|
||||
| (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
|
||||
| (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
|
||||
|
||||
ads->ctl17 = SM(keyType, AR_EncrType) |
|
||||
(flags & ATH9K_TXDESC_LDPC ? AR_LDPC : 0);
|
||||
ads->ctl18 = 0;
|
||||
ads->ctl19 = AR_Not_Sounding;
|
||||
|
||||
ads->ctl20 = 0;
|
||||
ads->ctl21 = 0;
|
||||
ads->ctl22 = 0;
|
||||
}
|
||||
|
||||
static void ar9003_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
|
||||
if (val)
|
||||
ads->ctl11 |= AR_ClrDestMask;
|
||||
else
|
||||
ads->ctl11 &= ~AR_ClrDestMask;
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
|
||||
void *lastds,
|
||||
u32 durUpdateEn, u32 rtsctsRate,
|
||||
u32 rtsctsDuration,
|
||||
struct ath9k_11n_rate_series series[],
|
||||
u32 nseries, u32 flags)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
struct ar9003_txc *last_ads = (struct ar9003_txc *) lastds;
|
||||
u_int32_t ctl11;
|
||||
|
||||
if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
|
||||
ctl11 = ads->ctl11;
|
||||
|
||||
if (flags & ATH9K_TXDESC_RTSENA) {
|
||||
ctl11 &= ~AR_CTSEnable;
|
||||
ctl11 |= AR_RTSEnable;
|
||||
} else {
|
||||
ctl11 &= ~AR_RTSEnable;
|
||||
ctl11 |= AR_CTSEnable;
|
||||
}
|
||||
|
||||
ads->ctl11 = ctl11;
|
||||
} else {
|
||||
ads->ctl11 = (ads->ctl11 & ~(AR_RTSEnable | AR_CTSEnable));
|
||||
}
|
||||
|
||||
ads->ctl13 = set11nTries(series, 0)
|
||||
| set11nTries(series, 1)
|
||||
| set11nTries(series, 2)
|
||||
| set11nTries(series, 3)
|
||||
| (durUpdateEn ? AR_DurUpdateEna : 0)
|
||||
| SM(0, AR_BurstDur);
|
||||
|
||||
ads->ctl14 = set11nRate(series, 0)
|
||||
| set11nRate(series, 1)
|
||||
| set11nRate(series, 2)
|
||||
| set11nRate(series, 3);
|
||||
|
||||
ads->ctl15 = set11nPktDurRTSCTS(series, 0)
|
||||
| set11nPktDurRTSCTS(series, 1);
|
||||
|
||||
ads->ctl16 = set11nPktDurRTSCTS(series, 2)
|
||||
| set11nPktDurRTSCTS(series, 3);
|
||||
|
||||
ads->ctl18 = set11nRateFlags(series, 0)
|
||||
| set11nRateFlags(series, 1)
|
||||
| set11nRateFlags(series, 2)
|
||||
| set11nRateFlags(series, 3)
|
||||
| SM(rtsctsRate, AR_RTSCTSRate);
|
||||
ads->ctl19 = AR_Not_Sounding;
|
||||
|
||||
last_ads->ctl13 = ads->ctl13;
|
||||
last_ads->ctl14 = ads->ctl14;
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
|
||||
u32 aggrLen)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
|
||||
ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
|
||||
|
||||
ads->ctl17 &= ~AR_AggrLen;
|
||||
ads->ctl17 |= SM(aggrLen, AR_AggrLen);
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
|
||||
u32 numDelims)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
unsigned int ctl17;
|
||||
|
||||
ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
|
||||
|
||||
/*
|
||||
* We use a stack variable to manipulate ctl6 to reduce uncached
|
||||
* read modify, modfiy, write.
|
||||
*/
|
||||
ctl17 = ads->ctl17;
|
||||
ctl17 &= ~AR_PadDelim;
|
||||
ctl17 |= SM(numDelims, AR_PadDelim);
|
||||
ads->ctl17 = ctl17;
|
||||
}
|
||||
|
||||
static void ar9003_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
|
||||
ads->ctl12 |= AR_IsAggr;
|
||||
ads->ctl12 &= ~AR_MoreAggr;
|
||||
ads->ctl17 &= ~AR_PadDelim;
|
||||
}
|
||||
|
||||
static void ar9003_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
|
||||
{
|
||||
struct ar9003_txc *ads = (struct ar9003_txc *) ds;
|
||||
|
||||
ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr);
|
||||
}
|
||||
|
||||
void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains)
|
||||
{
|
||||
struct ar9003_txc *ads = ds;
|
||||
|
||||
ads->ctl12 |= SM(chains, AR_PAPRDChainMask);
|
||||
}
|
||||
EXPORT_SYMBOL(ar9003_hw_set_paprd_txdesc);
|
||||
|
||||
void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
|
||||
{
|
||||
struct ath_hw_ops *ops = ath9k_hw_ops(hw);
|
||||
@ -472,15 +402,8 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
|
||||
ops->rx_enable = ar9003_hw_rx_enable;
|
||||
ops->set_desc_link = ar9003_hw_set_desc_link;
|
||||
ops->get_isr = ar9003_hw_get_isr;
|
||||
ops->fill_txdesc = ar9003_hw_fill_txdesc;
|
||||
ops->set_txdesc = ar9003_set_txdesc;
|
||||
ops->proc_txdesc = ar9003_hw_proc_txdesc;
|
||||
ops->set11n_txdesc = ar9003_hw_set11n_txdesc;
|
||||
ops->set11n_ratescenario = ar9003_hw_set11n_ratescenario;
|
||||
ops->set11n_aggr_first = ar9003_hw_set11n_aggr_first;
|
||||
ops->set11n_aggr_middle = ar9003_hw_set11n_aggr_middle;
|
||||
ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last;
|
||||
ops->clr11n_aggr = ar9003_hw_clr11n_aggr;
|
||||
ops->set_clrdmask = ar9003_hw_set_clrdmask;
|
||||
}
|
||||
|
||||
void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size)
|
||||
|
@ -113,7 +113,7 @@ static int ar9003_get_training_power_5g(struct ath_hw *ah)
|
||||
if (delta > scale)
|
||||
return -1;
|
||||
|
||||
switch (get_streams(common->tx_chainmask)) {
|
||||
switch (get_streams(ah->txchainmask)) {
|
||||
case 1:
|
||||
delta = 6;
|
||||
break;
|
||||
@ -126,7 +126,7 @@ static int ar9003_get_training_power_5g(struct ath_hw *ah)
|
||||
default:
|
||||
delta = 0;
|
||||
ath_dbg(common, ATH_DBG_CALIBRATE,
|
||||
"Invalid tx-chainmask: %u\n", common->tx_chainmask);
|
||||
"Invalid tx-chainmask: %u\n", ah->txchainmask);
|
||||
}
|
||||
|
||||
power += delta;
|
||||
@ -147,7 +147,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
|
||||
AR_PHY_PAPRD_CTRL1_B2
|
||||
};
|
||||
int training_power;
|
||||
int i;
|
||||
int i, val;
|
||||
|
||||
if (IS_CHAN_2GHZ(ah->curchan))
|
||||
training_power = ar9003_get_training_power_2g(ah);
|
||||
@ -207,8 +207,9 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
|
||||
AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
|
||||
AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1);
|
||||
val = AR_SREV_9480(ah) ? 0x91 : 147;
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL2,
|
||||
AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, 147);
|
||||
AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, val);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
|
||||
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN, 4);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
|
||||
@ -217,7 +218,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
|
||||
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
|
||||
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1);
|
||||
if (AR_SREV_9485(ah))
|
||||
if (AR_SREV_9485(ah) || AR_SREV_9480(ah))
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
|
||||
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
|
||||
-3);
|
||||
@ -225,9 +226,10 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah)
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
|
||||
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP,
|
||||
-6);
|
||||
val = AR_SREV_9480(ah) ? -10 : -15;
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
|
||||
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE,
|
||||
-15);
|
||||
val);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
|
||||
AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE, 1);
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL4,
|
||||
@ -757,6 +759,7 @@ void ar9003_paprd_populate_single_table(struct ath_hw *ah,
|
||||
training_power);
|
||||
|
||||
if (ah->caps.tx_chainmask & BIT(2))
|
||||
/* val AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL correct? */
|
||||
REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B2,
|
||||
AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
|
||||
training_power);
|
||||
|
@ -559,6 +559,9 @@ static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
|
||||
|
||||
if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7))
|
||||
REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
|
||||
else if (AR_SREV_9480(ah))
|
||||
/* xxx only when MCI support is enabled */
|
||||
REG_WRITE(ah, AR_SELFGEN_MASK, 0x3);
|
||||
else
|
||||
REG_WRITE(ah, AR_SELFGEN_MASK, tx);
|
||||
|
||||
@ -658,6 +661,10 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
|
||||
ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex);
|
||||
ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex);
|
||||
ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex);
|
||||
if (i == ATH_INI_POST && AR_SREV_9480_20(ah))
|
||||
ar9003_hw_prog_ini(ah,
|
||||
&ah->ini_radio_post_sys2ant,
|
||||
modesIndex);
|
||||
}
|
||||
|
||||
REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites);
|
||||
@ -677,6 +684,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
|
||||
if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
|
||||
REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites);
|
||||
|
||||
if (AR_SREV_9480(ah))
|
||||
ar9003_hw_prog_ini(ah, &ah->ini_BTCOEX_MAX_TXPWR, 1);
|
||||
|
||||
ar9003_hw_override_ini(ah);
|
||||
ar9003_hw_set_channel_regs(ah, chan);
|
||||
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
|
||||
|
@ -581,6 +581,9 @@
|
||||
#define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \
|
||||
(AR_SREV_9485(ah) ? \
|
||||
0x3d0 : 0x450) + ((_i) << 2))
|
||||
#define AR_PHY_RTT_CTRL (AR_SM_BASE + 0x380)
|
||||
#define AR_PHY_RTT_TABLE_SW_INTF_B (AR_SM_BASE + 0x384)
|
||||
#define AR_PHY_RTT_TABLE_SW_INTF_1_B0 (AR_SM_BASE + 0x388)
|
||||
|
||||
#define AR_PHY_WATCHDOG_STATUS (AR_SM_BASE + 0x5c0)
|
||||
#define AR_PHY_WATCHDOG_CTL_1 (AR_SM_BASE + 0x5c4)
|
||||
@ -600,6 +603,17 @@
|
||||
#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE 0x0000ff00
|
||||
#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_S 8
|
||||
|
||||
/* AIC Registers */
|
||||
#define AR_PHY_AIC_CTRL_0_B0 (AR_SM_BASE + 0x4b0)
|
||||
#define AR_PHY_AIC_CTRL_1_B0 (AR_SM_BASE + 0x4b4)
|
||||
#define AR_PHY_AIC_CTRL_2_B0 (AR_SM_BASE + 0x4b8)
|
||||
#define AR_PHY_AIC_CTRL_3_B0 (AR_SM_BASE + 0x4bc)
|
||||
#define AR_PHY_AIC_STAT_0_B0 (AR_SM_BASE + (AR_SREV_9480_10(ah) ? \
|
||||
0x4c0 : 0x4c4))
|
||||
#define AR_PHY_AIC_STAT_1_B0 (AR_SM_BASE + (AR_SREV_9480_10(ah) ? \
|
||||
0x4c4 : 0x4c8))
|
||||
#define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0)
|
||||
#define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc)
|
||||
|
||||
#define AR_PHY_65NM_CH0_SYNTH4 0x1608c
|
||||
#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT 0x00000002
|
||||
@ -609,7 +623,35 @@
|
||||
#define AR_PHY_65NM_CH0_BIAS2 0x160c4
|
||||
#define AR_PHY_65NM_CH0_BIAS4 0x160cc
|
||||
#define AR_PHY_65NM_CH0_RXTX4 0x1610c
|
||||
#define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 : 0x1628c)
|
||||
|
||||
#define AR_CH0_TOP (AR_SREV_9300(ah) ? 0x16288 : \
|
||||
((AR_SREV_9480(ah) ? 0x1628c : 0x16280)))
|
||||
#define AR_CH0_TOP_XPABIASLVL (0x300)
|
||||
#define AR_CH0_TOP_XPABIASLVL_S (8)
|
||||
|
||||
#define AR_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 : \
|
||||
((AR_SREV_9485(ah) ? 0x1628c : 0x16294)))
|
||||
#define AR_CH0_THERM_XPABIASLVL_MSB 0x3
|
||||
#define AR_CH0_THERM_XPABIASLVL_MSB_S 0
|
||||
#define AR_CH0_THERM_XPASHORT2GND 0x4
|
||||
#define AR_CH0_THERM_XPASHORT2GND_S 2
|
||||
|
||||
#define AR_SWITCH_TABLE_COM_ALL (0xffff)
|
||||
#define AR_SWITCH_TABLE_COM_ALL_S (0)
|
||||
#define AR_SWITCH_TABLE_COM_AR9480_ALL (0xffffff)
|
||||
#define AR_SWITCH_TABLE_COM_AR9480_ALL_S (0)
|
||||
#define AR_SWITCH_TABLE_COM_SPDT (0x00f00000)
|
||||
#define AR_SWITCH_TABLE_COM_SPDT_ALL (0x0000fff0)
|
||||
#define AR_SWITCH_TABLE_COM_SPDT_ALL_S (4)
|
||||
|
||||
#define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
|
||||
#define AR_SWITCH_TABLE_COM2_ALL_S (0)
|
||||
|
||||
#define AR_SWITCH_TABLE_ALL (0xfff)
|
||||
#define AR_SWITCH_TABLE_ALL_S (0)
|
||||
|
||||
#define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 :\
|
||||
(AR_SREV_9485(ah) ? 0x1628c : 0x16294))
|
||||
|
||||
#define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000
|
||||
#define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
|
||||
@ -625,21 +667,23 @@
|
||||
#define AR_PHY_65NM_CH2_RXTX1 0x16900
|
||||
#define AR_PHY_65NM_CH2_RXTX2 0x16904
|
||||
|
||||
#define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : 0x16284)
|
||||
#define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \
|
||||
(AR_SREV_9485(ah) ? 0x16284 : 0x16290))
|
||||
#define AR_CH0_TOP2_XPABIASLVL 0xf000
|
||||
#define AR_CH0_TOP2_XPABIASLVL_S 12
|
||||
|
||||
#define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : 0x16290)
|
||||
#define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : \
|
||||
(AR_SREV_9485(ah) ? 0x16290 : 0x16298))
|
||||
#define AR_CH0_XTAL_CAPINDAC 0x7f000000
|
||||
#define AR_CH0_XTAL_CAPINDAC_S 24
|
||||
#define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000
|
||||
#define AR_CH0_XTAL_CAPOUTDAC_S 17
|
||||
|
||||
#define AR_PHY_PMU1 0x16c40
|
||||
#define AR_PHY_PMU1 (AR_SREV_9480(ah) ? 0x16340 : 0x16c40)
|
||||
#define AR_PHY_PMU1_PWD 0x1
|
||||
#define AR_PHY_PMU1_PWD_S 0
|
||||
|
||||
#define AR_PHY_PMU2 0x16c44
|
||||
#define AR_PHY_PMU2 (AR_SREV_9480(ah) ? 0x16344 : 0x16c44)
|
||||
#define AR_PHY_PMU2_PGM 0x00200000
|
||||
#define AR_PHY_PMU2_PGM_S 21
|
||||
|
||||
@ -839,19 +883,38 @@
|
||||
*/
|
||||
#define AR_SM1_BASE 0xb200
|
||||
|
||||
#define AR_PHY_SWITCH_CHAIN_1 (AR_SM1_BASE + 0x84)
|
||||
#define AR_PHY_FCAL_2_1 (AR_SM1_BASE + 0xd0)
|
||||
#define AR_PHY_DFT_TONE_CTL_1 (AR_SM1_BASE + 0xd4)
|
||||
#define AR_PHY_CL_TAB_1 (AR_SM1_BASE + 0x100)
|
||||
#define AR_PHY_CHAN_INFO_GAIN_1 (AR_SM1_BASE + 0x180)
|
||||
#define AR_PHY_TPC_4_B1 (AR_SM1_BASE + 0x204)
|
||||
#define AR_PHY_TPC_5_B1 (AR_SM1_BASE + 0x208)
|
||||
#define AR_PHY_TPC_6_B1 (AR_SM1_BASE + 0x20c)
|
||||
#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220)
|
||||
#define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + 0x240)
|
||||
#define AR_PHY_SWITCH_CHAIN_1 (AR_SM1_BASE + 0x84)
|
||||
#define AR_PHY_FCAL_2_1 (AR_SM1_BASE + 0xd0)
|
||||
#define AR_PHY_DFT_TONE_CTL_1 (AR_SM1_BASE + 0xd4)
|
||||
#define AR_PHY_CL_TAB_1 (AR_SM1_BASE + 0x100)
|
||||
#define AR_PHY_CHAN_INFO_GAIN_1 (AR_SM1_BASE + 0x180)
|
||||
#define AR_PHY_TPC_4_B1 (AR_SM1_BASE + 0x204)
|
||||
#define AR_PHY_TPC_5_B1 (AR_SM1_BASE + 0x208)
|
||||
#define AR_PHY_TPC_6_B1 (AR_SM1_BASE + 0x20c)
|
||||
#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220)
|
||||
#define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + (AR_SREV_AR9300(ah) ? \
|
||||
0x240 : 0x280))
|
||||
#define AR_PHY_TPC_19_B1 (AR_SM1_BASE + 0x240)
|
||||
#define AR_PHY_TPC_19_B1_ALPHA_THERM 0xff
|
||||
#define AR_PHY_TPC_19_B1_ALPHA_THERM_S 0
|
||||
#define AR_PHY_TX_IQCAL_STATUS_B1 (AR_SM1_BASE + 0x48c)
|
||||
#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM1_BASE + 0x450 + ((_i) << 2))
|
||||
|
||||
/* SM 1 AIC Registers */
|
||||
|
||||
#define AR_PHY_AIC_CTRL_0_B1 (AR_SM1_BASE + 0x4b0)
|
||||
#define AR_PHY_AIC_CTRL_1_B1 (AR_SM1_BASE + 0x4b4)
|
||||
#define AR_PHY_AIC_CTRL_2_B1 (AR_SM1_BASE + 0x4b8)
|
||||
#define AR_PHY_AIC_STAT_0_B1 (AR_SM1_BASE + (AR_SREV_9480_10(ah) ? \
|
||||
0x4c0 : 0x4c4))
|
||||
#define AR_PHY_AIC_STAT_1_B1 (AR_SM1_BASE + (AR_SREV_9480_10(ah) ? \
|
||||
0x4c4 : 0x4c8))
|
||||
#define AR_PHY_AIC_CTRL_4_B1 (AR_SM1_BASE + 0x4c0)
|
||||
#define AR_PHY_AIC_STAT_2_B1 (AR_SM1_BASE + 0x4cc)
|
||||
|
||||
#define AR_PHY_AIC_SRAM_ADDR_B1 (AR_SM1_BASE + 0x5f0)
|
||||
#define AR_PHY_AIC_SRAM_DATA_B1 (AR_SM1_BASE + 0x5f4)
|
||||
|
||||
/*
|
||||
* Channel 2 Register Map
|
||||
*/
|
||||
@ -914,6 +977,13 @@
|
||||
|
||||
#define AR_PHY_RSSI_3 (AR_AGC3_BASE + 0x180)
|
||||
|
||||
/* GLB Registers */
|
||||
#define AR_GLB_BASE 0x20000
|
||||
#define AR_PHY_GLB_CONTROL (AR_GLB_BASE + 0x44)
|
||||
#define AR_GLB_SCRATCH(_ah) (AR_GLB_BASE + \
|
||||
(AR_SREV_9480_20(_ah) ? 0x4c : 0x50))
|
||||
#define AR_GLB_STATUS (AR_GLB_BASE + 0x48)
|
||||
|
||||
/*
|
||||
* Misc helper defines
|
||||
*/
|
||||
|
1833
drivers/net/wireless/ath/ath9k/ar9480_1p0_initvals.h
Normal file
1833
drivers/net/wireless/ath/ath9k/ar9480_1p0_initvals.h
Normal file
File diff suppressed because it is too large
Load Diff
1928
drivers/net/wireless/ath/ath9k/ar9480_2p0_initvals.h
Normal file
1928
drivers/net/wireless/ath/ath9k/ar9480_2p0_initvals.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -87,17 +87,14 @@ struct ath_config {
|
||||
* @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX)
|
||||
* @BUF_AGGR: Indicates whether the buffer can be aggregated
|
||||
* (used in aggregation scheduling)
|
||||
* @BUF_XRETRY: To denote excessive retries of the buffer
|
||||
*/
|
||||
enum buffer_type {
|
||||
BUF_AMPDU = BIT(0),
|
||||
BUF_AGGR = BIT(1),
|
||||
BUF_XRETRY = BIT(2),
|
||||
};
|
||||
|
||||
#define bf_isampdu(bf) (bf->bf_state.bf_type & BUF_AMPDU)
|
||||
#define bf_isaggr(bf) (bf->bf_state.bf_type & BUF_AGGR)
|
||||
#define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY)
|
||||
|
||||
#define ATH_TXSTATUS_RING_SIZE 64
|
||||
|
||||
@ -216,6 +213,7 @@ struct ath_frame_info {
|
||||
struct ath_buf_state {
|
||||
u8 bf_type;
|
||||
u8 bfs_paprd;
|
||||
u8 ndelim;
|
||||
u16 seqno;
|
||||
unsigned long bfs_paprd_timestamp;
|
||||
};
|
||||
@ -230,7 +228,6 @@ struct ath_buf {
|
||||
dma_addr_t bf_daddr; /* physical addr of desc */
|
||||
dma_addr_t bf_buf_addr; /* physical addr of data buffer, for DMA */
|
||||
bool bf_stale;
|
||||
u16 bf_flags;
|
||||
struct ath_buf_state bf_state;
|
||||
};
|
||||
|
||||
@ -277,8 +274,7 @@ struct ath_tx_control {
|
||||
};
|
||||
|
||||
#define ATH_TX_ERROR 0x01
|
||||
#define ATH_TX_XRETRY 0x02
|
||||
#define ATH_TX_BAR 0x04
|
||||
#define ATH_TX_BAR 0x02
|
||||
|
||||
/**
|
||||
* @txq_map: Index is mac80211 queue number. This is
|
||||
@ -425,6 +421,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status);
|
||||
|
||||
#define ATH_PAPRD_TIMEOUT 100 /* msecs */
|
||||
|
||||
void ath_reset_work(struct work_struct *work);
|
||||
void ath_hw_check(struct work_struct *work);
|
||||
void ath_hw_pll_work(struct work_struct *work);
|
||||
void ath_paprd_calibrate(struct work_struct *work);
|
||||
@ -460,6 +457,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc);
|
||||
#define ATH_LED_PIN_9287 8
|
||||
#define ATH_LED_PIN_9300 10
|
||||
#define ATH_LED_PIN_9485 6
|
||||
#define ATH_LED_PIN_9480 0
|
||||
|
||||
#ifdef CONFIG_MAC80211_LEDS
|
||||
void ath_init_leds(struct ath_softc *sc);
|
||||
@ -604,6 +602,7 @@ struct ath_softc {
|
||||
struct mutex mutex;
|
||||
struct work_struct paprd_work;
|
||||
struct work_struct hw_check_work;
|
||||
struct work_struct hw_reset_work;
|
||||
struct completion paprd_complete;
|
||||
|
||||
unsigned int hw_busy_count;
|
||||
@ -647,10 +646,10 @@ struct ath_softc {
|
||||
struct ath_descdma txsdma;
|
||||
|
||||
struct ath_ant_comb ant_comb;
|
||||
u8 ant_tx, ant_rx;
|
||||
};
|
||||
|
||||
void ath9k_tasklet(unsigned long data);
|
||||
int ath_reset(struct ath_softc *sc, bool retry_tx);
|
||||
int ath_cabq_update(struct ath_softc *);
|
||||
|
||||
static inline void ath_read_cachesize(struct ath_common *common, int *csz)
|
||||
@ -668,6 +667,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
|
||||
const struct ath_bus_ops *bus_ops);
|
||||
void ath9k_deinit_device(struct ath_softc *sc);
|
||||
void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
|
||||
void ath9k_reload_chainmask_settings(struct ath_softc *sc);
|
||||
|
||||
void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw);
|
||||
bool ath9k_uses_beacons(int type);
|
||||
|
@ -73,44 +73,39 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
|
||||
struct sk_buff *skb = bf->bf_mpdu;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath_desc *ds;
|
||||
struct ath9k_11n_rate_series series[4];
|
||||
int flags, ctsrate = 0, ctsduration = 0;
|
||||
struct ath_tx_info info;
|
||||
struct ieee80211_supported_band *sband;
|
||||
u8 chainmask = ah->txchainmask;
|
||||
u8 rate = 0;
|
||||
|
||||
ath9k_reset_beacon_status(sc);
|
||||
|
||||
ds = bf->bf_desc;
|
||||
flags = ATH9K_TXDESC_NOACK;
|
||||
|
||||
ds->ds_link = 0;
|
||||
|
||||
sband = &sc->sbands[common->hw->conf.channel->band];
|
||||
rate = sband->bitrates[rateidx].hw_value;
|
||||
if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
|
||||
rate |= sband->bitrates[rateidx].hw_value_short;
|
||||
|
||||
ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN,
|
||||
ATH9K_PKT_TYPE_BEACON,
|
||||
MAX_RATE_POWER,
|
||||
ATH9K_TXKEYIX_INVALID,
|
||||
ATH9K_KEY_TYPE_CLEAR,
|
||||
flags);
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.pkt_len = skb->len + FCS_LEN;
|
||||
info.type = ATH9K_PKT_TYPE_BEACON;
|
||||
info.txpower = MAX_RATE_POWER;
|
||||
info.keyix = ATH9K_TXKEYIX_INVALID;
|
||||
info.keytype = ATH9K_KEY_TYPE_CLEAR;
|
||||
info.flags = ATH9K_TXDESC_NOACK;
|
||||
|
||||
/* NB: beacon's BufLen must be a multiple of 4 bytes */
|
||||
ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4),
|
||||
true, true, ds, bf->bf_buf_addr,
|
||||
sc->beacon.beaconq);
|
||||
info.buf_addr[0] = bf->bf_buf_addr;
|
||||
info.buf_len[0] = roundup(skb->len, 4);
|
||||
|
||||
memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
|
||||
series[0].Tries = 1;
|
||||
series[0].Rate = rate;
|
||||
series[0].ChSel = ath_txchainmask_reduction(sc,
|
||||
common->tx_chainmask, series[0].Rate);
|
||||
series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
|
||||
ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration,
|
||||
series, 4, 0);
|
||||
info.is_first = true;
|
||||
info.is_last = true;
|
||||
|
||||
info.qcu = sc->beacon.beaconq;
|
||||
|
||||
info.rates[0].Tries = 1;
|
||||
info.rates[0].Rate = rate;
|
||||
info.rates[0].ChSel = ath_txchainmask_reduction(sc, chainmask, rate);
|
||||
|
||||
ath9k_hw_set_txdesc(ah, bf->bf_desc, &info);
|
||||
}
|
||||
|
||||
static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
@ -386,9 +381,7 @@ void ath_beacon_tasklet(unsigned long data)
|
||||
ath_dbg(common, ATH_DBG_BSTUCK,
|
||||
"beacon is officially stuck\n");
|
||||
sc->sc_flags |= SC_OP_TSF_RESET;
|
||||
spin_lock(&sc->sc_pcu_lock);
|
||||
ath_reset(sc, true);
|
||||
spin_unlock(&sc->sc_pcu_lock);
|
||||
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -519,6 +512,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc,
|
||||
/* Set the computed AP beacon timers */
|
||||
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
sc->sc_flags |= SC_OP_TSF_RESET;
|
||||
ath9k_beacon_init(sc, nexttbtt, intval);
|
||||
sc->beacon.bmisscnt = 0;
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
|
@ -95,11 +95,11 @@ 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);
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
char buf[32];
|
||||
unsigned int len;
|
||||
|
||||
len = sprintf(buf, "0x%08x\n", common->tx_chainmask);
|
||||
len = sprintf(buf, "0x%08x\n", ah->txchainmask);
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
@ -107,7 +107,7 @@ static ssize_t write_file_tx_chainmask(struct file *file, const char __user *use
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
unsigned long mask;
|
||||
char buf[32];
|
||||
ssize_t len;
|
||||
@ -120,8 +120,8 @@ static ssize_t write_file_tx_chainmask(struct file *file, const char __user *use
|
||||
if (strict_strtoul(buf, 0, &mask))
|
||||
return -EINVAL;
|
||||
|
||||
common->tx_chainmask = mask;
|
||||
sc->sc_ah->caps.tx_chainmask = mask;
|
||||
ah->txchainmask = mask;
|
||||
ah->caps.tx_chainmask = mask;
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -138,11 +138,11 @@ 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);
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
char buf[32];
|
||||
unsigned int len;
|
||||
|
||||
len = sprintf(buf, "0x%08x\n", common->rx_chainmask);
|
||||
len = sprintf(buf, "0x%08x\n", ah->rxchainmask);
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
@ -150,7 +150,7 @@ static ssize_t write_file_rx_chainmask(struct file *file, const char __user *use
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
unsigned long mask;
|
||||
char buf[32];
|
||||
ssize_t len;
|
||||
@ -163,8 +163,8 @@ static ssize_t write_file_rx_chainmask(struct file *file, const char __user *use
|
||||
if (strict_strtoul(buf, 0, &mask))
|
||||
return -EINVAL;
|
||||
|
||||
common->rx_chainmask = mask;
|
||||
sc->sc_ah->caps.rx_chainmask = mask;
|
||||
ah->rxchainmask = mask;
|
||||
ah->caps.rx_chainmask = mask;
|
||||
return count;
|
||||
}
|
||||
|
||||
@ -826,7 +826,8 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
|
||||
}
|
||||
|
||||
void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
|
||||
struct ath_tx_status *ts, struct ath_txq *txq)
|
||||
struct ath_tx_status *ts, struct ath_txq *txq,
|
||||
unsigned int flags)
|
||||
{
|
||||
#define TX_SAMP_DBG(c) (sc->debug.bb_mac_samp[sc->debug.sampidx].ts\
|
||||
[sc->debug.tsidx].c)
|
||||
@ -836,12 +837,12 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
|
||||
sc->debug.stats.txstats[qnum].tx_bytes_all += bf->bf_mpdu->len;
|
||||
|
||||
if (bf_isampdu(bf)) {
|
||||
if (bf_isxretried(bf))
|
||||
if (flags & ATH_TX_BAR)
|
||||
TX_STAT_INC(qnum, a_xretries);
|
||||
else
|
||||
TX_STAT_INC(qnum, a_completed);
|
||||
} else {
|
||||
if (bf_isxretried(bf))
|
||||
if (ts->ts_status & ATH9K_TXERR_XRETRY)
|
||||
TX_STAT_INC(qnum, xretries);
|
||||
else
|
||||
TX_STAT_INC(qnum, completed);
|
||||
@ -1323,16 +1324,17 @@ void ath9k_debug_samp_bb_mac(struct ath_softc *sc)
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
|
||||
spin_lock_bh(&sc->debug.samp_lock);
|
||||
|
||||
spin_lock_irqsave(&common->cc_lock, flags);
|
||||
ath_hw_cycle_counters_update(common);
|
||||
spin_unlock_irqrestore(&common->cc_lock, flags);
|
||||
|
||||
spin_lock_bh(&sc->debug.samp_lock);
|
||||
|
||||
ATH_SAMP_DBG(cc.cycles) = common->cc_ani.cycles;
|
||||
ATH_SAMP_DBG(cc.rx_busy) = common->cc_ani.rx_busy;
|
||||
ATH_SAMP_DBG(cc.rx_frame) = common->cc_ani.rx_frame;
|
||||
ATH_SAMP_DBG(cc.tx_frame) = common->cc_ani.tx_frame;
|
||||
spin_unlock_irqrestore(&common->cc_lock, flags);
|
||||
|
||||
ATH_SAMP_DBG(noise) = ah->noise;
|
||||
|
||||
REG_WRITE_D(ah, AR_MACMISC,
|
||||
@ -1373,6 +1375,9 @@ static int open_file_bb_mac_samps(struct inode *inode, struct file *file)
|
||||
u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
|
||||
u8 nread;
|
||||
|
||||
if (sc->sc_flags & SC_OP_INVALID)
|
||||
return -EAGAIN;
|
||||
|
||||
buf = vmalloc(size);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
@ -1381,10 +1386,14 @@ static int open_file_bb_mac_samps(struct inode *inode, struct file *file)
|
||||
vfree(buf);
|
||||
return -ENOMEM;
|
||||
}
|
||||
/* Account the current state too */
|
||||
ath9k_debug_samp_bb_mac(sc);
|
||||
|
||||
spin_lock_bh(&sc->debug.samp_lock);
|
||||
memcpy(bb_mac_samp, sc->debug.bb_mac_samp,
|
||||
sizeof(*bb_mac_samp) * ATH_DBG_MAX_SAMPLES);
|
||||
len += snprintf(buf + len, size - len,
|
||||
"Current Sample Index: %d\n", sc->debug.sampidx);
|
||||
spin_unlock_bh(&sc->debug.samp_lock);
|
||||
|
||||
len += snprintf(buf + len, size - len,
|
||||
|
@ -230,7 +230,8 @@ int ath9k_init_debug(struct ath_hw *ah);
|
||||
void ath9k_debug_samp_bb_mac(struct ath_softc *sc);
|
||||
void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
|
||||
void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
|
||||
struct ath_tx_status *ts, struct ath_txq *txq);
|
||||
struct ath_tx_status *ts, struct ath_txq *txq,
|
||||
unsigned int flags);
|
||||
void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
|
||||
|
||||
#else
|
||||
@ -252,7 +253,8 @@ static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
|
||||
static inline void ath_debug_stat_tx(struct ath_softc *sc,
|
||||
struct ath_buf *bf,
|
||||
struct ath_tx_status *ts,
|
||||
struct ath_txq *txq)
|
||||
struct ath_txq *txq,
|
||||
unsigned int flags)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,8 @@ void ath_init_leds(struct ath_softc *sc)
|
||||
sc->sc_ah->led_pin = ATH_LED_PIN_9485;
|
||||
else if (AR_SREV_9300(sc->sc_ah))
|
||||
sc->sc_ah->led_pin = ATH_LED_PIN_9300;
|
||||
else if (AR_SREV_9480(sc->sc_ah))
|
||||
sc->sc_ah->led_pin = ATH_LED_PIN_9480;
|
||||
else
|
||||
sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
|
||||
}
|
||||
|
@ -509,8 +509,8 @@ static void setup_ht_cap(struct ath9k_htc_priv *priv,
|
||||
memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
|
||||
|
||||
/* ath9k_htc supports only 1 or 2 stream devices */
|
||||
tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, 2);
|
||||
rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, 2);
|
||||
tx_streams = ath9k_cmn_count_streams(priv->ah->txchainmask, 2);
|
||||
rx_streams = ath9k_cmn_count_streams(priv->ah->rxchainmask, 2);
|
||||
|
||||
ath_dbg(common, ATH_DBG_CONFIG,
|
||||
"TX streams %d, RX streams: %d\n",
|
||||
@ -601,9 +601,6 @@ static void ath9k_init_misc(struct ath9k_htc_priv *priv)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(priv->ah);
|
||||
|
||||
common->tx_chainmask = priv->ah->caps.tx_chainmask;
|
||||
common->rx_chainmask = priv->ah->caps.rx_chainmask;
|
||||
|
||||
memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
|
||||
|
||||
priv->ah->opmode = NL80211_IFTYPE_STATION;
|
||||
|
@ -826,8 +826,7 @@ void ath9k_htc_ani_work(struct work_struct *work)
|
||||
if (longcal || shortcal)
|
||||
common->ani.caldone =
|
||||
ath9k_hw_calibrate(ah, ah->curchan,
|
||||
common->rx_chainmask,
|
||||
longcal);
|
||||
ah->rxchainmask, longcal);
|
||||
|
||||
ath9k_htc_ps_restore(priv);
|
||||
}
|
||||
|
@ -54,13 +54,10 @@ static inline bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
|
||||
return ath9k_hw_ops(ah)->get_isr(ah, masked);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_filltxdesc(struct ath_hw *ah, void *ds, u32 seglen,
|
||||
bool is_firstseg, bool is_lastseg,
|
||||
const void *ds0, dma_addr_t buf_addr,
|
||||
unsigned int qcu)
|
||||
static inline void ath9k_hw_set_txdesc(struct ath_hw *ah, void *ds,
|
||||
struct ath_tx_info *i)
|
||||
{
|
||||
ath9k_hw_ops(ah)->fill_txdesc(ah, ds, seglen, is_firstseg, is_lastseg,
|
||||
ds0, buf_addr, qcu);
|
||||
return ath9k_hw_ops(ah)->set_txdesc(ah, ds, i);
|
||||
}
|
||||
|
||||
static inline int ath9k_hw_txprocdesc(struct ath_hw *ah, void *ds,
|
||||
@ -69,55 +66,6 @@ static inline int ath9k_hw_txprocdesc(struct ath_hw *ah, void *ds,
|
||||
return ath9k_hw_ops(ah)->proc_txdesc(ah, ds, ts);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
|
||||
u32 pktLen, enum ath9k_pkt_type type,
|
||||
u32 txPower, u32 keyIx,
|
||||
enum ath9k_key_type keyType,
|
||||
u32 flags)
|
||||
{
|
||||
ath9k_hw_ops(ah)->set11n_txdesc(ah, ds, pktLen, type, txPower, keyIx,
|
||||
keyType, flags);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
|
||||
void *lastds,
|
||||
u32 durUpdateEn, u32 rtsctsRate,
|
||||
u32 rtsctsDuration,
|
||||
struct ath9k_11n_rate_series series[],
|
||||
u32 nseries, u32 flags)
|
||||
{
|
||||
ath9k_hw_ops(ah)->set11n_ratescenario(ah, ds, lastds, durUpdateEn,
|
||||
rtsctsRate, rtsctsDuration, series,
|
||||
nseries, flags);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
|
||||
u32 aggrLen)
|
||||
{
|
||||
ath9k_hw_ops(ah)->set11n_aggr_first(ah, ds, aggrLen);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
|
||||
u32 numDelims)
|
||||
{
|
||||
ath9k_hw_ops(ah)->set11n_aggr_middle(ah, ds, numDelims);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
|
||||
{
|
||||
ath9k_hw_ops(ah)->set11n_aggr_last(ah, ds);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
|
||||
{
|
||||
ath9k_hw_ops(ah)->clr11n_aggr(ah, ds);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val)
|
||||
{
|
||||
ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val);
|
||||
}
|
||||
|
||||
static inline void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
|
||||
struct ath_hw_antcomb_conf *antconf)
|
||||
{
|
||||
|
@ -580,6 +580,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
||||
case AR_SREV_VERSION_9330:
|
||||
case AR_SREV_VERSION_9485:
|
||||
case AR_SREV_VERSION_9340:
|
||||
case AR_SREV_VERSION_9480:
|
||||
break;
|
||||
default:
|
||||
ath_err(common,
|
||||
@ -664,6 +665,7 @@ int ath9k_hw_init(struct ath_hw *ah)
|
||||
case AR9300_DEVID_AR9330:
|
||||
case AR9300_DEVID_AR9340:
|
||||
case AR9300_DEVID_AR9580:
|
||||
case AR9300_DEVID_AR9480:
|
||||
break;
|
||||
default:
|
||||
if (common->bus_ops->ath_bus_type == ATH_USB)
|
||||
@ -960,7 +962,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ieee80211_conf *conf = &common->hw->conf;
|
||||
const struct ath9k_channel *chan = ah->curchan;
|
||||
int acktimeout;
|
||||
int acktimeout, ctstimeout;
|
||||
int slottime;
|
||||
int sifstime;
|
||||
int rx_lat = 0, tx_lat = 0, eifs = 0;
|
||||
@ -975,7 +977,10 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
|
||||
if (ah->misc_mode != 0)
|
||||
REG_SET_BIT(ah, AR_PCU_MISC, ah->misc_mode);
|
||||
|
||||
rx_lat = 37;
|
||||
if (IS_CHAN_A_FAST_CLOCK(ah, chan))
|
||||
rx_lat = 41;
|
||||
else
|
||||
rx_lat = 37;
|
||||
tx_lat = 54;
|
||||
|
||||
if (IS_CHAN_HALF_RATE(chan)) {
|
||||
@ -989,7 +994,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
|
||||
sifstime = 32;
|
||||
} else if (IS_CHAN_QUARTER_RATE(chan)) {
|
||||
eifs = 340;
|
||||
rx_lat *= 4;
|
||||
rx_lat = (rx_lat * 4) - 1;
|
||||
tx_lat *= 4;
|
||||
if (IS_CHAN_A_FAST_CLOCK(ah, chan))
|
||||
tx_lat += 22;
|
||||
@ -1017,6 +1022,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
|
||||
|
||||
/* As defined by IEEE 802.11-2007 17.3.8.6 */
|
||||
acktimeout = slottime + sifstime + 3 * ah->coverage_class;
|
||||
ctstimeout = acktimeout;
|
||||
|
||||
/*
|
||||
* Workaround for early ACK timeouts, add an offset to match the
|
||||
@ -1031,7 +1037,7 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
|
||||
ath9k_hw_set_sifs_time(ah, sifstime);
|
||||
ath9k_hw_setslottime(ah, slottime);
|
||||
ath9k_hw_set_ack_timeout(ah, acktimeout);
|
||||
ath9k_hw_set_cts_timeout(ah, acktimeout);
|
||||
ath9k_hw_set_cts_timeout(ah, ctstimeout);
|
||||
if (ah->globaltxtimeout != (u32) -1)
|
||||
ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
|
||||
|
||||
@ -1336,6 +1342,7 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
|
||||
|
||||
static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
|
||||
{
|
||||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
REG_WRITE(ah, AR_WA, ah->WARegVal);
|
||||
udelay(10);
|
||||
@ -1475,9 +1482,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
u64 tsf = 0;
|
||||
int i, r;
|
||||
|
||||
ah->txchainmask = common->tx_chainmask;
|
||||
ah->rxchainmask = common->rx_chainmask;
|
||||
|
||||
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
|
||||
return -EIO;
|
||||
|
||||
@ -1495,14 +1499,16 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
}
|
||||
ah->noise = ath9k_hw_getchan_noise(ah, chan);
|
||||
|
||||
if ((AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI) ||
|
||||
(AR_SREV_9300_20_OR_LATER(ah) && IS_CHAN_5GHZ(chan)))
|
||||
bChannelChange = false;
|
||||
|
||||
if (bChannelChange &&
|
||||
(ah->chip_fullsleep != true) &&
|
||||
(ah->curchan != NULL) &&
|
||||
(chan->channel != ah->curchan->channel) &&
|
||||
((chan->channelFlags & CHANNEL_ALL) ==
|
||||
(ah->curchan->channelFlags & CHANNEL_ALL)) &&
|
||||
(!AR_SREV_9280(ah) || AR_DEVID_7010(ah))) {
|
||||
|
||||
(ah->curchan->channelFlags & CHANNEL_ALL))) {
|
||||
if (ath9k_hw_channel_change(ah, chan)) {
|
||||
ath9k_hw_loadnf(ah, ah->curchan);
|
||||
ath9k_hw_start_nfcal(ah, true);
|
||||
@ -1742,25 +1748,41 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
|
||||
{
|
||||
REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
|
||||
if (setChip) {
|
||||
if (AR_SREV_9480(ah)) {
|
||||
REG_WRITE(ah, AR_TIMER_MODE,
|
||||
REG_READ(ah, AR_TIMER_MODE) & 0xFFFFFF00);
|
||||
REG_WRITE(ah, AR_NDP2_TIMER_MODE, REG_READ(ah,
|
||||
AR_NDP2_TIMER_MODE) & 0xFFFFFF00);
|
||||
REG_WRITE(ah, AR_SLP32_INC,
|
||||
REG_READ(ah, AR_SLP32_INC) & 0xFFF00000);
|
||||
/* xxx Required for WLAN only case ? */
|
||||
REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0);
|
||||
udelay(100);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the RTC force wake bit to allow the
|
||||
* mac to go to sleep.
|
||||
*/
|
||||
REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
|
||||
AR_RTC_FORCE_WAKE_EN);
|
||||
REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN);
|
||||
|
||||
if (AR_SREV_9480(ah))
|
||||
udelay(100);
|
||||
|
||||
if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah))
|
||||
REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
|
||||
|
||||
/* Shutdown chip. Active low */
|
||||
if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah))
|
||||
REG_CLR_BIT(ah, (AR_RTC_RESET),
|
||||
AR_RTC_RESET_EN);
|
||||
if (!AR_SREV_5416(ah) &&
|
||||
!AR_SREV_9271(ah) && !AR_SREV_9480_10(ah)) {
|
||||
REG_CLR_BIT(ah, AR_RTC_RESET, AR_RTC_RESET_EN);
|
||||
udelay(2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear Bit 14 of AR_WA after putting chip into Full Sleep mode. */
|
||||
if (AR_SREV_9300_20_OR_LATER(ah))
|
||||
REG_WRITE(ah, AR_WA,
|
||||
ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
|
||||
if (!AR_SREV_9480(ah))
|
||||
REG_WRITE(ah, AR_WA, ah->WARegVal & ~AR_WA_D3_L1_DISABLE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1770,6 +1792,8 @@ static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
|
||||
*/
|
||||
static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
|
||||
if (setChip) {
|
||||
struct ath9k_hw_capabilities *pCap = &ah->caps;
|
||||
@ -1779,12 +1803,30 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
|
||||
REG_WRITE(ah, AR_RTC_FORCE_WAKE,
|
||||
AR_RTC_FORCE_WAKE_ON_INT);
|
||||
} else {
|
||||
|
||||
/* When chip goes into network sleep, it could be waken
|
||||
* up by MCI_INT interrupt caused by BT's HW messages
|
||||
* (LNA_xxx, CONT_xxx) which chould be in a very fast
|
||||
* rate (~100us). This will cause chip to leave and
|
||||
* re-enter network sleep mode frequently, which in
|
||||
* consequence will have WLAN MCI HW to generate lots of
|
||||
* SYS_WAKING and SYS_SLEEPING messages which will make
|
||||
* BT CPU to busy to process.
|
||||
*/
|
||||
if (AR_SREV_9480(ah)) {
|
||||
val = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_EN) &
|
||||
~AR_MCI_INTERRUPT_RX_HW_MSG_MASK;
|
||||
REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, val);
|
||||
}
|
||||
/*
|
||||
* Clear the RTC force wake bit to allow the
|
||||
* mac to go to sleep.
|
||||
*/
|
||||
REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
|
||||
AR_RTC_FORCE_WAKE_EN);
|
||||
|
||||
if (AR_SREV_9480(ah))
|
||||
udelay(30);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2091,6 +2133,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
||||
|
||||
pCap->tx_chainmask = fixup_chainmask(chip_chainmask, pCap->tx_chainmask);
|
||||
pCap->rx_chainmask = fixup_chainmask(chip_chainmask, pCap->rx_chainmask);
|
||||
ah->txchainmask = pCap->tx_chainmask;
|
||||
ah->rxchainmask = pCap->rx_chainmask;
|
||||
|
||||
ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA;
|
||||
|
||||
@ -2401,6 +2445,9 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
|
||||
|
||||
ENABLE_REGWRITE_BUFFER(ah);
|
||||
|
||||
if (AR_SREV_9480(ah))
|
||||
bits |= ATH9K_RX_FILTER_CONTROL_WRAPPER;
|
||||
|
||||
REG_WRITE(ah, AR_RX_FILTER, bits);
|
||||
|
||||
phybits = 0;
|
||||
@ -2447,13 +2494,13 @@ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ath9k_channel *chan = ah->curchan;
|
||||
struct ieee80211_channel *channel = chan->chan;
|
||||
int reg_pwr = min_t(int, MAX_RATE_POWER, regulatory->power_limit);
|
||||
int reg_pwr = min_t(int, MAX_RATE_POWER, limit);
|
||||
int chan_pwr = channel->max_power * 2;
|
||||
|
||||
if (test)
|
||||
reg_pwr = chan_pwr = MAX_RATE_POWER;
|
||||
|
||||
regulatory->power_limit = min(limit, (u32) MAX_RATE_POWER);
|
||||
regulatory->power_limit = reg_pwr;
|
||||
|
||||
ah->eep_ops->set_txpower(ah, chan,
|
||||
ath9k_regd_get_ctl(regulatory, chan),
|
||||
@ -2657,6 +2704,20 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah,
|
||||
REG_SET_BIT(ah, gen_tmr_configuration[timer->index].mode_addr,
|
||||
gen_tmr_configuration[timer->index].mode_mask);
|
||||
|
||||
if (AR_SREV_9480(ah)) {
|
||||
/*
|
||||
* Starting from AR9480, each generic timer can select which tsf
|
||||
* to use. But we still follow the old rule, 0 - 7 use tsf and
|
||||
* 8 - 15 use tsf2.
|
||||
*/
|
||||
if ((timer->index < AR_GEN_TIMER_BANK_1_LEN))
|
||||
REG_CLR_BIT(ah, AR_MAC_PCU_GEN_TIMER_TSF_SEL,
|
||||
(1 << timer->index));
|
||||
else
|
||||
REG_SET_BIT(ah, AR_MAC_PCU_GEN_TIMER_TSF_SEL,
|
||||
(1 << timer->index));
|
||||
}
|
||||
|
||||
/* Enable both trigger and thresh interrupt masks */
|
||||
REG_SET_BIT(ah, AR_IMR_S5,
|
||||
(SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) |
|
||||
@ -2762,6 +2823,7 @@ static struct {
|
||||
{ AR_SREV_VERSION_9330, "9330" },
|
||||
{ AR_SREV_VERSION_9340, "9340" },
|
||||
{ AR_SREV_VERSION_9485, "9485" },
|
||||
{ AR_SREV_VERSION_9480, "9480" },
|
||||
};
|
||||
|
||||
/* For devices with external radios */
|
||||
|
@ -46,6 +46,7 @@
|
||||
#define AR9300_DEVID_AR9340 0x0031
|
||||
#define AR9300_DEVID_AR9485_PCIE 0x0032
|
||||
#define AR9300_DEVID_AR9580 0x0033
|
||||
#define AR9300_DEVID_AR9480 0x0034
|
||||
#define AR9300_DEVID_AR9330 0x0035
|
||||
|
||||
#define AR5416_AR9100_DEVID 0x000b
|
||||
@ -615,30 +616,10 @@ struct ath_hw_ops {
|
||||
u8 rxchainmask,
|
||||
bool longcal);
|
||||
bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked);
|
||||
void (*fill_txdesc)(struct ath_hw *ah, void *ds, u32 seglen,
|
||||
bool is_firstseg, bool is_is_lastseg,
|
||||
const void *ds0, dma_addr_t buf_addr,
|
||||
unsigned int qcu);
|
||||
void (*set_txdesc)(struct ath_hw *ah, void *ds,
|
||||
struct ath_tx_info *i);
|
||||
int (*proc_txdesc)(struct ath_hw *ah, void *ds,
|
||||
struct ath_tx_status *ts);
|
||||
void (*set11n_txdesc)(struct ath_hw *ah, void *ds,
|
||||
u32 pktLen, enum ath9k_pkt_type type,
|
||||
u32 txPower, u8 keyIx,
|
||||
enum ath9k_key_type keyType,
|
||||
u32 flags);
|
||||
void (*set11n_ratescenario)(struct ath_hw *ah, void *ds,
|
||||
void *lastds,
|
||||
u32 durUpdateEn, u32 rtsctsRate,
|
||||
u32 rtsctsDuration,
|
||||
struct ath9k_11n_rate_series series[],
|
||||
u32 nseries, u32 flags);
|
||||
void (*set11n_aggr_first)(struct ath_hw *ah, void *ds,
|
||||
u32 aggrLen);
|
||||
void (*set11n_aggr_middle)(struct ath_hw *ah, void *ds,
|
||||
u32 numDelims);
|
||||
void (*set11n_aggr_last)(struct ath_hw *ah, void *ds);
|
||||
void (*clr11n_aggr)(struct ath_hw *ah, void *ds);
|
||||
void (*set_clrdmask)(struct ath_hw *ah, void *ds, bool val);
|
||||
void (*antdiv_comb_conf_get)(struct ath_hw *ah,
|
||||
struct ath_hw_antcomb_conf *antconf);
|
||||
void (*antdiv_comb_conf_set)(struct ath_hw *ah,
|
||||
@ -827,11 +808,14 @@ struct ath_hw {
|
||||
struct ar5416IniArray iniModes_9271_1_0_only;
|
||||
struct ar5416IniArray iniCckfirNormal;
|
||||
struct ar5416IniArray iniCckfirJapan2484;
|
||||
struct ar5416IniArray ini_japan2484;
|
||||
struct ar5416IniArray iniCommon_normal_cck_fir_coeff_9271;
|
||||
struct ar5416IniArray iniCommon_japan_2484_cck_fir_coeff_9271;
|
||||
struct ar5416IniArray iniModes_9271_ANI_reg;
|
||||
struct ar5416IniArray iniModes_high_power_tx_gain_9271;
|
||||
struct ar5416IniArray iniModes_normal_power_tx_gain_9271;
|
||||
struct ar5416IniArray ini_radio_post_sys2ant;
|
||||
struct ar5416IniArray ini_BTCOEX_MAX_TXPWR;
|
||||
|
||||
struct ar5416IniArray iniMac[ATH_INI_NUM_SPLIT];
|
||||
struct ar5416IniArray iniBB[ATH_INI_NUM_SPLIT];
|
||||
|
@ -270,8 +270,8 @@ static void setup_ht_cap(struct ath_softc *sc,
|
||||
|
||||
/* set up supported mcs set */
|
||||
memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
|
||||
tx_streams = ath9k_cmn_count_streams(common->tx_chainmask, max_streams);
|
||||
rx_streams = ath9k_cmn_count_streams(common->rx_chainmask, max_streams);
|
||||
tx_streams = ath9k_cmn_count_streams(ah->txchainmask, max_streams);
|
||||
rx_streams = ath9k_cmn_count_streams(ah->rxchainmask, max_streams);
|
||||
|
||||
ath_dbg(common, ATH_DBG_CONFIG,
|
||||
"TX streams %d, RX streams: %d\n",
|
||||
@ -506,9 +506,6 @@ static void ath9k_init_misc(struct ath_softc *sc)
|
||||
sc->sc_flags |= SC_OP_RXAGGR;
|
||||
}
|
||||
|
||||
common->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
|
||||
common->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
|
||||
|
||||
ath9k_hw_set_diversity(sc->sc_ah, true);
|
||||
sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
|
||||
|
||||
@ -646,10 +643,8 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
|
||||
static void ath9k_init_txpower_limits(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath9k_channel *curchan = ah->curchan;
|
||||
|
||||
ah->txchainmask = common->tx_chainmask;
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
|
||||
ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ);
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
|
||||
@ -658,9 +653,22 @@ static void ath9k_init_txpower_limits(struct ath_softc *sc)
|
||||
ah->curchan = curchan;
|
||||
}
|
||||
|
||||
void ath9k_reload_chainmask_settings(struct ath_softc *sc)
|
||||
{
|
||||
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT))
|
||||
return;
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
|
||||
setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
|
||||
setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
|
||||
}
|
||||
|
||||
|
||||
void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
|
||||
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
|
||||
@ -698,6 +706,16 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||
hw->sta_data_size = sizeof(struct ath_node);
|
||||
hw->vif_data_size = sizeof(struct ath_vif);
|
||||
|
||||
hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1;
|
||||
hw->wiphy->available_antennas_tx = BIT(ah->caps.max_txchains) - 1;
|
||||
|
||||
/* single chain devices with rx diversity */
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
|
||||
hw->wiphy->available_antennas_rx = BIT(0) | BIT(1);
|
||||
|
||||
sc->ant_rx = hw->wiphy->available_antennas_rx;
|
||||
sc->ant_tx = hw->wiphy->available_antennas_tx;
|
||||
|
||||
#ifdef CONFIG_ATH9K_RATE_CONTROL
|
||||
hw->rate_control_algorithm = "ath9k_rate_control";
|
||||
#endif
|
||||
@ -709,12 +727,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||
hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
|
||||
&sc->sbands[IEEE80211_BAND_5GHZ];
|
||||
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
|
||||
setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
|
||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
|
||||
setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
|
||||
}
|
||||
ath9k_reload_chainmask_settings(sc);
|
||||
|
||||
SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
|
||||
}
|
||||
@ -782,6 +795,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
|
||||
goto error_world;
|
||||
}
|
||||
|
||||
INIT_WORK(&sc->hw_reset_work, ath_reset_work);
|
||||
INIT_WORK(&sc->hw_check_work, ath_hw_check);
|
||||
INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
|
||||
INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
|
||||
|
@ -62,18 +62,6 @@ void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_txstart);
|
||||
|
||||
void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds)
|
||||
{
|
||||
struct ar5416_desc *ads = AR5416DESC(ds);
|
||||
|
||||
ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
|
||||
ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
|
||||
ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
|
||||
ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
|
||||
ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
|
||||
}
|
||||
EXPORT_SYMBOL(ath9k_hw_cleartxdesc);
|
||||
|
||||
u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
|
||||
{
|
||||
u32 npend;
|
||||
|
@ -263,7 +263,11 @@ struct ath_desc {
|
||||
#define ATH9K_TXDESC_VMF 0x0100
|
||||
#define ATH9K_TXDESC_FRAG_IS_ON 0x0200
|
||||
#define ATH9K_TXDESC_LOWRXCHAIN 0x0400
|
||||
#define ATH9K_TXDESC_LDPC 0x00010000
|
||||
#define ATH9K_TXDESC_LDPC 0x0800
|
||||
#define ATH9K_TXDESC_CLRDMASK 0x1000
|
||||
|
||||
#define ATH9K_TXDESC_PAPRD 0x70000
|
||||
#define ATH9K_TXDESC_PAPRD_S 16
|
||||
|
||||
#define ATH9K_RXDESC_INTREQ 0x0020
|
||||
|
||||
@ -644,6 +648,7 @@ enum ath9k_rx_filter {
|
||||
ATH9K_RX_FILTER_PSPOLL = 0x00004000,
|
||||
ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
|
||||
ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000,
|
||||
ATH9K_RX_FILTER_CONTROL_WRAPPER = 0x00080000,
|
||||
};
|
||||
|
||||
#define ATH9K_RATESERIES_RTS_CTS 0x0001
|
||||
@ -659,6 +664,13 @@ struct ath9k_11n_rate_series {
|
||||
u32 RateFlags;
|
||||
};
|
||||
|
||||
enum aggr_type {
|
||||
AGGR_BUF_NONE,
|
||||
AGGR_BUF_FIRST,
|
||||
AGGR_BUF_MIDDLE,
|
||||
AGGR_BUF_LAST,
|
||||
};
|
||||
|
||||
enum ath9k_key_type {
|
||||
ATH9K_KEY_TYPE_CLEAR,
|
||||
ATH9K_KEY_TYPE_WEP,
|
||||
@ -666,6 +678,33 @@ enum ath9k_key_type {
|
||||
ATH9K_KEY_TYPE_TKIP,
|
||||
};
|
||||
|
||||
struct ath_tx_info {
|
||||
u8 qcu;
|
||||
|
||||
bool is_first;
|
||||
bool is_last;
|
||||
|
||||
enum aggr_type aggr;
|
||||
u8 ndelim;
|
||||
u16 aggr_len;
|
||||
|
||||
dma_addr_t link;
|
||||
int pkt_len;
|
||||
u32 flags;
|
||||
|
||||
dma_addr_t buf_addr[4];
|
||||
int buf_len[4];
|
||||
|
||||
struct ath9k_11n_rate_series rates[4];
|
||||
u8 rtscts_rate;
|
||||
bool dur_update;
|
||||
|
||||
enum ath9k_pkt_type type;
|
||||
enum ath9k_key_type keytype;
|
||||
u8 keyix;
|
||||
u8 txpower;
|
||||
};
|
||||
|
||||
struct ath_hw;
|
||||
struct ath9k_channel;
|
||||
enum ath9k_int;
|
||||
@ -673,7 +712,6 @@ enum ath9k_int;
|
||||
u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
|
||||
void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
|
||||
void ath9k_hw_txstart(struct ath_hw *ah, u32 q);
|
||||
void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds);
|
||||
u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
|
||||
bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
|
||||
bool ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q);
|
||||
|
@ -111,24 +111,29 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
|
||||
void ath9k_ps_restore(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
enum ath9k_power_mode mode;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&sc->sc_pm_lock, flags);
|
||||
if (--sc->ps_usecount != 0)
|
||||
goto unlock;
|
||||
|
||||
spin_lock(&common->cc_lock);
|
||||
ath_hw_cycle_counters_update(common);
|
||||
spin_unlock(&common->cc_lock);
|
||||
|
||||
if (sc->ps_idle)
|
||||
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
|
||||
mode = ATH9K_PM_FULL_SLEEP;
|
||||
else if (sc->ps_enabled &&
|
||||
!(sc->ps_flags & (PS_WAIT_FOR_BEACON |
|
||||
PS_WAIT_FOR_CAB |
|
||||
PS_WAIT_FOR_PSPOLL_DATA |
|
||||
PS_WAIT_FOR_TX_ACK)))
|
||||
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
|
||||
mode = ATH9K_PM_NETWORK_SLEEP;
|
||||
else
|
||||
goto unlock;
|
||||
|
||||
spin_lock(&common->cc_lock);
|
||||
ath_hw_cycle_counters_update(common);
|
||||
spin_unlock(&common->cc_lock);
|
||||
|
||||
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
|
||||
|
||||
unlock:
|
||||
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
|
||||
@ -212,6 +217,149 @@ static int ath_update_survey_stats(struct ath_softc *sc)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __ath_cancel_work(struct ath_softc *sc)
|
||||
{
|
||||
cancel_work_sync(&sc->paprd_work);
|
||||
cancel_work_sync(&sc->hw_check_work);
|
||||
cancel_delayed_work_sync(&sc->tx_complete_work);
|
||||
cancel_delayed_work_sync(&sc->hw_pll_work);
|
||||
}
|
||||
|
||||
static void ath_cancel_work(struct ath_softc *sc)
|
||||
{
|
||||
__ath_cancel_work(sc);
|
||||
cancel_work_sync(&sc->hw_reset_work);
|
||||
}
|
||||
|
||||
static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
bool ret;
|
||||
|
||||
ieee80211_stop_queues(sc->hw);
|
||||
|
||||
sc->hw_busy_count = 0;
|
||||
del_timer_sync(&common->ani.timer);
|
||||
|
||||
ath9k_debug_samp_bb_mac(sc);
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
|
||||
ret = ath_drain_all_txq(sc, retry_tx);
|
||||
|
||||
if (!ath_stoprecv(sc))
|
||||
ret = false;
|
||||
|
||||
if (!flush) {
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
|
||||
ath_rx_tasklet(sc, 1, true);
|
||||
ath_rx_tasklet(sc, 1, false);
|
||||
} else {
|
||||
ath_flushrecv(sc);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool ath_complete_reset(struct ath_softc *sc, bool start)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
if (ath_startrecv(sc) != 0) {
|
||||
ath_err(common, "Unable to restart recv logic\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
ath9k_cmn_update_txpow(ah, sc->curtxpow,
|
||||
sc->config.txpowlimit, &sc->curtxpow);
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
|
||||
if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) && start) {
|
||||
if (sc->sc_flags & SC_OP_BEACONS)
|
||||
ath_set_beacon(sc);
|
||||
|
||||
ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
|
||||
ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2);
|
||||
if (!common->disable_ani)
|
||||
ath_start_ani(common);
|
||||
}
|
||||
|
||||
if (ath9k_hw_ops(ah)->antdiv_comb_conf_get && sc->ant_rx != 3) {
|
||||
struct ath_hw_antcomb_conf div_ant_conf;
|
||||
u8 lna_conf;
|
||||
|
||||
ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf);
|
||||
|
||||
if (sc->ant_rx == 1)
|
||||
lna_conf = ATH_ANT_DIV_COMB_LNA1;
|
||||
else
|
||||
lna_conf = ATH_ANT_DIV_COMB_LNA2;
|
||||
div_ant_conf.main_lna_conf = lna_conf;
|
||||
div_ant_conf.alt_lna_conf = lna_conf;
|
||||
|
||||
ath9k_hw_antdiv_comb_conf_set(ah, &div_ant_conf);
|
||||
}
|
||||
|
||||
ieee80211_wake_queues(sc->hw);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
|
||||
bool retry_tx)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_hw_cal_data *caldata = NULL;
|
||||
bool fastcc = true;
|
||||
bool flush = false;
|
||||
int r;
|
||||
|
||||
__ath_cancel_work(sc);
|
||||
|
||||
spin_lock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
if (!(sc->sc_flags & SC_OP_OFFCHANNEL)) {
|
||||
fastcc = false;
|
||||
caldata = &sc->caldata;
|
||||
}
|
||||
|
||||
if (!hchan) {
|
||||
fastcc = false;
|
||||
flush = true;
|
||||
hchan = ah->curchan;
|
||||
}
|
||||
|
||||
if (fastcc && !ath9k_hw_check_alive(ah))
|
||||
fastcc = false;
|
||||
|
||||
if (!ath_prepare_reset(sc, retry_tx, flush))
|
||||
fastcc = false;
|
||||
|
||||
ath_dbg(common, ATH_DBG_CONFIG,
|
||||
"Reset to %u MHz, HT40: %d fastcc: %d\n",
|
||||
hchan->channel, !!(hchan->channelFlags & (CHANNEL_HT40MINUS |
|
||||
CHANNEL_HT40PLUS)),
|
||||
fastcc);
|
||||
|
||||
r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
|
||||
if (r) {
|
||||
ath_err(common,
|
||||
"Unable to reset channel, reset status %d\n", r);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ath_complete_reset(sc, true))
|
||||
r = -EIO;
|
||||
|
||||
out:
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set/change channels. If the channel is really being changed, it's done
|
||||
* by reseting the chip. To accomplish this we must first cleanup any pending
|
||||
@ -220,97 +368,17 @@ static int ath_update_survey_stats(struct ath_softc *sc)
|
||||
static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
|
||||
struct ath9k_channel *hchan)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ieee80211_conf *conf = &common->hw->conf;
|
||||
bool fastcc = true, stopped;
|
||||
struct ieee80211_channel *channel = hw->conf.channel;
|
||||
struct ath9k_hw_cal_data *caldata = NULL;
|
||||
int r;
|
||||
|
||||
if (sc->sc_flags & SC_OP_INVALID)
|
||||
return -EIO;
|
||||
|
||||
sc->hw_busy_count = 0;
|
||||
|
||||
del_timer_sync(&common->ani.timer);
|
||||
cancel_work_sync(&sc->paprd_work);
|
||||
cancel_work_sync(&sc->hw_check_work);
|
||||
cancel_delayed_work_sync(&sc->tx_complete_work);
|
||||
cancel_delayed_work_sync(&sc->hw_pll_work);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
|
||||
spin_lock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
/*
|
||||
* This is only performed if the channel settings have
|
||||
* actually changed.
|
||||
*
|
||||
* To switch channels clear any pending DMA operations;
|
||||
* wait long enough for the RX fifo to drain, reset the
|
||||
* hardware at the new frequency, and then re-enable
|
||||
* the relevant bits of the h/w.
|
||||
*/
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
stopped = ath_drain_all_txq(sc, false);
|
||||
|
||||
if (!ath_stoprecv(sc))
|
||||
stopped = false;
|
||||
|
||||
if (!ath9k_hw_check_alive(ah))
|
||||
stopped = false;
|
||||
|
||||
/* XXX: do not flush receive queue here. We don't want
|
||||
* to flush data frames already in queue because of
|
||||
* changing channel. */
|
||||
|
||||
if (!stopped || !(sc->sc_flags & SC_OP_OFFCHANNEL))
|
||||
fastcc = false;
|
||||
|
||||
if (!(sc->sc_flags & SC_OP_OFFCHANNEL))
|
||||
caldata = &sc->caldata;
|
||||
|
||||
ath_dbg(common, ATH_DBG_CONFIG,
|
||||
"(%u MHz) -> (%u MHz), conf_is_ht40: %d fastcc: %d\n",
|
||||
sc->sc_ah->curchan->channel,
|
||||
channel->center_freq, conf_is_ht40(conf),
|
||||
fastcc);
|
||||
|
||||
r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
|
||||
if (r) {
|
||||
ath_err(common,
|
||||
"Unable to reset channel (%u MHz), reset status %d\n",
|
||||
channel->center_freq, r);
|
||||
goto ps_restore;
|
||||
}
|
||||
|
||||
if (ath_startrecv(sc) != 0) {
|
||||
ath_err(common, "Unable to restart recv logic\n");
|
||||
r = -EIO;
|
||||
goto ps_restore;
|
||||
}
|
||||
|
||||
ath9k_cmn_update_txpow(ah, sc->curtxpow,
|
||||
sc->config.txpowlimit, &sc->curtxpow);
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
|
||||
if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
|
||||
if (sc->sc_flags & SC_OP_BEACONS)
|
||||
ath_set_beacon(sc);
|
||||
ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
|
||||
ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2);
|
||||
if (!common->disable_ani)
|
||||
ath_start_ani(common);
|
||||
}
|
||||
|
||||
ps_restore:
|
||||
ieee80211_wake_queues(hw);
|
||||
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
r = ath_reset_internal(sc, hchan, false);
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -318,7 +386,6 @@ static void ath_paprd_activate(struct ath_softc *sc)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath9k_hw_cal_data *caldata = ah->caldata;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
int chain;
|
||||
|
||||
if (!caldata || !caldata->paprd_done)
|
||||
@ -327,7 +394,7 @@ static void ath_paprd_activate(struct ath_softc *sc)
|
||||
ath9k_ps_wakeup(sc);
|
||||
ar9003_paprd_enable(ah, false);
|
||||
for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
|
||||
if (!(common->tx_chainmask & BIT(chain)))
|
||||
if (!(ah->txchainmask & BIT(chain)))
|
||||
continue;
|
||||
|
||||
ar9003_paprd_populate_single_table(ah, caldata, chain);
|
||||
@ -414,7 +481,7 @@ void ath_paprd_calibrate(struct work_struct *work)
|
||||
memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
|
||||
|
||||
for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
|
||||
if (!(common->tx_chainmask & BIT(chain)))
|
||||
if (!(ah->txchainmask & BIT(chain)))
|
||||
continue;
|
||||
|
||||
chain_ok = 0;
|
||||
@ -535,7 +602,7 @@ void ath_ani_calibrate(unsigned long data)
|
||||
if (longcal || shortcal) {
|
||||
common->ani.caldone =
|
||||
ath9k_hw_calibrate(ah, ah->curchan,
|
||||
common->rx_chainmask, longcal);
|
||||
ah->rxchainmask, longcal);
|
||||
}
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
@ -597,74 +664,6 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
|
||||
ath_tx_node_cleanup(sc, an);
|
||||
}
|
||||
|
||||
void ath_hw_check(struct work_struct *work)
|
||||
{
|
||||
struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work);
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
unsigned long flags;
|
||||
int busy;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
if (ath9k_hw_check_alive(sc->sc_ah))
|
||||
goto out;
|
||||
|
||||
spin_lock_irqsave(&common->cc_lock, flags);
|
||||
busy = ath_update_survey_stats(sc);
|
||||
spin_unlock_irqrestore(&common->cc_lock, flags);
|
||||
|
||||
ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, "
|
||||
"busy=%d (try %d)\n", busy, sc->hw_busy_count + 1);
|
||||
if (busy >= 99) {
|
||||
if (++sc->hw_busy_count >= 3) {
|
||||
spin_lock_bh(&sc->sc_pcu_lock);
|
||||
ath_reset(sc, true);
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
}
|
||||
} else if (busy >= 0)
|
||||
sc->hw_busy_count = 0;
|
||||
|
||||
out:
|
||||
ath9k_ps_restore(sc);
|
||||
}
|
||||
|
||||
static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
|
||||
{
|
||||
static int count;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
|
||||
if (pll_sqsum >= 0x40000) {
|
||||
count++;
|
||||
if (count == 3) {
|
||||
/* Rx is hung for more than 500ms. Reset it */
|
||||
ath_dbg(common, ATH_DBG_RESET,
|
||||
"Possible RX hang, resetting");
|
||||
spin_lock_bh(&sc->sc_pcu_lock);
|
||||
ath_reset(sc, true);
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
count = 0;
|
||||
}
|
||||
} else
|
||||
count = 0;
|
||||
}
|
||||
|
||||
void ath_hw_pll_work(struct work_struct *work)
|
||||
{
|
||||
struct ath_softc *sc = container_of(work, struct ath_softc,
|
||||
hw_pll_work.work);
|
||||
u32 pll_sqsum;
|
||||
|
||||
if (AR_SREV_9485(sc->sc_ah)) {
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
ath_hw_pll_rx_hang_check(sc, pll_sqsum);
|
||||
|
||||
ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ath9k_tasklet(unsigned long data)
|
||||
{
|
||||
@ -675,17 +674,15 @@ void ath9k_tasklet(unsigned long data)
|
||||
u32 status = sc->intrstatus;
|
||||
u32 rxmask;
|
||||
|
||||
if ((status & ATH9K_INT_FATAL) ||
|
||||
(status & ATH9K_INT_BB_WATCHDOG)) {
|
||||
spin_lock(&sc->sc_pcu_lock);
|
||||
ath_reset(sc, true);
|
||||
spin_unlock(&sc->sc_pcu_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
spin_lock(&sc->sc_pcu_lock);
|
||||
|
||||
if ((status & ATH9K_INT_FATAL) ||
|
||||
(status & ATH9K_INT_BB_WATCHDOG)) {
|
||||
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Only run the baseband hang check if beacons stop working in AP or
|
||||
* IBSS mode, because it has a high false positive rate. For station
|
||||
@ -733,6 +730,7 @@ void ath9k_tasklet(unsigned long data)
|
||||
if (status & ATH9K_INT_GENTIMER)
|
||||
ath_gen_timer_isr(sc->sc_ah);
|
||||
|
||||
out:
|
||||
/* re-enable hardware interrupt */
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
|
||||
@ -895,28 +893,13 @@ static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||
channel->center_freq, r);
|
||||
}
|
||||
|
||||
ath9k_cmn_update_txpow(ah, sc->curtxpow,
|
||||
sc->config.txpowlimit, &sc->curtxpow);
|
||||
if (ath_startrecv(sc) != 0) {
|
||||
ath_err(common, "Unable to restart recv logic\n");
|
||||
goto out;
|
||||
}
|
||||
if (sc->sc_flags & SC_OP_BEACONS)
|
||||
ath_set_beacon(sc); /* restart beacons */
|
||||
|
||||
/* Re-Enable interrupts */
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
ath_complete_reset(sc, true);
|
||||
|
||||
/* Enable LED */
|
||||
ath9k_hw_cfg_output(ah, ah->led_pin,
|
||||
AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
|
||||
ath9k_hw_set_gpio(ah, ah->led_pin, 0);
|
||||
|
||||
ieee80211_wake_queues(hw);
|
||||
ieee80211_queue_delayed_work(hw, &sc->hw_pll_work, HZ/2);
|
||||
|
||||
out:
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
@ -929,12 +912,11 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||
int r;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
cancel_delayed_work_sync(&sc->hw_pll_work);
|
||||
|
||||
ath_cancel_work(sc);
|
||||
|
||||
spin_lock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
ieee80211_stop_queues(hw);
|
||||
|
||||
/*
|
||||
* Keep the LED on when the radio is disabled
|
||||
* during idle unassociated state.
|
||||
@ -944,13 +926,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||
ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
|
||||
}
|
||||
|
||||
/* Disable interrupts */
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
|
||||
ath_drain_all_txq(sc, false); /* clear pending tx frames */
|
||||
|
||||
ath_stoprecv(sc); /* turn off frame recv */
|
||||
ath_flushrecv(sc); /* flush recv queue */
|
||||
ath_prepare_reset(sc, false, true);
|
||||
|
||||
if (!ah->curchan)
|
||||
ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
|
||||
@ -970,51 +946,13 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
|
||||
ath9k_ps_restore(sc);
|
||||
}
|
||||
|
||||
int ath_reset(struct ath_softc *sc, bool retry_tx)
|
||||
static int ath_reset(struct ath_softc *sc, bool retry_tx)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ieee80211_hw *hw = sc->hw;
|
||||
int r;
|
||||
|
||||
sc->hw_busy_count = 0;
|
||||
|
||||
ath9k_debug_samp_bb_mac(sc);
|
||||
/* Stop ANI */
|
||||
|
||||
del_timer_sync(&common->ani.timer);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
|
||||
ieee80211_stop_queues(hw);
|
||||
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
ath_drain_all_txq(sc, retry_tx);
|
||||
|
||||
ath_stoprecv(sc);
|
||||
ath_flushrecv(sc);
|
||||
|
||||
r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
|
||||
if (r)
|
||||
ath_err(common,
|
||||
"Unable to reset hardware; reset status %d\n", r);
|
||||
|
||||
if (ath_startrecv(sc) != 0)
|
||||
ath_err(common, "Unable to start recv logic\n");
|
||||
|
||||
/*
|
||||
* We may be doing a reset in response to a request
|
||||
* that changes the channel so update any state that
|
||||
* might change as a result.
|
||||
*/
|
||||
ath9k_cmn_update_txpow(ah, sc->curtxpow,
|
||||
sc->config.txpowlimit, &sc->curtxpow);
|
||||
|
||||
if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL)))
|
||||
ath_set_beacon(sc); /* restart beacons */
|
||||
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
r = ath_reset_internal(sc, NULL, retry_tx);
|
||||
|
||||
if (retry_tx) {
|
||||
int i;
|
||||
@ -1027,17 +965,82 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
|
||||
}
|
||||
}
|
||||
|
||||
ieee80211_wake_queues(hw);
|
||||
|
||||
/* Start ANI */
|
||||
if (!common->disable_ani)
|
||||
ath_start_ani(common);
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void ath_reset_work(struct work_struct *work)
|
||||
{
|
||||
struct ath_softc *sc = container_of(work, struct ath_softc, hw_reset_work);
|
||||
|
||||
ath_reset(sc, true);
|
||||
}
|
||||
|
||||
void ath_hw_check(struct work_struct *work)
|
||||
{
|
||||
struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work);
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
unsigned long flags;
|
||||
int busy;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
if (ath9k_hw_check_alive(sc->sc_ah))
|
||||
goto out;
|
||||
|
||||
spin_lock_irqsave(&common->cc_lock, flags);
|
||||
busy = ath_update_survey_stats(sc);
|
||||
spin_unlock_irqrestore(&common->cc_lock, flags);
|
||||
|
||||
ath_dbg(common, ATH_DBG_RESET, "Possible baseband hang, "
|
||||
"busy=%d (try %d)\n", busy, sc->hw_busy_count + 1);
|
||||
if (busy >= 99) {
|
||||
if (++sc->hw_busy_count >= 3)
|
||||
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
|
||||
|
||||
} else if (busy >= 0)
|
||||
sc->hw_busy_count = 0;
|
||||
|
||||
out:
|
||||
ath9k_ps_restore(sc);
|
||||
}
|
||||
|
||||
static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
|
||||
{
|
||||
static int count;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
|
||||
if (pll_sqsum >= 0x40000) {
|
||||
count++;
|
||||
if (count == 3) {
|
||||
/* Rx is hung for more than 500ms. Reset it */
|
||||
ath_dbg(common, ATH_DBG_RESET,
|
||||
"Possible RX hang, resetting");
|
||||
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
|
||||
count = 0;
|
||||
}
|
||||
} else
|
||||
count = 0;
|
||||
}
|
||||
|
||||
void ath_hw_pll_work(struct work_struct *work)
|
||||
{
|
||||
struct ath_softc *sc = container_of(work, struct ath_softc,
|
||||
hw_pll_work.work);
|
||||
u32 pll_sqsum;
|
||||
|
||||
if (AR_SREV_9485(sc->sc_ah)) {
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
ath_hw_pll_rx_hang_check(sc, pll_sqsum);
|
||||
|
||||
ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************/
|
||||
/* mac80211 callbacks */
|
||||
/**********************/
|
||||
@ -1084,28 +1087,6 @@ static int ath9k_start(struct ieee80211_hw *hw)
|
||||
goto mutex_unlock;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is needed only to setup initial state
|
||||
* but it's best done after a reset.
|
||||
*/
|
||||
ath9k_cmn_update_txpow(ah, sc->curtxpow,
|
||||
sc->config.txpowlimit, &sc->curtxpow);
|
||||
|
||||
/*
|
||||
* Setup the hardware after reset:
|
||||
* The receive engine is set going.
|
||||
* Frame transmit is handled entirely
|
||||
* in the frame output path; there's nothing to do
|
||||
* here except setup the interrupt mask.
|
||||
*/
|
||||
if (ath_startrecv(sc) != 0) {
|
||||
ath_err(common, "Unable to start recv logic\n");
|
||||
r = -EIO;
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
goto mutex_unlock;
|
||||
}
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
/* Setup our intr mask. */
|
||||
ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL |
|
||||
ATH9K_INT_RXORN | ATH9K_INT_FATAL |
|
||||
@ -1128,12 +1109,14 @@ static int ath9k_start(struct ieee80211_hw *hw)
|
||||
|
||||
/* Disable BMISS interrupt when we're not associated */
|
||||
ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
|
||||
ath9k_hw_set_interrupts(ah, ah->imask);
|
||||
ath9k_hw_enable_interrupts(ah);
|
||||
|
||||
ieee80211_wake_queues(hw);
|
||||
if (!ath_complete_reset(sc, false)) {
|
||||
r = -EIO;
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
goto mutex_unlock;
|
||||
}
|
||||
|
||||
ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) &&
|
||||
!ah->btcoex_hw.enabled) {
|
||||
@ -1226,10 +1209,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
|
||||
|
||||
mutex_lock(&sc->mutex);
|
||||
|
||||
cancel_delayed_work_sync(&sc->tx_complete_work);
|
||||
cancel_delayed_work_sync(&sc->hw_pll_work);
|
||||
cancel_work_sync(&sc->paprd_work);
|
||||
cancel_work_sync(&sc->hw_check_work);
|
||||
ath_cancel_work(sc);
|
||||
|
||||
if (sc->sc_flags & SC_OP_INVALID) {
|
||||
ath_dbg(common, ATH_DBG_ANY, "Device not present\n");
|
||||
@ -2340,9 +2320,11 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
|
||||
ath9k_ps_wakeup(sc);
|
||||
spin_lock_bh(&sc->sc_pcu_lock);
|
||||
drain_txq = ath_drain_all_txq(sc, false);
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
if (!drain_txq)
|
||||
ath_reset(sc, false);
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
|
||||
ath9k_ps_restore(sc);
|
||||
ieee80211_wake_queues(hw);
|
||||
|
||||
@ -2419,6 +2401,59 @@ static int ath9k_get_stats(struct ieee80211_hw *hw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 fill_chainmask(u32 cap, u32 new)
|
||||
{
|
||||
u32 filled = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; cap && new; i++, cap >>= 1) {
|
||||
if (!(cap & BIT(0)))
|
||||
continue;
|
||||
|
||||
if (new & BIT(0))
|
||||
filled |= BIT(i);
|
||||
|
||||
new >>= 1;
|
||||
}
|
||||
|
||||
return filled;
|
||||
}
|
||||
|
||||
static int ath9k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
|
||||
if (!rx_ant || !tx_ant)
|
||||
return -EINVAL;
|
||||
|
||||
sc->ant_rx = rx_ant;
|
||||
sc->ant_tx = tx_ant;
|
||||
|
||||
if (ah->caps.rx_chainmask == 1)
|
||||
return 0;
|
||||
|
||||
/* AR9100 runs into calibration issues if not all rx chains are enabled */
|
||||
if (AR_SREV_9100(ah))
|
||||
ah->rxchainmask = 0x7;
|
||||
else
|
||||
ah->rxchainmask = fill_chainmask(ah->caps.rx_chainmask, rx_ant);
|
||||
|
||||
ah->txchainmask = fill_chainmask(ah->caps.tx_chainmask, tx_ant);
|
||||
ath9k_reload_chainmask_settings(sc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
|
||||
*tx_ant = sc->ant_tx;
|
||||
*rx_ant = sc->ant_rx;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ieee80211_ops ath9k_ops = {
|
||||
.tx = ath9k_tx,
|
||||
.start = ath9k_start,
|
||||
@ -2445,4 +2480,6 @@ struct ieee80211_ops ath9k_ops = {
|
||||
.tx_frames_pending = ath9k_tx_frames_pending,
|
||||
.tx_last_beacon = ath9k_tx_last_beacon,
|
||||
.get_stats = ath9k_get_stats,
|
||||
.set_antenna = ath9k_set_antenna,
|
||||
.get_antenna = ath9k_get_antenna,
|
||||
};
|
||||
|
@ -33,6 +33,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */
|
||||
{ PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9480 */
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
@ -332,16 +333,16 @@ static int ath_pci_resume(struct device *device)
|
||||
if ((val & 0x0000ff00) != 0)
|
||||
pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
/* Enable LED */
|
||||
ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
|
||||
AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
|
||||
ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
|
||||
ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
|
||||
|
||||
/*
|
||||
* Reset key cache to sane defaults (all entries cleared) instead of
|
||||
* semi-random values after suspend/resume.
|
||||
*/
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath9k_cmn_init_crypto(sc->sc_ah);
|
||||
ath9k_ps_restore(sc);
|
||||
|
||||
|
@ -1839,7 +1839,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
|
||||
* If we're asked to flush receive queue, directly
|
||||
* chain it back at the queue without processing it.
|
||||
*/
|
||||
if (flush)
|
||||
if (sc->sc_flags & SC_OP_RXFLUSH)
|
||||
goto requeue_drop_frag;
|
||||
|
||||
retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
|
||||
@ -1950,7 +1950,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
|
||||
ath_rx_ps(sc, skb);
|
||||
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
|
||||
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
|
||||
if ((ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) && sc->ant_rx == 3)
|
||||
ath_ant_comb_scan(sc, &rs);
|
||||
|
||||
ieee80211_rx(hw, skb);
|
||||
@ -1967,7 +1967,8 @@ requeue:
|
||||
} else {
|
||||
list_move_tail(&bf->list, &sc->rx.rxbuf);
|
||||
ath_rx_buf_link(sc, bf);
|
||||
ath9k_hw_rxena(ah);
|
||||
if (!flush)
|
||||
ath9k_hw_rxena(ah);
|
||||
}
|
||||
} while (1);
|
||||
|
||||
|
@ -796,6 +796,9 @@
|
||||
#define AR_SREV_VERSION_9340 0x300
|
||||
#define AR_SREV_VERSION_9580 0x1C0
|
||||
#define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */
|
||||
#define AR_SREV_VERSION_9480 0x280
|
||||
#define AR_SREV_REVISION_9480_10 0
|
||||
#define AR_SREV_REVISION_9480_20 2
|
||||
|
||||
#define AR_SREV_5416(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
|
||||
@ -896,6 +899,21 @@
|
||||
(AR_SREV_9285_12_OR_LATER(_ah) && \
|
||||
((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1))
|
||||
|
||||
#define AR_SREV_9480(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9480))
|
||||
|
||||
#define AR_SREV_9480_10(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9480) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9480_10))
|
||||
|
||||
#define AR_SREV_9480_20(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9480) && \
|
||||
((_ah)->hw_version.macRev == AR_SREV_REVISION_9480_20))
|
||||
|
||||
#define AR_SREV_9480_20_OR_LATER(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9480) && \
|
||||
((_ah)->hw_version.macRev >= AR_SREV_REVISION_9480_20))
|
||||
|
||||
#define AR_SREV_9580(_ah) \
|
||||
(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9580) && \
|
||||
((_ah)->hw_version.macRev >= AR_SREV_REVISION_9580_10))
|
||||
@ -1132,7 +1150,7 @@ enum {
|
||||
#define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4)
|
||||
#define AR_ENT_OTP 0x40d8
|
||||
#define AR_ENT_OTP_CHAIN2_DISABLE 0x00020000
|
||||
#define AR_ENT_OTP_MPSD 0x00800000
|
||||
#define AR_ENT_OTP_MIN_PKT_SIZE_DISABLE 0x00800000
|
||||
|
||||
#define AR_CH0_BB_DPLL1 0x16180
|
||||
#define AR_CH0_BB_DPLL1_REFDIV 0xF8000000
|
||||
@ -1779,6 +1797,7 @@ enum {
|
||||
#define AR_TXOP_12_15 0x81fc
|
||||
|
||||
#define AR_NEXT_NDP2_TIMER 0x8180
|
||||
#define AR_GEN_TIMER_BANK_1_LEN 8
|
||||
#define AR_FIRST_NDP_TIMER 7
|
||||
#define AR_NDP2_PERIOD 0x81a0
|
||||
#define AR_NDP2_TIMER_MODE 0x81c0
|
||||
@ -1867,9 +1886,10 @@ enum {
|
||||
#define AR_PCU_MISC_MODE2_HWWAR2 0x02000000
|
||||
#define AR_PCU_MISC_MODE2_RESERVED2 0xFFFE0000
|
||||
|
||||
#define AR_MAC_PCU_ASYNC_FIFO_REG3 0x8358
|
||||
#define AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL 0x00000400
|
||||
#define AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET 0x80000000
|
||||
#define AR_MAC_PCU_ASYNC_FIFO_REG3 0x8358
|
||||
#define AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL 0x00000400
|
||||
#define AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET 0x80000000
|
||||
#define AR_MAC_PCU_GEN_TIMER_TSF_SEL 0x83d8
|
||||
|
||||
|
||||
#define AR_AES_MUTE_MASK0 0x805c
|
||||
@ -1920,4 +1940,38 @@ enum {
|
||||
#define AR_PHY_AGC_CONTROL_YCOK_MAX 0x000003c0
|
||||
#define AR_PHY_AGC_CONTROL_YCOK_MAX_S 6
|
||||
|
||||
/* MCI Registers */
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_EN 0x183c
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET 0x00000001
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET_S 0
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL 0x00000002
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL_S 1
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_CONT_NACK 0x00000004
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_CONT_NACK_S 2
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_CONT_INFO 0x00000008
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_CONT_INFO_S 3
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_CONT_RST 0x00000010
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_CONT_RST_S 4
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO 0x00000020
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO_S 5
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_CPU_INT 0x00000040
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_CPU_INT_S 6
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_GPM 0x00000100
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_GPM_S 8
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_LNA_INFO 0x00000200
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_LNA_INFO_S 9
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING 0x00000400
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING_S 10
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING 0x00000800
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING_S 11
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE 0x00001000
|
||||
#define AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE_S 12
|
||||
#define AR_MCI_INTERRUPT_RX_HW_MSG_MASK (AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO | \
|
||||
AR_MCI_INTERRUPT_RX_MSG_LNA_CONTROL| \
|
||||
AR_MCI_INTERRUPT_RX_MSG_LNA_INFO | \
|
||||
AR_MCI_INTERRUPT_RX_MSG_CONT_NACK | \
|
||||
AR_MCI_INTERRUPT_RX_MSG_CONT_INFO | \
|
||||
AR_MCI_INTERRUPT_RX_MSG_CONT_RST)
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -56,10 +56,9 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
|
||||
struct ath_tx_status *ts, int txok, int sendbar);
|
||||
static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
|
||||
struct list_head *head, bool internal);
|
||||
static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len);
|
||||
static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
|
||||
struct ath_tx_status *ts, int nframes, int nbad,
|
||||
int txok, bool update_rc);
|
||||
int txok);
|
||||
static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
|
||||
int seqno);
|
||||
static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
|
||||
@ -390,11 +389,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
while (bf) {
|
||||
bf_next = bf->bf_next;
|
||||
|
||||
bf->bf_state.bf_type |= BUF_XRETRY;
|
||||
if (!bf->bf_stale || bf_next != NULL)
|
||||
list_move_tail(&bf->list, &bf_head);
|
||||
|
||||
ath_tx_rc_status(sc, bf, ts, 1, 1, 0, false);
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
|
||||
0, 0);
|
||||
|
||||
@ -470,7 +467,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
clear_filter = true;
|
||||
txpending = 1;
|
||||
} else {
|
||||
bf->bf_state.bf_type |= BUF_XRETRY;
|
||||
txfail = 1;
|
||||
sendbar = 1;
|
||||
txfail_cnt++;
|
||||
@ -497,17 +493,14 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
|
||||
if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
|
||||
memcpy(tx_info->control.rates, rates, sizeof(rates));
|
||||
ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok, true);
|
||||
ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok);
|
||||
rc_update = false;
|
||||
} else {
|
||||
ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok, false);
|
||||
}
|
||||
|
||||
ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
|
||||
!txfail, sendbar);
|
||||
} else {
|
||||
/* retry the un-acked ones */
|
||||
ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, false);
|
||||
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) {
|
||||
if (bf->bf_next == NULL && bf_last->bf_stale) {
|
||||
struct ath_buf *tbf;
|
||||
@ -523,26 +516,13 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
ath_tx_update_baw(sc, tid, seqno);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
bf->bf_state.bf_type |=
|
||||
BUF_XRETRY;
|
||||
ath_tx_rc_status(sc, bf, ts, nframes,
|
||||
nbad, 0, false);
|
||||
ath_tx_complete_buf(sc, bf, txq,
|
||||
&bf_head,
|
||||
ts, 0, 0);
|
||||
ts, 0, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
ath9k_hw_cleartxdesc(sc->sc_ah,
|
||||
tbf->bf_desc);
|
||||
fi->bf = tbf;
|
||||
} else {
|
||||
/*
|
||||
* Clear descriptor status words for
|
||||
* software retry
|
||||
*/
|
||||
ath9k_hw_cleartxdesc(sc->sc_ah,
|
||||
bf->bf_desc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -582,7 +562,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
rcu_read_unlock();
|
||||
|
||||
if (needreset)
|
||||
ath_reset(sc, false);
|
||||
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
|
||||
}
|
||||
|
||||
static bool ath_lookup_legacy(struct ath_buf *bf)
|
||||
@ -709,7 +689,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
|
||||
* Add delimiter when using RTS/CTS with aggregation
|
||||
* and non enterprise AR9003 card
|
||||
*/
|
||||
if (first_subfrm)
|
||||
if (first_subfrm && !AR_SREV_9580_10_OR_LATER(sc->sc_ah) &&
|
||||
(sc->sc_ah->ent_mode & AR_ENT_OTP_MIN_PKT_SIZE_DISABLE))
|
||||
ndelim = max(ndelim, FIRST_DESC_NDELIMS);
|
||||
|
||||
/*
|
||||
@ -777,7 +758,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
|
||||
if (!bf)
|
||||
continue;
|
||||
|
||||
bf->bf_state.bf_type |= BUF_AMPDU;
|
||||
bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR;
|
||||
seqno = bf->bf_state.seqno;
|
||||
if (!bf_first)
|
||||
bf_first = bf;
|
||||
@ -804,8 +785,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
|
||||
}
|
||||
|
||||
tx_info = IEEE80211_SKB_CB(bf->bf_mpdu);
|
||||
if (nframes && ((tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) ||
|
||||
!(tx_info->control.rates[0].flags & IEEE80211_TX_RC_MCS)))
|
||||
if (nframes && (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE))
|
||||
break;
|
||||
|
||||
/* do not exceed subframe limit */
|
||||
@ -827,20 +807,17 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
|
||||
|
||||
nframes++;
|
||||
bf->bf_next = NULL;
|
||||
ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0);
|
||||
|
||||
/* link buffers of this frame to the aggregate */
|
||||
if (!fi->retries)
|
||||
ath_tx_addto_baw(sc, tid, seqno);
|
||||
ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
|
||||
bf->bf_state.ndelim = ndelim;
|
||||
|
||||
__skb_unlink(skb, &tid->buf_q);
|
||||
list_add_tail(&bf->list, bf_q);
|
||||
if (bf_prev) {
|
||||
if (bf_prev)
|
||||
bf_prev->bf_next = bf;
|
||||
ath9k_hw_set_desc_link(sc->sc_ah, bf_prev->bf_desc,
|
||||
bf->bf_daddr);
|
||||
}
|
||||
|
||||
bf_prev = bf;
|
||||
|
||||
} while (!skb_queue_empty(&tid->buf_q));
|
||||
@ -851,12 +828,245 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
|
||||
#undef PADBYTES
|
||||
}
|
||||
|
||||
/*
|
||||
* rix - rate index
|
||||
* pktlen - total bytes (delims + data + fcs + pads + pad delims)
|
||||
* width - 0 for 20 MHz, 1 for 40 MHz
|
||||
* half_gi - to use 4us v/s 3.6 us for symbol time
|
||||
*/
|
||||
static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen,
|
||||
int width, int half_gi, bool shortPreamble)
|
||||
{
|
||||
u32 nbits, nsymbits, duration, nsymbols;
|
||||
int streams;
|
||||
|
||||
/* find number of symbols: PLCP + data */
|
||||
streams = HT_RC_2_STREAMS(rix);
|
||||
nbits = (pktlen << 3) + OFDM_PLCP_BITS;
|
||||
nsymbits = bits_per_symbol[rix % 8][width] * streams;
|
||||
nsymbols = (nbits + nsymbits - 1) / nsymbits;
|
||||
|
||||
if (!half_gi)
|
||||
duration = SYMBOL_TIME(nsymbols);
|
||||
else
|
||||
duration = SYMBOL_TIME_HALFGI(nsymbols);
|
||||
|
||||
/* addup duration for legacy/ht training and signal fields */
|
||||
duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
|
||||
|
||||
return duration;
|
||||
}
|
||||
|
||||
static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf,
|
||||
struct ath_tx_info *info, int len)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct sk_buff *skb;
|
||||
struct ieee80211_tx_info *tx_info;
|
||||
struct ieee80211_tx_rate *rates;
|
||||
const struct ieee80211_rate *rate;
|
||||
struct ieee80211_hdr *hdr;
|
||||
int i;
|
||||
u8 rix = 0;
|
||||
|
||||
skb = bf->bf_mpdu;
|
||||
tx_info = IEEE80211_SKB_CB(skb);
|
||||
rates = tx_info->control.rates;
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
|
||||
/* set dur_update_en for l-sig computation except for PS-Poll frames */
|
||||
info->dur_update = !ieee80211_is_pspoll(hdr->frame_control);
|
||||
|
||||
/*
|
||||
* We check if Short Preamble is needed for the CTS rate by
|
||||
* checking the BSS's global flag.
|
||||
* But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
|
||||
*/
|
||||
rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info);
|
||||
info->rtscts_rate = rate->hw_value;
|
||||
if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
|
||||
info->rtscts_rate |= rate->hw_value_short;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
bool is_40, is_sgi, is_sp;
|
||||
int phy;
|
||||
|
||||
if (!rates[i].count || (rates[i].idx < 0))
|
||||
continue;
|
||||
|
||||
rix = rates[i].idx;
|
||||
info->rates[i].Tries = rates[i].count;
|
||||
|
||||
if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
|
||||
info->rates[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
|
||||
info->flags |= ATH9K_TXDESC_RTSENA;
|
||||
} else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
|
||||
info->rates[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
|
||||
info->flags |= ATH9K_TXDESC_CTSENA;
|
||||
}
|
||||
|
||||
if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||
info->rates[i].RateFlags |= ATH9K_RATESERIES_2040;
|
||||
if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
|
||||
info->rates[i].RateFlags |= ATH9K_RATESERIES_HALFGI;
|
||||
|
||||
is_sgi = !!(rates[i].flags & IEEE80211_TX_RC_SHORT_GI);
|
||||
is_40 = !!(rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH);
|
||||
is_sp = !!(rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
|
||||
|
||||
if (rates[i].flags & IEEE80211_TX_RC_MCS) {
|
||||
/* MCS rates */
|
||||
info->rates[i].Rate = rix | 0x80;
|
||||
info->rates[i].ChSel = ath_txchainmask_reduction(sc,
|
||||
ah->txchainmask, info->rates[i].Rate);
|
||||
info->rates[i].PktDuration = ath_pkt_duration(sc, rix, len,
|
||||
is_40, is_sgi, is_sp);
|
||||
if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC))
|
||||
info->rates[i].RateFlags |= ATH9K_RATESERIES_STBC;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* legacy rates */
|
||||
if ((tx_info->band == IEEE80211_BAND_2GHZ) &&
|
||||
!(rate->flags & IEEE80211_RATE_ERP_G))
|
||||
phy = WLAN_RC_PHY_CCK;
|
||||
else
|
||||
phy = WLAN_RC_PHY_OFDM;
|
||||
|
||||
rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx];
|
||||
info->rates[i].Rate = rate->hw_value;
|
||||
if (rate->hw_value_short) {
|
||||
if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
|
||||
info->rates[i].Rate |= rate->hw_value_short;
|
||||
} else {
|
||||
is_sp = false;
|
||||
}
|
||||
|
||||
if (bf->bf_state.bfs_paprd)
|
||||
info->rates[i].ChSel = ah->txchainmask;
|
||||
else
|
||||
info->rates[i].ChSel = ath_txchainmask_reduction(sc,
|
||||
ah->txchainmask, info->rates[i].Rate);
|
||||
|
||||
info->rates[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah,
|
||||
phy, rate->bitrate * 100, len, rix, is_sp);
|
||||
}
|
||||
|
||||
/* For AR5416 - RTS cannot be followed by a frame larger than 8K */
|
||||
if (bf_isaggr(bf) && (len > sc->sc_ah->caps.rts_aggr_limit))
|
||||
info->flags &= ~ATH9K_TXDESC_RTSENA;
|
||||
|
||||
/* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */
|
||||
if (info->flags & ATH9K_TXDESC_RTSENA)
|
||||
info->flags &= ~ATH9K_TXDESC_CTSENA;
|
||||
}
|
||||
|
||||
static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
enum ath9k_pkt_type htype;
|
||||
__le16 fc;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
fc = hdr->frame_control;
|
||||
|
||||
if (ieee80211_is_beacon(fc))
|
||||
htype = ATH9K_PKT_TYPE_BEACON;
|
||||
else if (ieee80211_is_probe_resp(fc))
|
||||
htype = ATH9K_PKT_TYPE_PROBE_RESP;
|
||||
else if (ieee80211_is_atim(fc))
|
||||
htype = ATH9K_PKT_TYPE_ATIM;
|
||||
else if (ieee80211_is_pspoll(fc))
|
||||
htype = ATH9K_PKT_TYPE_PSPOLL;
|
||||
else
|
||||
htype = ATH9K_PKT_TYPE_NORMAL;
|
||||
|
||||
return htype;
|
||||
}
|
||||
|
||||
static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf,
|
||||
struct ath_txq *txq, int len)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(bf->bf_mpdu);
|
||||
struct ath_buf *bf_first = bf;
|
||||
struct ath_tx_info info;
|
||||
bool aggr = !!(bf->bf_state.bf_type & BUF_AGGR);
|
||||
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.is_first = true;
|
||||
info.is_last = true;
|
||||
info.txpower = MAX_RATE_POWER;
|
||||
info.qcu = txq->axq_qnum;
|
||||
|
||||
info.flags = ATH9K_TXDESC_INTREQ;
|
||||
if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
|
||||
info.flags |= ATH9K_TXDESC_NOACK;
|
||||
if (tx_info->flags & IEEE80211_TX_CTL_LDPC)
|
||||
info.flags |= ATH9K_TXDESC_LDPC;
|
||||
|
||||
ath_buf_set_rate(sc, bf, &info, len);
|
||||
|
||||
if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
|
||||
info.flags |= ATH9K_TXDESC_CLRDMASK;
|
||||
|
||||
if (bf->bf_state.bfs_paprd)
|
||||
info.flags |= (u32) bf->bf_state.bfs_paprd << ATH9K_TXDESC_PAPRD_S;
|
||||
|
||||
|
||||
while (bf) {
|
||||
struct sk_buff *skb = bf->bf_mpdu;
|
||||
struct ath_frame_info *fi = get_frame_info(skb);
|
||||
struct ieee80211_hdr *hdr;
|
||||
int padpos, padsize;
|
||||
|
||||
info.type = get_hw_packet_type(skb);
|
||||
if (bf->bf_next)
|
||||
info.link = bf->bf_next->bf_daddr;
|
||||
else
|
||||
info.link = 0;
|
||||
|
||||
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
padpos = ath9k_cmn_padpos(hdr->frame_control);
|
||||
padsize = padpos & 3;
|
||||
|
||||
info.buf_addr[0] = bf->bf_buf_addr;
|
||||
info.buf_len[0] = padpos + padsize;
|
||||
info.buf_addr[1] = info.buf_addr[0] + padpos;
|
||||
info.buf_len[1] = skb->len - padpos;
|
||||
} else {
|
||||
info.buf_addr[0] = bf->bf_buf_addr;
|
||||
info.buf_len[0] = skb->len;
|
||||
}
|
||||
|
||||
info.pkt_len = fi->framelen;
|
||||
info.keyix = fi->keyix;
|
||||
info.keytype = fi->keytype;
|
||||
|
||||
if (aggr) {
|
||||
if (bf == bf_first)
|
||||
info.aggr = AGGR_BUF_FIRST;
|
||||
else if (!bf->bf_next)
|
||||
info.aggr = AGGR_BUF_LAST;
|
||||
else
|
||||
info.aggr = AGGR_BUF_MIDDLE;
|
||||
|
||||
info.ndelim = bf->bf_state.ndelim;
|
||||
info.aggr_len = len;
|
||||
}
|
||||
|
||||
ath9k_hw_set_txdesc(ah, bf->bf_desc, &info);
|
||||
bf = bf->bf_next;
|
||||
}
|
||||
}
|
||||
|
||||
static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
struct ath_atx_tid *tid)
|
||||
{
|
||||
struct ath_buf *bf;
|
||||
enum ATH_AGGR_STATUS status;
|
||||
struct ath_frame_info *fi;
|
||||
struct ieee80211_tx_info *tx_info;
|
||||
struct list_head bf_q;
|
||||
int aggr_len;
|
||||
|
||||
@ -877,34 +1087,25 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
|
||||
bf = list_first_entry(&bf_q, struct ath_buf, list);
|
||||
bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list);
|
||||
tx_info = IEEE80211_SKB_CB(bf->bf_mpdu);
|
||||
|
||||
if (tid->ac->clear_ps_filter) {
|
||||
tid->ac->clear_ps_filter = false;
|
||||
ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true);
|
||||
tx_info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
|
||||
} else {
|
||||
tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT;
|
||||
}
|
||||
|
||||
/* if only one frame, send as non-aggregate */
|
||||
if (bf == bf->bf_lastbf) {
|
||||
fi = get_frame_info(bf->bf_mpdu);
|
||||
|
||||
bf->bf_state.bf_type &= ~BUF_AGGR;
|
||||
ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc);
|
||||
ath_buf_set_rate(sc, bf, fi->framelen);
|
||||
ath_tx_txqaddbuf(sc, txq, &bf_q, false);
|
||||
continue;
|
||||
aggr_len = get_frame_info(bf->bf_mpdu)->framelen;
|
||||
bf->bf_state.bf_type = BUF_AMPDU;
|
||||
} else {
|
||||
TX_STAT_INC(txq->axq_qnum, a_aggr);
|
||||
}
|
||||
|
||||
/* setup first desc of aggregate */
|
||||
bf->bf_state.bf_type |= BUF_AGGR;
|
||||
ath_buf_set_rate(sc, bf, aggr_len);
|
||||
ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, aggr_len);
|
||||
|
||||
/* anchor last desc of aggregate */
|
||||
ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc);
|
||||
|
||||
ath_tx_fill_desc(sc, bf, txq, aggr_len);
|
||||
ath_tx_txqaddbuf(sc, txq, &bf_q, false);
|
||||
TX_STAT_INC(txq->axq_qnum, a_aggr);
|
||||
|
||||
} while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH &&
|
||||
status != ATH_AGGR_BAW_CLOSED);
|
||||
}
|
||||
@ -1332,7 +1533,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
|
||||
struct ath_atx_ac *ac, *ac_tmp, *last_ac;
|
||||
struct ath_atx_tid *tid, *last_tid;
|
||||
|
||||
if (list_empty(&txq->axq_acq) ||
|
||||
if (work_pending(&sc->hw_reset_work) || list_empty(&txq->axq_acq) ||
|
||||
txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
|
||||
return;
|
||||
|
||||
@ -1482,7 +1683,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
|
||||
if (!bf)
|
||||
return;
|
||||
|
||||
bf->bf_state.bf_type |= BUF_AMPDU;
|
||||
bf->bf_state.bf_type = BUF_AMPDU;
|
||||
INIT_LIST_HEAD(&bf_head);
|
||||
list_add(&bf->list, &bf_head);
|
||||
|
||||
@ -1492,7 +1693,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
|
||||
/* Queue to h/w without aggregation */
|
||||
TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw);
|
||||
bf->bf_lastbf = bf;
|
||||
ath_buf_set_rate(sc, bf, fi->framelen);
|
||||
ath_tx_fill_desc(sc, bf, txctl->txq, fi->framelen);
|
||||
ath_tx_txqaddbuf(sc, txctl->txq, &bf_head, false);
|
||||
}
|
||||
|
||||
@ -1512,41 +1713,18 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
|
||||
|
||||
INIT_LIST_HEAD(&bf_head);
|
||||
list_add_tail(&bf->list, &bf_head);
|
||||
bf->bf_state.bf_type &= ~BUF_AMPDU;
|
||||
bf->bf_state.bf_type = 0;
|
||||
|
||||
/* update starting sequence number for subsequent ADDBA request */
|
||||
if (tid)
|
||||
INCR(tid->seq_start, IEEE80211_SEQ_MAX);
|
||||
|
||||
bf->bf_lastbf = bf;
|
||||
ath_buf_set_rate(sc, bf, fi->framelen);
|
||||
ath_tx_fill_desc(sc, bf, txq, fi->framelen);
|
||||
ath_tx_txqaddbuf(sc, txq, &bf_head, false);
|
||||
TX_STAT_INC(txq->axq_qnum, queued);
|
||||
}
|
||||
|
||||
static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_hdr *hdr;
|
||||
enum ath9k_pkt_type htype;
|
||||
__le16 fc;
|
||||
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
fc = hdr->frame_control;
|
||||
|
||||
if (ieee80211_is_beacon(fc))
|
||||
htype = ATH9K_PKT_TYPE_BEACON;
|
||||
else if (ieee80211_is_probe_resp(fc))
|
||||
htype = ATH9K_PKT_TYPE_PROBE_RESP;
|
||||
else if (ieee80211_is_atim(fc))
|
||||
htype = ATH9K_PKT_TYPE_ATIM;
|
||||
else if (ieee80211_is_pspoll(fc))
|
||||
htype = ATH9K_PKT_TYPE_PSPOLL;
|
||||
else
|
||||
htype = ATH9K_PKT_TYPE_NORMAL;
|
||||
|
||||
return htype;
|
||||
}
|
||||
|
||||
static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
int framelen)
|
||||
{
|
||||
@ -1574,51 +1752,6 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
fi->framelen = framelen;
|
||||
}
|
||||
|
||||
static int setup_tx_flags(struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||
int flags = 0;
|
||||
|
||||
flags |= ATH9K_TXDESC_INTREQ;
|
||||
|
||||
if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
|
||||
flags |= ATH9K_TXDESC_NOACK;
|
||||
|
||||
if (tx_info->flags & IEEE80211_TX_CTL_LDPC)
|
||||
flags |= ATH9K_TXDESC_LDPC;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
/*
|
||||
* rix - rate index
|
||||
* pktlen - total bytes (delims + data + fcs + pads + pad delims)
|
||||
* width - 0 for 20 MHz, 1 for 40 MHz
|
||||
* half_gi - to use 4us v/s 3.6 us for symbol time
|
||||
*/
|
||||
static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen,
|
||||
int width, int half_gi, bool shortPreamble)
|
||||
{
|
||||
u32 nbits, nsymbits, duration, nsymbols;
|
||||
int streams;
|
||||
|
||||
/* find number of symbols: PLCP + data */
|
||||
streams = HT_RC_2_STREAMS(rix);
|
||||
nbits = (pktlen << 3) + OFDM_PLCP_BITS;
|
||||
nsymbits = bits_per_symbol[rix % 8][width] * streams;
|
||||
nsymbols = (nbits + nsymbits - 1) / nsymbits;
|
||||
|
||||
if (!half_gi)
|
||||
duration = SYMBOL_TIME(nsymbols);
|
||||
else
|
||||
duration = SYMBOL_TIME_HALFGI(nsymbols);
|
||||
|
||||
/* addup duration for legacy/ht training and signal fields */
|
||||
duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
|
||||
|
||||
return duration;
|
||||
}
|
||||
|
||||
u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
@ -1631,118 +1764,6 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
|
||||
return chainmask;
|
||||
}
|
||||
|
||||
static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath9k_11n_rate_series series[4];
|
||||
struct sk_buff *skb;
|
||||
struct ieee80211_tx_info *tx_info;
|
||||
struct ieee80211_tx_rate *rates;
|
||||
const struct ieee80211_rate *rate;
|
||||
struct ieee80211_hdr *hdr;
|
||||
int i, flags = 0;
|
||||
u8 rix = 0, ctsrate = 0;
|
||||
bool is_pspoll;
|
||||
|
||||
memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
|
||||
|
||||
skb = bf->bf_mpdu;
|
||||
tx_info = IEEE80211_SKB_CB(skb);
|
||||
rates = tx_info->control.rates;
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
is_pspoll = ieee80211_is_pspoll(hdr->frame_control);
|
||||
|
||||
/*
|
||||
* We check if Short Preamble is needed for the CTS rate by
|
||||
* checking the BSS's global flag.
|
||||
* But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
|
||||
*/
|
||||
rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info);
|
||||
ctsrate = rate->hw_value;
|
||||
if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
|
||||
ctsrate |= rate->hw_value_short;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
bool is_40, is_sgi, is_sp;
|
||||
int phy;
|
||||
|
||||
if (!rates[i].count || (rates[i].idx < 0))
|
||||
continue;
|
||||
|
||||
rix = rates[i].idx;
|
||||
series[i].Tries = rates[i].count;
|
||||
|
||||
if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
|
||||
series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
|
||||
flags |= ATH9K_TXDESC_RTSENA;
|
||||
} else if (rates[i].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
|
||||
series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
|
||||
flags |= ATH9K_TXDESC_CTSENA;
|
||||
}
|
||||
|
||||
if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||
series[i].RateFlags |= ATH9K_RATESERIES_2040;
|
||||
if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
|
||||
series[i].RateFlags |= ATH9K_RATESERIES_HALFGI;
|
||||
|
||||
is_sgi = !!(rates[i].flags & IEEE80211_TX_RC_SHORT_GI);
|
||||
is_40 = !!(rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH);
|
||||
is_sp = !!(rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
|
||||
|
||||
if (rates[i].flags & IEEE80211_TX_RC_MCS) {
|
||||
/* MCS rates */
|
||||
series[i].Rate = rix | 0x80;
|
||||
series[i].ChSel = ath_txchainmask_reduction(sc,
|
||||
common->tx_chainmask, series[i].Rate);
|
||||
series[i].PktDuration = ath_pkt_duration(sc, rix, len,
|
||||
is_40, is_sgi, is_sp);
|
||||
if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC))
|
||||
series[i].RateFlags |= ATH9K_RATESERIES_STBC;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* legacy rates */
|
||||
if ((tx_info->band == IEEE80211_BAND_2GHZ) &&
|
||||
!(rate->flags & IEEE80211_RATE_ERP_G))
|
||||
phy = WLAN_RC_PHY_CCK;
|
||||
else
|
||||
phy = WLAN_RC_PHY_OFDM;
|
||||
|
||||
rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx];
|
||||
series[i].Rate = rate->hw_value;
|
||||
if (rate->hw_value_short) {
|
||||
if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
|
||||
series[i].Rate |= rate->hw_value_short;
|
||||
} else {
|
||||
is_sp = false;
|
||||
}
|
||||
|
||||
if (bf->bf_state.bfs_paprd)
|
||||
series[i].ChSel = common->tx_chainmask;
|
||||
else
|
||||
series[i].ChSel = ath_txchainmask_reduction(sc,
|
||||
common->tx_chainmask, series[i].Rate);
|
||||
|
||||
series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah,
|
||||
phy, rate->bitrate * 100, len, rix, is_sp);
|
||||
}
|
||||
|
||||
/* For AR5416 - RTS cannot be followed by a frame larger than 8K */
|
||||
if (bf_isaggr(bf) && (len > sc->sc_ah->caps.rts_aggr_limit))
|
||||
flags &= ~ATH9K_TXDESC_RTSENA;
|
||||
|
||||
/* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */
|
||||
if (flags & ATH9K_TXDESC_RTSENA)
|
||||
flags &= ~ATH9K_TXDESC_CTSENA;
|
||||
|
||||
/* set dur_update_en for l-sig computation except for PS-Poll frames */
|
||||
ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
|
||||
bf->bf_lastbf->bf_desc,
|
||||
!is_pspoll, ctsrate,
|
||||
0, series, 4, flags);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Assign a descriptor (and sequence number if necessary,
|
||||
* and map buffer for DMA. Frees skb on error
|
||||
@ -1752,13 +1773,10 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
|
||||
struct ath_atx_tid *tid,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_frame_info *fi = get_frame_info(skb);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
struct ath_buf *bf;
|
||||
struct ath_desc *ds;
|
||||
int frm_type;
|
||||
u16 seqno;
|
||||
|
||||
bf = ath_tx_get_buffer(sc);
|
||||
@ -1776,7 +1794,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
|
||||
bf->bf_state.seqno = seqno;
|
||||
}
|
||||
|
||||
bf->bf_flags = setup_tx_flags(skb);
|
||||
bf->bf_mpdu = skb;
|
||||
|
||||
bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
|
||||
@ -1790,22 +1807,6 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
|
||||
goto error;
|
||||
}
|
||||
|
||||
frm_type = get_hw_packet_type(skb);
|
||||
|
||||
ds = bf->bf_desc;
|
||||
ath9k_hw_set_desc_link(ah, ds, 0);
|
||||
|
||||
ath9k_hw_set11n_txdesc(ah, ds, fi->framelen, frm_type, MAX_RATE_POWER,
|
||||
fi->keyix, fi->keytype, bf->bf_flags);
|
||||
|
||||
ath9k_hw_filltxdesc(ah, ds,
|
||||
skb->len, /* segment length */
|
||||
true, /* first segment */
|
||||
true, /* last segment */
|
||||
ds, /* first descriptor */
|
||||
bf->bf_buf_addr,
|
||||
txq->axq_qnum);
|
||||
|
||||
fi->bf = bf;
|
||||
|
||||
return bf;
|
||||
@ -1848,16 +1849,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
|
||||
|
||||
bf->bf_state.bfs_paprd = txctl->paprd;
|
||||
|
||||
if (bf->bf_state.bfs_paprd)
|
||||
ar9003_hw_set_paprd_txdesc(sc->sc_ah, bf->bf_desc,
|
||||
bf->bf_state.bfs_paprd);
|
||||
|
||||
if (txctl->paprd)
|
||||
bf->bf_state.bfs_paprd_timestamp = jiffies;
|
||||
|
||||
if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
|
||||
ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true);
|
||||
|
||||
ath_tx_send_normal(sc, txctl->txq, tid, skb);
|
||||
}
|
||||
|
||||
@ -1898,15 +1892,17 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
|
||||
hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
|
||||
}
|
||||
|
||||
/* Add the padding after the header if this is not already done */
|
||||
padpos = ath9k_cmn_padpos(hdr->frame_control);
|
||||
padsize = padpos & 3;
|
||||
if (padsize && skb->len > padpos) {
|
||||
if (skb_headroom(skb) < padsize)
|
||||
return -ENOMEM;
|
||||
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) {
|
||||
/* Add the padding after the header if this is not already done */
|
||||
padpos = ath9k_cmn_padpos(hdr->frame_control);
|
||||
padsize = padpos & 3;
|
||||
if (padsize && skb->len > padpos) {
|
||||
if (skb_headroom(skb) < padsize)
|
||||
return -ENOMEM;
|
||||
|
||||
skb_push(skb, padsize);
|
||||
memmove(skb->data, skb->data + padsize, padpos);
|
||||
skb_push(skb, padsize);
|
||||
memmove(skb->data, skb->data + padsize, padpos);
|
||||
}
|
||||
}
|
||||
|
||||
if ((vif && vif->type != NL80211_IFTYPE_AP &&
|
||||
@ -1952,20 +1948,21 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
|
||||
if (tx_flags & ATH_TX_BAR)
|
||||
tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
|
||||
|
||||
if (!(tx_flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
|
||||
if (!(tx_flags & ATH_TX_ERROR))
|
||||
/* Frame was ACKed */
|
||||
tx_info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
}
|
||||
|
||||
padpos = ath9k_cmn_padpos(hdr->frame_control);
|
||||
padsize = padpos & 3;
|
||||
if (padsize && skb->len>padpos+padsize) {
|
||||
/*
|
||||
* Remove MAC header padding before giving the frame back to
|
||||
* mac80211.
|
||||
*/
|
||||
memmove(skb->data + padsize, skb->data, padpos);
|
||||
skb_pull(skb, padsize);
|
||||
if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) {
|
||||
padpos = ath9k_cmn_padpos(hdr->frame_control);
|
||||
padsize = padpos & 3;
|
||||
if (padsize && skb->len>padpos+padsize) {
|
||||
/*
|
||||
* Remove MAC header padding before giving the frame back to
|
||||
* mac80211.
|
||||
*/
|
||||
memmove(skb->data + padsize, skb->data, padpos);
|
||||
skb_pull(skb, padsize);
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) {
|
||||
@ -1999,18 +1996,18 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
|
||||
struct ath_tx_status *ts, int txok, int sendbar)
|
||||
{
|
||||
struct sk_buff *skb = bf->bf_mpdu;
|
||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||
unsigned long flags;
|
||||
int tx_flags = 0;
|
||||
|
||||
if (sendbar)
|
||||
tx_flags = ATH_TX_BAR;
|
||||
|
||||
if (!txok) {
|
||||
if (!txok)
|
||||
tx_flags |= ATH_TX_ERROR;
|
||||
|
||||
if (bf_isxretried(bf))
|
||||
tx_flags |= ATH_TX_XRETRY;
|
||||
}
|
||||
if (ts->ts_status & ATH9K_TXERR_FILT)
|
||||
tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
|
||||
|
||||
dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE);
|
||||
bf->bf_buf_addr = 0;
|
||||
@ -2023,7 +2020,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
|
||||
else
|
||||
complete(&sc->paprd_complete);
|
||||
} else {
|
||||
ath_debug_stat_tx(sc, bf, ts, txq);
|
||||
ath_debug_stat_tx(sc, bf, ts, txq, tx_flags);
|
||||
ath_tx_complete(sc, skb, tx_flags, txq);
|
||||
}
|
||||
/* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't
|
||||
@ -2041,7 +2038,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
|
||||
|
||||
static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
|
||||
struct ath_tx_status *ts, int nframes, int nbad,
|
||||
int txok, bool update_rc)
|
||||
int txok)
|
||||
{
|
||||
struct sk_buff *skb = bf->bf_mpdu;
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
@ -2056,9 +2053,7 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
|
||||
tx_rateindex = ts->ts_rateindex;
|
||||
WARN_ON(tx_rateindex >= hw->max_rates);
|
||||
|
||||
if (ts->ts_status & ATH9K_TXERR_FILT)
|
||||
tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
|
||||
if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) {
|
||||
if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
|
||||
tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
|
||||
|
||||
BUG_ON(nbad > nframes);
|
||||
@ -2068,7 +2063,7 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
|
||||
}
|
||||
|
||||
if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 &&
|
||||
(bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
|
||||
(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) == 0) {
|
||||
/*
|
||||
* If an underrun error is seen assume it as an excessive
|
||||
* retry only if max frame trigger level has been reached
|
||||
@ -2081,9 +2076,9 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf,
|
||||
* successfully by eventually preferring slower rates.
|
||||
* This itself should also alleviate congestion on the bus.
|
||||
*/
|
||||
if (ieee80211_is_data(hdr->frame_control) &&
|
||||
(ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN |
|
||||
ATH9K_TX_DELIM_UNDERRUN)) &&
|
||||
if (unlikely(ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN |
|
||||
ATH9K_TX_DELIM_UNDERRUN)) &&
|
||||
ieee80211_is_data(hdr->frame_control) &&
|
||||
ah->tx_trig_level >= sc->sc_ah->config.max_txtrig_level)
|
||||
tx_info->status.rates[tx_rateindex].count =
|
||||
hw->max_rate_tries;
|
||||
@ -2114,13 +2109,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
|
||||
if (!bf_isampdu(bf)) {
|
||||
/*
|
||||
* This frame is sent out as a single frame.
|
||||
* Use hardware retry status for this frame.
|
||||
*/
|
||||
if (ts->ts_status & ATH9K_TXERR_XRETRY)
|
||||
bf->bf_state.bf_type |= BUF_XRETRY;
|
||||
ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok, true);
|
||||
ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok);
|
||||
ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok, 0);
|
||||
} else
|
||||
ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true);
|
||||
@ -2147,6 +2136,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
||||
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
for (;;) {
|
||||
if (work_pending(&sc->hw_reset_work))
|
||||
break;
|
||||
|
||||
if (list_empty(&txq->axq_q)) {
|
||||
txq->axq_link = NULL;
|
||||
if (sc->sc_flags & SC_OP_TXAGGR)
|
||||
@ -2234,9 +2226,7 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
|
||||
if (needreset) {
|
||||
ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_RESET,
|
||||
"tx hung, resetting the chip\n");
|
||||
spin_lock_bh(&sc->sc_pcu_lock);
|
||||
ath_reset(sc, true);
|
||||
spin_unlock_bh(&sc->sc_pcu_lock);
|
||||
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
|
||||
}
|
||||
|
||||
ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
|
||||
@ -2269,6 +2259,9 @@ void ath_tx_edma_tasklet(struct ath_softc *sc)
|
||||
int status;
|
||||
|
||||
for (;;) {
|
||||
if (work_pending(&sc->hw_reset_work))
|
||||
break;
|
||||
|
||||
status = ath9k_hw_txprocdesc(ah, NULL, (void *)&ts);
|
||||
if (status == -EINPROGRESS)
|
||||
break;
|
||||
|
@ -110,6 +110,8 @@
|
||||
#define B43_MMIO_TSF_CFP_START_LOW 0x604
|
||||
#define B43_MMIO_TSF_CFP_START_HIGH 0x606
|
||||
#define B43_MMIO_TSF_CFP_PRETBTT 0x612
|
||||
#define B43_MMIO_TSF_CLK_FRAC_LOW 0x62E
|
||||
#define B43_MMIO_TSF_CLK_FRAC_HIGH 0x630
|
||||
#define B43_MMIO_TSF_0 0x632 /* core rev < 3 only */
|
||||
#define B43_MMIO_TSF_1 0x634 /* core rev < 3 only */
|
||||
#define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */
|
||||
|
@ -3,6 +3,8 @@
|
||||
Broadcom B43 wireless driver
|
||||
Bus abstraction layer
|
||||
|
||||
Copyright (c) 2011 Rafał Miłecki <zajec5@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
|
@ -7,6 +7,7 @@
|
||||
Copyright (c) 2005-2009 Michael Buesch <m@bues.ch>
|
||||
Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
|
||||
Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
|
||||
Copyright (c) 2010-2011 Rafał Miłecki <zajec5@gmail.com>
|
||||
|
||||
SDIO support
|
||||
Copyright (c) 2009 Albert Herranz <albert_herranz@yahoo.es>
|
||||
@ -64,6 +65,7 @@ MODULE_AUTHOR("Martin Langer");
|
||||
MODULE_AUTHOR("Stefano Brivio");
|
||||
MODULE_AUTHOR("Michael Buesch");
|
||||
MODULE_AUTHOR("Gábor Stefanik");
|
||||
MODULE_AUTHOR("Rafał Miłecki");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
MODULE_FIRMWARE("b43/ucode11.fw");
|
||||
@ -2953,6 +2955,7 @@ static void b43_rate_memory_init(struct b43_wldev *dev)
|
||||
case B43_PHYTYPE_N:
|
||||
case B43_PHYTYPE_LP:
|
||||
case B43_PHYTYPE_HT:
|
||||
case B43_PHYTYPE_LCN:
|
||||
b43_rate_memory_write(dev, B43_OFDM_RATE_6MB, 1);
|
||||
b43_rate_memory_write(dev, B43_OFDM_RATE_12MB, 1);
|
||||
b43_rate_memory_write(dev, B43_OFDM_RATE_18MB, 1);
|
||||
|
@ -3,6 +3,8 @@
|
||||
Broadcom B43 wireless driver
|
||||
IEEE 802.11n HT-PHY support
|
||||
|
||||
Copyright (c) 2011 Rafał Miłecki <zajec5@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
|
@ -3,6 +3,8 @@
|
||||
Broadcom B43 wireless driver
|
||||
IEEE 802.11n LCN-PHY support
|
||||
|
||||
Copyright (c) 2011 Rafał Miłecki <zajec5@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
@ -31,24 +33,78 @@
|
||||
* Radio 2064.
|
||||
**************************************************/
|
||||
|
||||
/* wlc_lcnphy_radio_2064_channel_tune_4313 */
|
||||
static void b43_radio_2064_channel_setup(struct b43_wldev *dev)
|
||||
{
|
||||
u16 save[2];
|
||||
|
||||
b43_radio_set(dev, 0x09d, 0x4);
|
||||
b43_radio_write(dev, 0x09e, 0xf);
|
||||
|
||||
/* Channel specific values in theory, in practice always the same */
|
||||
b43_radio_write(dev, 0x02a, 0xb);
|
||||
b43_radio_maskset(dev, 0x030, ~0x3, 0xa);
|
||||
b43_radio_maskset(dev, 0x091, ~0x3, 0);
|
||||
b43_radio_maskset(dev, 0x038, ~0xf, 0x7);
|
||||
b43_radio_maskset(dev, 0x030, ~0xc, 0x8);
|
||||
b43_radio_maskset(dev, 0x05e, ~0xf, 0x8);
|
||||
b43_radio_maskset(dev, 0x05e, ~0xf0, 0x80);
|
||||
b43_radio_write(dev, 0x06c, 0x80);
|
||||
|
||||
save[0] = b43_radio_read(dev, 0x044);
|
||||
save[1] = b43_radio_read(dev, 0x12b);
|
||||
|
||||
b43_radio_set(dev, 0x044, 0x7);
|
||||
b43_radio_set(dev, 0x12b, 0xe);
|
||||
|
||||
/* TODO */
|
||||
|
||||
b43_radio_write(dev, 0x040, 0xfb);
|
||||
|
||||
b43_radio_write(dev, 0x041, 0x9a);
|
||||
b43_radio_write(dev, 0x042, 0xa3);
|
||||
b43_radio_write(dev, 0x043, 0x0c);
|
||||
|
||||
/* TODO */
|
||||
|
||||
b43_radio_set(dev, 0x044, 0x0c);
|
||||
udelay(1);
|
||||
|
||||
b43_radio_write(dev, 0x044, save[0]);
|
||||
b43_radio_write(dev, 0x12b, save[1]);
|
||||
|
||||
if (dev->phy.rev == 1) {
|
||||
/* brcmsmac uses outdated 0x3 for 0x038 */
|
||||
b43_radio_write(dev, 0x038, 0x0);
|
||||
b43_radio_write(dev, 0x091, 0x7);
|
||||
}
|
||||
}
|
||||
|
||||
/* wlc_radio_2064_init */
|
||||
static void b43_radio_2064_init(struct b43_wldev *dev)
|
||||
{
|
||||
b43_radio_write(dev, 0x09c, 0x0020);
|
||||
b43_radio_write(dev, 0x105, 0x0008);
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
|
||||
b43_radio_write(dev, 0x09c, 0x0020);
|
||||
b43_radio_write(dev, 0x105, 0x0008);
|
||||
} else {
|
||||
/* TODO */
|
||||
}
|
||||
b43_radio_write(dev, 0x032, 0x0062);
|
||||
b43_radio_write(dev, 0x033, 0x0019);
|
||||
b43_radio_write(dev, 0x090, 0x0010);
|
||||
b43_radio_write(dev, 0x010, 0x0000);
|
||||
b43_radio_write(dev, 0x060, 0x007f);
|
||||
b43_radio_write(dev, 0x061, 0x0072);
|
||||
b43_radio_write(dev, 0x062, 0x007f);
|
||||
if (dev->phy.rev == 1) {
|
||||
b43_radio_write(dev, 0x060, 0x007f);
|
||||
b43_radio_write(dev, 0x061, 0x0072);
|
||||
b43_radio_write(dev, 0x062, 0x007f);
|
||||
}
|
||||
b43_radio_write(dev, 0x01d, 0x0002);
|
||||
b43_radio_write(dev, 0x01e, 0x0006);
|
||||
|
||||
b43_phy_write(dev, 0x4ea, 0x4688);
|
||||
b43_phy_maskset(dev, 0x4eb, ~0x7, 0x2);
|
||||
b43_phy_mask(dev, 0x4eb, ~0x01c0);
|
||||
b43_phy_maskset(dev, 0x4eb, 0xff00, 0x19);
|
||||
b43_phy_maskset(dev, 0x46a, 0xff00, 0x19);
|
||||
|
||||
b43_lcntab_write(dev, B43_LCNTAB16(0x00, 0x55), 0);
|
||||
|
||||
@ -80,6 +136,7 @@ static void b43_radio_2064_init(struct b43_wldev *dev)
|
||||
* Various PHY ops
|
||||
**************************************************/
|
||||
|
||||
/* wlc_lcnphy_toggle_afe_pwdn */
|
||||
static void b43_phy_lcn_afe_set_unset(struct b43_wldev *dev)
|
||||
{
|
||||
u16 afe_ctl2 = b43_phy_read(dev, B43_PHY_LCN_AFE_CTL2);
|
||||
@ -95,22 +152,17 @@ static void b43_phy_lcn_afe_set_unset(struct b43_wldev *dev)
|
||||
b43_phy_write(dev, B43_PHY_LCN_AFE_CTL1, afe_ctl1);
|
||||
}
|
||||
|
||||
static void b43_phy_lcn_clean_0x18_table(struct b43_wldev *dev)
|
||||
/* wlc_lcnphy_clear_tx_power_offsets */
|
||||
static void b43_phy_lcn_clear_tx_power_offsets(struct b43_wldev *dev)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
for (i = 0; i < 0x80; i++)
|
||||
b43_lcntab_write(dev, B43_LCNTAB32(0x18, i), 0x80000);
|
||||
}
|
||||
|
||||
static void b43_phy_lcn_clear_0x07_table(struct b43_wldev *dev)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, (0x7 << 10) | 0x340);
|
||||
for (i = 0; i < 30; i++) {
|
||||
b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI, 0);
|
||||
b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, 0);
|
||||
if (1) { /* FIXME */
|
||||
b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, (0x7 << 10) | 0x340);
|
||||
for (i = 0; i < 30; i++) {
|
||||
b43_phy_write(dev, B43_PHY_LCN_TABLE_DATAHI, 0);
|
||||
b43_phy_write(dev, B43_PHY_LCN_TABLE_DATALO, 0);
|
||||
}
|
||||
}
|
||||
|
||||
b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, (0x7 << 10) | 0x80);
|
||||
@ -120,6 +172,134 @@ static void b43_phy_lcn_clear_0x07_table(struct b43_wldev *dev)
|
||||
}
|
||||
}
|
||||
|
||||
/* wlc_lcnphy_rev0_baseband_init */
|
||||
static void b43_phy_lcn_rev0_baseband_init(struct b43_wldev *dev)
|
||||
{
|
||||
b43_radio_write(dev, 0x11c, 0);
|
||||
|
||||
b43_phy_write(dev, 0x43b, 0);
|
||||
b43_phy_write(dev, 0x43c, 0);
|
||||
b43_phy_write(dev, 0x44c, 0);
|
||||
b43_phy_write(dev, 0x4e6, 0);
|
||||
b43_phy_write(dev, 0x4f9, 0);
|
||||
b43_phy_write(dev, 0x4b0, 0);
|
||||
b43_phy_write(dev, 0x938, 0);
|
||||
b43_phy_write(dev, 0x4b0, 0);
|
||||
b43_phy_write(dev, 0x44e, 0);
|
||||
|
||||
b43_phy_set(dev, 0x567, 0x03);
|
||||
|
||||
b43_phy_set(dev, 0x44a, 0x44);
|
||||
b43_phy_write(dev, 0x44a, 0x80);
|
||||
|
||||
if (!(dev->dev->bus_sprom->boardflags_lo & B43_BFL_FEM))
|
||||
; /* TODO */
|
||||
b43_phy_maskset(dev, 0x634, ~0xff, 0xc);
|
||||
if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_FEM) {
|
||||
b43_phy_maskset(dev, 0x634, ~0xff, 0xa);
|
||||
b43_phy_write(dev, 0x910, 0x1);
|
||||
}
|
||||
|
||||
b43_phy_write(dev, 0x910, 0x1);
|
||||
|
||||
b43_phy_maskset(dev, 0x448, ~0x300, 0x100);
|
||||
b43_phy_maskset(dev, 0x608, ~0xff, 0x17);
|
||||
b43_phy_maskset(dev, 0x604, ~0x7ff, 0x3ea);
|
||||
}
|
||||
|
||||
/* wlc_lcnphy_bu_tweaks */
|
||||
static void b43_phy_lcn_bu_tweaks(struct b43_wldev *dev)
|
||||
{
|
||||
b43_phy_set(dev, 0x805, 0x1);
|
||||
|
||||
b43_phy_maskset(dev, 0x42f, ~0x7, 0x3);
|
||||
b43_phy_maskset(dev, 0x030, ~0x7, 0x3);
|
||||
|
||||
b43_phy_write(dev, 0x414, 0x1e10);
|
||||
b43_phy_write(dev, 0x415, 0x0640);
|
||||
|
||||
b43_phy_maskset(dev, 0x4df, (u16) ~0xff00, 0xf700);
|
||||
|
||||
b43_phy_set(dev, 0x44a, 0x44);
|
||||
b43_phy_write(dev, 0x44a, 0x80);
|
||||
|
||||
b43_phy_maskset(dev, 0x434, ~0xff, 0xfd);
|
||||
b43_phy_maskset(dev, 0x420, ~0xff, 0x10);
|
||||
|
||||
if (dev->dev->bus_sprom->board_rev >= 0x1204)
|
||||
b43_radio_set(dev, 0x09b, 0xf0);
|
||||
|
||||
b43_phy_write(dev, 0x7d6, 0x0902);
|
||||
|
||||
/* TODO: more ops */
|
||||
|
||||
if (dev->phy.rev == 1) {
|
||||
/* TODO: more ops */
|
||||
|
||||
b43_phy_lcn_clear_tx_power_offsets(dev);
|
||||
}
|
||||
}
|
||||
|
||||
/* wlc_lcnphy_vbat_temp_sense_setup */
|
||||
static void b43_phy_lcn_sense_setup(struct b43_wldev *dev)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
u16 save_radio_regs[6][2] = {
|
||||
{ 0x007, 0 }, { 0x0ff, 0 }, { 0x11f, 0 }, { 0x005, 0 },
|
||||
{ 0x025, 0 }, { 0x112, 0 },
|
||||
};
|
||||
u16 save_phy_regs[14][2] = {
|
||||
{ 0x503, 0 }, { 0x4a4, 0 }, { 0x4d0, 0 }, { 0x4d9, 0 },
|
||||
{ 0x4da, 0 }, { 0x4a6, 0 }, { 0x938, 0 }, { 0x939, 0 },
|
||||
{ 0x4d8, 0 }, { 0x4d0, 0 }, { 0x4d7, 0 }, { 0x4a5, 0 },
|
||||
{ 0x40d, 0 }, { 0x4a2, 0 },
|
||||
};
|
||||
u16 save_radio_4a4;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
save_radio_regs[i][1] = b43_radio_read(dev,
|
||||
save_radio_regs[i][0]);
|
||||
for (i = 0; i < 14; i++)
|
||||
save_phy_regs[i][1] = b43_phy_read(dev, save_phy_regs[i][0]);
|
||||
save_radio_4a4 = b43_radio_read(dev, 0x4a4);
|
||||
|
||||
/* TODO: config sth */
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
b43_radio_write(dev, save_radio_regs[i][0],
|
||||
save_radio_regs[i][1]);
|
||||
for (i = 0; i < 14; i++)
|
||||
b43_phy_write(dev, save_phy_regs[i][0], save_phy_regs[i][1]);
|
||||
b43_radio_write(dev, 0x4a4, save_radio_4a4);
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Channel switching ops.
|
||||
**************************************************/
|
||||
|
||||
static int b43_phy_lcn_set_channel(struct b43_wldev *dev,
|
||||
struct ieee80211_channel *channel,
|
||||
enum nl80211_channel_type channel_type)
|
||||
{
|
||||
/* TODO: PLL and PHY ops */
|
||||
|
||||
b43_phy_set(dev, 0x44a, 0x44);
|
||||
b43_phy_write(dev, 0x44a, 0x80);
|
||||
|
||||
b43_phy_set(dev, 0x44a, 0x44);
|
||||
b43_phy_write(dev, 0x44a, 0x80);
|
||||
|
||||
b43_radio_2064_channel_setup(dev);
|
||||
mdelay(1);
|
||||
|
||||
b43_phy_lcn_afe_set_unset(dev);
|
||||
|
||||
/* TODO */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* Basic PHY ops.
|
||||
**************************************************/
|
||||
@ -153,6 +333,7 @@ static void b43_phy_lcn_op_prepare_structs(struct b43_wldev *dev)
|
||||
memset(phy_lcn, 0, sizeof(*phy_lcn));
|
||||
}
|
||||
|
||||
/* wlc_phy_init_lcnphy */
|
||||
static int b43_phy_lcn_op_init(struct b43_wldev *dev)
|
||||
{
|
||||
b43_phy_set(dev, 0x44a, 0x80);
|
||||
@ -167,18 +348,17 @@ static int b43_phy_lcn_op_init(struct b43_wldev *dev)
|
||||
b43_phy_maskset(dev, 0x663, 0xFF00, 0x64);
|
||||
|
||||
b43_phy_lcn_tables_init(dev);
|
||||
/* TODO: various tables ops here */
|
||||
b43_phy_lcn_clean_0x18_table(dev);
|
||||
|
||||
/* TODO: some ops here */
|
||||
|
||||
b43_phy_lcn_clear_0x07_table(dev);
|
||||
b43_phy_lcn_rev0_baseband_init(dev);
|
||||
b43_phy_lcn_bu_tweaks(dev);
|
||||
|
||||
if (dev->phy.radio_ver == 0x2064)
|
||||
b43_radio_2064_init(dev);
|
||||
else
|
||||
B43_WARN_ON(1);
|
||||
|
||||
b43_phy_lcn_sense_setup(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -215,6 +395,22 @@ static void b43_phy_lcn_op_switch_analog(struct b43_wldev *dev, bool on)
|
||||
}
|
||||
}
|
||||
|
||||
static int b43_phy_lcn_op_switch_channel(struct b43_wldev *dev,
|
||||
unsigned int new_channel)
|
||||
{
|
||||
struct ieee80211_channel *channel = dev->wl->hw->conf.channel;
|
||||
enum nl80211_channel_type channel_type = dev->wl->hw->conf.channel_type;
|
||||
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
|
||||
if ((new_channel < 1) || (new_channel > 14))
|
||||
return -EINVAL;
|
||||
} else {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return b43_phy_lcn_set_channel(dev, channel, channel_type);
|
||||
}
|
||||
|
||||
static unsigned int b43_phy_lcn_op_get_default_chan(struct b43_wldev *dev)
|
||||
{
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
|
||||
@ -232,6 +428,46 @@ static void b43_phy_lcn_op_adjust_txpower(struct b43_wldev *dev)
|
||||
{
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* R/W ops.
|
||||
**************************************************/
|
||||
|
||||
static u16 b43_phy_lcn_op_read(struct b43_wldev *dev, u16 reg)
|
||||
{
|
||||
b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
|
||||
return b43_read16(dev, B43_MMIO_PHY_DATA);
|
||||
}
|
||||
|
||||
static void b43_phy_lcn_op_write(struct b43_wldev *dev, u16 reg, u16 value)
|
||||
{
|
||||
b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
|
||||
b43_write16(dev, B43_MMIO_PHY_DATA, value);
|
||||
}
|
||||
|
||||
static void b43_phy_lcn_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask,
|
||||
u16 set)
|
||||
{
|
||||
b43_write16(dev, B43_MMIO_PHY_CONTROL, reg);
|
||||
b43_write16(dev, B43_MMIO_PHY_DATA,
|
||||
(b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set);
|
||||
}
|
||||
|
||||
static u16 b43_phy_lcn_op_radio_read(struct b43_wldev *dev, u16 reg)
|
||||
{
|
||||
/* LCN-PHY needs 0x200 for read access */
|
||||
reg |= 0x200;
|
||||
|
||||
b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
|
||||
return b43_read16(dev, B43_MMIO_RADIO24_DATA);
|
||||
}
|
||||
|
||||
static void b43_phy_lcn_op_radio_write(struct b43_wldev *dev, u16 reg,
|
||||
u16 value)
|
||||
{
|
||||
b43_write16(dev, B43_MMIO_RADIO24_CONTROL, reg);
|
||||
b43_write16(dev, B43_MMIO_RADIO24_DATA, value);
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* PHY ops struct.
|
||||
**************************************************/
|
||||
@ -241,18 +477,14 @@ const struct b43_phy_operations b43_phyops_lcn = {
|
||||
.free = b43_phy_lcn_op_free,
|
||||
.prepare_structs = b43_phy_lcn_op_prepare_structs,
|
||||
.init = b43_phy_lcn_op_init,
|
||||
/*
|
||||
.phy_read = b43_phy_lcn_op_read,
|
||||
.phy_write = b43_phy_lcn_op_write,
|
||||
.phy_maskset = b43_phy_lcn_op_maskset,
|
||||
.radio_read = b43_phy_lcn_op_radio_read,
|
||||
.radio_write = b43_phy_lcn_op_radio_write,
|
||||
*/
|
||||
.software_rfkill = b43_phy_lcn_op_software_rfkill,
|
||||
.switch_analog = b43_phy_lcn_op_switch_analog,
|
||||
/*
|
||||
.switch_channel = b43_phy_lcn_op_switch_channel,
|
||||
*/
|
||||
.get_default_chan = b43_phy_lcn_op_get_default_chan,
|
||||
.recalc_txpower = b43_phy_lcn_op_recalc_txpower,
|
||||
.adjust_txpower = b43_phy_lcn_op_adjust_txpower,
|
||||
|
@ -4,6 +4,7 @@
|
||||
IEEE 802.11n PHY support
|
||||
|
||||
Copyright (c) 2008 Michael Buesch <m@bues.ch>
|
||||
Copyright (c) 2010-2011 Rafał Miłecki <zajec5@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -77,6 +78,7 @@ enum b43_nphy_rssi_type {
|
||||
B43_NPHY_RSSI_TBD,
|
||||
};
|
||||
|
||||
/* TODO: reorder functions */
|
||||
static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev,
|
||||
bool enable);
|
||||
static void b43_nphy_set_rf_sequence(struct b43_wldev *dev, u8 cmd,
|
||||
@ -87,6 +89,14 @@ static void b43_nphy_rf_control_override(struct b43_wldev *dev, u16 field,
|
||||
u16 value, u8 core, bool off);
|
||||
static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field,
|
||||
u16 value, u8 core);
|
||||
static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev);
|
||||
|
||||
static inline bool b43_nphy_ipa(struct b43_wldev *dev)
|
||||
{
|
||||
enum ieee80211_band band = b43_current_band(dev->wl);
|
||||
return ((dev->phy.n->ipa2g_on && band == IEEE80211_BAND_2GHZ) ||
|
||||
(dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ));
|
||||
}
|
||||
|
||||
void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
|
||||
{//TODO
|
||||
@ -248,15 +258,25 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
|
||||
{
|
||||
struct b43_phy_n *nphy = dev->phy.n;
|
||||
u8 i;
|
||||
u16 tmp;
|
||||
u16 bmask, val, tmp;
|
||||
enum ieee80211_band band = b43_current_band(dev->wl);
|
||||
|
||||
if (nphy->hang_avoid)
|
||||
b43_nphy_stay_in_carrier_search(dev, 1);
|
||||
|
||||
nphy->txpwrctrl = enable;
|
||||
if (!enable) {
|
||||
if (dev->phy.rev >= 3)
|
||||
; /* TODO */
|
||||
if (dev->phy.rev >= 3 &&
|
||||
(b43_phy_read(dev, B43_NPHY_TXPCTL_CMD) &
|
||||
(B43_NPHY_TXPCTL_CMD_COEFF |
|
||||
B43_NPHY_TXPCTL_CMD_HWPCTLEN |
|
||||
B43_NPHY_TXPCTL_CMD_PCTLEN))) {
|
||||
/* We disable enabled TX pwr ctl, save it's state */
|
||||
nphy->tx_pwr_idx[0] = b43_phy_read(dev,
|
||||
B43_NPHY_C1_TXPCTL_STAT) & 0x7f;
|
||||
nphy->tx_pwr_idx[1] = b43_phy_read(dev,
|
||||
B43_NPHY_C2_TXPCTL_STAT) & 0x7f;
|
||||
}
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x6840);
|
||||
for (i = 0; i < 84; i++)
|
||||
@ -285,10 +305,67 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable)
|
||||
b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
|
||||
~B43_NPHY_BPHY_CTL3_SCALE, 0x5A);
|
||||
|
||||
if (dev->phy.rev < 2 && 0)
|
||||
; /* TODO */
|
||||
if (dev->phy.rev < 2 && dev->phy.is_40mhz)
|
||||
b43_hf_write(dev, b43_hf_read(dev) | B43_HF_TSSIRPSMW);
|
||||
} else {
|
||||
b43err(dev->wl, "enabling tx pwr ctrl not implemented yet\n");
|
||||
b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84,
|
||||
nphy->adj_pwr_tbl);
|
||||
b43_ntab_write_bulk(dev, B43_NTAB16(27, 64), 84,
|
||||
nphy->adj_pwr_tbl);
|
||||
|
||||
bmask = B43_NPHY_TXPCTL_CMD_COEFF |
|
||||
B43_NPHY_TXPCTL_CMD_HWPCTLEN;
|
||||
/* wl does useless check for "enable" param here */
|
||||
val = B43_NPHY_TXPCTL_CMD_COEFF | B43_NPHY_TXPCTL_CMD_HWPCTLEN;
|
||||
if (dev->phy.rev >= 3) {
|
||||
bmask |= B43_NPHY_TXPCTL_CMD_PCTLEN;
|
||||
if (val)
|
||||
val |= B43_NPHY_TXPCTL_CMD_PCTLEN;
|
||||
}
|
||||
b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD, ~(bmask), val);
|
||||
|
||||
if (band == IEEE80211_BAND_5GHZ) {
|
||||
b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
|
||||
~B43_NPHY_TXPCTL_CMD_INIT, 0x64);
|
||||
if (dev->phy.rev > 1)
|
||||
b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT,
|
||||
~B43_NPHY_TXPCTL_INIT_PIDXI1,
|
||||
0x64);
|
||||
}
|
||||
|
||||
if (dev->phy.rev >= 3) {
|
||||
if (nphy->tx_pwr_idx[0] != 128 &&
|
||||
nphy->tx_pwr_idx[1] != 128) {
|
||||
/* Recover TX pwr ctl state */
|
||||
b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD,
|
||||
~B43_NPHY_TXPCTL_CMD_INIT,
|
||||
nphy->tx_pwr_idx[0]);
|
||||
if (dev->phy.rev > 1)
|
||||
b43_phy_maskset(dev,
|
||||
B43_NPHY_TXPCTL_INIT,
|
||||
~0xff, nphy->tx_pwr_idx[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->phy.rev >= 3) {
|
||||
b43_phy_mask(dev, B43_NPHY_AFECTL_OVER1, ~0x100);
|
||||
b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x100);
|
||||
} else {
|
||||
b43_phy_mask(dev, B43_NPHY_AFECTL_OVER, ~0x4000);
|
||||
}
|
||||
|
||||
if (dev->phy.rev == 2)
|
||||
b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, ~0xFF, 0x3b);
|
||||
else if (dev->phy.rev < 2)
|
||||
b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, ~0xFF, 0x40);
|
||||
|
||||
if (dev->phy.rev < 2 && dev->phy.is_40mhz)
|
||||
b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_TSSIRPSMW);
|
||||
|
||||
if (b43_nphy_ipa(dev)) {
|
||||
b43_phy_mask(dev, B43_NPHY_PAPD_EN0, ~0x4);
|
||||
b43_phy_mask(dev, B43_NPHY_PAPD_EN1, ~0x4);
|
||||
}
|
||||
}
|
||||
|
||||
if (nphy->hang_avoid)
|
||||
@ -369,22 +446,23 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
|
||||
else
|
||||
b43_phy_write(dev, B43_NPHY_AFECTL_DACGAIN2, dac_gain);
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x1D10 + i);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, radio_gain);
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C57);
|
||||
tmp = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
|
||||
b43_ntab_write(dev, B43_NTAB16(0x7, 0x110 + i), radio_gain);
|
||||
|
||||
tmp = b43_ntab_read(dev, B43_NTAB16(0xF, 0x57));
|
||||
if (i == 0)
|
||||
tmp = (tmp & 0x00FF) | (bbmult << 8);
|
||||
else
|
||||
tmp = (tmp & 0xFF00) | bbmult;
|
||||
b43_ntab_write(dev, B43_NTAB16(0xF, 0x57), tmp);
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C57);
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_DATALO, tmp);
|
||||
|
||||
if (0)
|
||||
; /* TODO */
|
||||
if (b43_nphy_ipa(dev)) {
|
||||
u32 tmp32;
|
||||
u16 reg = (i == 0) ?
|
||||
B43_NPHY_PAPD_EN0 : B43_NPHY_PAPD_EN1;
|
||||
tmp32 = b43_ntab_read(dev, B43_NTAB32(26 + i, txpi[i]));
|
||||
b43_phy_maskset(dev, reg, 0xE00F, (u32) tmp32 << 4);
|
||||
b43_phy_set(dev, reg, 0x4);
|
||||
}
|
||||
}
|
||||
|
||||
b43_phy_mask(dev, B43_NPHY_BPHY_CTL2, ~B43_NPHY_BPHY_CTL2_LUT);
|
||||
@ -393,6 +471,57 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
|
||||
b43_nphy_stay_in_carrier_search(dev, 0);
|
||||
}
|
||||
|
||||
static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
|
||||
const u32 *table = NULL;
|
||||
#if 0
|
||||
TODO: b43_ntab_papd_pga_gain_delta_ipa_2*
|
||||
u32 rfpwr_offset;
|
||||
u8 pga_gain;
|
||||
int i;
|
||||
#endif
|
||||
|
||||
if (phy->rev >= 3) {
|
||||
if (b43_nphy_ipa(dev)) {
|
||||
table = b43_nphy_get_ipa_gain_table(dev);
|
||||
} else {
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
|
||||
if (phy->rev == 3)
|
||||
table = b43_ntab_tx_gain_rev3_5ghz;
|
||||
if (phy->rev == 4)
|
||||
table = b43_ntab_tx_gain_rev4_5ghz;
|
||||
else
|
||||
table = b43_ntab_tx_gain_rev5plus_5ghz;
|
||||
} else {
|
||||
table = b43_ntab_tx_gain_rev3plus_2ghz;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
table = b43_ntab_tx_gain_rev0_1_2;
|
||||
}
|
||||
b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table);
|
||||
b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table);
|
||||
|
||||
if (phy->rev >= 3) {
|
||||
#if 0
|
||||
nphy->gmval = (table[0] >> 16) & 0x7000;
|
||||
|
||||
for (i = 0; i < 128; i++) {
|
||||
pga_gain = (table[i] >> 24) & 0xF;
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
|
||||
rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain];
|
||||
else
|
||||
rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_5g[pga_gain];
|
||||
b43_ntab_write(dev, B43_NTAB32(26, 576 + i),
|
||||
rfpwr_offset);
|
||||
b43_ntab_write(dev, B43_NTAB32(27, 576 + i),
|
||||
rfpwr_offset);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/Radio/2055Setup */
|
||||
static void b43_radio_2055_setup(struct b43_wldev *dev,
|
||||
@ -581,14 +710,10 @@ static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable)
|
||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw */
|
||||
static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_n *nphy = dev->phy.n;
|
||||
u16 tmp;
|
||||
enum ieee80211_band band = b43_current_band(dev->wl);
|
||||
bool ipa = (nphy->ipa2g_on && band == IEEE80211_BAND_2GHZ) ||
|
||||
(nphy->ipa5g_on && band == IEEE80211_BAND_5GHZ);
|
||||
|
||||
if (dev->phy.rev >= 3) {
|
||||
if (ipa) {
|
||||
if (b43_nphy_ipa(dev)) {
|
||||
tmp = 4;
|
||||
b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
|
||||
(((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
|
||||
@ -899,11 +1024,7 @@ static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask)
|
||||
static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev)
|
||||
{
|
||||
u16 array[4];
|
||||
int i;
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C50);
|
||||
for (i = 0; i < 4; i++)
|
||||
array[i] = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
|
||||
b43_ntab_read_bulk(dev, B43_NTAB16(0xF, 0x50), 4, array);
|
||||
|
||||
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW0, array[0]);
|
||||
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW1, array[1]);
|
||||
@ -1366,8 +1487,118 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
|
||||
}
|
||||
}
|
||||
|
||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */
|
||||
static void b43_nphy_workarounds(struct b43_wldev *dev)
|
||||
static void b43_nphy_workarounds_rev3plus(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy_n *nphy = dev->phy.n;
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
|
||||
/* TX to RX */
|
||||
u8 tx2rx_events[9] = { 0x4, 0x3, 0x6, 0x5, 0x2, 0x1, 0x8, 0x1F };
|
||||
u8 tx2rx_delays[9] = { 8, 4, 2, 2, 4, 4, 6, 1 };
|
||||
/* RX to TX */
|
||||
u8 rx2tx_events_ipa[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0xF, 0x3,
|
||||
0x1F };
|
||||
u8 rx2tx_delays_ipa[9] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
|
||||
u8 rx2tx_events[9] = { 0x0, 0x1, 0x2, 0x8, 0x5, 0x6, 0x3, 0x4, 0x1F };
|
||||
u8 rx2tx_delays[9] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
|
||||
|
||||
u16 tmp16;
|
||||
u32 tmp32;
|
||||
|
||||
tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0));
|
||||
tmp32 &= 0xffffff;
|
||||
b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32);
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x0125);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x01B3);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x0105);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x016E);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0x00CD);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x0020);
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_C2_CLIP1_MEDGAIN, 0x000C);
|
||||
b43_phy_write(dev, 0x2AE, 0x000C);
|
||||
|
||||
/* TX to RX */
|
||||
b43_nphy_set_rf_sequence(dev, 1, tx2rx_events, tx2rx_delays, 9);
|
||||
|
||||
/* RX to TX */
|
||||
if (b43_nphy_ipa(dev))
|
||||
b43_nphy_set_rf_sequence(dev, 1, rx2tx_events_ipa,
|
||||
rx2tx_delays_ipa, 9);
|
||||
if (nphy->hw_phyrxchain != 3 &&
|
||||
nphy->hw_phyrxchain != nphy->hw_phytxchain) {
|
||||
if (b43_nphy_ipa(dev)) {
|
||||
rx2tx_delays[5] = 59;
|
||||
rx2tx_delays[6] = 1;
|
||||
rx2tx_events[7] = 0x1F;
|
||||
}
|
||||
b43_nphy_set_rf_sequence(dev, 1, rx2tx_events, rx2tx_delays, 9);
|
||||
}
|
||||
|
||||
tmp16 = (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ?
|
||||
0x2 : 0x9C40;
|
||||
b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, tmp16);
|
||||
|
||||
b43_phy_maskset(dev, 0x294, 0xF0FF, 0x0700);
|
||||
|
||||
b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D);
|
||||
b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D);
|
||||
|
||||
b43_nphy_gain_ctrl_workarounds(dev);
|
||||
|
||||
b43_ntab_write(dev, B43_NTAB32(8, 0), 2);
|
||||
b43_ntab_write(dev, B43_NTAB32(8, 16), 2);
|
||||
|
||||
/* TODO */
|
||||
|
||||
b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_MAST_BIAS, 0x00);
|
||||
b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_MAST_BIAS, 0x00);
|
||||
b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_MAIN, 0x06);
|
||||
b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_MAIN, 0x06);
|
||||
b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_AUX, 0x07);
|
||||
b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_AUX, 0x07);
|
||||
b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_LOB_BIAS, 0x88);
|
||||
b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_LOB_BIAS, 0x88);
|
||||
b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXG_CMFB_IDAC, 0x00);
|
||||
b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXG_CMFB_IDAC, 0x00);
|
||||
|
||||
/* N PHY WAR TX Chain Update with hw_phytxchain as argument */
|
||||
|
||||
if ((sprom->boardflags2_lo & B43_BFL2_APLL_WAR &&
|
||||
b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ||
|
||||
(sprom->boardflags2_lo & B43_BFL2_GPLL_WAR &&
|
||||
b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ))
|
||||
tmp32 = 0x00088888;
|
||||
else
|
||||
tmp32 = 0x88888888;
|
||||
b43_ntab_write(dev, B43_NTAB32(30, 1), tmp32);
|
||||
b43_ntab_write(dev, B43_NTAB32(30, 2), tmp32);
|
||||
b43_ntab_write(dev, B43_NTAB32(30, 3), tmp32);
|
||||
|
||||
if (dev->phy.rev == 4 &&
|
||||
b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
|
||||
b43_radio_write(dev, B2056_TX0 | B2056_TX_GMBB_IDAC,
|
||||
0x70);
|
||||
b43_radio_write(dev, B2056_TX1 | B2056_TX_GMBB_IDAC,
|
||||
0x70);
|
||||
}
|
||||
|
||||
b43_phy_write(dev, 0x224, 0x039C);
|
||||
b43_phy_write(dev, 0x225, 0x0357);
|
||||
b43_phy_write(dev, 0x226, 0x0317);
|
||||
b43_phy_write(dev, 0x227, 0x02D7);
|
||||
b43_phy_write(dev, 0x228, 0x039C);
|
||||
b43_phy_write(dev, 0x229, 0x0357);
|
||||
b43_phy_write(dev, 0x22A, 0x0317);
|
||||
b43_phy_write(dev, 0x22B, 0x02D7);
|
||||
b43_phy_write(dev, 0x22C, 0x039C);
|
||||
b43_phy_write(dev, 0x22D, 0x0357);
|
||||
b43_phy_write(dev, 0x22E, 0x0317);
|
||||
b43_phy_write(dev, 0x22F, 0x02D7);
|
||||
}
|
||||
|
||||
static void b43_nphy_workarounds_rev1_2(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
@ -1379,8 +1610,81 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
|
||||
u8 events2[7] = { 0x0, 0x3, 0x5, 0x4, 0x2, 0x1, 0x8 };
|
||||
u8 delays2[7] = { 0x8, 0x6, 0x2, 0x4, 0x4, 0x6, 0x1 };
|
||||
|
||||
u16 tmp16;
|
||||
u32 tmp32;
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ &&
|
||||
nphy->band5g_pwrgain) {
|
||||
b43_radio_mask(dev, B2055_C1_TX_RF_SPARE, ~0x8);
|
||||
b43_radio_mask(dev, B2055_C2_TX_RF_SPARE, ~0x8);
|
||||
} else {
|
||||
b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8);
|
||||
b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8);
|
||||
}
|
||||
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0x000A);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0x000A);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA);
|
||||
|
||||
if (dev->phy.rev < 2) {
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0x0000);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0x0000);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x0800);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x0800);
|
||||
}
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
|
||||
b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301);
|
||||
b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
|
||||
b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
|
||||
|
||||
if (sprom->boardflags2_lo & B43_BFL2_SKWRKFEM_BRD &&
|
||||
dev->dev->board_type == 0x8B) {
|
||||
delays1[0] = 0x1;
|
||||
delays1[5] = 0x14;
|
||||
}
|
||||
b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7);
|
||||
b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7);
|
||||
|
||||
b43_nphy_gain_ctrl_workarounds(dev);
|
||||
|
||||
if (dev->phy.rev < 2) {
|
||||
if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2)
|
||||
b43_hf_write(dev, b43_hf_read(dev) |
|
||||
B43_HF_MLADVW);
|
||||
} else if (dev->phy.rev == 2) {
|
||||
b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0);
|
||||
b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0);
|
||||
}
|
||||
|
||||
if (dev->phy.rev < 2)
|
||||
b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL,
|
||||
~B43_NPHY_SCRAM_SIGCTL_SCM);
|
||||
|
||||
/* Set phase track alpha and beta */
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20);
|
||||
|
||||
b43_phy_mask(dev, B43_NPHY_PIL_DW1,
|
||||
~B43_NPHY_PIL_DW_64QAM & 0xFFFF);
|
||||
b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5);
|
||||
b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4);
|
||||
b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00);
|
||||
|
||||
if (dev->phy.rev == 2)
|
||||
b43_phy_set(dev, B43_NPHY_FINERX2_CGC,
|
||||
B43_NPHY_FINERX2_CGC_DECGC);
|
||||
}
|
||||
|
||||
/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */
|
||||
static void b43_nphy_workarounds(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
struct b43_phy_n *nphy = phy->n;
|
||||
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
|
||||
b43_nphy_classifier(dev, 1, 0);
|
||||
@ -1393,153 +1697,10 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
|
||||
b43_phy_set(dev, B43_NPHY_IQFLIP,
|
||||
B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2);
|
||||
|
||||
if (dev->phy.rev >= 3) {
|
||||
tmp32 = b43_ntab_read(dev, B43_NTAB32(30, 0));
|
||||
tmp32 &= 0xffffff;
|
||||
b43_ntab_write(dev, B43_NTAB32(30, 0), tmp32);
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x0125);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x01B3);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x0105);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x016E);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0x00CD);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x0020);
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_C2_CLIP1_MEDGAIN, 0x000C);
|
||||
b43_phy_write(dev, 0x2AE, 0x000C);
|
||||
|
||||
/* TODO */
|
||||
|
||||
tmp16 = (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ?
|
||||
0x2 : 0x9C40;
|
||||
b43_phy_write(dev, B43_NPHY_ENDROP_TLEN, tmp16);
|
||||
|
||||
b43_phy_maskset(dev, 0x294, 0xF0FF, 0x0700);
|
||||
|
||||
b43_ntab_write(dev, B43_NTAB32(16, 3), 0x18D);
|
||||
b43_ntab_write(dev, B43_NTAB32(16, 127), 0x18D);
|
||||
|
||||
b43_nphy_gain_ctrl_workarounds(dev);
|
||||
|
||||
b43_ntab_write(dev, B43_NTAB32(8, 0), 2);
|
||||
b43_ntab_write(dev, B43_NTAB32(8, 16), 2);
|
||||
|
||||
/* TODO */
|
||||
|
||||
b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_MAST_BIAS, 0x00);
|
||||
b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_MAST_BIAS, 0x00);
|
||||
b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_MAIN, 0x06);
|
||||
b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_MAIN, 0x06);
|
||||
b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_BIAS_AUX, 0x07);
|
||||
b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_BIAS_AUX, 0x07);
|
||||
b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXA_LOB_BIAS, 0x88);
|
||||
b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXA_LOB_BIAS, 0x88);
|
||||
b43_radio_write(dev, B2056_RX0 | B2056_RX_MIXG_CMFB_IDAC, 0x00);
|
||||
b43_radio_write(dev, B2056_RX1 | B2056_RX_MIXG_CMFB_IDAC, 0x00);
|
||||
|
||||
/* N PHY WAR TX Chain Update with hw_phytxchain as argument */
|
||||
|
||||
if ((sprom->boardflags2_lo & B43_BFL2_APLL_WAR &&
|
||||
b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ||
|
||||
(sprom->boardflags2_lo & B43_BFL2_GPLL_WAR &&
|
||||
b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ))
|
||||
tmp32 = 0x00088888;
|
||||
else
|
||||
tmp32 = 0x88888888;
|
||||
b43_ntab_write(dev, B43_NTAB32(30, 1), tmp32);
|
||||
b43_ntab_write(dev, B43_NTAB32(30, 2), tmp32);
|
||||
b43_ntab_write(dev, B43_NTAB32(30, 3), tmp32);
|
||||
|
||||
if (dev->phy.rev == 4 &&
|
||||
b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
|
||||
b43_radio_write(dev, B2056_TX0 | B2056_TX_GMBB_IDAC,
|
||||
0x70);
|
||||
b43_radio_write(dev, B2056_TX1 | B2056_TX_GMBB_IDAC,
|
||||
0x70);
|
||||
}
|
||||
|
||||
b43_phy_write(dev, 0x224, 0x039C);
|
||||
b43_phy_write(dev, 0x225, 0x0357);
|
||||
b43_phy_write(dev, 0x226, 0x0317);
|
||||
b43_phy_write(dev, 0x227, 0x02D7);
|
||||
b43_phy_write(dev, 0x228, 0x039C);
|
||||
b43_phy_write(dev, 0x229, 0x0357);
|
||||
b43_phy_write(dev, 0x22A, 0x0317);
|
||||
b43_phy_write(dev, 0x22B, 0x02D7);
|
||||
b43_phy_write(dev, 0x22C, 0x039C);
|
||||
b43_phy_write(dev, 0x22D, 0x0357);
|
||||
b43_phy_write(dev, 0x22E, 0x0317);
|
||||
b43_phy_write(dev, 0x22F, 0x02D7);
|
||||
} else {
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ &&
|
||||
nphy->band5g_pwrgain) {
|
||||
b43_radio_mask(dev, B2055_C1_TX_RF_SPARE, ~0x8);
|
||||
b43_radio_mask(dev, B2055_C2_TX_RF_SPARE, ~0x8);
|
||||
} else {
|
||||
b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8);
|
||||
b43_radio_set(dev, B2055_C2_TX_RF_SPARE, 0x8);
|
||||
}
|
||||
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0x000A);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0x000A);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA);
|
||||
|
||||
if (dev->phy.rev < 2) {
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0x0000);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0x0000);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x0800);
|
||||
b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x0800);
|
||||
}
|
||||
|
||||
b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8);
|
||||
b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301);
|
||||
b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8);
|
||||
b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301);
|
||||
|
||||
if (sprom->boardflags2_lo & 0x100 &&
|
||||
dev->dev->board_type == 0x8B) {
|
||||
delays1[0] = 0x1;
|
||||
delays1[5] = 0x14;
|
||||
}
|
||||
b43_nphy_set_rf_sequence(dev, 0, events1, delays1, 7);
|
||||
b43_nphy_set_rf_sequence(dev, 1, events2, delays2, 7);
|
||||
|
||||
b43_nphy_gain_ctrl_workarounds(dev);
|
||||
|
||||
if (dev->phy.rev < 2) {
|
||||
if (b43_phy_read(dev, B43_NPHY_RXCTL) & 0x2)
|
||||
b43_hf_write(dev, b43_hf_read(dev) |
|
||||
B43_HF_MLADVW);
|
||||
} else if (dev->phy.rev == 2) {
|
||||
b43_phy_write(dev, B43_NPHY_CRSCHECK2, 0);
|
||||
b43_phy_write(dev, B43_NPHY_CRSCHECK3, 0);
|
||||
}
|
||||
|
||||
if (dev->phy.rev < 2)
|
||||
b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL,
|
||||
~B43_NPHY_SCRAM_SIGCTL_SCM);
|
||||
|
||||
/* Set phase track alpha and beta */
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD);
|
||||
b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20);
|
||||
|
||||
b43_phy_mask(dev, B43_NPHY_PIL_DW1,
|
||||
~B43_NPHY_PIL_DW_64QAM & 0xFFFF);
|
||||
b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B1, 0xB5);
|
||||
b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B2, 0xA4);
|
||||
b43_phy_write(dev, B43_NPHY_TXF_20CO_S2B3, 0x00);
|
||||
|
||||
if (dev->phy.rev == 2)
|
||||
b43_phy_set(dev, B43_NPHY_FINERX2_CGC,
|
||||
B43_NPHY_FINERX2_CGC_DECGC);
|
||||
}
|
||||
if (dev->phy.rev >= 3)
|
||||
b43_nphy_workarounds_rev3plus(dev);
|
||||
else
|
||||
b43_nphy_workarounds_rev1_2(dev);
|
||||
|
||||
if (nphy->hang_avoid)
|
||||
b43_nphy_stay_in_carrier_search(dev, 0);
|
||||
@ -2135,7 +2296,6 @@ static void b43_nphy_rev2_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
|
||||
|
||||
static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
|
||||
{
|
||||
struct b43_phy_n *nphy = dev->phy.n;
|
||||
u8 i;
|
||||
u16 reg, val;
|
||||
|
||||
@ -2199,10 +2359,7 @@ static void b43_nphy_rev3_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
|
||||
enum ieee80211_band band =
|
||||
b43_current_band(dev->wl);
|
||||
|
||||
if ((nphy->ipa2g_on &&
|
||||
band == IEEE80211_BAND_2GHZ) ||
|
||||
(nphy->ipa5g_on &&
|
||||
band == IEEE80211_BAND_5GHZ))
|
||||
if (b43_nphy_ipa(dev))
|
||||
val = (band == IEEE80211_BAND_5GHZ) ? 0xC : 0xE;
|
||||
else
|
||||
val = 0x11;
|
||||
@ -2577,8 +2734,8 @@ static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev)
|
||||
{
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
|
||||
if (dev->phy.rev >= 6) {
|
||||
/* TODO If the chip is 47162
|
||||
return txpwrctrl_tx_gain_ipa_rev5 */
|
||||
if (dev->dev->chip_id == 47162)
|
||||
return txpwrctrl_tx_gain_ipa_rev5;
|
||||
return txpwrctrl_tx_gain_ipa_rev6;
|
||||
} else if (dev->phy.rev >= 5) {
|
||||
return txpwrctrl_tx_gain_ipa_rev5;
|
||||
@ -2828,10 +2985,7 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
|
||||
enum ieee80211_band band =
|
||||
b43_current_band(dev->wl);
|
||||
|
||||
if ((nphy->ipa2g_on &&
|
||||
band == IEEE80211_BAND_2GHZ) ||
|
||||
(nphy->ipa5g_on &&
|
||||
band == IEEE80211_BAND_5GHZ)) {
|
||||
if (b43_nphy_ipa(dev)) {
|
||||
table = b43_nphy_get_ipa_gain_table(dev);
|
||||
} else {
|
||||
if (band == IEEE80211_BAND_5GHZ) {
|
||||
@ -3648,7 +3802,7 @@ int b43_phy_initn(struct b43_wldev *dev)
|
||||
b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20);
|
||||
b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20);
|
||||
|
||||
if (sprom->boardflags2_lo & 0x100 ||
|
||||
if (sprom->boardflags2_lo & B43_BFL2_SKWRKFEM_BRD ||
|
||||
(dev->dev->board_vendor == PCI_VENDOR_ID_APPLE &&
|
||||
dev->dev->board_type == 0x8B))
|
||||
b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0);
|
||||
@ -3667,8 +3821,7 @@ int b43_phy_initn(struct b43_wldev *dev)
|
||||
}
|
||||
|
||||
tmp2 = b43_current_band(dev->wl);
|
||||
if ((nphy->ipa2g_on && tmp2 == IEEE80211_BAND_2GHZ) ||
|
||||
(nphy->ipa5g_on && tmp2 == IEEE80211_BAND_5GHZ)) {
|
||||
if (b43_nphy_ipa(dev)) {
|
||||
b43_phy_set(dev, B43_NPHY_PAPD_EN0, 0x1);
|
||||
b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ0, 0x007F,
|
||||
nphy->papd_epsilon_offset[0] << 7);
|
||||
@ -3706,15 +3859,7 @@ int b43_phy_initn(struct b43_wldev *dev)
|
||||
b43_nphy_tx_power_fix(dev);
|
||||
/* TODO N PHY TX Power Control Idle TSSI */
|
||||
/* TODO N PHY TX Power Control Setup */
|
||||
|
||||
if (phy->rev >= 3) {
|
||||
/* TODO */
|
||||
} else {
|
||||
b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128,
|
||||
b43_ntab_tx_gain_rev0_1_2);
|
||||
b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128,
|
||||
b43_ntab_tx_gain_rev0_1_2);
|
||||
}
|
||||
b43_nphy_tx_gain_table_upload(dev);
|
||||
|
||||
if (nphy->phyrxchain != 3)
|
||||
b43_nphy_set_rx_core_state(dev, nphy->phyrxchain);
|
||||
@ -3918,6 +4063,10 @@ static void b43_nphy_op_prepare_structs(struct b43_wldev *dev)
|
||||
nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */
|
||||
nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */
|
||||
nphy->perical = 2; /* avoid additional rssi cal on init (like wl) */
|
||||
/* 128 can mean disabled-by-default state of TX pwr ctl. Max value is
|
||||
* 0x7f == 127 and we check for 128 when restoring TX pwr ctl. */
|
||||
nphy->tx_pwr_idx[0] = 128;
|
||||
nphy->tx_pwr_idx[1] = 128;
|
||||
}
|
||||
|
||||
static void b43_nphy_op_free(struct b43_wldev *dev)
|
||||
|
@ -764,6 +764,8 @@ struct b43_phy_n {
|
||||
u8 cal_orig_pwr_idx[2];
|
||||
u8 measure_hold;
|
||||
u8 phyrxchain;
|
||||
u8 hw_phyrxchain;
|
||||
u8 hw_phytxchain;
|
||||
u8 perical;
|
||||
u32 deaf_count;
|
||||
u32 rxcalparams;
|
||||
@ -783,6 +785,8 @@ struct b43_phy_n {
|
||||
u16 mphase_txcal_bestcoeffs[11];
|
||||
|
||||
bool txpwrctrl;
|
||||
u8 tx_pwr_idx[2];
|
||||
u16 adj_pwr_tbl[84];
|
||||
u16 txcal_bbmult;
|
||||
u16 txiqlocal_bestc[11];
|
||||
bool txiqlocal_coeffsvalid;
|
||||
|
@ -4,6 +4,7 @@
|
||||
IEEE 802.11n PHY and radio device data tables
|
||||
|
||||
Copyright (c) 2008 Michael Buesch <m@bues.ch>
|
||||
Copyright (c) 2010 Rafał Miłecki <zajec5@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -3,6 +3,8 @@
|
||||
Broadcom B43 wireless driver
|
||||
IEEE 802.11n 2056 radio device data tables
|
||||
|
||||
Copyright (c) 2010 Rafał Miłecki <zajec5@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
|
@ -1,29 +1,3 @@
|
||||
/*
|
||||
|
||||
Broadcom B43 wireless driver
|
||||
|
||||
Copyright (c) 2010 Rafał Miłecki <zajec5@gmail.com>
|
||||
|
||||
Some parts of the code in this file are derived from the brcm80211
|
||||
driver Copyright (c) 2010 Broadcom Corporation
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef B43_RADIO_2056_H_
|
||||
#define B43_RADIO_2056_H_
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
Broadcom B43 wireless driver
|
||||
IEEE 802.11n 2059 radio device data tables
|
||||
|
||||
Copyright (c) 2011 Rafał Miłecki <zajec5@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
|
@ -4,6 +4,7 @@
|
||||
IEEE 802.11n PHY data tables
|
||||
|
||||
Copyright (c) 2008 Michael Buesch <m@bues.ch>
|
||||
Copyright (c) 2010 Rafał Miłecki <zajec5@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -3,6 +3,8 @@
|
||||
Broadcom B43 wireless driver
|
||||
IEEE 802.11n HT-PHY data tables
|
||||
|
||||
Copyright (c) 2011 Rafał Miłecki <zajec5@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
|
@ -3,6 +3,8 @@
|
||||
Broadcom B43 wireless driver
|
||||
IEEE 802.11n LCN-PHY data tables
|
||||
|
||||
Copyright (c) 2011 Rafał Miłecki <zajec5@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
@ -25,6 +27,18 @@
|
||||
#include "phy_common.h"
|
||||
#include "phy_lcn.h"
|
||||
|
||||
struct b43_lcntab_tx_gain_tbl_entry {
|
||||
u8 gm;
|
||||
u8 pga;
|
||||
u8 pad;
|
||||
u8 dac;
|
||||
u8 bb_mult;
|
||||
};
|
||||
|
||||
/**************************************************
|
||||
* Static tables.
|
||||
**************************************************/
|
||||
|
||||
static const u16 b43_lcntab_0x02[] = {
|
||||
0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
|
||||
0x014d, 0x014d, 0x014d, 0x014d, 0x014d, 0x014d,
|
||||
@ -295,6 +309,160 @@ static const u32 b43_lcntab_0x18[] = {
|
||||
0x00080000, 0x00080000, 0x00080000, 0x00080000,
|
||||
};
|
||||
|
||||
/**************************************************
|
||||
* TX gain.
|
||||
**************************************************/
|
||||
|
||||
const struct b43_lcntab_tx_gain_tbl_entry
|
||||
b43_lcntab_tx_gain_tbl_2ghz_ext_pa_rev0[B43_LCNTAB_TX_GAIN_SIZE] = {
|
||||
{ 0x03, 0x00, 0x1f, 0x0, 0x48 },
|
||||
{ 0x03, 0x00, 0x1f, 0x0, 0x46 },
|
||||
{ 0x03, 0x00, 0x1f, 0x0, 0x44 },
|
||||
{ 0x03, 0x00, 0x1e, 0x0, 0x43 },
|
||||
{ 0x03, 0x00, 0x1d, 0x0, 0x44 },
|
||||
{ 0x03, 0x00, 0x1c, 0x0, 0x44 },
|
||||
{ 0x03, 0x00, 0x1b, 0x0, 0x45 },
|
||||
{ 0x03, 0x00, 0x1a, 0x0, 0x46 },
|
||||
{ 0x03, 0x00, 0x19, 0x0, 0x46 },
|
||||
{ 0x03, 0x00, 0x18, 0x0, 0x47 },
|
||||
{ 0x03, 0x00, 0x17, 0x0, 0x48 },
|
||||
{ 0x03, 0x00, 0x17, 0x0, 0x46 },
|
||||
{ 0x03, 0x00, 0x16, 0x0, 0x47 },
|
||||
{ 0x03, 0x00, 0x15, 0x0, 0x48 },
|
||||
{ 0x03, 0x00, 0x15, 0x0, 0x46 },
|
||||
{ 0x03, 0x00, 0x15, 0x0, 0x44 },
|
||||
{ 0x03, 0x00, 0x15, 0x0, 0x42 },
|
||||
{ 0x03, 0x00, 0x15, 0x0, 0x40 },
|
||||
{ 0x03, 0x00, 0x15, 0x0, 0x3f },
|
||||
{ 0x03, 0x00, 0x14, 0x0, 0x40 },
|
||||
{ 0x03, 0x00, 0x13, 0x0, 0x41 },
|
||||
{ 0x03, 0x00, 0x13, 0x0, 0x40 },
|
||||
{ 0x03, 0x00, 0x12, 0x0, 0x41 },
|
||||
{ 0x03, 0x00, 0x12, 0x0, 0x40 },
|
||||
{ 0x03, 0x00, 0x11, 0x0, 0x41 },
|
||||
{ 0x03, 0x00, 0x11, 0x0, 0x40 },
|
||||
{ 0x03, 0x00, 0x10, 0x0, 0x41 },
|
||||
{ 0x03, 0x00, 0x10, 0x0, 0x40 },
|
||||
{ 0x03, 0x00, 0x10, 0x0, 0x3e },
|
||||
{ 0x03, 0x00, 0x10, 0x0, 0x3c },
|
||||
{ 0x03, 0x00, 0x10, 0x0, 0x3a },
|
||||
{ 0x03, 0x00, 0x0f, 0x0, 0x3d },
|
||||
{ 0x03, 0x00, 0x0f, 0x0, 0x3b },
|
||||
{ 0x03, 0x00, 0x0e, 0x0, 0x3d },
|
||||
{ 0x03, 0x00, 0x0e, 0x0, 0x3c },
|
||||
{ 0x03, 0x00, 0x0e, 0x0, 0x3a },
|
||||
{ 0x03, 0x00, 0x0d, 0x0, 0x3c },
|
||||
{ 0x03, 0x00, 0x0d, 0x0, 0x3b },
|
||||
{ 0x03, 0x00, 0x0c, 0x0, 0x3e },
|
||||
{ 0x03, 0x00, 0x0c, 0x0, 0x3c },
|
||||
{ 0x03, 0x00, 0x0c, 0x0, 0x3a },
|
||||
{ 0x03, 0x00, 0x0b, 0x0, 0x3e },
|
||||
{ 0x03, 0x00, 0x0b, 0x0, 0x3c },
|
||||
{ 0x03, 0x00, 0x0b, 0x0, 0x3b },
|
||||
{ 0x03, 0x00, 0x0b, 0x0, 0x39 },
|
||||
{ 0x03, 0x00, 0x0a, 0x0, 0x3d },
|
||||
{ 0x03, 0x00, 0x0a, 0x0, 0x3b },
|
||||
{ 0x03, 0x00, 0x0a, 0x0, 0x39 },
|
||||
{ 0x03, 0x00, 0x09, 0x0, 0x3e },
|
||||
{ 0x03, 0x00, 0x09, 0x0, 0x3c },
|
||||
{ 0x03, 0x00, 0x09, 0x0, 0x3a },
|
||||
{ 0x03, 0x00, 0x09, 0x0, 0x39 },
|
||||
{ 0x03, 0x00, 0x08, 0x0, 0x3e },
|
||||
{ 0x03, 0x00, 0x08, 0x0, 0x3c },
|
||||
{ 0x03, 0x00, 0x08, 0x0, 0x3a },
|
||||
{ 0x03, 0x00, 0x08, 0x0, 0x39 },
|
||||
{ 0x03, 0x00, 0x08, 0x0, 0x37 },
|
||||
{ 0x03, 0x00, 0x07, 0x0, 0x3d },
|
||||
{ 0x03, 0x00, 0x07, 0x0, 0x3c },
|
||||
{ 0x03, 0x00, 0x07, 0x0, 0x3a },
|
||||
{ 0x03, 0x00, 0x07, 0x0, 0x38 },
|
||||
{ 0x03, 0x00, 0x07, 0x0, 0x37 },
|
||||
{ 0x03, 0x00, 0x06, 0x0, 0x3e },
|
||||
{ 0x03, 0x00, 0x06, 0x0, 0x3c },
|
||||
{ 0x03, 0x00, 0x06, 0x0, 0x3a },
|
||||
{ 0x03, 0x00, 0x06, 0x0, 0x39 },
|
||||
{ 0x03, 0x00, 0x06, 0x0, 0x37 },
|
||||
{ 0x03, 0x00, 0x06, 0x0, 0x36 },
|
||||
{ 0x03, 0x00, 0x06, 0x0, 0x34 },
|
||||
{ 0x03, 0x00, 0x05, 0x0, 0x3d },
|
||||
{ 0x03, 0x00, 0x05, 0x0, 0x3b },
|
||||
{ 0x03, 0x00, 0x05, 0x0, 0x39 },
|
||||
{ 0x03, 0x00, 0x05, 0x0, 0x38 },
|
||||
{ 0x03, 0x00, 0x05, 0x0, 0x36 },
|
||||
{ 0x03, 0x00, 0x05, 0x0, 0x35 },
|
||||
{ 0x03, 0x00, 0x05, 0x0, 0x33 },
|
||||
{ 0x03, 0x00, 0x04, 0x0, 0x3e },
|
||||
{ 0x03, 0x00, 0x04, 0x0, 0x3c },
|
||||
{ 0x03, 0x00, 0x04, 0x0, 0x3a },
|
||||
{ 0x03, 0x00, 0x04, 0x0, 0x39 },
|
||||
{ 0x03, 0x00, 0x04, 0x0, 0x37 },
|
||||
{ 0x03, 0x00, 0x04, 0x0, 0x36 },
|
||||
{ 0x03, 0x00, 0x04, 0x0, 0x34 },
|
||||
{ 0x03, 0x00, 0x04, 0x0, 0x33 },
|
||||
{ 0x03, 0x00, 0x04, 0x0, 0x31 },
|
||||
{ 0x03, 0x00, 0x04, 0x0, 0x30 },
|
||||
{ 0x03, 0x00, 0x04, 0x0, 0x2e },
|
||||
{ 0x03, 0x00, 0x03, 0x0, 0x3c },
|
||||
{ 0x03, 0x00, 0x03, 0x0, 0x3a },
|
||||
{ 0x03, 0x00, 0x03, 0x0, 0x39 },
|
||||
{ 0x03, 0x00, 0x03, 0x0, 0x37 },
|
||||
{ 0x03, 0x00, 0x03, 0x0, 0x36 },
|
||||
{ 0x03, 0x00, 0x03, 0x0, 0x34 },
|
||||
{ 0x03, 0x00, 0x03, 0x0, 0x33 },
|
||||
{ 0x03, 0x00, 0x03, 0x0, 0x31 },
|
||||
{ 0x03, 0x00, 0x03, 0x0, 0x30 },
|
||||
{ 0x03, 0x00, 0x03, 0x0, 0x2e },
|
||||
{ 0x03, 0x00, 0x03, 0x0, 0x2d },
|
||||
{ 0x03, 0x00, 0x03, 0x0, 0x2c },
|
||||
{ 0x03, 0x00, 0x03, 0x0, 0x2b },
|
||||
{ 0x03, 0x00, 0x03, 0x0, 0x29 },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x3d },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x3b },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x39 },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x38 },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x36 },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x35 },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x33 },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x32 },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x30 },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x2f },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x2e },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x2c },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x2b },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x2a },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x29 },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x27 },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x26 },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x25 },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x24 },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x23 },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x22 },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x21 },
|
||||
{ 0x03, 0x00, 0x02, 0x0, 0x20 },
|
||||
{ 0x03, 0x00, 0x01, 0x0, 0x3f },
|
||||
{ 0x03, 0x00, 0x01, 0x0, 0x3d },
|
||||
{ 0x03, 0x00, 0x01, 0x0, 0x3b },
|
||||
{ 0x03, 0x00, 0x01, 0x0, 0x39 },
|
||||
};
|
||||
|
||||
/**************************************************
|
||||
* SW control.
|
||||
**************************************************/
|
||||
|
||||
const u16 b43_lcntab_sw_ctl_4313_epa_rev0[] = {
|
||||
0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
|
||||
0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
|
||||
0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
|
||||
0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
|
||||
0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
|
||||
0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
|
||||
0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
|
||||
0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
|
||||
0x0002, 0x0008, 0x0004, 0x0001, 0x0002, 0x0008,
|
||||
0x0004, 0x0001, 0x0002, 0x0008, 0x0004, 0x0001,
|
||||
0x0002, 0x0008, 0x0004, 0x0001,
|
||||
};
|
||||
|
||||
/**************************************************
|
||||
* R/W ops.
|
||||
**************************************************/
|
||||
@ -318,9 +486,8 @@ u32 b43_lcntab_read(struct b43_wldev *dev, u32 offset)
|
||||
break;
|
||||
case B43_LCNTAB_32BIT:
|
||||
b43_phy_write(dev, B43_PHY_LCN_TABLE_ADDR, offset);
|
||||
value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATAHI);
|
||||
value <<= 16;
|
||||
value |= b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO);
|
||||
value = b43_phy_read(dev, B43_PHY_LCN_TABLE_DATALO);
|
||||
value |= (b43_phy_read(dev, B43_PHY_LCN_TABLE_DATAHI) << 16);
|
||||
break;
|
||||
default:
|
||||
B43_WARN_ON(1);
|
||||
@ -357,10 +524,9 @@ void b43_lcntab_read_bulk(struct b43_wldev *dev, u32 offset,
|
||||
break;
|
||||
case B43_LCNTAB_32BIT:
|
||||
*((u32 *)data) = b43_phy_read(dev,
|
||||
B43_PHY_LCN_TABLE_DATAHI);
|
||||
*((u32 *)data) <<= 16;
|
||||
*((u32 *)data) |= b43_phy_read(dev,
|
||||
B43_PHY_LCN_TABLE_DATALO);
|
||||
*((u32 *)data) |= (b43_phy_read(dev,
|
||||
B43_PHY_LCN_TABLE_DATAHI) << 16);
|
||||
data += 4;
|
||||
break;
|
||||
default:
|
||||
@ -447,7 +613,7 @@ void b43_lcntab_write_bulk(struct b43_wldev *dev, u32 offset,
|
||||
#define lcntab_upload(dev, offset, data) do { \
|
||||
b43_lcntab_write_bulk(dev, offset, ARRAY_SIZE(data), data); \
|
||||
} while (0)
|
||||
void b43_phy_lcn_tables_init(struct b43_wldev *dev)
|
||||
static void b43_phy_lcn_upload_static_tables(struct b43_wldev *dev)
|
||||
{
|
||||
lcntab_upload(dev, B43_LCNTAB16(0x02, 0), b43_lcntab_0x02);
|
||||
lcntab_upload(dev, B43_LCNTAB16(0x01, 0), b43_lcntab_0x01);
|
||||
@ -464,3 +630,78 @@ void b43_phy_lcn_tables_init(struct b43_wldev *dev)
|
||||
lcntab_upload(dev, B43_LCNTAB16(0x00, 0), b43_lcntab_0x00);
|
||||
lcntab_upload(dev, B43_LCNTAB32(0x18, 0), b43_lcntab_0x18);
|
||||
}
|
||||
|
||||
void b43_phy_lcn_load_tx_gain_tab(struct b43_wldev *dev,
|
||||
const struct b43_lcntab_tx_gain_tbl_entry *gain_table)
|
||||
{
|
||||
u32 i;
|
||||
u32 val;
|
||||
|
||||
u16 pa_gain = 0x70;
|
||||
if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_FEM)
|
||||
pa_gain = 0x10;
|
||||
|
||||
for (i = 0; i < B43_LCNTAB_TX_GAIN_SIZE; i++) {
|
||||
val = ((pa_gain << 24) |
|
||||
(gain_table[i].pad << 16) |
|
||||
(gain_table[i].pga << 8) |
|
||||
gain_table[i].gm);
|
||||
b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0xc0 + i), val);
|
||||
|
||||
/* brcmsmac doesn't maskset, we follow newer wl here */
|
||||
val = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x140 + i));
|
||||
val &= 0x000fffff;
|
||||
val |= ((gain_table[i].dac << 28) |
|
||||
(gain_table[i].bb_mult << 20));
|
||||
b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x140 + i), val);
|
||||
}
|
||||
}
|
||||
|
||||
/* Not implemented in brcmsmac, noticed in wl in MMIO dump */
|
||||
static void b43_phy_lcn_rewrite_tables(struct b43_wldev *dev)
|
||||
{
|
||||
int i;
|
||||
u32 tmp;
|
||||
for (i = 0; i < 128; i++) {
|
||||
tmp = b43_lcntab_read(dev, B43_LCNTAB32(0x7, 0x240 + i));
|
||||
b43_lcntab_write(dev, B43_LCNTAB32(0x7, 0x240 + i), tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/* wlc_lcnphy_clear_papd_comptable */
|
||||
static void b43_phy_lcn_clean_papd_comp_table(struct b43_wldev *dev)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
for (i = 0; i < 0x80; i++)
|
||||
b43_lcntab_write(dev, B43_LCNTAB32(0x18, i), 0x80000);
|
||||
}
|
||||
|
||||
/* wlc_lcnphy_tbl_init */
|
||||
void b43_phy_lcn_tables_init(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_sprom *sprom = dev->dev->bus_sprom;
|
||||
|
||||
b43_phy_lcn_upload_static_tables(dev);
|
||||
|
||||
if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
|
||||
if (sprom->boardflags_lo & B43_BFL_EXTLNA)
|
||||
b43_phy_lcn_load_tx_gain_tab(dev,
|
||||
b43_lcntab_tx_gain_tbl_2ghz_ext_pa_rev0);
|
||||
else
|
||||
b43err(dev->wl,
|
||||
"TX gain table unknown for this card\n");
|
||||
}
|
||||
|
||||
if (sprom->boardflags_lo & B43_BFL_FEM &&
|
||||
!(sprom->boardflags_hi & B43_BFH_FEM_BT))
|
||||
b43_lcntab_write_bulk(dev, B43_LCNTAB16(0xf, 0),
|
||||
ARRAY_SIZE(b43_lcntab_sw_ctl_4313_epa_rev0),
|
||||
b43_lcntab_sw_ctl_4313_epa_rev0);
|
||||
else
|
||||
b43err(dev->wl, "SW ctl table is unknown for this card\n");
|
||||
|
||||
/* TODO: various tables ops here */
|
||||
b43_phy_lcn_rewrite_tables(dev);
|
||||
b43_phy_lcn_clean_papd_comp_table(dev);
|
||||
}
|
||||
|
@ -10,6 +10,8 @@
|
||||
#define B43_LCNTAB16(table, offset) (((table) << 10) | (offset) | B43_LCNTAB_16BIT)
|
||||
#define B43_LCNTAB32(table, offset) (((table) << 10) | (offset) | B43_LCNTAB_32BIT)
|
||||
|
||||
#define B43_LCNTAB_TX_GAIN_SIZE 128
|
||||
|
||||
u32 b43_lcntab_read(struct b43_wldev *dev, u32 offset);
|
||||
void b43_lcntab_read_bulk(struct b43_wldev *dev, u32 offset,
|
||||
unsigned int nr_elements, void *_data);
|
||||
|
@ -285,6 +285,7 @@ struct iwl_cfg iwl2000_2bg_cfg = {
|
||||
struct iwl_cfg iwl2000_2bgn_d_cfg = {
|
||||
.name = "2000D Series 2x2 BGN",
|
||||
IWL_DEVICE_2000,
|
||||
.ht_params = &iwl2000_ht_params,
|
||||
};
|
||||
|
||||
#define IWL_DEVICE_2030 \
|
||||
|
@ -659,7 +659,7 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
|
||||
IWL_SCD_BE_MSK | IWL_SCD_BK_MSK |
|
||||
IWL_SCD_MGMT_MSK;
|
||||
if ((flush_control & BIT(IWL_RXON_CTX_PAN)) &&
|
||||
(priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)))
|
||||
(priv->shrd->valid_contexts != BIT(IWL_RXON_CTX_BSS)))
|
||||
flush_cmd.fifo_control |= IWL_PAN_SCD_VO_MSK |
|
||||
IWL_PAN_SCD_VI_MSK | IWL_PAN_SCD_BE_MSK |
|
||||
IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK |
|
||||
|
@ -311,7 +311,7 @@ int iwlagn_set_pan_params(struct iwl_priv *priv)
|
||||
int slot0 = 300, slot1 = 0;
|
||||
int ret;
|
||||
|
||||
if (priv->valid_contexts == BIT(IWL_RXON_CTX_BSS))
|
||||
if (priv->shrd->valid_contexts == BIT(IWL_RXON_CTX_BSS))
|
||||
return 0;
|
||||
|
||||
BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
|
||||
@ -456,7 +456,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
|
||||
else
|
||||
ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
|
||||
|
||||
iwl_print_rx_config_cmd(priv, ctx);
|
||||
iwl_print_rx_config_cmd(priv, ctx->ctxid);
|
||||
ret = iwl_check_rxon_cmd(priv, ctx);
|
||||
if (ret) {
|
||||
IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
|
||||
|
@ -117,7 +117,6 @@ struct iwl_tt_mgmt {
|
||||
u8 iwl_tt_current_power_mode(struct iwl_priv *priv);
|
||||
bool iwl_tt_is_low_power_state(struct iwl_priv *priv);
|
||||
bool iwl_ht_enabled(struct iwl_priv *priv);
|
||||
bool iwl_check_for_ct_kill(struct iwl_priv *priv);
|
||||
enum iwl_antenna_ok iwl_tx_ant_restriction(struct iwl_priv *priv);
|
||||
enum iwl_antenna_ok iwl_rx_ant_restriction(struct iwl_priv *priv);
|
||||
void iwl_tt_enter_ct_kill(struct iwl_priv *priv);
|
||||
|
@ -741,7 +741,7 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
|
||||
int txq_id = SEQ_TO_QUEUE(sequence);
|
||||
int cmd_index = SEQ_TO_INDEX(sequence);
|
||||
int cmd_index __maybe_unused = SEQ_TO_INDEX(sequence);
|
||||
struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
|
||||
struct ieee80211_hdr *hdr;
|
||||
u32 status = le16_to_cpu(tx_resp->status.status);
|
||||
|
@ -114,7 +114,7 @@ static int iwlagn_load_section(struct iwl_priv *priv, const char *name,
|
||||
FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
|
||||
|
||||
IWL_DEBUG_FW(priv, "%s uCode section being loaded...\n", name);
|
||||
ret = wait_event_interruptible_timeout(priv->wait_command_queue,
|
||||
ret = wait_event_interruptible_timeout(priv->shrd->wait_command_queue,
|
||||
priv->ucode_write_complete, 5 * HZ);
|
||||
if (ret == -ERESTARTSYS) {
|
||||
IWL_ERR(priv, "Could not load the %s uCode section due "
|
||||
@ -349,6 +349,7 @@ int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
|
||||
|
||||
static int iwlagn_alive_notify(struct iwl_priv *priv)
|
||||
{
|
||||
struct iwl_rxon_context *ctx;
|
||||
int ret;
|
||||
|
||||
if (!priv->tx_cmd_pool)
|
||||
@ -361,6 +362,8 @@ static int iwlagn_alive_notify(struct iwl_priv *priv)
|
||||
return -ENOMEM;
|
||||
|
||||
iwl_trans_tx_start(trans(priv));
|
||||
for_each_context(priv, ctx)
|
||||
ctx->last_tx_rejected = false;
|
||||
|
||||
ret = iwlagn_send_wimax_coex(priv);
|
||||
if (ret)
|
||||
|
@ -623,9 +623,9 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags)
|
||||
* The default context is always valid,
|
||||
* the PAN context depends on uCode.
|
||||
*/
|
||||
priv->valid_contexts = BIT(IWL_RXON_CTX_BSS);
|
||||
priv->shrd->valid_contexts = BIT(IWL_RXON_CTX_BSS);
|
||||
if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN)
|
||||
priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
|
||||
priv->shrd->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
|
||||
|
||||
for (i = 0; i < NUM_IWL_RXON_CTX; i++)
|
||||
priv->contexts[i].ctxid = i;
|
||||
@ -2880,7 +2880,7 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw,
|
||||
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_PAN];
|
||||
int err = 0;
|
||||
|
||||
if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
|
||||
if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!(ctx->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)))
|
||||
@ -2945,7 +2945,7 @@ static int iwl_mac_cancel_remain_on_channel(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct iwl_priv *priv = hw->priv;
|
||||
|
||||
if (!(priv->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
|
||||
if (!(priv->shrd->valid_contexts & BIT(IWL_RXON_CTX_PAN)))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
mutex_lock(&priv->shrd->mutex);
|
||||
@ -3032,7 +3032,7 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
|
||||
{
|
||||
priv->shrd->workqueue = create_singlethread_workqueue(DRV_NAME);
|
||||
|
||||
init_waitqueue_head(&priv->wait_command_queue);
|
||||
init_waitqueue_head(&priv->shrd->wait_command_queue);
|
||||
|
||||
INIT_WORK(&priv->restart, iwl_bg_restart);
|
||||
INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
|
||||
|
@ -98,7 +98,6 @@ int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
|
||||
enum iwlagn_ucode_type ucode_type);
|
||||
|
||||
/* lib */
|
||||
int iwlagn_hw_valid_rtc_data_addr(u32 addr);
|
||||
int iwlagn_send_tx_power(struct iwl_priv *priv);
|
||||
void iwlagn_temperature(struct iwl_priv *priv);
|
||||
u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv);
|
||||
@ -109,7 +108,6 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
|
||||
/* rx */
|
||||
int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
|
||||
void iwl_setup_rx_handlers(struct iwl_priv *priv);
|
||||
void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
|
||||
|
||||
|
||||
/* tx */
|
||||
|
@ -3213,12 +3213,7 @@ enum iwl_ucode_calib_cfg {
|
||||
IWL_CALIB_CFG_LO_IDX | \
|
||||
IWL_CALIB_CFG_TX_IQ_IDX | \
|
||||
IWL_CALIB_CFG_RX_IQ_IDX | \
|
||||
IWL_CALIB_CFG_NOISE_IDX | \
|
||||
IWL_CALIB_CFG_CRYSTAL_IDX | \
|
||||
IWL_CALIB_CFG_TEMPERATURE_IDX | \
|
||||
IWL_CALIB_CFG_PAPD_IDX | \
|
||||
IWL_CALIB_CFG_SENSITIVITY_IDX | \
|
||||
IWL_CALIB_CFG_TX_PWR_IDX)
|
||||
IWL_CALIB_CFG_CRYSTAL_IDX)
|
||||
|
||||
#define IWL_CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_MSK cpu_to_le32(BIT(0))
|
||||
|
||||
|
@ -817,9 +817,9 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
void iwl_print_rx_config_cmd(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx)
|
||||
void iwl_print_rx_config_cmd(struct iwl_priv *priv, u8 ctxid)
|
||||
{
|
||||
struct iwl_rxon_context *ctx = &priv->contexts[ctxid];
|
||||
struct iwl_rxon_cmd *rxon = &ctx->staging;
|
||||
|
||||
IWL_DEBUG_RADIO(priv, "RX CONFIG:\n");
|
||||
@ -868,7 +868,7 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
|
||||
* commands by clearing the ready bit */
|
||||
clear_bit(STATUS_READY, &priv->shrd->status);
|
||||
|
||||
wake_up_interruptible(&priv->wait_command_queue);
|
||||
wake_up_interruptible(&priv->shrd->wait_command_queue);
|
||||
|
||||
if (!ondemand) {
|
||||
/*
|
||||
@ -1842,7 +1842,7 @@ void iwl_start_tx_ba_trans_ready(struct iwl_priv *priv,
|
||||
enum iwl_rxon_context_id ctx,
|
||||
u8 sta_id, u8 tid)
|
||||
{
|
||||
struct ieee80211_vif *vif = priv->contexts[ctx].vif;
|
||||
struct ieee80211_vif *vif;
|
||||
u8 *addr = priv->stations[sta_id].sta.sta.addr;
|
||||
|
||||
if (ctx == NUM_IWL_RXON_CTX)
|
||||
@ -1865,3 +1865,14 @@ void iwl_stop_tx_ba_trans_ready(struct iwl_priv *priv,
|
||||
|
||||
ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid);
|
||||
}
|
||||
|
||||
void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state)
|
||||
{
|
||||
wiphy_rfkill_set_hw_state(priv->hw->wiphy, state);
|
||||
}
|
||||
|
||||
void iwl_nic_config(struct iwl_priv *priv)
|
||||
{
|
||||
priv->cfg->lib->nic_config(priv);
|
||||
|
||||
}
|
||||
|
@ -73,8 +73,6 @@ struct iwl_cmd;
|
||||
|
||||
#define TIME_UNIT 1024
|
||||
|
||||
#define IWL_CMD(x) case x: return #x
|
||||
|
||||
struct iwl_lib_ops {
|
||||
/* set hw dependent parameters */
|
||||
int (*set_hw_params)(struct iwl_priv *priv);
|
||||
@ -271,7 +269,6 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw,
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
int iwl_alloc_traffic_mem(struct iwl_priv *priv);
|
||||
void iwl_free_traffic_mem(struct iwl_priv *priv);
|
||||
void iwl_reset_traffic_log(struct iwl_priv *priv);
|
||||
void iwl_dbg_log_tx_data_frame(struct iwl_priv *priv,
|
||||
u16 length, struct ieee80211_hdr *header);
|
||||
void iwl_dbg_log_rx_data_frame(struct iwl_priv *priv,
|
||||
@ -360,26 +357,12 @@ int __must_check iwl_scan_initiate(struct iwl_priv *priv,
|
||||
* S e n d i n g H o s t C o m m a n d s *
|
||||
*****************************************************/
|
||||
|
||||
const char *get_cmd_string(u8 cmd);
|
||||
void iwl_bg_watchdog(unsigned long data);
|
||||
u32 iwl_usecs_to_beacons(struct iwl_priv *priv, u32 usec, u32 beacon_interval);
|
||||
__le32 iwl_add_beacon_time(struct iwl_priv *priv, u32 base,
|
||||
u32 addon, u32 beacon_interval);
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* Error Handling Debugging
|
||||
******************************************************/
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
void iwl_print_rx_config_cmd(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx);
|
||||
#else
|
||||
static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv,
|
||||
struct iwl_rxon_context *ctx)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/*****************************************************
|
||||
* GEOS
|
||||
******************************************************/
|
||||
@ -389,8 +372,6 @@ void iwl_free_geos(struct iwl_priv *priv);
|
||||
extern void iwl_send_bt_config(struct iwl_priv *priv);
|
||||
extern int iwl_send_statistics_request(struct iwl_priv *priv,
|
||||
u8 flags, bool clear);
|
||||
void iwl_apm_stop(struct iwl_priv *priv);
|
||||
int iwl_apm_init(struct iwl_priv *priv);
|
||||
|
||||
int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
|
||||
|
||||
@ -408,7 +389,4 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv)
|
||||
|
||||
extern bool bt_siso_mode;
|
||||
|
||||
|
||||
void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand);
|
||||
|
||||
#endif /* __iwl_core_h__ */
|
||||
|
@ -439,4 +439,22 @@
|
||||
*/
|
||||
#define HBUS_TARG_WRPTR (HBUS_BASE+0x060)
|
||||
|
||||
/**********************************************************
|
||||
* CSR values
|
||||
**********************************************************/
|
||||
/*
|
||||
* host interrupt timeout value
|
||||
* used with setting interrupt coalescing timer
|
||||
* the CSR_INT_COALESCING is an 8 bit register in 32-usec unit
|
||||
*
|
||||
* default interrupt coalescing timer is 64 x 32 = 2048 usecs
|
||||
* default interrupt coalescing calibration timer is 16 x 32 = 512 usecs
|
||||
*/
|
||||
#define IWL_HOST_INT_TIMEOUT_MAX (0xFF)
|
||||
#define IWL_HOST_INT_TIMEOUT_DEF (0x40)
|
||||
#define IWL_HOST_INT_TIMEOUT_MIN (0x0)
|
||||
#define IWL_HOST_INT_CALIB_TIMEOUT_MAX (0xFF)
|
||||
#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10)
|
||||
#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0)
|
||||
|
||||
#endif /* !__iwl_csr_h__ */
|
||||
|
@ -804,6 +804,89 @@ DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
|
||||
DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override);
|
||||
DEBUGFS_READ_FILE_OPS(current_sleep_command);
|
||||
|
||||
static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_priv *priv = file->private_data;
|
||||
int pos = 0, ofs = 0;
|
||||
int cnt = 0, entry;
|
||||
|
||||
char *buf;
|
||||
int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
|
||||
(hw_params(priv).max_txq_num * 32 * 8) + 400;
|
||||
const u8 *ptr;
|
||||
ssize_t ret;
|
||||
|
||||
buf = kzalloc(bufsz, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
IWL_ERR(priv, "Can not allocate buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (priv->tx_traffic &&
|
||||
(iwl_get_debug_level(priv->shrd) & IWL_DL_TX)) {
|
||||
ptr = priv->tx_traffic;
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"Tx Traffic idx: %u\n", priv->tx_traffic_idx);
|
||||
for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
|
||||
for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
|
||||
entry++, ofs += 16) {
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"0x%.4x ", ofs);
|
||||
hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
|
||||
buf + pos, bufsz - pos, 0);
|
||||
pos += strlen(buf + pos);
|
||||
if (bufsz - pos > 0)
|
||||
buf[pos++] = '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (priv->rx_traffic &&
|
||||
(iwl_get_debug_level(priv->shrd) & IWL_DL_RX)) {
|
||||
ptr = priv->rx_traffic;
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"Rx Traffic idx: %u\n", priv->rx_traffic_idx);
|
||||
for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
|
||||
for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
|
||||
entry++, ofs += 16) {
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"0x%.4x ", ofs);
|
||||
hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
|
||||
buf + pos, bufsz - pos, 0);
|
||||
pos += strlen(buf + pos);
|
||||
if (bufsz - pos > 0)
|
||||
buf[pos++] = '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_traffic_log_write(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_priv *priv = file->private_data;
|
||||
char buf[8];
|
||||
int buf_size;
|
||||
int traffic_log;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
buf_size = min(count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, user_buf, buf_size))
|
||||
return -EFAULT;
|
||||
if (sscanf(buf, "%d", &traffic_log) != 1)
|
||||
return -EFAULT;
|
||||
if (traffic_log == 0)
|
||||
iwl_reset_traffic_log(priv);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const char *fmt_value = " %-30s %10u\n";
|
||||
static const char *fmt_hex = " %-30s 0x%02X\n";
|
||||
static const char *fmt_table = " %-30s %10u %10u %10u %10u\n";
|
||||
@ -2340,6 +2423,7 @@ static ssize_t iwl_dbgfs_protection_mode_write(struct file *file,
|
||||
|
||||
DEBUGFS_READ_FILE_OPS(rx_statistics);
|
||||
DEBUGFS_READ_FILE_OPS(tx_statistics);
|
||||
DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
|
||||
DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
|
||||
DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
|
||||
DEBUGFS_READ_FILE_OPS(ucode_general_stats);
|
||||
@ -2400,6 +2484,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
|
||||
DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | 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);
|
||||
|
@ -32,7 +32,6 @@
|
||||
#define __iwl_dev_h__
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pci.h> /* for struct pci_device_id */
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/leds.h>
|
||||
@ -89,100 +88,6 @@ struct iwl_tx_queue;
|
||||
#define DEFAULT_SHORT_RETRY_LIMIT 7U
|
||||
#define DEFAULT_LONG_RETRY_LIMIT 4U
|
||||
|
||||
/* defined below */
|
||||
struct iwl_device_cmd;
|
||||
|
||||
struct iwl_cmd_meta {
|
||||
/* only for SYNC commands, iff the reply skb is wanted */
|
||||
struct iwl_host_cmd *source;
|
||||
/*
|
||||
* only for ASYNC commands
|
||||
* (which is somewhat stupid -- look at iwl-sta.c for instance
|
||||
* which duplicates a bunch of code because the callback isn't
|
||||
* invoked for SYNC commands, if it were and its result passed
|
||||
* through it would be simpler...)
|
||||
*/
|
||||
void (*callback)(struct iwl_priv *priv,
|
||||
struct iwl_device_cmd *cmd,
|
||||
struct iwl_rx_packet *pkt);
|
||||
|
||||
u32 flags;
|
||||
|
||||
DEFINE_DMA_UNMAP_ADDR(mapping);
|
||||
DEFINE_DMA_UNMAP_LEN(len);
|
||||
};
|
||||
|
||||
/*
|
||||
* Generic queue structure
|
||||
*
|
||||
* Contains common data for Rx and Tx queues.
|
||||
*
|
||||
* Note the difference between n_bd and n_window: the hardware
|
||||
* always assumes 256 descriptors, so n_bd is always 256 (unless
|
||||
* there might be HW changes in the future). For the normal TX
|
||||
* queues, n_window, which is the size of the software queue data
|
||||
* is also 256; however, for the command queue, n_window is only
|
||||
* 32 since we don't need so many commands pending. Since the HW
|
||||
* still uses 256 BDs for DMA though, n_bd stays 256. As a result,
|
||||
* the software buffers (in the variables @meta, @txb in struct
|
||||
* iwl_tx_queue) only have 32 entries, while the HW buffers (@tfds
|
||||
* in the same struct) have 256.
|
||||
* This means that we end up with the following:
|
||||
* HW entries: | 0 | ... | N * 32 | ... | N * 32 + 31 | ... | 255 |
|
||||
* SW entries: | 0 | ... | 31 |
|
||||
* where N is a number between 0 and 7. This means that the SW
|
||||
* data is a window overlayed over the HW queue.
|
||||
*/
|
||||
struct iwl_queue {
|
||||
int n_bd; /* number of BDs in this queue */
|
||||
int write_ptr; /* 1-st empty entry (index) host_w*/
|
||||
int read_ptr; /* last used entry (index) host_r*/
|
||||
/* use for monitoring and recovering the stuck queue */
|
||||
dma_addr_t dma_addr; /* physical addr for BD's */
|
||||
int n_window; /* safe queue window */
|
||||
u32 id;
|
||||
int low_mark; /* low watermark, resume queue if free
|
||||
* space more than this */
|
||||
int high_mark; /* high watermark, stop queue if free
|
||||
* space less than this */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_tx_queue - Tx Queue for DMA
|
||||
* @q: generic Rx/Tx queue descriptor
|
||||
* @bd: base of circular buffer of TFDs
|
||||
* @cmd: array of command/TX buffer pointers
|
||||
* @meta: array of meta data for each command/tx buffer
|
||||
* @dma_addr_cmd: physical address of cmd/tx buffer array
|
||||
* @txb: array of per-TFD driver data
|
||||
* @time_stamp: time (in jiffies) of last read_ptr change
|
||||
* @need_update: indicates need to update read/write index
|
||||
* @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled
|
||||
* @sta_id: valid if sched_retry is set
|
||||
* @tid: valid if sched_retry is set
|
||||
*
|
||||
* A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
|
||||
* descriptors) and required locking structures.
|
||||
*/
|
||||
#define TFD_TX_CMD_SLOTS 256
|
||||
#define TFD_CMD_SLOTS 32
|
||||
|
||||
struct iwl_tx_queue {
|
||||
struct iwl_queue q;
|
||||
struct iwl_tfd *tfds;
|
||||
struct iwl_device_cmd **cmd;
|
||||
struct iwl_cmd_meta *meta;
|
||||
struct sk_buff **skbs;
|
||||
unsigned long time_stamp;
|
||||
u8 need_update;
|
||||
u8 sched_retry;
|
||||
u8 active;
|
||||
u8 swq_id;
|
||||
|
||||
u16 sta_id;
|
||||
u16 tid;
|
||||
};
|
||||
|
||||
#define IWL_NUM_SCAN_RATES (2)
|
||||
|
||||
/*
|
||||
@ -212,21 +117,6 @@ struct iwl_channel_info {
|
||||
u8 ht40_extension_channel; /* HT_IE_EXT_CHANNEL_* */
|
||||
};
|
||||
|
||||
#define IWL_TX_FIFO_BK 0 /* shared */
|
||||
#define IWL_TX_FIFO_BE 1
|
||||
#define IWL_TX_FIFO_VI 2 /* shared */
|
||||
#define IWL_TX_FIFO_VO 3
|
||||
#define IWL_TX_FIFO_BK_IPAN IWL_TX_FIFO_BK
|
||||
#define IWL_TX_FIFO_BE_IPAN 4
|
||||
#define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI
|
||||
#define IWL_TX_FIFO_VO_IPAN 5
|
||||
/* re-uses the VO FIFO, uCode will properly flush/schedule */
|
||||
#define IWL_TX_FIFO_AUX 5
|
||||
#define IWL_TX_FIFO_UNUSED -1
|
||||
|
||||
/* AUX (TX during scan dwell) queue */
|
||||
#define IWL_AUX_QUEUE 10
|
||||
|
||||
/*
|
||||
* Minimum number of queues. MAX_NUM is defined in hw specific files.
|
||||
* Set the minimum to accommodate
|
||||
@ -249,70 +139,6 @@ struct iwl_channel_info {
|
||||
#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN)
|
||||
#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
|
||||
|
||||
|
||||
#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
|
||||
#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
|
||||
#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
|
||||
|
||||
enum {
|
||||
CMD_SYNC = 0,
|
||||
CMD_ASYNC = BIT(0),
|
||||
CMD_WANT_SKB = BIT(1),
|
||||
CMD_ON_DEMAND = BIT(2),
|
||||
};
|
||||
|
||||
#define DEF_CMD_PAYLOAD_SIZE 320
|
||||
|
||||
/**
|
||||
* struct iwl_device_cmd
|
||||
*
|
||||
* For allocation of the command and tx queues, this establishes the overall
|
||||
* size of the largest command we send to uCode, except for commands that
|
||||
* aren't fully copied and use other TFD space.
|
||||
*/
|
||||
struct iwl_device_cmd {
|
||||
struct iwl_cmd_header hdr; /* uCode API */
|
||||
union {
|
||||
u32 flags;
|
||||
u8 val8;
|
||||
u16 val16;
|
||||
u32 val32;
|
||||
struct iwl_tx_cmd tx;
|
||||
struct iwl6000_channel_switch_cmd chswitch;
|
||||
u8 payload[DEF_CMD_PAYLOAD_SIZE];
|
||||
} __packed cmd;
|
||||
} __packed;
|
||||
|
||||
#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))
|
||||
|
||||
#define IWL_MAX_CMD_TFDS 2
|
||||
|
||||
enum iwl_hcmd_dataflag {
|
||||
IWL_HCMD_DFL_NOCOPY = BIT(0),
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_host_cmd - Host command to the uCode
|
||||
* @data: array of chunks that composes the data of the host command
|
||||
* @reply_page: pointer to the page that holds the response to the host command
|
||||
* @callback:
|
||||
* @flags: can be CMD_* note CMD_WANT_SKB is incompatible withe CMD_ASYNC
|
||||
* @len: array of the lenths of the chunks in data
|
||||
* @dataflags:
|
||||
* @id: id of the host command
|
||||
*/
|
||||
struct iwl_host_cmd {
|
||||
const void *data[IWL_MAX_CMD_TFDS];
|
||||
unsigned long reply_page;
|
||||
void (*callback)(struct iwl_priv *priv,
|
||||
struct iwl_device_cmd *cmd,
|
||||
struct iwl_rx_packet *pkt);
|
||||
u32 flags;
|
||||
u16 len[IWL_MAX_CMD_TFDS];
|
||||
u8 dataflags[IWL_MAX_CMD_TFDS];
|
||||
u8 id;
|
||||
};
|
||||
|
||||
#define SUP_RATE_11A_MAX_NUM_CHANNELS 8
|
||||
#define SUP_RATE_11B_MAX_NUM_CHANNELS 4
|
||||
#define SUP_RATE_11G_MAX_NUM_CHANNELS 12
|
||||
@ -580,9 +406,6 @@ extern const u8 iwl_bcast_addr[ETH_ALEN];
|
||||
#define IWL_OPERATION_MODE_MIXED 2
|
||||
#define IWL_OPERATION_MODE_20MHZ 3
|
||||
|
||||
#define IWL_TX_CRC_SIZE 4
|
||||
#define IWL_TX_DELIMITER_SIZE 4
|
||||
|
||||
#define TX_POWER_IWL_ILLEGAL_VOLTAGE -10000
|
||||
|
||||
/* Sensitivity and chain noise calibration */
|
||||
@ -706,9 +529,6 @@ struct iwl_chain_noise_data {
|
||||
#define EEPROM_SEM_TIMEOUT 10 /* milliseconds */
|
||||
#define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */
|
||||
|
||||
#define IWL_TRAFFIC_ENTRIES (256)
|
||||
#define IWL_TRAFFIC_ENTRY_SIZE (64)
|
||||
|
||||
enum {
|
||||
MEASUREMENT_READY = (1 << 0),
|
||||
MEASUREMENT_ACTIVE = (1 << 1),
|
||||
@ -849,21 +669,6 @@ struct iwl_event_log {
|
||||
int wraps_more_count;
|
||||
};
|
||||
|
||||
/*
|
||||
* host interrupt timeout value
|
||||
* used with setting interrupt coalescing timer
|
||||
* the CSR_INT_COALESCING is an 8 bit register in 32-usec unit
|
||||
*
|
||||
* default interrupt coalescing timer is 64 x 32 = 2048 usecs
|
||||
* default interrupt coalescing calibration timer is 16 x 32 = 512 usecs
|
||||
*/
|
||||
#define IWL_HOST_INT_TIMEOUT_MAX (0xFF)
|
||||
#define IWL_HOST_INT_TIMEOUT_DEF (0x40)
|
||||
#define IWL_HOST_INT_TIMEOUT_MIN (0x0)
|
||||
#define IWL_HOST_INT_CALIB_TIMEOUT_MAX (0xFF)
|
||||
#define IWL_HOST_INT_CALIB_TIMEOUT_DEF (0x10)
|
||||
#define IWL_HOST_INT_CALIB_TIMEOUT_MIN (0x0)
|
||||
|
||||
/*
|
||||
* This is the threshold value of plcp error rate per 100mSecs. It is
|
||||
* used to set and check for the validity of plcp_delta.
|
||||
@ -1095,9 +900,6 @@ struct iwl_priv {
|
||||
/*TODO: remove these pointers - use bus(priv) instead */
|
||||
struct iwl_bus *bus; /* bus specific data */
|
||||
|
||||
/* microcode/device supports multiple contexts */
|
||||
u8 valid_contexts;
|
||||
|
||||
/* max number of station keys */
|
||||
u8 sta_key_max_num;
|
||||
|
||||
@ -1142,8 +944,6 @@ struct iwl_priv {
|
||||
/* Rate scaling data */
|
||||
u8 retry_rate;
|
||||
|
||||
wait_queue_head_t wait_command_queue;
|
||||
|
||||
int activity_timer_active;
|
||||
|
||||
/* counts mgmt, ctl, and data packets */
|
||||
@ -1327,7 +1127,7 @@ iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif)
|
||||
#define for_each_context(priv, ctx) \
|
||||
for (ctx = &priv->contexts[IWL_RXON_CTX_BSS]; \
|
||||
ctx < &priv->contexts[NUM_IWL_RXON_CTX]; ctx++) \
|
||||
if (priv->valid_contexts & BIT(ctx->ctxid))
|
||||
if (priv->shrd->valid_contexts & BIT(ctx->ctxid))
|
||||
|
||||
static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx)
|
||||
{
|
||||
|
@ -35,35 +35,12 @@
|
||||
|
||||
#include "iwl-io.h"
|
||||
|
||||
#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
|
||||
|
||||
|
||||
static inline struct ieee80211_conf *ieee80211_get_hw_conf(
|
||||
struct ieee80211_hw *hw)
|
||||
{
|
||||
return &hw->conf;
|
||||
}
|
||||
|
||||
/**
|
||||
* iwl_queue_inc_wrap - increment queue index, wrap back to beginning
|
||||
* @index -- current index
|
||||
* @n_bd -- total number of entries in queue (must be power of 2)
|
||||
*/
|
||||
static inline int iwl_queue_inc_wrap(int index, int n_bd)
|
||||
{
|
||||
return ++index & (n_bd - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* iwl_queue_dec_wrap - decrement queue index, wrap back to end
|
||||
* @index -- current index
|
||||
* @n_bd -- total number of entries in queue (must be power of 2)
|
||||
*/
|
||||
static inline int iwl_queue_dec_wrap(int index, int n_bd)
|
||||
{
|
||||
return --index & (n_bd - 1);
|
||||
}
|
||||
|
||||
static inline void iwl_enable_rfkill_int(struct iwl_priv *priv)
|
||||
{
|
||||
IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n");
|
||||
|
@ -483,9 +483,13 @@ out_no_pci:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void iwl_pci_down(struct iwl_bus *bus)
|
||||
static void __devexit iwl_pci_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct iwl_pci_bus *pci_bus = (struct iwl_pci_bus *) bus->bus_specific;
|
||||
struct iwl_shared *shrd = pci_get_drvdata(pdev);
|
||||
struct iwl_bus *bus = shrd->bus;
|
||||
struct iwl_pci_bus *pci_bus = IWL_BUS_GET_PCI_BUS(bus);
|
||||
|
||||
iwl_remove(shrd->priv);
|
||||
|
||||
pci_disable_msi(pci_bus->pci_dev);
|
||||
pci_iounmap(pci_bus->pci_dev, pci_bus->hw_base);
|
||||
@ -496,16 +500,6 @@ static void iwl_pci_down(struct iwl_bus *bus)
|
||||
kfree(bus);
|
||||
}
|
||||
|
||||
static void __devexit iwl_pci_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct iwl_shared *shrd = pci_get_drvdata(pdev);
|
||||
struct iwl_bus *bus = shrd->bus;
|
||||
|
||||
iwl_remove(shrd->priv);
|
||||
|
||||
iwl_pci_down(bus);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
|
||||
static int iwl_pci_suspend(struct device *device)
|
||||
|
@ -42,6 +42,87 @@
|
||||
#include "iwl-agn.h"
|
||||
#include "iwl-shared.h"
|
||||
|
||||
const char *get_cmd_string(u8 cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
IWL_CMD(REPLY_ALIVE);
|
||||
IWL_CMD(REPLY_ERROR);
|
||||
IWL_CMD(REPLY_RXON);
|
||||
IWL_CMD(REPLY_RXON_ASSOC);
|
||||
IWL_CMD(REPLY_QOS_PARAM);
|
||||
IWL_CMD(REPLY_RXON_TIMING);
|
||||
IWL_CMD(REPLY_ADD_STA);
|
||||
IWL_CMD(REPLY_REMOVE_STA);
|
||||
IWL_CMD(REPLY_REMOVE_ALL_STA);
|
||||
IWL_CMD(REPLY_TXFIFO_FLUSH);
|
||||
IWL_CMD(REPLY_WEPKEY);
|
||||
IWL_CMD(REPLY_TX);
|
||||
IWL_CMD(REPLY_LEDS_CMD);
|
||||
IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
|
||||
IWL_CMD(COEX_PRIORITY_TABLE_CMD);
|
||||
IWL_CMD(COEX_MEDIUM_NOTIFICATION);
|
||||
IWL_CMD(COEX_EVENT_CMD);
|
||||
IWL_CMD(REPLY_QUIET_CMD);
|
||||
IWL_CMD(REPLY_CHANNEL_SWITCH);
|
||||
IWL_CMD(CHANNEL_SWITCH_NOTIFICATION);
|
||||
IWL_CMD(REPLY_SPECTRUM_MEASUREMENT_CMD);
|
||||
IWL_CMD(SPECTRUM_MEASURE_NOTIFICATION);
|
||||
IWL_CMD(POWER_TABLE_CMD);
|
||||
IWL_CMD(PM_SLEEP_NOTIFICATION);
|
||||
IWL_CMD(PM_DEBUG_STATISTIC_NOTIFIC);
|
||||
IWL_CMD(REPLY_SCAN_CMD);
|
||||
IWL_CMD(REPLY_SCAN_ABORT_CMD);
|
||||
IWL_CMD(SCAN_START_NOTIFICATION);
|
||||
IWL_CMD(SCAN_RESULTS_NOTIFICATION);
|
||||
IWL_CMD(SCAN_COMPLETE_NOTIFICATION);
|
||||
IWL_CMD(BEACON_NOTIFICATION);
|
||||
IWL_CMD(REPLY_TX_BEACON);
|
||||
IWL_CMD(WHO_IS_AWAKE_NOTIFICATION);
|
||||
IWL_CMD(QUIET_NOTIFICATION);
|
||||
IWL_CMD(REPLY_TX_PWR_TABLE_CMD);
|
||||
IWL_CMD(MEASURE_ABORT_NOTIFICATION);
|
||||
IWL_CMD(REPLY_BT_CONFIG);
|
||||
IWL_CMD(REPLY_STATISTICS_CMD);
|
||||
IWL_CMD(STATISTICS_NOTIFICATION);
|
||||
IWL_CMD(REPLY_CARD_STATE_CMD);
|
||||
IWL_CMD(CARD_STATE_NOTIFICATION);
|
||||
IWL_CMD(MISSED_BEACONS_NOTIFICATION);
|
||||
IWL_CMD(REPLY_CT_KILL_CONFIG_CMD);
|
||||
IWL_CMD(SENSITIVITY_CMD);
|
||||
IWL_CMD(REPLY_PHY_CALIBRATION_CMD);
|
||||
IWL_CMD(REPLY_RX_PHY_CMD);
|
||||
IWL_CMD(REPLY_RX_MPDU_CMD);
|
||||
IWL_CMD(REPLY_RX);
|
||||
IWL_CMD(REPLY_COMPRESSED_BA);
|
||||
IWL_CMD(CALIBRATION_CFG_CMD);
|
||||
IWL_CMD(CALIBRATION_RES_NOTIFICATION);
|
||||
IWL_CMD(CALIBRATION_COMPLETE_NOTIFICATION);
|
||||
IWL_CMD(REPLY_TX_POWER_DBM_CMD);
|
||||
IWL_CMD(TEMPERATURE_NOTIFICATION);
|
||||
IWL_CMD(TX_ANT_CONFIGURATION_CMD);
|
||||
IWL_CMD(REPLY_BT_COEX_PROFILE_NOTIF);
|
||||
IWL_CMD(REPLY_BT_COEX_PRIO_TABLE);
|
||||
IWL_CMD(REPLY_BT_COEX_PROT_ENV);
|
||||
IWL_CMD(REPLY_WIPAN_PARAMS);
|
||||
IWL_CMD(REPLY_WIPAN_RXON);
|
||||
IWL_CMD(REPLY_WIPAN_RXON_TIMING);
|
||||
IWL_CMD(REPLY_WIPAN_RXON_ASSOC);
|
||||
IWL_CMD(REPLY_WIPAN_QOS_PARAM);
|
||||
IWL_CMD(REPLY_WIPAN_WEPKEY);
|
||||
IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH);
|
||||
IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION);
|
||||
IWL_CMD(REPLY_WIPAN_DEACTIVATION_COMPLETE);
|
||||
IWL_CMD(REPLY_WOWLAN_PATTERNS);
|
||||
IWL_CMD(REPLY_WOWLAN_WAKEUP_FILTER);
|
||||
IWL_CMD(REPLY_WOWLAN_TSC_RSC_PARAMS);
|
||||
IWL_CMD(REPLY_WOWLAN_TKIP_PARAMS);
|
||||
IWL_CMD(REPLY_WOWLAN_KEK_KCK_MATERIAL);
|
||||
IWL_CMD(REPLY_WOWLAN_GET_STATUS);
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
@ -563,7 +644,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
|
||||
wiphy_rfkill_set_hw_state(priv->hw->wiphy,
|
||||
test_bit(STATUS_RF_KILL_HW, &priv->shrd->status));
|
||||
else
|
||||
wake_up_interruptible(&priv->wait_command_queue);
|
||||
wake_up_interruptible(&priv->shrd->wait_command_queue);
|
||||
}
|
||||
|
||||
static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
|
||||
|
@ -67,6 +67,7 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/mm.h> /* for page_address */
|
||||
#include <net/mac80211.h>
|
||||
|
||||
#include "iwl-commands.h"
|
||||
@ -212,6 +213,7 @@ struct iwl_tid_data {
|
||||
* @ucode_owner: IWL_OWNERSHIP_*
|
||||
* @cmd_queue: command queue number
|
||||
* @status: STATUS_*
|
||||
* @valid_contexts: microcode/device supports multiple contexts
|
||||
* @bus: pointer to the bus layer data
|
||||
* @priv: pointer to the upper layer data
|
||||
* @hw_params: see struct iwl_hw_params
|
||||
@ -232,6 +234,7 @@ struct iwl_shared {
|
||||
u8 cmd_queue;
|
||||
unsigned long status;
|
||||
bool wowlan;
|
||||
u8 valid_contexts;
|
||||
|
||||
struct iwl_bus *bus;
|
||||
struct iwl_priv *priv;
|
||||
@ -250,6 +253,8 @@ struct iwl_shared {
|
||||
struct ieee80211_hw *hw;
|
||||
|
||||
struct iwl_tid_data tid_data[IWLAGN_STATION_COUNT][IWL_MAX_TID_COUNT];
|
||||
|
||||
wait_queue_head_t wait_command_queue;
|
||||
};
|
||||
|
||||
/*Whatever _m is (iwl_trans, iwl_priv, iwl_bus, these macros will work */
|
||||
@ -285,6 +290,26 @@ static inline void iwl_free_pages(struct iwl_shared *shrd, unsigned long page)
|
||||
free_pages(page, shrd->hw_params.rx_page_order);
|
||||
}
|
||||
|
||||
/**
|
||||
* iwl_queue_inc_wrap - increment queue index, wrap back to beginning
|
||||
* @index -- current index
|
||||
* @n_bd -- total number of entries in queue (must be power of 2)
|
||||
*/
|
||||
static inline int iwl_queue_inc_wrap(int index, int n_bd)
|
||||
{
|
||||
return ++index & (n_bd - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* iwl_queue_dec_wrap - decrement queue index, wrap back to end
|
||||
* @index -- current index
|
||||
* @n_bd -- total number of entries in queue (must be power of 2)
|
||||
*/
|
||||
static inline int iwl_queue_dec_wrap(int index, int n_bd)
|
||||
{
|
||||
return --index & (n_bd - 1);
|
||||
}
|
||||
|
||||
struct iwl_rx_mem_buffer {
|
||||
dma_addr_t page_dma;
|
||||
struct page *page;
|
||||
@ -355,12 +380,39 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
|
||||
struct iwl_cfg *cfg);
|
||||
void __devexit iwl_remove(struct iwl_priv * priv);
|
||||
|
||||
void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
|
||||
int iwlagn_hw_valid_rtc_data_addr(u32 addr);
|
||||
void iwl_start_tx_ba_trans_ready(struct iwl_priv *priv,
|
||||
enum iwl_rxon_context_id ctx,
|
||||
u8 sta_id, u8 tid);
|
||||
void iwl_stop_tx_ba_trans_ready(struct iwl_priv *priv,
|
||||
enum iwl_rxon_context_id ctx,
|
||||
u8 sta_id, u8 tid);
|
||||
void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state);
|
||||
void iwl_nic_config(struct iwl_priv *priv);
|
||||
void iwl_apm_stop(struct iwl_priv *priv);
|
||||
int iwl_apm_init(struct iwl_priv *priv);
|
||||
void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand);
|
||||
const char *get_cmd_string(u8 cmd);
|
||||
bool iwl_check_for_ct_kill(struct iwl_priv *priv);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
void iwl_reset_traffic_log(struct iwl_priv *priv);
|
||||
#endif /* CONFIG_IWLWIFI_DEBUGFS */
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
void iwl_print_rx_config_cmd(struct iwl_priv *priv, u8 ctxid);
|
||||
#else
|
||||
static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv, u8 ctxid)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#define IWL_CMD(x) case x: return #x
|
||||
#define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo))))
|
||||
|
||||
#define IWL_TRAFFIC_ENTRIES (256)
|
||||
#define IWL_TRAFFIC_ENTRY_SIZE (64)
|
||||
|
||||
/*****************************************************
|
||||
* DRIVER STATUS FUNCTIONS
|
||||
|
@ -123,14 +123,14 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void iwl_add_sta_callback(struct iwl_priv *priv,
|
||||
static void iwl_add_sta_callback(struct iwl_shared *shrd,
|
||||
struct iwl_device_cmd *cmd,
|
||||
struct iwl_rx_packet *pkt)
|
||||
{
|
||||
struct iwl_addsta_cmd *addsta =
|
||||
(struct iwl_addsta_cmd *)cmd->cmd.payload;
|
||||
|
||||
iwl_process_add_sta_resp(priv, addsta, pkt, false);
|
||||
iwl_process_add_sta_resp(shrd->priv, addsta, pkt, false);
|
||||
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <net/cfg80211.h>
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include "iwl-fh.h"
|
||||
#include "iwl-csr.h"
|
||||
@ -114,6 +115,97 @@ struct iwl_dma_ptr {
|
||||
*/
|
||||
#define IWL_IPAN_MCAST_QUEUE 8
|
||||
|
||||
struct iwl_cmd_meta {
|
||||
/* only for SYNC commands, iff the reply skb is wanted */
|
||||
struct iwl_host_cmd *source;
|
||||
/*
|
||||
* only for ASYNC commands
|
||||
* (which is somewhat stupid -- look at iwl-sta.c for instance
|
||||
* which duplicates a bunch of code because the callback isn't
|
||||
* invoked for SYNC commands, if it were and its result passed
|
||||
* through it would be simpler...)
|
||||
*/
|
||||
void (*callback)(struct iwl_shared *shrd,
|
||||
struct iwl_device_cmd *cmd,
|
||||
struct iwl_rx_packet *pkt);
|
||||
|
||||
u32 flags;
|
||||
|
||||
DEFINE_DMA_UNMAP_ADDR(mapping);
|
||||
DEFINE_DMA_UNMAP_LEN(len);
|
||||
};
|
||||
|
||||
/*
|
||||
* Generic queue structure
|
||||
*
|
||||
* Contains common data for Rx and Tx queues.
|
||||
*
|
||||
* Note the difference between n_bd and n_window: the hardware
|
||||
* always assumes 256 descriptors, so n_bd is always 256 (unless
|
||||
* there might be HW changes in the future). For the normal TX
|
||||
* queues, n_window, which is the size of the software queue data
|
||||
* is also 256; however, for the command queue, n_window is only
|
||||
* 32 since we don't need so many commands pending. Since the HW
|
||||
* still uses 256 BDs for DMA though, n_bd stays 256. As a result,
|
||||
* the software buffers (in the variables @meta, @txb in struct
|
||||
* iwl_tx_queue) only have 32 entries, while the HW buffers (@tfds
|
||||
* in the same struct) have 256.
|
||||
* This means that we end up with the following:
|
||||
* HW entries: | 0 | ... | N * 32 | ... | N * 32 + 31 | ... | 255 |
|
||||
* SW entries: | 0 | ... | 31 |
|
||||
* where N is a number between 0 and 7. This means that the SW
|
||||
* data is a window overlayed over the HW queue.
|
||||
*/
|
||||
struct iwl_queue {
|
||||
int n_bd; /* number of BDs in this queue */
|
||||
int write_ptr; /* 1-st empty entry (index) host_w*/
|
||||
int read_ptr; /* last used entry (index) host_r*/
|
||||
/* use for monitoring and recovering the stuck queue */
|
||||
dma_addr_t dma_addr; /* physical addr for BD's */
|
||||
int n_window; /* safe queue window */
|
||||
u32 id;
|
||||
int low_mark; /* low watermark, resume queue if free
|
||||
* space more than this */
|
||||
int high_mark; /* high watermark, stop queue if free
|
||||
* space less than this */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_tx_queue - Tx Queue for DMA
|
||||
* @q: generic Rx/Tx queue descriptor
|
||||
* @bd: base of circular buffer of TFDs
|
||||
* @cmd: array of command/TX buffer pointers
|
||||
* @meta: array of meta data for each command/tx buffer
|
||||
* @dma_addr_cmd: physical address of cmd/tx buffer array
|
||||
* @txb: array of per-TFD driver data
|
||||
* @time_stamp: time (in jiffies) of last read_ptr change
|
||||
* @need_update: indicates need to update read/write index
|
||||
* @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled
|
||||
* @sta_id: valid if sched_retry is set
|
||||
* @tid: valid if sched_retry is set
|
||||
*
|
||||
* A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
|
||||
* descriptors) and required locking structures.
|
||||
*/
|
||||
#define TFD_TX_CMD_SLOTS 256
|
||||
#define TFD_CMD_SLOTS 32
|
||||
|
||||
struct iwl_tx_queue {
|
||||
struct iwl_queue q;
|
||||
struct iwl_tfd *tfds;
|
||||
struct iwl_device_cmd **cmd;
|
||||
struct iwl_cmd_meta *meta;
|
||||
struct sk_buff **skbs;
|
||||
unsigned long time_stamp;
|
||||
u8 need_update;
|
||||
u8 sched_retry;
|
||||
u8 active;
|
||||
u8 swq_id;
|
||||
|
||||
u16 sta_id;
|
||||
u16 tid;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_trans_pcie - PCIe transport specific data
|
||||
* @rxq: all the RX queue data
|
||||
@ -195,7 +287,8 @@ int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id);
|
||||
int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
|
||||
int __must_check iwl_trans_pcie_send_cmd_pdu(struct iwl_trans *trans, u8 id,
|
||||
u32 flags, u16 len, const void *data);
|
||||
void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
|
||||
void iwl_tx_cmd_complete(struct iwl_trans *trans,
|
||||
struct iwl_rx_mem_buffer *rxb);
|
||||
void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans,
|
||||
struct iwl_tx_queue *txq,
|
||||
u16 byte_cnt);
|
||||
@ -343,4 +436,19 @@ static inline u8 get_cmd_index(struct iwl_queue *q, u32 index)
|
||||
return index & (q->n_window - 1);
|
||||
}
|
||||
|
||||
#define IWL_TX_FIFO_BK 0 /* shared */
|
||||
#define IWL_TX_FIFO_BE 1
|
||||
#define IWL_TX_FIFO_VI 2 /* shared */
|
||||
#define IWL_TX_FIFO_VO 3
|
||||
#define IWL_TX_FIFO_BK_IPAN IWL_TX_FIFO_BK
|
||||
#define IWL_TX_FIFO_BE_IPAN 4
|
||||
#define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI
|
||||
#define IWL_TX_FIFO_VO_IPAN 5
|
||||
/* re-uses the VO FIFO, uCode will properly flush/schedule */
|
||||
#define IWL_TX_FIFO_AUX 5
|
||||
#define IWL_TX_FIFO_UNUSED -1
|
||||
|
||||
/* AUX (TX during scan dwell) queue */
|
||||
#define IWL_AUX_QUEUE 10
|
||||
|
||||
#endif /* __iwl_trans_int_pcie_h__ */
|
||||
|
@ -30,8 +30,7 @@
|
||||
#include <linux/wait.h>
|
||||
#include <linux/gfp.h>
|
||||
|
||||
#include "iwl-dev.h"
|
||||
#include "iwl-agn.h"
|
||||
/*TODO: Remove include to iwl-core.h*/
|
||||
#include "iwl-core.h"
|
||||
#include "iwl-io.h"
|
||||
#include "iwl-helpers.h"
|
||||
@ -453,7 +452,7 @@ static void iwl_rx_handle(struct iwl_trans *trans)
|
||||
* iwl_trans_send_cmd()
|
||||
* as we reclaim the driver command queue */
|
||||
if (rxb->page)
|
||||
iwl_tx_cmd_complete(priv(trans), rxb);
|
||||
iwl_tx_cmd_complete(trans, rxb);
|
||||
else
|
||||
IWL_WARN(trans, "Claim null rxb?\n");
|
||||
}
|
||||
@ -646,7 +645,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans)
|
||||
*/
|
||||
clear_bit(STATUS_READY, &trans->shrd->status);
|
||||
clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
|
||||
wake_up_interruptible(&priv->wait_command_queue);
|
||||
wake_up_interruptible(&priv->shrd->wait_command_queue);
|
||||
IWL_ERR(trans, "RF is used by WiMAX\n");
|
||||
return;
|
||||
}
|
||||
@ -660,8 +659,7 @@ static void iwl_irq_handle_error(struct iwl_trans *trans)
|
||||
iwl_dump_nic_event_log(trans, false, NULL, false);
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
if (iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS)
|
||||
iwl_print_rx_config_cmd(priv,
|
||||
&priv->contexts[IWL_RXON_CTX_BSS]);
|
||||
iwl_print_rx_config_cmd(priv(trans), IWL_RXON_CTX_BSS);
|
||||
#endif
|
||||
|
||||
iwlagn_fw_error(priv, false);
|
||||
@ -705,18 +703,18 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
|
||||
ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
|
||||
|
||||
/* Make sure device is powered up for SRAM reads */
|
||||
spin_lock_irqsave(&bus(priv)->reg_lock, reg_flags);
|
||||
iwl_grab_nic_access(bus(priv));
|
||||
spin_lock_irqsave(&bus(trans)->reg_lock, reg_flags);
|
||||
iwl_grab_nic_access(bus(trans));
|
||||
|
||||
/* Set starting address; reads will auto-increment */
|
||||
iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, ptr);
|
||||
iwl_write32(bus(trans), HBUS_TARG_MEM_RADDR, ptr);
|
||||
rmb();
|
||||
|
||||
/* "time" is actually "data" for mode 0 (no timestamp).
|
||||
* place event id # at far right for easier visual parsing. */
|
||||
for (i = 0; i < num_events; i++) {
|
||||
ev = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT);
|
||||
time = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT);
|
||||
ev = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT);
|
||||
time = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT);
|
||||
if (mode == 0) {
|
||||
/* data, ev */
|
||||
if (bufsz) {
|
||||
@ -730,7 +728,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
|
||||
time, ev);
|
||||
}
|
||||
} else {
|
||||
data = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT);
|
||||
data = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT);
|
||||
if (bufsz) {
|
||||
pos += scnprintf(*buf + pos, bufsz - pos,
|
||||
"EVT_LOGT:%010u:0x%08x:%04u\n",
|
||||
@ -745,8 +743,8 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
|
||||
}
|
||||
|
||||
/* Allow device to power down */
|
||||
iwl_release_nic_access(bus(priv));
|
||||
spin_unlock_irqrestore(&bus(priv)->reg_lock, reg_flags);
|
||||
iwl_release_nic_access(bus(trans));
|
||||
spin_unlock_irqrestore(&bus(trans)->reg_lock, reg_flags);
|
||||
return pos;
|
||||
}
|
||||
|
||||
@ -823,10 +821,10 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log,
|
||||
}
|
||||
|
||||
/* event log header */
|
||||
capacity = iwl_read_targ_mem(bus(priv), base);
|
||||
mode = iwl_read_targ_mem(bus(priv), base + (1 * sizeof(u32)));
|
||||
num_wraps = iwl_read_targ_mem(bus(priv), base + (2 * sizeof(u32)));
|
||||
next_entry = iwl_read_targ_mem(bus(priv), base + (3 * sizeof(u32)));
|
||||
capacity = iwl_read_targ_mem(bus(trans), base);
|
||||
mode = iwl_read_targ_mem(bus(trans), base + (1 * sizeof(u32)));
|
||||
num_wraps = iwl_read_targ_mem(bus(trans), base + (2 * sizeof(u32)));
|
||||
next_entry = iwl_read_targ_mem(bus(trans), base + (3 * sizeof(u32)));
|
||||
|
||||
if (capacity > logsize) {
|
||||
IWL_ERR(trans, "Log capacity %d is bogus, limit to %d "
|
||||
@ -848,9 +846,6 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log,
|
||||
return pos;
|
||||
}
|
||||
|
||||
/* enable/disable bt channel inhibition */
|
||||
priv->bt_ch_announce = iwlagn_mod_params.bt_ch_announce;
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
if (!(iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) && !full_log)
|
||||
size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES)
|
||||
@ -908,8 +903,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
|
||||
u32 inta_mask;
|
||||
#endif
|
||||
|
||||
struct iwl_trans_pcie *trans_pcie =
|
||||
IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
struct isr_statistics *isr_stats = &trans_pcie->isr_stats;
|
||||
|
||||
|
||||
@ -1003,8 +997,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
|
||||
else
|
||||
clear_bit(STATUS_RF_KILL_HW,
|
||||
&trans->shrd->status);
|
||||
wiphy_rfkill_set_hw_state(priv(trans)->hw->wiphy,
|
||||
hw_rf_kill);
|
||||
iwl_set_hw_rfkill_state(priv(trans), hw_rf_kill);
|
||||
}
|
||||
|
||||
handled |= CSR_INT_BIT_RF_KILL;
|
||||
@ -1093,7 +1086,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
|
||||
handled |= CSR_INT_BIT_FH_TX;
|
||||
/* Wake up uCode load routine, now that load is complete */
|
||||
priv(trans)->ucode_write_complete = 1;
|
||||
wake_up_interruptible(&priv(trans)->wait_command_queue);
|
||||
wake_up_interruptible(&trans->shrd->wait_command_queue);
|
||||
}
|
||||
|
||||
if (inta & ~handled) {
|
||||
|
@ -30,13 +30,19 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#include "iwl-agn.h"
|
||||
/* TODO: remove include to iwl-dev.h */
|
||||
#include "iwl-dev.h"
|
||||
#include "iwl-core.h"
|
||||
#include "iwl-debug.h"
|
||||
#include "iwl-csr.h"
|
||||
#include "iwl-prph.h"
|
||||
#include "iwl-io.h"
|
||||
#include "iwl-agn-hw.h"
|
||||
#include "iwl-helpers.h"
|
||||
#include "iwl-trans-int-pcie.h"
|
||||
|
||||
#define IWL_TX_CRC_SIZE 4
|
||||
#define IWL_TX_DELIMITER_SIZE 4
|
||||
|
||||
/**
|
||||
* iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
|
||||
*/
|
||||
@ -535,8 +541,7 @@ int iwl_trans_pcie_tx_agg_alloc(struct iwl_trans *trans,
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
struct iwl_tid_data *tid_data;
|
||||
unsigned long flags;
|
||||
u16 txq_id;
|
||||
struct iwl_priv *priv = priv(trans);
|
||||
int txq_id;
|
||||
|
||||
txq_id = iwlagn_txq_ctx_activate_free(trans);
|
||||
if (txq_id == -1) {
|
||||
@ -560,7 +565,7 @@ int iwl_trans_pcie_tx_agg_alloc(struct iwl_trans *trans,
|
||||
"queue\n", tid_data->tfds_in_queue);
|
||||
tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
|
||||
spin_unlock_irqrestore(&trans->shrd->sta_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -856,16 +861,16 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
|
||||
* need to be reclaimed. As result, some free space forms. If there is
|
||||
* enough free space (> low mark), wake the stack that feeds us.
|
||||
*/
|
||||
static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int idx)
|
||||
static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id,
|
||||
int idx)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie =
|
||||
IWL_TRANS_GET_PCIE_TRANS(trans(priv));
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id];
|
||||
struct iwl_queue *q = &txq->q;
|
||||
int nfreed = 0;
|
||||
|
||||
if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) {
|
||||
IWL_ERR(priv, "%s: Read index for DMA queue txq id (%d), "
|
||||
IWL_ERR(trans, "%s: Read index for DMA queue txq id (%d), "
|
||||
"index %d is out of range [0-%d] %d %d.\n", __func__,
|
||||
txq_id, idx, q->n_bd, q->write_ptr, q->read_ptr);
|
||||
return;
|
||||
@ -875,9 +880,9 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int idx)
|
||||
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
|
||||
|
||||
if (nfreed++ > 0) {
|
||||
IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", idx,
|
||||
IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", idx,
|
||||
q->write_ptr, q->read_ptr);
|
||||
iwlagn_fw_error(priv, false);
|
||||
iwlagn_fw_error(priv(trans), false);
|
||||
}
|
||||
|
||||
}
|
||||
@ -891,7 +896,7 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int idx)
|
||||
* will be executed. The attached skb (if present) will only be freed
|
||||
* if the callback returns 1
|
||||
*/
|
||||
void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb)
|
||||
{
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
|
||||
@ -900,7 +905,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
int cmd_index;
|
||||
struct iwl_device_cmd *cmd;
|
||||
struct iwl_cmd_meta *meta;
|
||||
struct iwl_trans *trans = trans(priv);
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue];
|
||||
unsigned long flags;
|
||||
@ -913,7 +917,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
txq_id, trans->shrd->cmd_queue, sequence,
|
||||
trans_pcie->txq[trans->shrd->cmd_queue].q.read_ptr,
|
||||
trans_pcie->txq[trans->shrd->cmd_queue].q.write_ptr)) {
|
||||
iwl_print_hex_error(priv, pkt, 32);
|
||||
iwl_print_hex_error(trans, pkt, 32);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -929,17 +933,17 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
meta->source->reply_page = (unsigned long)rxb_addr(rxb);
|
||||
rxb->page = NULL;
|
||||
} else if (meta->callback)
|
||||
meta->callback(priv, cmd, pkt);
|
||||
meta->callback(trans->shrd, cmd, pkt);
|
||||
|
||||
spin_lock_irqsave(&trans->hcmd_lock, flags);
|
||||
|
||||
iwl_hcmd_queue_reclaim(priv, txq_id, index);
|
||||
iwl_hcmd_queue_reclaim(trans, txq_id, index);
|
||||
|
||||
if (!(meta->flags & CMD_ASYNC)) {
|
||||
clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
|
||||
IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n",
|
||||
get_cmd_string(cmd->hdr.cmd));
|
||||
wake_up_interruptible(&priv->wait_command_queue);
|
||||
wake_up_interruptible(&trans->shrd->wait_command_queue);
|
||||
}
|
||||
|
||||
meta->flags = 0;
|
||||
@ -947,96 +951,14 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
|
||||
spin_unlock_irqrestore(&trans->hcmd_lock, flags);
|
||||
}
|
||||
|
||||
const char *get_cmd_string(u8 cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
IWL_CMD(REPLY_ALIVE);
|
||||
IWL_CMD(REPLY_ERROR);
|
||||
IWL_CMD(REPLY_RXON);
|
||||
IWL_CMD(REPLY_RXON_ASSOC);
|
||||
IWL_CMD(REPLY_QOS_PARAM);
|
||||
IWL_CMD(REPLY_RXON_TIMING);
|
||||
IWL_CMD(REPLY_ADD_STA);
|
||||
IWL_CMD(REPLY_REMOVE_STA);
|
||||
IWL_CMD(REPLY_REMOVE_ALL_STA);
|
||||
IWL_CMD(REPLY_TXFIFO_FLUSH);
|
||||
IWL_CMD(REPLY_WEPKEY);
|
||||
IWL_CMD(REPLY_TX);
|
||||
IWL_CMD(REPLY_LEDS_CMD);
|
||||
IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
|
||||
IWL_CMD(COEX_PRIORITY_TABLE_CMD);
|
||||
IWL_CMD(COEX_MEDIUM_NOTIFICATION);
|
||||
IWL_CMD(COEX_EVENT_CMD);
|
||||
IWL_CMD(REPLY_QUIET_CMD);
|
||||
IWL_CMD(REPLY_CHANNEL_SWITCH);
|
||||
IWL_CMD(CHANNEL_SWITCH_NOTIFICATION);
|
||||
IWL_CMD(REPLY_SPECTRUM_MEASUREMENT_CMD);
|
||||
IWL_CMD(SPECTRUM_MEASURE_NOTIFICATION);
|
||||
IWL_CMD(POWER_TABLE_CMD);
|
||||
IWL_CMD(PM_SLEEP_NOTIFICATION);
|
||||
IWL_CMD(PM_DEBUG_STATISTIC_NOTIFIC);
|
||||
IWL_CMD(REPLY_SCAN_CMD);
|
||||
IWL_CMD(REPLY_SCAN_ABORT_CMD);
|
||||
IWL_CMD(SCAN_START_NOTIFICATION);
|
||||
IWL_CMD(SCAN_RESULTS_NOTIFICATION);
|
||||
IWL_CMD(SCAN_COMPLETE_NOTIFICATION);
|
||||
IWL_CMD(BEACON_NOTIFICATION);
|
||||
IWL_CMD(REPLY_TX_BEACON);
|
||||
IWL_CMD(WHO_IS_AWAKE_NOTIFICATION);
|
||||
IWL_CMD(QUIET_NOTIFICATION);
|
||||
IWL_CMD(REPLY_TX_PWR_TABLE_CMD);
|
||||
IWL_CMD(MEASURE_ABORT_NOTIFICATION);
|
||||
IWL_CMD(REPLY_BT_CONFIG);
|
||||
IWL_CMD(REPLY_STATISTICS_CMD);
|
||||
IWL_CMD(STATISTICS_NOTIFICATION);
|
||||
IWL_CMD(REPLY_CARD_STATE_CMD);
|
||||
IWL_CMD(CARD_STATE_NOTIFICATION);
|
||||
IWL_CMD(MISSED_BEACONS_NOTIFICATION);
|
||||
IWL_CMD(REPLY_CT_KILL_CONFIG_CMD);
|
||||
IWL_CMD(SENSITIVITY_CMD);
|
||||
IWL_CMD(REPLY_PHY_CALIBRATION_CMD);
|
||||
IWL_CMD(REPLY_RX_PHY_CMD);
|
||||
IWL_CMD(REPLY_RX_MPDU_CMD);
|
||||
IWL_CMD(REPLY_RX);
|
||||
IWL_CMD(REPLY_COMPRESSED_BA);
|
||||
IWL_CMD(CALIBRATION_CFG_CMD);
|
||||
IWL_CMD(CALIBRATION_RES_NOTIFICATION);
|
||||
IWL_CMD(CALIBRATION_COMPLETE_NOTIFICATION);
|
||||
IWL_CMD(REPLY_TX_POWER_DBM_CMD);
|
||||
IWL_CMD(TEMPERATURE_NOTIFICATION);
|
||||
IWL_CMD(TX_ANT_CONFIGURATION_CMD);
|
||||
IWL_CMD(REPLY_BT_COEX_PROFILE_NOTIF);
|
||||
IWL_CMD(REPLY_BT_COEX_PRIO_TABLE);
|
||||
IWL_CMD(REPLY_BT_COEX_PROT_ENV);
|
||||
IWL_CMD(REPLY_WIPAN_PARAMS);
|
||||
IWL_CMD(REPLY_WIPAN_RXON);
|
||||
IWL_CMD(REPLY_WIPAN_RXON_TIMING);
|
||||
IWL_CMD(REPLY_WIPAN_RXON_ASSOC);
|
||||
IWL_CMD(REPLY_WIPAN_QOS_PARAM);
|
||||
IWL_CMD(REPLY_WIPAN_WEPKEY);
|
||||
IWL_CMD(REPLY_WIPAN_P2P_CHANNEL_SWITCH);
|
||||
IWL_CMD(REPLY_WIPAN_NOA_NOTIFICATION);
|
||||
IWL_CMD(REPLY_WIPAN_DEACTIVATION_COMPLETE);
|
||||
IWL_CMD(REPLY_WOWLAN_PATTERNS);
|
||||
IWL_CMD(REPLY_WOWLAN_WAKEUP_FILTER);
|
||||
IWL_CMD(REPLY_WOWLAN_TSC_RSC_PARAMS);
|
||||
IWL_CMD(REPLY_WOWLAN_TKIP_PARAMS);
|
||||
IWL_CMD(REPLY_WOWLAN_KEK_KCK_MATERIAL);
|
||||
IWL_CMD(REPLY_WOWLAN_GET_STATUS);
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#define HOST_COMPLETE_TIMEOUT (2 * HZ)
|
||||
|
||||
static void iwl_generic_cmd_callback(struct iwl_priv *priv,
|
||||
static void iwl_generic_cmd_callback(struct iwl_shared *shrd,
|
||||
struct iwl_device_cmd *cmd,
|
||||
struct iwl_rx_packet *pkt)
|
||||
{
|
||||
if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
|
||||
IWL_ERR(priv, "Bad return from %s (0x%08X)\n",
|
||||
IWL_ERR(shrd->trans, "Bad return from %s (0x%08X)\n",
|
||||
get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
|
||||
return;
|
||||
}
|
||||
@ -1045,11 +967,11 @@ static void iwl_generic_cmd_callback(struct iwl_priv *priv,
|
||||
switch (cmd->hdr.cmd) {
|
||||
case REPLY_TX_LINK_QUALITY_CMD:
|
||||
case SENSITIVITY_CMD:
|
||||
IWL_DEBUG_HC_DUMP(priv, "back from %s (0x%08X)\n",
|
||||
IWL_DEBUG_HC_DUMP(shrd->trans, "back from %s (0x%08X)\n",
|
||||
get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
|
||||
break;
|
||||
default:
|
||||
IWL_DEBUG_HC(priv, "back from %s (0x%08X)\n",
|
||||
IWL_DEBUG_HC(shrd->trans, "back from %s (0x%08X)\n",
|
||||
get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
|
||||
}
|
||||
#endif
|
||||
@ -1107,7 +1029,7 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = wait_event_interruptible_timeout(priv(trans)->wait_command_queue,
|
||||
ret = wait_event_interruptible_timeout(trans->shrd->wait_command_queue,
|
||||
!test_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status),
|
||||
HOST_COMPLETE_TIMEOUT);
|
||||
if (!ret) {
|
||||
|
@ -65,14 +65,13 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/gfp.h>
|
||||
|
||||
#include "iwl-dev.h"
|
||||
#include "iwl-trans.h"
|
||||
#include "iwl-core.h"
|
||||
#include "iwl-helpers.h"
|
||||
#include "iwl-trans-int-pcie.h"
|
||||
/*TODO remove uneeded includes when the transport layer tx_free will be here */
|
||||
#include "iwl-agn.h"
|
||||
#include "iwl-csr.h"
|
||||
#include "iwl-prph.h"
|
||||
#include "iwl-shared.h"
|
||||
#include "iwl-eeprom.h"
|
||||
#include "iwl-agn-hw.h"
|
||||
|
||||
static int iwl_trans_rx_alloc(struct iwl_trans *trans)
|
||||
{
|
||||
@ -604,9 +603,8 @@ error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void iwl_set_pwr_vmain(struct iwl_priv *priv)
|
||||
static void iwl_set_pwr_vmain(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans *trans = trans(priv);
|
||||
/*
|
||||
* (for documentation purposes)
|
||||
* to set power to V_AUX, do:
|
||||
@ -625,11 +623,10 @@ static void iwl_set_pwr_vmain(struct iwl_priv *priv)
|
||||
static int iwl_nic_init(struct iwl_trans *trans)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct iwl_priv *priv = priv(trans);
|
||||
|
||||
/* nic_init */
|
||||
spin_lock_irqsave(&trans->shrd->lock, flags);
|
||||
iwl_apm_init(priv);
|
||||
iwl_apm_init(priv(trans));
|
||||
|
||||
/* Set interrupt coalescing calibration timer to default (512 usecs) */
|
||||
iwl_write8(bus(trans), CSR_INT_COALESCING,
|
||||
@ -637,9 +634,9 @@ static int iwl_nic_init(struct iwl_trans *trans)
|
||||
|
||||
spin_unlock_irqrestore(&trans->shrd->lock, flags);
|
||||
|
||||
iwl_set_pwr_vmain(priv);
|
||||
iwl_set_pwr_vmain(trans);
|
||||
|
||||
priv->cfg->lib->nic_config(priv);
|
||||
iwl_nic_config(priv(trans));
|
||||
|
||||
/* Allocate the RX queue, or reset if it is already allocated */
|
||||
iwl_rx_init(trans);
|
||||
@ -764,7 +761,6 @@ static const u8 iwlagn_pan_ac_to_queue[] = {
|
||||
static int iwl_trans_pcie_start_device(struct iwl_trans *trans)
|
||||
{
|
||||
int ret;
|
||||
struct iwl_priv *priv = priv(trans);
|
||||
struct iwl_trans_pcie *trans_pcie =
|
||||
IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
|
||||
@ -792,7 +788,7 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans)
|
||||
set_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
|
||||
|
||||
if (iwl_is_rfkill(trans->shrd)) {
|
||||
wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
|
||||
iwl_set_hw_rfkill_state(priv(trans), true);
|
||||
iwl_enable_interrupts(trans);
|
||||
return -ERFKILL;
|
||||
}
|
||||
@ -833,8 +829,6 @@ static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask)
|
||||
static void iwl_trans_pcie_tx_start(struct iwl_trans *trans)
|
||||
{
|
||||
const struct queue_to_fifo_ac *queue_to_fifo;
|
||||
struct iwl_rxon_context *ctx;
|
||||
struct iwl_priv *priv = priv(trans);
|
||||
struct iwl_trans_pcie *trans_pcie =
|
||||
IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
u32 a;
|
||||
@ -902,7 +896,7 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans)
|
||||
iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7));
|
||||
|
||||
/* map queues to FIFOs */
|
||||
if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
|
||||
if (trans->shrd->valid_contexts != BIT(IWL_RXON_CTX_BSS))
|
||||
queue_to_fifo = iwlagn_ipan_queue_to_tx_fifo;
|
||||
else
|
||||
queue_to_fifo = iwlagn_default_queue_to_tx_fifo;
|
||||
@ -914,8 +908,6 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans)
|
||||
sizeof(trans_pcie->queue_stopped));
|
||||
for (i = 0; i < 4; i++)
|
||||
atomic_set(&trans_pcie->queue_stop_count[i], 0);
|
||||
for_each_context(priv, ctx)
|
||||
ctx->last_tx_rejected = false;
|
||||
|
||||
/* reset to 0 to enable all the queue first */
|
||||
trans_pcie->txq_ctx_active_msk = 0;
|
||||
@ -1397,7 +1389,7 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans)
|
||||
else
|
||||
clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status);
|
||||
|
||||
wiphy_rfkill_set_hw_state(priv(trans)->hw->wiphy, hw_rfkill);
|
||||
iwl_set_hw_rfkill_state(priv(trans), hw_rfkill);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1505,12 +1497,144 @@ static int iwl_trans_pcie_check_stuck_queue(struct iwl_trans *trans, int cnt)
|
||||
if (time_after(jiffies, timeout)) {
|
||||
IWL_ERR(trans, "Queue %d stuck for %u ms.\n", q->id,
|
||||
hw_params(trans).wd_timeout);
|
||||
IWL_ERR(trans, "Current read_ptr %d write_ptr %d\n",
|
||||
q->read_ptr, q->write_ptr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *get_fh_string(int cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
|
||||
IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
|
||||
IWL_CMD(FH_RSCSR_CHNL0_WPTR);
|
||||
IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
|
||||
IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
|
||||
IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
|
||||
IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
|
||||
IWL_CMD(FH_TSSR_TX_STATUS_REG);
|
||||
IWL_CMD(FH_TSSR_TX_ERROR_REG);
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display)
|
||||
{
|
||||
int i;
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
int pos = 0;
|
||||
size_t bufsz = 0;
|
||||
#endif
|
||||
static const u32 fh_tbl[] = {
|
||||
FH_RSCSR_CHNL0_STTS_WPTR_REG,
|
||||
FH_RSCSR_CHNL0_RBDCB_BASE_REG,
|
||||
FH_RSCSR_CHNL0_WPTR,
|
||||
FH_MEM_RCSR_CHNL0_CONFIG_REG,
|
||||
FH_MEM_RSSR_SHARED_CTRL_REG,
|
||||
FH_MEM_RSSR_RX_STATUS_REG,
|
||||
FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
|
||||
FH_TSSR_TX_STATUS_REG,
|
||||
FH_TSSR_TX_ERROR_REG
|
||||
};
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
if (display) {
|
||||
bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
|
||||
*buf = kmalloc(bufsz, GFP_KERNEL);
|
||||
if (!*buf)
|
||||
return -ENOMEM;
|
||||
pos += scnprintf(*buf + pos, bufsz - pos,
|
||||
"FH register values:\n");
|
||||
for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
|
||||
pos += scnprintf(*buf + pos, bufsz - pos,
|
||||
" %34s: 0X%08x\n",
|
||||
get_fh_string(fh_tbl[i]),
|
||||
iwl_read_direct32(bus(trans), fh_tbl[i]));
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
#endif
|
||||
IWL_ERR(trans, "FH register values:\n");
|
||||
for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
|
||||
IWL_ERR(trans, " %34s: 0X%08x\n",
|
||||
get_fh_string(fh_tbl[i]),
|
||||
iwl_read_direct32(bus(trans), fh_tbl[i]));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *get_csr_string(int cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
IWL_CMD(CSR_HW_IF_CONFIG_REG);
|
||||
IWL_CMD(CSR_INT_COALESCING);
|
||||
IWL_CMD(CSR_INT);
|
||||
IWL_CMD(CSR_INT_MASK);
|
||||
IWL_CMD(CSR_FH_INT_STATUS);
|
||||
IWL_CMD(CSR_GPIO_IN);
|
||||
IWL_CMD(CSR_RESET);
|
||||
IWL_CMD(CSR_GP_CNTRL);
|
||||
IWL_CMD(CSR_HW_REV);
|
||||
IWL_CMD(CSR_EEPROM_REG);
|
||||
IWL_CMD(CSR_EEPROM_GP);
|
||||
IWL_CMD(CSR_OTP_GP_REG);
|
||||
IWL_CMD(CSR_GIO_REG);
|
||||
IWL_CMD(CSR_GP_UCODE_REG);
|
||||
IWL_CMD(CSR_GP_DRIVER_REG);
|
||||
IWL_CMD(CSR_UCODE_DRV_GP1);
|
||||
IWL_CMD(CSR_UCODE_DRV_GP2);
|
||||
IWL_CMD(CSR_LED_REG);
|
||||
IWL_CMD(CSR_DRAM_INT_TBL_REG);
|
||||
IWL_CMD(CSR_GIO_CHICKEN_BITS);
|
||||
IWL_CMD(CSR_ANA_PLL_CFG);
|
||||
IWL_CMD(CSR_HW_REV_WA_REG);
|
||||
IWL_CMD(CSR_DBG_HPET_MEM_REG);
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
void iwl_dump_csr(struct iwl_trans *trans)
|
||||
{
|
||||
int i;
|
||||
static const u32 csr_tbl[] = {
|
||||
CSR_HW_IF_CONFIG_REG,
|
||||
CSR_INT_COALESCING,
|
||||
CSR_INT,
|
||||
CSR_INT_MASK,
|
||||
CSR_FH_INT_STATUS,
|
||||
CSR_GPIO_IN,
|
||||
CSR_RESET,
|
||||
CSR_GP_CNTRL,
|
||||
CSR_HW_REV,
|
||||
CSR_EEPROM_REG,
|
||||
CSR_EEPROM_GP,
|
||||
CSR_OTP_GP_REG,
|
||||
CSR_GIO_REG,
|
||||
CSR_GP_UCODE_REG,
|
||||
CSR_GP_DRIVER_REG,
|
||||
CSR_UCODE_DRV_GP1,
|
||||
CSR_UCODE_DRV_GP2,
|
||||
CSR_LED_REG,
|
||||
CSR_DRAM_INT_TBL_REG,
|
||||
CSR_GIO_CHICKEN_BITS,
|
||||
CSR_ANA_PLL_CFG,
|
||||
CSR_HW_REV_WA_REG,
|
||||
CSR_DBG_HPET_MEM_REG
|
||||
};
|
||||
IWL_ERR(trans, "CSR values:\n");
|
||||
IWL_ERR(trans, "(2nd byte of CSR_INT_COALESCING is "
|
||||
"CSR_INT_PERIODIC_REG)\n");
|
||||
for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) {
|
||||
IWL_ERR(trans, " %25s: 0X%08x\n",
|
||||
get_csr_string(csr_tbl[i]),
|
||||
iwl_read32(bus(trans), csr_tbl[i]));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
/* create and remove of files */
|
||||
#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
|
||||
@ -1563,118 +1687,12 @@ static const struct file_operations iwl_dbgfs_##name##_ops = { \
|
||||
.llseek = generic_file_llseek, \
|
||||
};
|
||||
|
||||
static ssize_t iwl_dbgfs_traffic_log_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_trans *trans = file->private_data;
|
||||
struct iwl_priv *priv = priv(trans);
|
||||
int pos = 0, ofs = 0;
|
||||
int cnt = 0, entry;
|
||||
struct iwl_trans_pcie *trans_pcie =
|
||||
IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
struct iwl_tx_queue *txq;
|
||||
struct iwl_queue *q;
|
||||
struct iwl_rx_queue *rxq = &trans_pcie->rxq;
|
||||
char *buf;
|
||||
int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
|
||||
(hw_params(trans).max_txq_num * 32 * 8) + 400;
|
||||
const u8 *ptr;
|
||||
ssize_t ret;
|
||||
|
||||
if (!trans_pcie->txq) {
|
||||
IWL_ERR(trans, "txq not ready\n");
|
||||
return -EAGAIN;
|
||||
}
|
||||
buf = kzalloc(bufsz, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
IWL_ERR(trans, "Can not allocate buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
|
||||
for (cnt = 0; cnt < hw_params(trans).max_txq_num; cnt++) {
|
||||
txq = &trans_pcie->txq[cnt];
|
||||
q = &txq->q;
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"q[%d]: read_ptr: %u, write_ptr: %u\n",
|
||||
cnt, q->read_ptr, q->write_ptr);
|
||||
}
|
||||
if (priv->tx_traffic &&
|
||||
(iwl_get_debug_level(trans->shrd) & IWL_DL_TX)) {
|
||||
ptr = priv->tx_traffic;
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"Tx Traffic idx: %u\n", priv->tx_traffic_idx);
|
||||
for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
|
||||
for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
|
||||
entry++, ofs += 16) {
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"0x%.4x ", ofs);
|
||||
hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
|
||||
buf + pos, bufsz - pos, 0);
|
||||
pos += strlen(buf + pos);
|
||||
if (bufsz - pos > 0)
|
||||
buf[pos++] = '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"read: %u, write: %u\n",
|
||||
rxq->read, rxq->write);
|
||||
|
||||
if (priv->rx_traffic &&
|
||||
(iwl_get_debug_level(trans->shrd) & IWL_DL_RX)) {
|
||||
ptr = priv->rx_traffic;
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"Rx Traffic idx: %u\n", priv->rx_traffic_idx);
|
||||
for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) {
|
||||
for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16;
|
||||
entry++, ofs += 16) {
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"0x%.4x ", ofs);
|
||||
hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
|
||||
buf + pos, bufsz - pos, 0);
|
||||
pos += strlen(buf + pos);
|
||||
if (bufsz - pos > 0)
|
||||
buf[pos++] = '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_traffic_log_write(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_trans *trans = file->private_data;
|
||||
char buf[8];
|
||||
int buf_size;
|
||||
int traffic_log;
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
buf_size = min(count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, user_buf, buf_size))
|
||||
return -EFAULT;
|
||||
if (sscanf(buf, "%d", &traffic_log) != 1)
|
||||
return -EFAULT;
|
||||
if (traffic_log == 0)
|
||||
iwl_reset_traffic_log(priv(trans));
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_trans *trans = file->private_data;
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
struct iwl_priv *priv = priv(trans);
|
||||
struct iwl_tx_queue *txq;
|
||||
struct iwl_queue *q;
|
||||
char *buf;
|
||||
@ -1684,7 +1702,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
|
||||
const size_t bufsz = sizeof(char) * 64 * hw_params(trans).max_txq_num;
|
||||
|
||||
if (!trans_pcie->txq) {
|
||||
IWL_ERR(priv, "txq not ready\n");
|
||||
IWL_ERR(trans, "txq not ready\n");
|
||||
return -EAGAIN;
|
||||
}
|
||||
buf = kzalloc(bufsz, GFP_KERNEL);
|
||||
@ -1864,75 +1882,6 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file *file,
|
||||
return count;
|
||||
}
|
||||
|
||||
static const char *get_csr_string(int cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
IWL_CMD(CSR_HW_IF_CONFIG_REG);
|
||||
IWL_CMD(CSR_INT_COALESCING);
|
||||
IWL_CMD(CSR_INT);
|
||||
IWL_CMD(CSR_INT_MASK);
|
||||
IWL_CMD(CSR_FH_INT_STATUS);
|
||||
IWL_CMD(CSR_GPIO_IN);
|
||||
IWL_CMD(CSR_RESET);
|
||||
IWL_CMD(CSR_GP_CNTRL);
|
||||
IWL_CMD(CSR_HW_REV);
|
||||
IWL_CMD(CSR_EEPROM_REG);
|
||||
IWL_CMD(CSR_EEPROM_GP);
|
||||
IWL_CMD(CSR_OTP_GP_REG);
|
||||
IWL_CMD(CSR_GIO_REG);
|
||||
IWL_CMD(CSR_GP_UCODE_REG);
|
||||
IWL_CMD(CSR_GP_DRIVER_REG);
|
||||
IWL_CMD(CSR_UCODE_DRV_GP1);
|
||||
IWL_CMD(CSR_UCODE_DRV_GP2);
|
||||
IWL_CMD(CSR_LED_REG);
|
||||
IWL_CMD(CSR_DRAM_INT_TBL_REG);
|
||||
IWL_CMD(CSR_GIO_CHICKEN_BITS);
|
||||
IWL_CMD(CSR_ANA_PLL_CFG);
|
||||
IWL_CMD(CSR_HW_REV_WA_REG);
|
||||
IWL_CMD(CSR_DBG_HPET_MEM_REG);
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
void iwl_dump_csr(struct iwl_trans *trans)
|
||||
{
|
||||
int i;
|
||||
static const u32 csr_tbl[] = {
|
||||
CSR_HW_IF_CONFIG_REG,
|
||||
CSR_INT_COALESCING,
|
||||
CSR_INT,
|
||||
CSR_INT_MASK,
|
||||
CSR_FH_INT_STATUS,
|
||||
CSR_GPIO_IN,
|
||||
CSR_RESET,
|
||||
CSR_GP_CNTRL,
|
||||
CSR_HW_REV,
|
||||
CSR_EEPROM_REG,
|
||||
CSR_EEPROM_GP,
|
||||
CSR_OTP_GP_REG,
|
||||
CSR_GIO_REG,
|
||||
CSR_GP_UCODE_REG,
|
||||
CSR_GP_DRIVER_REG,
|
||||
CSR_UCODE_DRV_GP1,
|
||||
CSR_UCODE_DRV_GP2,
|
||||
CSR_LED_REG,
|
||||
CSR_DRAM_INT_TBL_REG,
|
||||
CSR_GIO_CHICKEN_BITS,
|
||||
CSR_ANA_PLL_CFG,
|
||||
CSR_HW_REV_WA_REG,
|
||||
CSR_DBG_HPET_MEM_REG
|
||||
};
|
||||
IWL_ERR(trans, "CSR values:\n");
|
||||
IWL_ERR(trans, "(2nd byte of CSR_INT_COALESCING is "
|
||||
"CSR_INT_PERIODIC_REG)\n");
|
||||
for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) {
|
||||
IWL_ERR(trans, " %25s: 0X%08x\n",
|
||||
get_csr_string(csr_tbl[i]),
|
||||
iwl_read32(bus(trans), csr_tbl[i]));
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_csr_write(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
@ -1954,67 +1903,6 @@ static ssize_t iwl_dbgfs_csr_write(struct file *file,
|
||||
return count;
|
||||
}
|
||||
|
||||
static const char *get_fh_string(int cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
|
||||
IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
|
||||
IWL_CMD(FH_RSCSR_CHNL0_WPTR);
|
||||
IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
|
||||
IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
|
||||
IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
|
||||
IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
|
||||
IWL_CMD(FH_TSSR_TX_STATUS_REG);
|
||||
IWL_CMD(FH_TSSR_TX_ERROR_REG);
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display)
|
||||
{
|
||||
int i;
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
int pos = 0;
|
||||
size_t bufsz = 0;
|
||||
#endif
|
||||
static const u32 fh_tbl[] = {
|
||||
FH_RSCSR_CHNL0_STTS_WPTR_REG,
|
||||
FH_RSCSR_CHNL0_RBDCB_BASE_REG,
|
||||
FH_RSCSR_CHNL0_WPTR,
|
||||
FH_MEM_RCSR_CHNL0_CONFIG_REG,
|
||||
FH_MEM_RSSR_SHARED_CTRL_REG,
|
||||
FH_MEM_RSSR_RX_STATUS_REG,
|
||||
FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
|
||||
FH_TSSR_TX_STATUS_REG,
|
||||
FH_TSSR_TX_ERROR_REG
|
||||
};
|
||||
#ifdef CONFIG_IWLWIFI_DEBUG
|
||||
if (display) {
|
||||
bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
|
||||
*buf = kmalloc(bufsz, GFP_KERNEL);
|
||||
if (!*buf)
|
||||
return -ENOMEM;
|
||||
pos += scnprintf(*buf + pos, bufsz - pos,
|
||||
"FH register values:\n");
|
||||
for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
|
||||
pos += scnprintf(*buf + pos, bufsz - pos,
|
||||
" %34s: 0X%08x\n",
|
||||
get_fh_string(fh_tbl[i]),
|
||||
iwl_read_direct32(bus(trans), fh_tbl[i]));
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
#endif
|
||||
IWL_ERR(trans, "FH register values:\n");
|
||||
for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
|
||||
IWL_ERR(trans, " %34s: 0X%08x\n",
|
||||
get_fh_string(fh_tbl[i]),
|
||||
iwl_read_direct32(bus(trans), fh_tbl[i]));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
@ -2034,7 +1922,6 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file,
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
|
||||
DEBUGFS_READ_WRITE_FILE_OPS(log_event);
|
||||
DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
|
||||
DEBUGFS_READ_FILE_OPS(fh_reg);
|
||||
@ -2049,7 +1936,6 @@ DEBUGFS_WRITE_FILE_OPS(csr);
|
||||
static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,
|
||||
struct dentry *dir)
|
||||
{
|
||||
DEBUGFS_ADD_FILE(traffic_log, dir, S_IWUSR | S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(rx_queue, dir, S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(tx_queue, dir, S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(log_event, dir, S_IWUSR | S_IRUSR);
|
||||
|
@ -73,10 +73,70 @@
|
||||
* layer */
|
||||
|
||||
struct iwl_priv;
|
||||
struct iwl_rxon_context;
|
||||
struct iwl_host_cmd;
|
||||
struct iwl_shared;
|
||||
struct iwl_device_cmd;
|
||||
|
||||
#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
|
||||
#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
|
||||
#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
|
||||
|
||||
enum {
|
||||
CMD_SYNC = 0,
|
||||
CMD_ASYNC = BIT(0),
|
||||
CMD_WANT_SKB = BIT(1),
|
||||
CMD_ON_DEMAND = BIT(2),
|
||||
};
|
||||
|
||||
#define DEF_CMD_PAYLOAD_SIZE 320
|
||||
|
||||
/**
|
||||
* struct iwl_device_cmd
|
||||
*
|
||||
* For allocation of the command and tx queues, this establishes the overall
|
||||
* size of the largest command we send to uCode, except for commands that
|
||||
* aren't fully copied and use other TFD space.
|
||||
*/
|
||||
struct iwl_device_cmd {
|
||||
struct iwl_cmd_header hdr; /* uCode API */
|
||||
union {
|
||||
u32 flags;
|
||||
u8 val8;
|
||||
u16 val16;
|
||||
u32 val32;
|
||||
struct iwl_tx_cmd tx;
|
||||
struct iwl6000_channel_switch_cmd chswitch;
|
||||
u8 payload[DEF_CMD_PAYLOAD_SIZE];
|
||||
} __packed cmd;
|
||||
} __packed;
|
||||
|
||||
#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))
|
||||
|
||||
#define IWL_MAX_CMD_TFDS 2
|
||||
|
||||
enum iwl_hcmd_dataflag {
|
||||
IWL_HCMD_DFL_NOCOPY = BIT(0),
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_host_cmd - Host command to the uCode
|
||||
* @data: array of chunks that composes the data of the host command
|
||||
* @reply_page: pointer to the page that holds the response to the host command
|
||||
* @callback:
|
||||
* @flags: can be CMD_* note CMD_WANT_SKB is incompatible withe CMD_ASYNC
|
||||
* @len: array of the lenths of the chunks in data
|
||||
* @dataflags:
|
||||
* @id: id of the host command
|
||||
*/
|
||||
struct iwl_host_cmd {
|
||||
const void *data[IWL_MAX_CMD_TFDS];
|
||||
unsigned long reply_page;
|
||||
void (*callback)(struct iwl_shared *shrd,
|
||||
struct iwl_device_cmd *cmd,
|
||||
struct iwl_rx_packet *pkt);
|
||||
u32 flags;
|
||||
u16 len[IWL_MAX_CMD_TFDS];
|
||||
u8 dataflags[IWL_MAX_CMD_TFDS];
|
||||
u8 id;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_trans_ops - transport specific operations
|
||||
|
@ -973,6 +973,23 @@ static const struct {
|
||||
{ MODEL_8682, "libertas/usb8682.bin" }
|
||||
};
|
||||
|
||||
#ifdef CONFIG_OLPC
|
||||
|
||||
static int try_olpc_fw(struct if_usb_card *cardp)
|
||||
{
|
||||
int retval = -ENOENT;
|
||||
|
||||
/* try the OLPC firmware first; fall back to fw_table list */
|
||||
if (machine_is_olpc() && cardp->model == MODEL_8388)
|
||||
retval = request_firmware(&cardp->fw,
|
||||
"libertas/usb8388_olpc.bin", &cardp->udev->dev);
|
||||
return retval;
|
||||
}
|
||||
|
||||
#else
|
||||
static int try_olpc_fw(struct if_usb_card *cardp) { return -ENOENT; }
|
||||
#endif /* !CONFIG_OLPC */
|
||||
|
||||
static int get_fw(struct if_usb_card *cardp, const char *fwname)
|
||||
{
|
||||
int i;
|
||||
@ -981,6 +998,10 @@ static int get_fw(struct if_usb_card *cardp, const char *fwname)
|
||||
if (fwname)
|
||||
return request_firmware(&cardp->fw, fwname, &cardp->udev->dev);
|
||||
|
||||
/* Handle OLPC firmware */
|
||||
if (try_olpc_fw(cardp) == 0)
|
||||
return 0;
|
||||
|
||||
/* Otherwise search for firmware to use */
|
||||
for (i = 0; i < ARRAY_SIZE(fw_table); i++) {
|
||||
if (fw_table[i].model != cardp->model)
|
||||
|
@ -147,13 +147,12 @@ static int mwifiex_get_common_rates(struct mwifiex_private *priv, u8 *rate1,
|
||||
u8 *ptr = rate1, *tmp;
|
||||
u32 i, j;
|
||||
|
||||
tmp = kmalloc(rate1_size, GFP_KERNEL);
|
||||
tmp = kmemdup(rate1, rate1_size, GFP_KERNEL);
|
||||
if (!tmp) {
|
||||
dev_err(priv->adapter->dev, "failed to alloc tmp buf\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(tmp, rate1, rate1_size);
|
||||
memset(rate1, 0, rate1_size);
|
||||
|
||||
for (i = 0; rate2[i] && i < rate2_size; i++) {
|
||||
|
@ -1479,12 +1479,12 @@ mwifiex_update_curr_bss_params(struct mwifiex_private *priv,
|
||||
dev_err(priv->adapter->dev, " failed to alloc bss_desc\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
beacon_ie = kzalloc(ie_len, GFP_KERNEL);
|
||||
|
||||
beacon_ie = kmemdup(ie_buf, ie_len, GFP_KERNEL);
|
||||
if (!beacon_ie) {
|
||||
dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(beacon_ie, ie_buf, ie_len);
|
||||
|
||||
ret = mwifiex_fill_new_bss_desc(priv, bssid, rssi, beacon_ie,
|
||||
ie_len, beacon_period,
|
||||
@ -1986,7 +1986,7 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv)
|
||||
priv->curr_bcn_size = curr_bss->beacon_buf_size;
|
||||
|
||||
kfree(priv->curr_bcn_buf);
|
||||
priv->curr_bcn_buf = kzalloc(curr_bss->beacon_buf_size,
|
||||
priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size,
|
||||
GFP_KERNEL);
|
||||
if (!priv->curr_bcn_buf) {
|
||||
dev_err(priv->adapter->dev,
|
||||
|
@ -199,13 +199,14 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
|
||||
dev_err(priv->adapter->dev, " failed to alloc bss_desc\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
beacon_ie = kzalloc(bss->len_beacon_ies, GFP_KERNEL);
|
||||
|
||||
beacon_ie = kmemdup(bss->information_elements,
|
||||
bss->len_beacon_ies, GFP_KERNEL);
|
||||
if (!beacon_ie) {
|
||||
dev_err(priv->adapter->dev, " failed to alloc bss_desc\n");
|
||||
dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
memcpy(beacon_ie, bss->information_elements,
|
||||
bss->len_beacon_ies);
|
||||
|
||||
ret = mwifiex_fill_new_bss_desc(priv, bss->bssid, bss->signal,
|
||||
beacon_ie, bss->len_beacon_ies,
|
||||
bss->beacon_interval,
|
||||
|
@ -5501,6 +5501,14 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv)
|
||||
|
||||
/* Set rssi values to dBm */
|
||||
hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_HAS_RATE_CONTROL;
|
||||
|
||||
/*
|
||||
* Ask mac80211 to not to trigger PS mode
|
||||
* based on PM bit of incoming frames.
|
||||
*/
|
||||
if (priv->ap_fw)
|
||||
hw->flags |= IEEE80211_HW_AP_LINK_PS;
|
||||
|
||||
hw->vif_data_size = sizeof(struct mwl8k_vif);
|
||||
hw->sta_data_size = sizeof(struct mwl8k_sta);
|
||||
|
||||
|
@ -664,6 +664,9 @@
|
||||
|
||||
/*
|
||||
* LED_CFG: LED control
|
||||
* ON_PERIOD: LED active time (ms) during TX (only used for LED mode 1)
|
||||
* OFF_PERIOD: LED inactive time (ms) during TX (only used for LED mode 1)
|
||||
* SLOW_BLINK_PERIOD: LED blink interval in seconds (only used for LED mode 2)
|
||||
* color LED's:
|
||||
* 0: off
|
||||
* 1: blinking upon TX2
|
||||
|
@ -493,7 +493,7 @@ void rt2800_write_tx_data(struct queue_entry *entry,
|
||||
rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->u.ht.ba_size);
|
||||
rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID,
|
||||
test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ?
|
||||
txdesc->key_idx : 0xff);
|
||||
txdesc->key_idx : txdesc->u.ht.wcid);
|
||||
rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
|
||||
txdesc->length);
|
||||
rt2x00_set_field32(&word, TXWI_W1_PACKETID_QUEUE, entry->queue->qid);
|
||||
@ -601,7 +601,7 @@ void rt2800_process_rxwi(struct queue_entry *entry,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_process_rxwi);
|
||||
|
||||
void rt2800_txdone_entry(struct queue_entry *entry, u32 status)
|
||||
void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
|
||||
struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
|
||||
@ -609,13 +609,11 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status)
|
||||
u32 word;
|
||||
u16 mcs, real_mcs;
|
||||
int aggr, ampdu;
|
||||
__le32 *txwi;
|
||||
|
||||
/*
|
||||
* Obtain the status about this packet.
|
||||
*/
|
||||
txdesc.flags = 0;
|
||||
txwi = rt2800_drv_get_txwi(entry);
|
||||
rt2x00_desc_read(txwi, 0, &word);
|
||||
|
||||
mcs = rt2x00_get_field32(word, TXWI_W0_MCS);
|
||||
@ -899,28 +897,12 @@ static void rt2800_brightness_set(struct led_classdev *led_cdev,
|
||||
}
|
||||
}
|
||||
|
||||
static int rt2800_blink_set(struct led_classdev *led_cdev,
|
||||
unsigned long *delay_on, unsigned long *delay_off)
|
||||
{
|
||||
struct rt2x00_led *led =
|
||||
container_of(led_cdev, struct rt2x00_led, led_dev);
|
||||
u32 reg;
|
||||
|
||||
rt2800_register_read(led->rt2x00dev, LED_CFG, ®);
|
||||
rt2x00_set_field32(®, LED_CFG_ON_PERIOD, *delay_on);
|
||||
rt2x00_set_field32(®, LED_CFG_OFF_PERIOD, *delay_off);
|
||||
rt2800_register_write(led->rt2x00dev, LED_CFG, reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rt2800_init_led(struct rt2x00_dev *rt2x00dev,
|
||||
struct rt2x00_led *led, enum led_type type)
|
||||
{
|
||||
led->rt2x00dev = rt2x00dev;
|
||||
led->type = type;
|
||||
led->led_dev.brightness_set = rt2800_brightness_set;
|
||||
led->led_dev.blink_set = rt2800_blink_set;
|
||||
led->flags = LED_INITIALIZED;
|
||||
}
|
||||
#endif /* CONFIG_RT2X00_LIB_LEDS */
|
||||
@ -928,11 +910,51 @@ static void rt2800_init_led(struct rt2x00_dev *rt2x00dev,
|
||||
/*
|
||||
* Configuration handlers.
|
||||
*/
|
||||
static void rt2800_config_wcid_attr(struct rt2x00_dev *rt2x00dev,
|
||||
struct rt2x00lib_crypto *crypto,
|
||||
struct ieee80211_key_conf *key)
|
||||
static void rt2800_config_wcid(struct rt2x00_dev *rt2x00dev,
|
||||
const u8 *address,
|
||||
int wcid)
|
||||
{
|
||||
struct mac_wcid_entry wcid_entry;
|
||||
u32 offset;
|
||||
|
||||
offset = MAC_WCID_ENTRY(wcid);
|
||||
|
||||
memset(&wcid_entry, 0xff, sizeof(wcid_entry));
|
||||
if (address)
|
||||
memcpy(wcid_entry.mac, address, ETH_ALEN);
|
||||
|
||||
rt2800_register_multiwrite(rt2x00dev, offset,
|
||||
&wcid_entry, sizeof(wcid_entry));
|
||||
}
|
||||
|
||||
static void rt2800_delete_wcid_attr(struct rt2x00_dev *rt2x00dev, int wcid)
|
||||
{
|
||||
u32 offset;
|
||||
offset = MAC_WCID_ATTR_ENTRY(wcid);
|
||||
rt2800_register_write(rt2x00dev, offset, 0);
|
||||
}
|
||||
|
||||
static void rt2800_config_wcid_attr_bssidx(struct rt2x00_dev *rt2x00dev,
|
||||
int wcid, u32 bssidx)
|
||||
{
|
||||
u32 offset = MAC_WCID_ATTR_ENTRY(wcid);
|
||||
u32 reg;
|
||||
|
||||
/*
|
||||
* The BSS Idx numbers is split in a main value of 3 bits,
|
||||
* and a extended field for adding one additional bit to the value.
|
||||
*/
|
||||
rt2800_register_read(rt2x00dev, offset, ®);
|
||||
rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX, (bssidx & 0x7));
|
||||
rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX_EXT,
|
||||
(bssidx & 0x8) >> 3);
|
||||
rt2800_register_write(rt2x00dev, offset, reg);
|
||||
}
|
||||
|
||||
static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev,
|
||||
struct rt2x00lib_crypto *crypto,
|
||||
struct ieee80211_key_conf *key)
|
||||
{
|
||||
struct mac_iveiv_entry iveiv_entry;
|
||||
u32 offset;
|
||||
u32 reg;
|
||||
@ -952,14 +974,16 @@ static void rt2800_config_wcid_attr(struct rt2x00_dev *rt2x00dev,
|
||||
(crypto->cipher & 0x7));
|
||||
rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_CIPHER_EXT,
|
||||
(crypto->cipher & 0x8) >> 3);
|
||||
rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX,
|
||||
(crypto->bssidx & 0x7));
|
||||
rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_BSS_IDX_EXT,
|
||||
(crypto->bssidx & 0x8) >> 3);
|
||||
rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher);
|
||||
rt2800_register_write(rt2x00dev, offset, reg);
|
||||
} else {
|
||||
rt2800_register_write(rt2x00dev, offset, 0);
|
||||
/* Delete the cipher without touching the bssidx */
|
||||
rt2800_register_read(rt2x00dev, offset, ®);
|
||||
rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_KEYTAB, 0);
|
||||
rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_CIPHER, 0);
|
||||
rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_CIPHER_EXT, 0);
|
||||
rt2x00_set_field32(®, MAC_WCID_ATTRIBUTE_RX_WIUDF, 0);
|
||||
rt2800_register_write(rt2x00dev, offset, reg);
|
||||
}
|
||||
|
||||
offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
|
||||
@ -972,14 +996,6 @@ static void rt2800_config_wcid_attr(struct rt2x00_dev *rt2x00dev,
|
||||
iveiv_entry.iv[3] |= key->keyidx << 6;
|
||||
rt2800_register_multiwrite(rt2x00dev, offset,
|
||||
&iveiv_entry, sizeof(iveiv_entry));
|
||||
|
||||
offset = MAC_WCID_ENTRY(key->hw_key_idx);
|
||||
|
||||
memset(&wcid_entry, 0, sizeof(wcid_entry));
|
||||
if (crypto->cmd == SET_KEY)
|
||||
memcpy(wcid_entry.mac, crypto->address, ETH_ALEN);
|
||||
rt2800_register_multiwrite(rt2x00dev, offset,
|
||||
&wcid_entry, sizeof(wcid_entry));
|
||||
}
|
||||
|
||||
int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
|
||||
@ -1026,20 +1042,24 @@ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
|
||||
/*
|
||||
* Update WCID information
|
||||
*/
|
||||
rt2800_config_wcid_attr(rt2x00dev, crypto, key);
|
||||
rt2800_config_wcid(rt2x00dev, crypto->address, key->hw_key_idx);
|
||||
rt2800_config_wcid_attr_bssidx(rt2x00dev, key->hw_key_idx,
|
||||
crypto->bssidx);
|
||||
rt2800_config_wcid_attr_cipher(rt2x00dev, crypto, key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_config_shared_key);
|
||||
|
||||
static inline int rt2800_find_pairwise_keyslot(struct rt2x00_dev *rt2x00dev)
|
||||
static inline int rt2800_find_wcid(struct rt2x00_dev *rt2x00dev)
|
||||
{
|
||||
struct mac_wcid_entry wcid_entry;
|
||||
int idx;
|
||||
u32 offset, reg;
|
||||
u32 offset;
|
||||
|
||||
/*
|
||||
* Search for the first free pairwise key entry and return the
|
||||
* corresponding index.
|
||||
* Search for the first free WCID entry and return the corresponding
|
||||
* index.
|
||||
*
|
||||
* Make sure the WCID starts _after_ the last possible shared key
|
||||
* entry (>32).
|
||||
@ -1049,11 +1069,17 @@ static inline int rt2800_find_pairwise_keyslot(struct rt2x00_dev *rt2x00dev)
|
||||
* first 222 entries.
|
||||
*/
|
||||
for (idx = 33; idx <= 222; idx++) {
|
||||
offset = MAC_WCID_ATTR_ENTRY(idx);
|
||||
rt2800_register_read(rt2x00dev, offset, ®);
|
||||
if (!reg)
|
||||
offset = MAC_WCID_ENTRY(idx);
|
||||
rt2800_register_multiread(rt2x00dev, offset, &wcid_entry,
|
||||
sizeof(wcid_entry));
|
||||
if (is_broadcast_ether_addr(wcid_entry.mac))
|
||||
return idx;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use -1 to indicate that we don't have any more space in the WCID
|
||||
* table.
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1063,13 +1089,15 @@ int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
|
||||
{
|
||||
struct hw_key_entry key_entry;
|
||||
u32 offset;
|
||||
int idx;
|
||||
|
||||
if (crypto->cmd == SET_KEY) {
|
||||
idx = rt2800_find_pairwise_keyslot(rt2x00dev);
|
||||
if (idx < 0)
|
||||
/*
|
||||
* Allow key configuration only for STAs that are
|
||||
* known by the hw.
|
||||
*/
|
||||
if (crypto->wcid < 0)
|
||||
return -ENOSPC;
|
||||
key->hw_key_idx = idx;
|
||||
key->hw_key_idx = crypto->wcid;
|
||||
|
||||
memcpy(key_entry.key, crypto->key,
|
||||
sizeof(key_entry.key));
|
||||
@ -1086,12 +1114,59 @@ int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
|
||||
/*
|
||||
* Update WCID information
|
||||
*/
|
||||
rt2800_config_wcid_attr(rt2x00dev, crypto, key);
|
||||
rt2800_config_wcid_attr_cipher(rt2x00dev, crypto, key);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_config_pairwise_key);
|
||||
|
||||
int rt2800_sta_add(struct rt2x00_dev *rt2x00dev, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
int wcid;
|
||||
struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta);
|
||||
|
||||
/*
|
||||
* Find next free WCID.
|
||||
*/
|
||||
wcid = rt2800_find_wcid(rt2x00dev);
|
||||
|
||||
/*
|
||||
* Store selected wcid even if it is invalid so that we can
|
||||
* later decide if the STA is uploaded into the hw.
|
||||
*/
|
||||
sta_priv->wcid = wcid;
|
||||
|
||||
/*
|
||||
* No space left in the device, however, we can still communicate
|
||||
* with the STA -> No error.
|
||||
*/
|
||||
if (wcid < 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Clean up WCID attributes and write STA address to the device.
|
||||
*/
|
||||
rt2800_delete_wcid_attr(rt2x00dev, wcid);
|
||||
rt2800_config_wcid(rt2x00dev, sta->addr, wcid);
|
||||
rt2800_config_wcid_attr_bssidx(rt2x00dev, wcid,
|
||||
rt2x00lib_get_bssidx(rt2x00dev, vif));
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_sta_add);
|
||||
|
||||
int rt2800_sta_remove(struct rt2x00_dev *rt2x00dev, int wcid)
|
||||
{
|
||||
/*
|
||||
* Remove WCID entry, no need to clean the attributes as they will
|
||||
* get renewed when the WCID is reused.
|
||||
*/
|
||||
rt2800_config_wcid(rt2x00dev, NULL, wcid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2800_sta_remove);
|
||||
|
||||
void rt2800_config_filter(struct rt2x00_dev *rt2x00dev,
|
||||
const unsigned int filter_flags)
|
||||
{
|
||||
@ -2771,11 +2846,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
|
||||
SHARED_KEY_MODE_ENTRY(i), 0);
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
static const u32 wcid[2] = { 0xffffffff, 0x00ffffff };
|
||||
rt2800_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i),
|
||||
wcid, sizeof(wcid));
|
||||
|
||||
rt2800_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 0);
|
||||
rt2800_config_wcid(rt2x00dev, NULL, i);
|
||||
rt2800_delete_wcid_attr(rt2x00dev, i);
|
||||
rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
|
||||
}
|
||||
|
||||
@ -4409,8 +4481,19 @@ int rt2800_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, u16 tid, u16 *ssn,
|
||||
u8 buf_size)
|
||||
{
|
||||
struct rt2x00_sta *sta_priv = (struct rt2x00_sta *)sta->drv_priv;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* Don't allow aggregation for stations the hardware isn't aware
|
||||
* of because tx status reports for frames to an unknown station
|
||||
* always contain wcid=255 and thus we can't distinguish between
|
||||
* multiple stations which leads to unwanted situations when the
|
||||
* hw reorders frames due to aggregation.
|
||||
*/
|
||||
if (sta_priv->wcid < 0)
|
||||
return 1;
|
||||
|
||||
switch (action) {
|
||||
case IEEE80211_AMPDU_RX_START:
|
||||
case IEEE80211_AMPDU_RX_STOP:
|
||||
|
@ -152,7 +152,7 @@ void rt2800_write_tx_data(struct queue_entry *entry,
|
||||
struct txentry_desc *txdesc);
|
||||
void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc);
|
||||
|
||||
void rt2800_txdone_entry(struct queue_entry *entry, u32 status);
|
||||
void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32* txwi);
|
||||
|
||||
void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc);
|
||||
void rt2800_clear_beacon(struct queue_entry *entry);
|
||||
@ -166,6 +166,9 @@ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
|
||||
int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
|
||||
struct rt2x00lib_crypto *crypto,
|
||||
struct ieee80211_key_conf *key);
|
||||
int rt2800_sta_add(struct rt2x00_dev *rt2x00dev, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta);
|
||||
int rt2800_sta_remove(struct rt2x00_dev *rt2x00dev, int wcid);
|
||||
void rt2800_config_filter(struct rt2x00_dev *rt2x00dev,
|
||||
const unsigned int filter_flags);
|
||||
void rt2800_config_intf(struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf,
|
||||
|
@ -619,11 +619,11 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry,
|
||||
/*
|
||||
* Initialize TX descriptor
|
||||
*/
|
||||
rt2x00_desc_read(txd, 0, &word);
|
||||
word = 0;
|
||||
rt2x00_set_field32(&word, TXD_W0_SD_PTR0, skbdesc->skb_dma);
|
||||
rt2x00_desc_write(txd, 0, word);
|
||||
|
||||
rt2x00_desc_read(txd, 1, &word);
|
||||
word = 0;
|
||||
rt2x00_set_field32(&word, TXD_W1_SD_LEN1, entry->skb->len);
|
||||
rt2x00_set_field32(&word, TXD_W1_LAST_SEC1,
|
||||
!test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
|
||||
@ -634,12 +634,12 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry,
|
||||
rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0);
|
||||
rt2x00_desc_write(txd, 1, word);
|
||||
|
||||
rt2x00_desc_read(txd, 2, &word);
|
||||
word = 0;
|
||||
rt2x00_set_field32(&word, TXD_W2_SD_PTR1,
|
||||
skbdesc->skb_dma + TXWI_DESC_SIZE);
|
||||
rt2x00_desc_write(txd, 2, word);
|
||||
|
||||
rt2x00_desc_read(txd, 3, &word);
|
||||
word = 0;
|
||||
rt2x00_set_field32(&word, TXD_W3_WIV,
|
||||
!test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
|
||||
rt2x00_set_field32(&word, TXD_W3_QSEL, 2);
|
||||
@ -760,7 +760,7 @@ static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
|
||||
}
|
||||
|
||||
entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
|
||||
rt2800_txdone_entry(entry, status);
|
||||
rt2800_txdone_entry(entry, status, rt2800pci_get_txwi(entry));
|
||||
|
||||
if (--max_tx_done == 0)
|
||||
break;
|
||||
@ -1015,6 +1015,8 @@ static const struct ieee80211_ops rt2800pci_mac80211_ops = {
|
||||
.get_stats = rt2x00mac_get_stats,
|
||||
.get_tkip_seq = rt2800_get_tkip_seq,
|
||||
.set_rts_threshold = rt2800_set_rts_threshold,
|
||||
.sta_add = rt2x00mac_sta_add,
|
||||
.sta_remove = rt2x00mac_sta_remove,
|
||||
.bss_info_changed = rt2x00mac_bss_info_changed,
|
||||
.conf_tx = rt2800_conf_tx,
|
||||
.get_tsf = rt2800_get_tsf,
|
||||
@ -1076,6 +1078,8 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = {
|
||||
.config_erp = rt2800_config_erp,
|
||||
.config_ant = rt2800_config_ant,
|
||||
.config = rt2800_config,
|
||||
.sta_add = rt2800_sta_add,
|
||||
.sta_remove = rt2800_sta_remove,
|
||||
};
|
||||
|
||||
static const struct data_queue_desc rt2800pci_queue_rx = {
|
||||
@ -1153,6 +1157,7 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = {
|
||||
#endif
|
||||
#ifdef CONFIG_RT2800PCI_RT53XX
|
||||
{ PCI_DEVICE(0x1814, 0x5390) },
|
||||
{ PCI_DEVICE(0x1814, 0x539a) },
|
||||
{ PCI_DEVICE(0x1814, 0x539f) },
|
||||
#endif
|
||||
{ 0, }
|
||||
|
@ -534,7 +534,8 @@ static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev)
|
||||
if (!entry || rt2x00queue_empty(queue))
|
||||
break;
|
||||
|
||||
rt2800_txdone_entry(entry, reg);
|
||||
rt2800_txdone_entry(entry, reg,
|
||||
rt2800usb_get_txwi(entry));
|
||||
}
|
||||
}
|
||||
|
||||
@ -749,6 +750,8 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = {
|
||||
.get_stats = rt2x00mac_get_stats,
|
||||
.get_tkip_seq = rt2800_get_tkip_seq,
|
||||
.set_rts_threshold = rt2800_set_rts_threshold,
|
||||
.sta_add = rt2x00mac_sta_add,
|
||||
.sta_remove = rt2x00mac_sta_remove,
|
||||
.bss_info_changed = rt2x00mac_bss_info_changed,
|
||||
.conf_tx = rt2800_conf_tx,
|
||||
.get_tsf = rt2800_get_tsf,
|
||||
@ -806,6 +809,8 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
|
||||
.config_erp = rt2800_config_erp,
|
||||
.config_ant = rt2800_config_ant,
|
||||
.config = rt2800_config,
|
||||
.sta_add = rt2800_sta_add,
|
||||
.sta_remove = rt2800_sta_remove,
|
||||
};
|
||||
|
||||
static const struct data_queue_desc rt2800usb_queue_rx = {
|
||||
|
@ -478,6 +478,8 @@ struct rt2x00lib_crypto {
|
||||
u8 key[16];
|
||||
u8 tx_mic[8];
|
||||
u8 rx_mic[8];
|
||||
|
||||
int wcid;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -511,6 +513,19 @@ struct rt2x00intf_conf {
|
||||
__le32 bssid[2];
|
||||
};
|
||||
|
||||
/*
|
||||
* Private structure for storing STA details
|
||||
* wcid: Wireless Client ID
|
||||
*/
|
||||
struct rt2x00_sta {
|
||||
int wcid;
|
||||
};
|
||||
|
||||
static inline struct rt2x00_sta* sta_to_rt2x00_sta(struct ieee80211_sta *sta)
|
||||
{
|
||||
return (struct rt2x00_sta *)sta->drv_priv;
|
||||
}
|
||||
|
||||
/*
|
||||
* rt2x00lib callback functions.
|
||||
*/
|
||||
@ -620,6 +635,11 @@ struct rt2x00lib_ops {
|
||||
void (*config) (struct rt2x00_dev *rt2x00dev,
|
||||
struct rt2x00lib_conf *libconf,
|
||||
const unsigned int changed_flags);
|
||||
int (*sta_add) (struct rt2x00_dev *rt2x00dev,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta);
|
||||
int (*sta_remove) (struct rt2x00_dev *rt2x00dev,
|
||||
int wcid);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -1225,6 +1245,12 @@ static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev,
|
||||
}
|
||||
#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
|
||||
|
||||
/*
|
||||
* Utility functions.
|
||||
*/
|
||||
u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev,
|
||||
struct ieee80211_vif *vif);
|
||||
|
||||
/*
|
||||
* Interrupt context handlers.
|
||||
*/
|
||||
@ -1261,6 +1287,10 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
#else
|
||||
#define rt2x00mac_set_key NULL
|
||||
#endif /* CONFIG_RT2X00_LIB_CRYPTO */
|
||||
int rt2x00mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta);
|
||||
int rt2x00mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta);
|
||||
void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw);
|
||||
void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw);
|
||||
int rt2x00mac_get_stats(struct ieee80211_hw *hw,
|
||||
|
@ -32,6 +32,22 @@
|
||||
#include "rt2x00.h"
|
||||
#include "rt2x00lib.h"
|
||||
|
||||
/*
|
||||
* Utility functions.
|
||||
*/
|
||||
u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
/*
|
||||
* When in STA mode, bssidx is always 0 otherwise local_address[5]
|
||||
* contains the bss number, see BSS_ID_MASK comments for details.
|
||||
*/
|
||||
if (rt2x00dev->intf_sta_count)
|
||||
return 0;
|
||||
return vif->addr[5] & (rt2x00dev->ops->max_ap_intf - 1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00lib_get_bssidx);
|
||||
|
||||
/*
|
||||
* Radio control handlers.
|
||||
*/
|
||||
@ -914,6 +930,11 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
|
||||
else if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags))
|
||||
rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE;
|
||||
|
||||
/*
|
||||
* Tell mac80211 about the size of our private STA structure.
|
||||
*/
|
||||
rt2x00dev->hw->sta_data_size = sizeof(struct rt2x00_sta);
|
||||
|
||||
/*
|
||||
* Allocate tx status FIFO for driver use.
|
||||
*/
|
||||
|
@ -494,6 +494,7 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
struct rt2x00lib_crypto crypto;
|
||||
static const u8 bcast_addr[ETH_ALEN] =
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, };
|
||||
struct rt2x00_sta *sta_priv = NULL;
|
||||
|
||||
if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
|
||||
return 0;
|
||||
@ -504,24 +505,18 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
|
||||
memset(&crypto, 0, sizeof(crypto));
|
||||
|
||||
/*
|
||||
* When in STA mode, bssidx is always 0 otherwise local_address[5]
|
||||
* contains the bss number, see BSS_ID_MASK comments for details.
|
||||
*/
|
||||
if (rt2x00dev->intf_sta_count)
|
||||
crypto.bssidx = 0;
|
||||
else
|
||||
crypto.bssidx = vif->addr[5] & (rt2x00dev->ops->max_ap_intf - 1);
|
||||
|
||||
crypto.bssidx = rt2x00lib_get_bssidx(rt2x00dev, vif);
|
||||
crypto.cipher = rt2x00crypto_key_to_cipher(key);
|
||||
if (crypto.cipher == CIPHER_NONE)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
crypto.cmd = cmd;
|
||||
|
||||
if (sta)
|
||||
if (sta) {
|
||||
crypto.address = sta->addr;
|
||||
else
|
||||
sta_priv = sta_to_rt2x00_sta(sta);
|
||||
crypto.wcid = sta_priv->wcid;
|
||||
} else
|
||||
crypto.address = bcast_addr;
|
||||
|
||||
if (crypto.cipher == CIPHER_TKIP)
|
||||
@ -560,6 +555,39 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
EXPORT_SYMBOL_GPL(rt2x00mac_set_key);
|
||||
#endif /* CONFIG_RT2X00_LIB_CRYPTO */
|
||||
|
||||
int rt2x00mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta);
|
||||
|
||||
/*
|
||||
* If there's no space left in the device table store
|
||||
* -1 as wcid but tell mac80211 everything went ok.
|
||||
*/
|
||||
if (rt2x00dev->ops->lib->sta_add(rt2x00dev, vif, sta))
|
||||
sta_priv->wcid = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00mac_sta_add);
|
||||
|
||||
int rt2x00mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
struct rt2x00_sta *sta_priv = sta_to_rt2x00_sta(sta);
|
||||
|
||||
/*
|
||||
* If we never sent the STA to the device no need to clean it up.
|
||||
*/
|
||||
if (sta_priv->wcid < 0)
|
||||
return 0;
|
||||
|
||||
return rt2x00dev->ops->lib->sta_remove(rt2x00dev, sta_priv->wcid);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rt2x00mac_sta_remove);
|
||||
|
||||
void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
|
@ -310,11 +310,16 @@ static void rt2x00queue_create_tx_descriptor_ht(struct rt2x00_dev *rt2x00dev,
|
||||
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
struct rt2x00_sta *sta_priv = NULL;
|
||||
|
||||
if (tx_info->control.sta)
|
||||
if (tx_info->control.sta) {
|
||||
txdesc->u.ht.mpdu_density =
|
||||
tx_info->control.sta->ht_cap.ampdu_density;
|
||||
|
||||
sta_priv = sta_to_rt2x00_sta(tx_info->control.sta);
|
||||
txdesc->u.ht.wcid = sta_priv->wcid;
|
||||
}
|
||||
|
||||
txdesc->u.ht.ba_size = 7; /* FIXME: What value is needed? */
|
||||
|
||||
/*
|
||||
|
@ -288,8 +288,8 @@ enum txentry_desc_flags {
|
||||
* @signal: PLCP signal.
|
||||
* @service: PLCP service.
|
||||
* @msc: MCS.
|
||||
* @stbc: STBC.
|
||||
* @ba_size: BA size.
|
||||
* @stbc: Use Space Time Block Coding (only available for MCS rates < 8).
|
||||
* @ba_size: Size of the recepients RX reorder buffer - 1.
|
||||
* @rate_mode: Rate mode (See @enum rate_modulation).
|
||||
* @mpdu_density: MDPU density.
|
||||
* @retry_limit: Max number of retries.
|
||||
@ -321,6 +321,7 @@ struct txentry_desc {
|
||||
u8 ba_size;
|
||||
u8 mpdu_density;
|
||||
enum txop txop;
|
||||
int wcid;
|
||||
} ht;
|
||||
} u;
|
||||
|
||||
|
@ -294,9 +294,7 @@ static int wl1271_boot_upload_nvs(struct wl1271 *wl)
|
||||
*/
|
||||
if (wl->nvs_len == sizeof(struct wl1271_nvs_file) ||
|
||||
wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) {
|
||||
/* for now 11a is unsupported in AP mode */
|
||||
if (wl->bss_type != BSS_TYPE_AP_BSS &&
|
||||
nvs->general_params.dual_mode_select)
|
||||
if (nvs->general_params.dual_mode_select)
|
||||
wl->enable_11a = true;
|
||||
}
|
||||
|
||||
|
@ -236,7 +236,7 @@ static struct conf_drv_settings default_conf = {
|
||||
.ps_poll_recovery_period = 700,
|
||||
.bet_enable = CONF_BET_MODE_ENABLE,
|
||||
.bet_max_consecutive = 50,
|
||||
.psm_entry_retries = 5,
|
||||
.psm_entry_retries = 8,
|
||||
.psm_exit_retries = 16,
|
||||
.psm_entry_nullfunc_retries = 3,
|
||||
.psm_entry_hangover_period = 1,
|
||||
@ -2064,6 +2064,7 @@ deinit:
|
||||
wl->session_counter = 0;
|
||||
wl->rate_set = CONF_TX_RATE_MASK_BASIC;
|
||||
wl->vif = NULL;
|
||||
wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
|
||||
wl1271_free_ap_keys(wl);
|
||||
memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map));
|
||||
wl->ap_fw_ps_map = 0;
|
||||
@ -2199,10 +2200,14 @@ out:
|
||||
|
||||
static void wl1271_set_band_rate(struct wl1271 *wl)
|
||||
{
|
||||
if (wl->band == IEEE80211_BAND_2GHZ)
|
||||
if (wl->band == IEEE80211_BAND_2GHZ) {
|
||||
wl->basic_rate_set = wl->conf.tx.basic_rate;
|
||||
else
|
||||
wl->rate_set = wl->conf.tx.basic_rate;
|
||||
} else {
|
||||
wl->basic_rate_set = wl->conf.tx.basic_rate_5;
|
||||
wl->rate_set = wl->conf.tx.basic_rate_5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static bool wl12xx_is_roc(struct wl1271 *wl)
|
||||
@ -2653,6 +2658,17 @@ static int wl1271_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
|
||||
/*
|
||||
* A STA set to GEM cipher requires 2 tx spare blocks.
|
||||
* Return to default value when GEM cipher key is removed
|
||||
*/
|
||||
if (key_type == KEY_GEM) {
|
||||
if (action == KEY_ADD_OR_REPLACE)
|
||||
wl->tx_spare_blocks = 2;
|
||||
else if (action == KEY_REMOVE)
|
||||
wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
|
||||
}
|
||||
|
||||
addr = sta ? sta->addr : bcast_addr;
|
||||
|
||||
if (is_zero_ether_addr(addr)) {
|
||||
@ -3345,19 +3361,6 @@ sta_not_found:
|
||||
ret = wl1271_acx_conn_monit_params(wl, true);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
/* If we want to go in PSM but we're not there yet */
|
||||
if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) &&
|
||||
!test_bit(WL1271_FLAG_PSM, &wl->flags)) {
|
||||
enum wl1271_cmd_ps_mode mode;
|
||||
|
||||
mode = STATION_POWER_SAVE_MODE;
|
||||
ret = wl1271_ps_set_mode(wl, mode,
|
||||
wl->basic_rate,
|
||||
true);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* use defaults when not associated */
|
||||
bool was_assoc =
|
||||
@ -3501,6 +3504,19 @@ sta_not_found:
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* If we want to go in PSM but we're not there yet */
|
||||
if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) &&
|
||||
!test_bit(WL1271_FLAG_PSM, &wl->flags)) {
|
||||
enum wl1271_cmd_ps_mode mode;
|
||||
|
||||
mode = STATION_POWER_SAVE_MODE;
|
||||
ret = wl1271_ps_set_mode(wl, mode,
|
||||
wl->basic_rate,
|
||||
true);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle new association with HT. Do this after join. */
|
||||
@ -4475,6 +4491,7 @@ int wl1271_init_ieee80211(struct wl1271 *wl)
|
||||
wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
|
||||
wl->hw->wiphy->max_scan_ssids = 1;
|
||||
wl->hw->wiphy->max_sched_scan_ssids = 8;
|
||||
/*
|
||||
* Maximum length of elements in scanning probe request templates
|
||||
* should be the maximum length possible for a template, without
|
||||
@ -4599,6 +4616,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
|
||||
wl->sched_scanning = false;
|
||||
wl->tx_security_seq = 0;
|
||||
wl->tx_security_last_seq_lsb = 0;
|
||||
wl->tx_spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
|
||||
wl->role_id = WL12XX_INVALID_ROLE_ID;
|
||||
wl->system_hlid = WL12XX_SYSTEM_HLID;
|
||||
wl->sta_hlid = WL12XX_INVALID_LINK_ID;
|
||||
|
@ -473,6 +473,51 @@ wl1271_scan_sched_scan_channels(struct wl1271 *wl,
|
||||
cfg->passive[2] || cfg->active[2];
|
||||
}
|
||||
|
||||
/* Returns 0 if no wildcard is used, 1 if wildcard is used or a
|
||||
* negative value on error */
|
||||
static int
|
||||
wl12xx_scan_sched_scan_ssid_list(struct wl1271 *wl,
|
||||
struct cfg80211_sched_scan_request *req)
|
||||
{
|
||||
struct wl1271_cmd_sched_scan_ssid_list *cmd = NULL;
|
||||
struct cfg80211_ssid *ssid = req->ssids;
|
||||
int ret, wildcard = 0;
|
||||
|
||||
wl1271_debug(DEBUG_CMD, "cmd sched scan ssid list");
|
||||
|
||||
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
|
||||
while ((cmd->n_ssids < req->n_ssids) && ssid) {
|
||||
if (ssid->ssid_len == 0) {
|
||||
wildcard = 1;
|
||||
cmd->ssids[cmd->n_ssids].type = SCAN_SSID_TYPE_PUBLIC;
|
||||
} else {
|
||||
cmd->ssids[cmd->n_ssids].type = SCAN_SSID_TYPE_HIDDEN;
|
||||
}
|
||||
cmd->ssids[cmd->n_ssids].len = ssid->ssid_len;
|
||||
memcpy(cmd->ssids[cmd->n_ssids].ssid, ssid->ssid,
|
||||
ssid->ssid_len);
|
||||
ssid++;
|
||||
cmd->n_ssids++;
|
||||
}
|
||||
|
||||
wl1271_dump(DEBUG_SCAN, "SSID_LIST: ", cmd, sizeof(*cmd));
|
||||
|
||||
ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_SSID_CFG, cmd,
|
||||
sizeof(*cmd), 0);
|
||||
if (ret < 0) {
|
||||
wl1271_error("cmd sched scan ssid list failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = wildcard;
|
||||
out:
|
||||
kfree(cmd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wl1271_scan_sched_scan_config(struct wl1271 *wl,
|
||||
struct cfg80211_sched_scan_request *req,
|
||||
struct ieee80211_sched_scan_ies *ies)
|
||||
@ -504,14 +549,21 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl,
|
||||
for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++)
|
||||
cfg->intervals[i] = cpu_to_le32(req->interval);
|
||||
|
||||
if (!force_passive && req->ssids[0].ssid_len && req->ssids[0].ssid) {
|
||||
cfg->filter_type = SCAN_SSID_FILTER_SPECIFIC;
|
||||
cfg->ssid_len = req->ssids[0].ssid_len;
|
||||
memcpy(cfg->ssid, req->ssids[0].ssid,
|
||||
req->ssids[0].ssid_len);
|
||||
} else {
|
||||
cfg->ssid_len = 0;
|
||||
if (req->n_ssids == 0) {
|
||||
wl1271_debug(DEBUG_SCAN, "using SCAN_SSID_FILTER_ANY");
|
||||
cfg->filter_type = SCAN_SSID_FILTER_ANY;
|
||||
cfg->ssid_len = 0;
|
||||
} else {
|
||||
ret = wl12xx_scan_sched_scan_ssid_list(wl, req);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
if (ret) {
|
||||
wl1271_debug(DEBUG_SCAN, "using SCAN_SSID_FILTER_DISABLED");
|
||||
cfg->filter_type = SCAN_SSID_FILTER_DISABLED;
|
||||
} else {
|
||||
wl1271_debug(DEBUG_SCAN, "using SCAN_SSID_FILTER_LIST");
|
||||
cfg->filter_type = SCAN_SSID_FILTER_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
if (!wl1271_scan_sched_scan_channels(wl, req, cfg)) {
|
||||
|
@ -204,9 +204,7 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
|
||||
u32 len;
|
||||
u32 total_blocks;
|
||||
int id, ret = -EBUSY, ac;
|
||||
|
||||
/* we use 1 spare block */
|
||||
u32 spare_blocks = 1;
|
||||
u32 spare_blocks = wl->tx_spare_blocks;
|
||||
|
||||
if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE)
|
||||
return -EAGAIN;
|
||||
@ -220,6 +218,10 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
|
||||
in the firmware */
|
||||
len = wl12xx_calc_packet_alignment(wl, total_len);
|
||||
|
||||
/* in case of a dummy packet, use default amount of spare mem blocks */
|
||||
if (unlikely(wl12xx_is_dummy_packet(wl, skb)))
|
||||
spare_blocks = TX_HW_BLOCK_SPARE_DEFAULT;
|
||||
|
||||
total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE +
|
||||
spare_blocks;
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#ifndef __TX_H__
|
||||
#define __TX_H__
|
||||
|
||||
#define TX_HW_BLOCK_SPARE_DEFAULT 1
|
||||
#define TX_HW_BLOCK_SIZE 252
|
||||
|
||||
#define TX_HW_MGMT_PKT_LIFETIME_TU 2000
|
||||
|
@ -425,6 +425,9 @@ struct wl1271 {
|
||||
u32 tx_allocated_blocks;
|
||||
u32 tx_results_count;
|
||||
|
||||
/* amount of spare TX blocks to use */
|
||||
u32 tx_spare_blocks;
|
||||
|
||||
/* Accounting for allocated / available Tx packets in HW */
|
||||
u32 tx_pkts_freed[NUM_TX_QUEUES];
|
||||
u32 tx_allocated_pkts[NUM_TX_QUEUES];
|
||||
|
@ -130,6 +130,8 @@
|
||||
#define IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK 0x0060
|
||||
/* A-MSDU 802.11n */
|
||||
#define IEEE80211_QOS_CTL_A_MSDU_PRESENT 0x0080
|
||||
/* Mesh Control 802.11s */
|
||||
#define IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT 0x0100
|
||||
|
||||
/* U-APSD queue for WMM IEs sent by AP */
|
||||
#define IEEE80211_WMM_IE_AP_QOSINFO_UAPSD (1<<7)
|
||||
|
@ -769,6 +769,8 @@ enum nl80211_commands {
|
||||
* that can be added to a scan request
|
||||
* @NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN: maximum length of information
|
||||
* elements that can be added to a scheduled scan request
|
||||
* @NL80211_ATTR_MAX_MATCH_SETS: maximum number of sets that can be
|
||||
* used with @NL80211_ATTR_SCHED_SCAN_MATCH, a wiphy attribute.
|
||||
*
|
||||
* @NL80211_ATTR_SCAN_FREQUENCIES: nested attribute with frequencies (in MHz)
|
||||
* @NL80211_ATTR_SCAN_SSIDS: nested attribute with SSIDs, leave out for passive
|
||||
@ -1011,6 +1013,24 @@ enum nl80211_commands {
|
||||
|
||||
* @NL80211_ATTR_SCHED_SCAN_INTERVAL: Interval between scheduled scan
|
||||
* cycles, in msecs.
|
||||
|
||||
* @NL80211_ATTR_SCHED_SCAN_MATCH: Nested attribute with one or more
|
||||
* sets of attributes to match during scheduled scans. Only BSSs
|
||||
* that match any of the sets will be reported. These are
|
||||
* pass-thru filter rules.
|
||||
* For a match to succeed, the BSS must match all attributes of a
|
||||
* set. Since not every hardware supports matching all types of
|
||||
* attributes, there is no guarantee that the reported BSSs are
|
||||
* fully complying with the match sets and userspace needs to be
|
||||
* able to ignore them by itself.
|
||||
* Thus, the implementation is somewhat hardware-dependent, but
|
||||
* this is only an optimization and the userspace application
|
||||
* needs to handle all the non-filtered results anyway.
|
||||
* If the match attributes don't make sense when combined with
|
||||
* the values passed in @NL80211_ATTR_SCAN_SSIDS (eg. if an SSID
|
||||
* is included in the probe request, but the match attributes
|
||||
* will never let it go through), -EINVAL may be returned.
|
||||
* If ommited, no filtering is done.
|
||||
*
|
||||
* @NL80211_ATTR_INTERFACE_COMBINATIONS: Nested attribute listing the supported
|
||||
* interface combinations. In each nested item, it contains attributes
|
||||
@ -1044,6 +1064,11 @@ enum nl80211_commands {
|
||||
*
|
||||
* @NL80211_ATTR_STA_WME: Nested attribute containing the wme configuration
|
||||
* of the station, see &enum nl80211_sta_wme_attr.
|
||||
* @NL80211_ATTR_SUPPORT_AP_UAPSD: the device supports uapsd when working
|
||||
* as AP.
|
||||
*
|
||||
* @NL80211_ATTR_ROAM_SUPPORT: Indicates whether the firmware is capable of
|
||||
* roaming to another AP in the same ESS if the signal lever is low.
|
||||
*
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||
@ -1256,6 +1281,12 @@ enum nl80211_attrs {
|
||||
NL80211_ATTR_IE_ASSOC_RESP,
|
||||
|
||||
NL80211_ATTR_STA_WME,
|
||||
NL80211_ATTR_SUPPORT_AP_UAPSD,
|
||||
|
||||
NL80211_ATTR_ROAM_SUPPORT,
|
||||
|
||||
NL80211_ATTR_SCHED_SCAN_MATCH,
|
||||
NL80211_ATTR_MAX_MATCH_SETS,
|
||||
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
@ -1715,6 +1746,26 @@ enum nl80211_reg_rule_attr {
|
||||
NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
/**
|
||||
* enum nl80211_sched_scan_match_attr - scheduled scan match attributes
|
||||
* @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved
|
||||
* @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching,
|
||||
* only report BSS with matching SSID.
|
||||
* @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter
|
||||
* attribute number currently defined
|
||||
* @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use
|
||||
*/
|
||||
enum nl80211_sched_scan_match_attr {
|
||||
__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID,
|
||||
|
||||
NL80211_ATTR_SCHED_SCAN_MATCH_SSID,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST,
|
||||
NL80211_SCHED_SCAN_MATCH_ATTR_MAX =
|
||||
__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST - 1
|
||||
};
|
||||
|
||||
/**
|
||||
* enum nl80211_reg_rule_flags - regulatory rule flags
|
||||
*
|
||||
@ -2490,8 +2541,10 @@ enum nl80211_hidden_ssid {
|
||||
/**
|
||||
* enum nl80211_sta_wme_attr - station WME attributes
|
||||
* @__NL80211_STA_WME_INVALID: invalid number for nested attribute
|
||||
* @NL80211_STA_WME_QUEUES: bitmap of uapsd queues.
|
||||
* @NL80211_STA_WME_MAX_SP: max service period.
|
||||
* @NL80211_STA_WME_UAPSD_QUEUES: bitmap of uapsd queues. the format
|
||||
* is the same as the AC bitmap in the QoS info field.
|
||||
* @NL80211_STA_WME_MAX_SP: max service period. the format is the same
|
||||
* as the MAX_SP field in the QoS info field (but already shifted down).
|
||||
* @__NL80211_STA_WME_AFTER_LAST: internal
|
||||
* @NL80211_STA_WME_MAX: highest station WME attribute
|
||||
*/
|
||||
|
@ -25,7 +25,7 @@ struct ssb_sprom {
|
||||
u8 et1phyaddr; /* MII address for enet1 */
|
||||
u8 et0mdcport; /* MDIO for enet0 */
|
||||
u8 et1mdcport; /* MDIO for enet1 */
|
||||
u8 board_rev; /* Board revision number from SPROM. */
|
||||
u16 board_rev; /* Board revision number from SPROM. */
|
||||
u8 country_code; /* Country Code */
|
||||
u16 leddc_on_time; /* LED Powersave Duty Cycle On Count */
|
||||
u16 leddc_off_time; /* LED Powersave Duty Cycle Off Count */
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user