mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-13 09:28:44 -04:00
Merge tag 'wireless-drivers-next-for-davem-2017-10-18' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says: ==================== wireless-drivers-next patches for 4.15 The first pull request for 4.15, unusually late this time but still relatively small. Also includes merge from wireless-drivers to fix conflicts in iwlwifi. Major changes: rsi * add P2P mode support * sdio suspend and resume support iwlwifi * A fix and an addition for PCI devices for the A000 family * Dump PCI registers when an error occurs, to make it easier to debug rtlwifi * add support for 64 bit DMA, enabled with a module parameter * add module parameter to enable ASPM ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -10,14 +10,15 @@ menuconfig BCMA
|
||||
Bus driver for Broadcom specific Advanced Microcontroller Bus
|
||||
Architecture.
|
||||
|
||||
if BCMA
|
||||
|
||||
# Support for Block-I/O. SELECT this from the driver that needs it.
|
||||
config BCMA_BLOCKIO
|
||||
bool
|
||||
depends on BCMA
|
||||
|
||||
config BCMA_HOST_PCI_POSSIBLE
|
||||
bool
|
||||
depends on BCMA && PCI = y
|
||||
depends on PCI = y
|
||||
default y
|
||||
|
||||
config BCMA_HOST_PCI
|
||||
@@ -28,7 +29,6 @@ config BCMA_HOST_PCI
|
||||
|
||||
config BCMA_HOST_SOC
|
||||
bool "Support for BCMA in a SoC"
|
||||
depends on BCMA
|
||||
help
|
||||
Host interface for a Broadcom AIX bus directly mapped into
|
||||
the memory. This only works with the Broadcom SoCs from the
|
||||
@@ -38,7 +38,7 @@ config BCMA_HOST_SOC
|
||||
|
||||
config BCMA_DRIVER_PCI
|
||||
bool "BCMA Broadcom PCI core driver"
|
||||
depends on BCMA && PCI
|
||||
depends on PCI
|
||||
default y
|
||||
help
|
||||
BCMA bus may have many versions of PCIe core. This driver
|
||||
@@ -54,13 +54,13 @@ config BCMA_DRIVER_PCI
|
||||
|
||||
config BCMA_DRIVER_PCI_HOSTMODE
|
||||
bool "Driver for PCI core working in hostmode"
|
||||
depends on BCMA && MIPS && BCMA_DRIVER_PCI
|
||||
depends on MIPS && BCMA_DRIVER_PCI
|
||||
help
|
||||
PCI core hostmode operation (external PCI bus).
|
||||
|
||||
config BCMA_DRIVER_MIPS
|
||||
bool "BCMA Broadcom MIPS core driver"
|
||||
depends on BCMA && MIPS
|
||||
depends on MIPS
|
||||
help
|
||||
Driver for the Broadcom MIPS core attached to Broadcom specific
|
||||
Advanced Microcontroller Bus.
|
||||
@@ -91,7 +91,6 @@ config BCMA_NFLASH
|
||||
|
||||
config BCMA_DRIVER_GMAC_CMN
|
||||
bool "BCMA Broadcom GBIT MAC COMMON core driver"
|
||||
depends on BCMA
|
||||
help
|
||||
Driver for the Broadcom GBIT MAC COMMON core attached to Broadcom
|
||||
specific Advanced Microcontroller Bus.
|
||||
@@ -100,7 +99,7 @@ config BCMA_DRIVER_GMAC_CMN
|
||||
|
||||
config BCMA_DRIVER_GPIO
|
||||
bool "BCMA GPIO driver"
|
||||
depends on BCMA && GPIOLIB
|
||||
depends on GPIOLIB
|
||||
select GPIOLIB_IRQCHIP if BCMA_HOST_SOC
|
||||
help
|
||||
Driver to provide access to the GPIO pins of the bcma bus.
|
||||
@@ -109,8 +108,9 @@ config BCMA_DRIVER_GPIO
|
||||
|
||||
config BCMA_DEBUG
|
||||
bool "BCMA debugging"
|
||||
depends on BCMA
|
||||
help
|
||||
This turns on additional debugging messages.
|
||||
|
||||
If unsure, say N
|
||||
|
||||
endif # BCMA
|
||||
|
||||
@@ -184,10 +184,11 @@ static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
|
||||
{
|
||||
int i;
|
||||
static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
|
||||
printk(KERN_DEBUG KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
|
||||
|
||||
bcma_debug(dev->bus, "core 0x%04x, irq :", dev->id.id);
|
||||
for (i = 0; i <= 6; i++)
|
||||
printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
|
||||
printk("\n");
|
||||
pr_cont(" %s%s", irq_name[i], i == irq ? "*" : " ");
|
||||
pr_cont("\n");
|
||||
}
|
||||
|
||||
static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
|
||||
|
||||
@@ -2297,7 +2297,7 @@ static u8 b43_gphy_aci_detect(struct b43_wldev *dev, u8 channel)
|
||||
static u8 b43_gphy_aci_scan(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
u8 ret[13];
|
||||
u8 ret[13] = { 0 };
|
||||
unsigned int channel = phy->channel;
|
||||
unsigned int i, j, start, end;
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ static void b43_radio_2059_rcal(struct b43_wldev *dev)
|
||||
/* Calibrate the internal RC oscillator? */
|
||||
static void b43_radio_2057_rccal(struct b43_wldev *dev)
|
||||
{
|
||||
const u16 radio_values[3][2] = {
|
||||
static const u16 radio_values[3][2] = {
|
||||
{ 0x61, 0xE9 }, { 0x69, 0xD5 }, { 0x73, 0x99 },
|
||||
};
|
||||
int i;
|
||||
@@ -154,7 +154,7 @@ static void b43_radio_2059_init_pre(struct b43_wldev *dev)
|
||||
|
||||
static void b43_radio_2059_init(struct b43_wldev *dev)
|
||||
{
|
||||
const u16 routing[] = { R2059_C1, R2059_C2, R2059_C3 };
|
||||
static const u16 routing[] = { R2059_C1, R2059_C2, R2059_C3 };
|
||||
int i;
|
||||
|
||||
/* Prepare (reset?) radio */
|
||||
@@ -263,7 +263,7 @@ static void b43_phy_ht_reset_cca(struct b43_wldev *dev)
|
||||
static void b43_phy_ht_zero_extg(struct b43_wldev *dev)
|
||||
{
|
||||
u8 i, j;
|
||||
u16 base[] = { 0x40, 0x60, 0x80 };
|
||||
static const u16 base[] = { 0x40, 0x60, 0x80 };
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(base); i++) {
|
||||
for (j = 0; j < 4; j++)
|
||||
|
||||
@@ -280,7 +280,7 @@ u8 b43legacy_radio_aci_detect(struct b43legacy_wldev *dev, u8 channel)
|
||||
u8 b43legacy_radio_aci_scan(struct b43legacy_wldev *dev)
|
||||
{
|
||||
struct b43legacy_phy *phy = &dev->phy;
|
||||
u8 ret[13];
|
||||
u8 ret[13] = { 0 };
|
||||
unsigned int channel = phy->channel;
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
|
||||
@@ -257,11 +257,6 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
|
||||
brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data,
|
||||
min_t(u32, emsg.datalen, 64),
|
||||
"event payload, len=%d\n", emsg.datalen);
|
||||
if (emsg.datalen > event->datalen) {
|
||||
brcmf_err("event invalid length header=%d, msg=%d\n",
|
||||
event->datalen, emsg.datalen);
|
||||
goto event_free;
|
||||
}
|
||||
|
||||
/* special handling of interface event */
|
||||
if (event->code == BRCMF_E_IF) {
|
||||
@@ -429,7 +424,8 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr,
|
||||
if (code != BRCMF_E_IF && !fweh->evt_handler[code])
|
||||
return;
|
||||
|
||||
if (datalen > BRCMF_DCMD_MAXLEN)
|
||||
if (datalen > BRCMF_DCMD_MAXLEN ||
|
||||
datalen + sizeof(*event_packet) > packet_len)
|
||||
return;
|
||||
|
||||
if (in_interrupt())
|
||||
|
||||
@@ -1853,7 +1853,6 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
|
||||
struct afx_hdl *afx_hdl = &p2p->afx_hdl;
|
||||
struct brcmf_cfg80211_vif *vif = ifp->vif;
|
||||
struct brcmf_rx_mgmt_data *rxframe = (struct brcmf_rx_mgmt_data *)data;
|
||||
u16 chanspec = be16_to_cpu(rxframe->chanspec);
|
||||
struct brcmu_chan ch;
|
||||
u8 *mgmt_frame;
|
||||
u32 mgmt_frame_len;
|
||||
@@ -1906,7 +1905,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probereq(struct brcmf_if *ifp,
|
||||
cfg80211_rx_mgmt(&vif->wdev, freq, 0, mgmt_frame, mgmt_frame_len, 0);
|
||||
|
||||
brcmf_dbg(INFO, "mgmt_frame_len (%d) , e->datalen (%d), chanspec (%04x), freq (%d)\n",
|
||||
mgmt_frame_len, e->datalen, chanspec, freq);
|
||||
mgmt_frame_len, e->datalen, ch.chspec, freq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4144,10 +4144,8 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
|
||||
init_waitqueue_head(&bus->dcmd_resp_wait);
|
||||
|
||||
/* Set up the watchdog timer */
|
||||
init_timer(&bus->timer);
|
||||
bus->timer.data = (unsigned long)bus;
|
||||
bus->timer.function = brcmf_sdio_watchdog;
|
||||
|
||||
setup_timer(&bus->timer, brcmf_sdio_watchdog,
|
||||
(unsigned long)bus);
|
||||
/* Initialize watchdog thread */
|
||||
init_completion(&bus->watchdog_wait);
|
||||
bus->watchdog_tsk = kthread_run(brcmf_sdio_watchdog_thread,
|
||||
|
||||
@@ -1916,7 +1916,7 @@ void wlc_phy_txpower_update_shm(struct brcms_phy *pi)
|
||||
pi->hwpwr_txcur);
|
||||
|
||||
for (j = TXP_FIRST_OFDM; j <= TXP_LAST_OFDM; j++) {
|
||||
const u8 ucode_ofdm_rates[] = {
|
||||
static const u8 ucode_ofdm_rates[] = {
|
||||
0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c
|
||||
};
|
||||
offset = wlapi_bmac_rate_shm_offset(
|
||||
|
||||
@@ -14764,8 +14764,8 @@ static void wlc_phy_ipa_restore_tx_digi_filts_nphy(struct brcms_phy *pi)
|
||||
}
|
||||
|
||||
static void
|
||||
wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *events, u8 *dlys,
|
||||
u8 len)
|
||||
wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, const u8 *events,
|
||||
const u8 *dlys, u8 len)
|
||||
{
|
||||
u32 t1_offset, t2_offset;
|
||||
u8 ctr;
|
||||
@@ -15240,16 +15240,16 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(struct brcms_phy *pi)
|
||||
static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
|
||||
{
|
||||
u16 currband;
|
||||
s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 };
|
||||
s8 *lna1_gain_db = NULL;
|
||||
s8 *lna1_gain_db_2 = NULL;
|
||||
s8 *lna2_gain_db = NULL;
|
||||
s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 };
|
||||
s8 *tia_gain_db;
|
||||
s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 };
|
||||
s8 *tia_gainbits;
|
||||
u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f };
|
||||
u16 *rfseq_init_gain;
|
||||
static const s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 };
|
||||
const s8 *lna1_gain_db = NULL;
|
||||
const s8 *lna1_gain_db_2 = NULL;
|
||||
const s8 *lna2_gain_db = NULL;
|
||||
static const s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 };
|
||||
const s8 *tia_gain_db;
|
||||
static const s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 };
|
||||
const s8 *tia_gainbits;
|
||||
static const u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f };
|
||||
const u16 *rfseq_init_gain;
|
||||
u16 init_gaincode;
|
||||
u16 clip1hi_gaincode;
|
||||
u16 clip1md_gaincode = 0;
|
||||
@@ -15310,10 +15310,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
|
||||
|
||||
if ((freq <= 5080) || (freq == 5825)) {
|
||||
|
||||
s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 };
|
||||
s8 lna1A_gain_db_2_rev7[] = {
|
||||
11, 17, 22, 25};
|
||||
s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
|
||||
static const s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 };
|
||||
static const s8 lna1A_gain_db_2_rev7[] = { 11, 17, 22, 25};
|
||||
static const s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
|
||||
|
||||
crsminu_th = 0x3e;
|
||||
lna1_gain_db = lna1A_gain_db_rev7;
|
||||
@@ -15321,10 +15320,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
|
||||
lna2_gain_db = lna2A_gain_db_rev7;
|
||||
} else if ((freq >= 5500) && (freq <= 5700)) {
|
||||
|
||||
s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 };
|
||||
s8 lna1A_gain_db_2_rev7[] = {
|
||||
12, 18, 22, 26};
|
||||
s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 };
|
||||
static const s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 };
|
||||
static const s8 lna1A_gain_db_2_rev7[] = { 12, 18, 22, 26};
|
||||
static const s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 };
|
||||
|
||||
crsminu_th = 0x45;
|
||||
clip1md_gaincode_B = 0x14;
|
||||
@@ -15335,10 +15333,9 @@ static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi)
|
||||
lna2_gain_db = lna2A_gain_db_rev7;
|
||||
} else {
|
||||
|
||||
s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 };
|
||||
s8 lna1A_gain_db_2_rev7[] = {
|
||||
12, 18, 22, 26};
|
||||
s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
|
||||
static const s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 };
|
||||
static const s8 lna1A_gain_db_2_rev7[] = { 12, 18, 22, 26};
|
||||
static const s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 };
|
||||
|
||||
crsminu_th = 0x41;
|
||||
lna1_gain_db = lna1A_gain_db_rev7;
|
||||
@@ -15450,65 +15447,65 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi)
|
||||
NPHY_RFSEQ_CMD_CLR_HIQ_DIS,
|
||||
NPHY_RFSEQ_CMD_SET_HPF_BW
|
||||
};
|
||||
u8 rfseq_updategainu_dlys[] = { 10, 30, 1 };
|
||||
s8 lna1G_gain_db[] = { 7, 11, 16, 23 };
|
||||
s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 };
|
||||
s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 };
|
||||
s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 };
|
||||
s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 };
|
||||
s8 lna1A_gain_db[] = { 7, 11, 17, 23 };
|
||||
s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 };
|
||||
s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 };
|
||||
s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 };
|
||||
s8 *lna1_gain_db = NULL;
|
||||
s8 lna2G_gain_db[] = { -5, 6, 10, 14 };
|
||||
s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 };
|
||||
s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 };
|
||||
s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 };
|
||||
s8 lna2A_gain_db[] = { -6, 2, 6, 10 };
|
||||
s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 };
|
||||
s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 };
|
||||
s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 };
|
||||
s8 *lna2_gain_db = NULL;
|
||||
s8 tiaG_gain_db[] = {
|
||||
static const u8 rfseq_updategainu_dlys[] = { 10, 30, 1 };
|
||||
static const s8 lna1G_gain_db[] = { 7, 11, 16, 23 };
|
||||
static const s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 };
|
||||
static const s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 };
|
||||
static const s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 };
|
||||
static const s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 };
|
||||
static const s8 lna1A_gain_db[] = { 7, 11, 17, 23 };
|
||||
static const s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 };
|
||||
static const s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 };
|
||||
static const s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 };
|
||||
const s8 *lna1_gain_db = NULL;
|
||||
static const s8 lna2G_gain_db[] = { -5, 6, 10, 14 };
|
||||
static const s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 };
|
||||
static const s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 };
|
||||
static const s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 };
|
||||
static const s8 lna2A_gain_db[] = { -6, 2, 6, 10 };
|
||||
static const s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 };
|
||||
static const s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 };
|
||||
static const s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 };
|
||||
const s8 *lna2_gain_db = NULL;
|
||||
static const s8 tiaG_gain_db[] = {
|
||||
0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A };
|
||||
s8 tiaA_gain_db[] = {
|
||||
static const s8 tiaA_gain_db[] = {
|
||||
0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 };
|
||||
s8 tiaA_gain_db_rev4[] = {
|
||||
static const s8 tiaA_gain_db_rev4[] = {
|
||||
0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
|
||||
s8 tiaA_gain_db_rev5[] = {
|
||||
static const s8 tiaA_gain_db_rev5[] = {
|
||||
0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
|
||||
s8 tiaA_gain_db_rev6[] = {
|
||||
static const s8 tiaA_gain_db_rev6[] = {
|
||||
0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d };
|
||||
s8 *tia_gain_db;
|
||||
s8 tiaG_gainbits[] = {
|
||||
const s8 *tia_gain_db;
|
||||
static const s8 tiaG_gainbits[] = {
|
||||
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 };
|
||||
s8 tiaA_gainbits[] = {
|
||||
static const s8 tiaA_gainbits[] = {
|
||||
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 };
|
||||
s8 tiaA_gainbits_rev4[] = {
|
||||
static const s8 tiaA_gainbits_rev4[] = {
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
|
||||
s8 tiaA_gainbits_rev5[] = {
|
||||
static const s8 tiaA_gainbits_rev5[] = {
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
|
||||
s8 tiaA_gainbits_rev6[] = {
|
||||
static const s8 tiaA_gainbits_rev6[] = {
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 };
|
||||
s8 *tia_gainbits;
|
||||
s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 };
|
||||
s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 };
|
||||
u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f };
|
||||
u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f };
|
||||
u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f };
|
||||
u16 rfseqG_init_gain_rev5_elna[] = {
|
||||
const s8 *tia_gainbits;
|
||||
static const s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 };
|
||||
static const s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 };
|
||||
static const u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f };
|
||||
static const u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f };
|
||||
static const u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f };
|
||||
static const u16 rfseqG_init_gain_rev5_elna[] = {
|
||||
0x013f, 0x013f, 0x013f, 0x013f };
|
||||
u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f };
|
||||
u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f };
|
||||
u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f };
|
||||
u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f };
|
||||
u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f };
|
||||
u16 rfseqA_init_gain_rev4_elna[] = {
|
||||
static const u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f };
|
||||
static const u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f };
|
||||
static const u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f };
|
||||
static const u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f };
|
||||
static const u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f };
|
||||
static const u16 rfseqA_init_gain_rev4_elna[] = {
|
||||
0x314f, 0x314f, 0x314f, 0x314f };
|
||||
u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f };
|
||||
u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f };
|
||||
u16 *rfseq_init_gain;
|
||||
static const u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f };
|
||||
static const u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f };
|
||||
const u16 *rfseq_init_gain;
|
||||
u16 initG_gaincode = 0x627e;
|
||||
u16 initG_gaincode_rev4 = 0x527e;
|
||||
u16 initG_gaincode_rev5 = 0x427e;
|
||||
@@ -15538,10 +15535,10 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi)
|
||||
u16 clip1mdA_gaincode_rev6 = 0x2084;
|
||||
u16 clip1md_gaincode = 0;
|
||||
u16 clip1loG_gaincode = 0x0074;
|
||||
u16 clip1loG_gaincode_rev5[] = {
|
||||
static const u16 clip1loG_gaincode_rev5[] = {
|
||||
0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c
|
||||
};
|
||||
u16 clip1loG_gaincode_rev6[] = {
|
||||
static const u16 clip1loG_gaincode_rev6[] = {
|
||||
0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e
|
||||
};
|
||||
u16 clip1loG_gaincode_rev6_224B0 = 0x1074;
|
||||
@@ -16066,7 +16063,7 @@ static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi)
|
||||
|
||||
static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
|
||||
{
|
||||
u8 rfseq_rx2tx_events[] = {
|
||||
static const u8 rfseq_rx2tx_events[] = {
|
||||
NPHY_RFSEQ_CMD_NOP,
|
||||
NPHY_RFSEQ_CMD_RXG_FBW,
|
||||
NPHY_RFSEQ_CMD_TR_SWITCH,
|
||||
@@ -16076,7 +16073,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
|
||||
NPHY_RFSEQ_CMD_EXT_PA
|
||||
};
|
||||
u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 };
|
||||
u8 rfseq_tx2rx_events[] = {
|
||||
static const u8 rfseq_tx2rx_events[] = {
|
||||
NPHY_RFSEQ_CMD_NOP,
|
||||
NPHY_RFSEQ_CMD_EXT_PA,
|
||||
NPHY_RFSEQ_CMD_TX_GAIN,
|
||||
@@ -16085,8 +16082,8 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
|
||||
NPHY_RFSEQ_CMD_RXG_FBW,
|
||||
NPHY_RFSEQ_CMD_CLR_HIQ_DIS
|
||||
};
|
||||
u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
|
||||
u8 rfseq_tx2rx_events_rev3[] = {
|
||||
static const u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 };
|
||||
static const u8 rfseq_tx2rx_events_rev3[] = {
|
||||
NPHY_REV3_RFSEQ_CMD_EXT_PA,
|
||||
NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
|
||||
NPHY_REV3_RFSEQ_CMD_TX_GAIN,
|
||||
@@ -16096,7 +16093,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
|
||||
NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS,
|
||||
NPHY_REV3_RFSEQ_CMD_END
|
||||
};
|
||||
u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
|
||||
static const u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 };
|
||||
u8 rfseq_rx2tx_events_rev3[] = {
|
||||
NPHY_REV3_RFSEQ_CMD_NOP,
|
||||
NPHY_REV3_RFSEQ_CMD_RXG_FBW,
|
||||
@@ -16110,7 +16107,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
|
||||
};
|
||||
u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 };
|
||||
|
||||
u8 rfseq_rx2tx_events_rev3_ipa[] = {
|
||||
static const u8 rfseq_rx2tx_events_rev3_ipa[] = {
|
||||
NPHY_REV3_RFSEQ_CMD_NOP,
|
||||
NPHY_REV3_RFSEQ_CMD_RXG_FBW,
|
||||
NPHY_REV3_RFSEQ_CMD_TR_SWITCH,
|
||||
@@ -16121,15 +16118,15 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
|
||||
NPHY_REV3_RFSEQ_CMD_INT_PA_PU,
|
||||
NPHY_REV3_RFSEQ_CMD_END
|
||||
};
|
||||
u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
|
||||
u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
|
||||
static const u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 };
|
||||
static const u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f };
|
||||
|
||||
s16 alpha0, alpha1, alpha2;
|
||||
s16 beta0, beta1, beta2;
|
||||
u32 leg_data_weights, ht_data_weights, nss1_data_weights,
|
||||
stbc_data_weights;
|
||||
u8 chan_freq_range = 0;
|
||||
u16 dac_control = 0x0002;
|
||||
static const u16 dac_control = 0x0002;
|
||||
u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 };
|
||||
u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 };
|
||||
u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 };
|
||||
@@ -16139,8 +16136,8 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
|
||||
u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 };
|
||||
u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 };
|
||||
u16 *aux_adc_gain;
|
||||
u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
|
||||
u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
|
||||
static const u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 };
|
||||
static const u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 };
|
||||
s32 min_nvar_val = 0x18d;
|
||||
s32 min_nvar_offset_6mbps = 20;
|
||||
u8 pdetrange;
|
||||
@@ -16151,9 +16148,9 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi)
|
||||
u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77;
|
||||
u16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77;
|
||||
u16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77;
|
||||
u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 };
|
||||
u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
|
||||
u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
|
||||
static const u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 };
|
||||
static const u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
|
||||
static const u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 };
|
||||
u16 ipalvlshift_3p3_war_en = 0;
|
||||
u16 rccal_bcap_val, rccal_scap_val;
|
||||
u16 rccal_tx20_11b_bcap = 0;
|
||||
@@ -24291,13 +24288,13 @@ static void wlc_phy_update_txcal_ladder_nphy(struct brcms_phy *pi, u16 core)
|
||||
u16 bbmult;
|
||||
u16 tblentry;
|
||||
|
||||
struct nphy_txiqcal_ladder ladder_lo[] = {
|
||||
static const struct nphy_txiqcal_ladder ladder_lo[] = {
|
||||
{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
|
||||
{25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5},
|
||||
{25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7}
|
||||
};
|
||||
|
||||
struct nphy_txiqcal_ladder ladder_iq[] = {
|
||||
static const struct nphy_txiqcal_ladder ladder_iq[] = {
|
||||
{3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0},
|
||||
{25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1},
|
||||
{100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7}
|
||||
@@ -25773,67 +25770,67 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain,
|
||||
u16 cal_gain[2];
|
||||
struct nphy_iqcal_params cal_params[2];
|
||||
u32 tbl_len;
|
||||
void *tbl_ptr;
|
||||
const void *tbl_ptr;
|
||||
bool ladder_updated[2];
|
||||
u8 mphase_cal_lastphase = 0;
|
||||
int bcmerror = 0;
|
||||
bool phyhang_avoid_state = false;
|
||||
|
||||
u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
|
||||
static const u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
|
||||
0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901,
|
||||
0x1902,
|
||||
0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607,
|
||||
0x6407
|
||||
};
|
||||
|
||||
u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
|
||||
static const u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
|
||||
0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400,
|
||||
0x3200,
|
||||
0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406,
|
||||
0x6407
|
||||
};
|
||||
|
||||
u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
|
||||
static const u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
|
||||
0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201,
|
||||
0x1202,
|
||||
0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207,
|
||||
0x4707
|
||||
};
|
||||
|
||||
u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
|
||||
static const u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
|
||||
0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900,
|
||||
0x2300,
|
||||
0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706,
|
||||
0x4707
|
||||
};
|
||||
|
||||
u16 tbl_tx_iqlo_cal_startcoefs[] = {
|
||||
static const u16 tbl_tx_iqlo_cal_startcoefs[] = {
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000
|
||||
};
|
||||
|
||||
u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
|
||||
static const u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
|
||||
0x8123, 0x8264, 0x8086, 0x8245, 0x8056,
|
||||
0x9123, 0x9264, 0x9086, 0x9245, 0x9056
|
||||
};
|
||||
|
||||
u16 tbl_tx_iqlo_cal_cmds_recal[] = {
|
||||
static const u16 tbl_tx_iqlo_cal_cmds_recal[] = {
|
||||
0x8101, 0x8253, 0x8053, 0x8234, 0x8034,
|
||||
0x9101, 0x9253, 0x9053, 0x9234, 0x9034
|
||||
};
|
||||
|
||||
u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = {
|
||||
static const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = {
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000
|
||||
};
|
||||
|
||||
u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
|
||||
static const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
|
||||
0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234,
|
||||
0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234
|
||||
};
|
||||
|
||||
u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
|
||||
static const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
|
||||
0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223,
|
||||
0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223
|
||||
};
|
||||
|
||||
@@ -1480,7 +1480,7 @@ il4965_get_ac_from_tid(u16 tid)
|
||||
static inline int
|
||||
il4965_get_fifo_from_tid(u16 tid)
|
||||
{
|
||||
const u8 ac_to_fifo[] = {
|
||||
static const u8 ac_to_fifo[] = {
|
||||
IL_TX_FIFO_VO,
|
||||
IL_TX_FIFO_VI,
|
||||
IL_TX_FIFO_BE,
|
||||
|
||||
@@ -13,6 +13,7 @@ iwlwifi-objs += iwl-trans.o
|
||||
iwlwifi-objs += fw/notif-wait.o
|
||||
iwlwifi-$(CONFIG_IWLMVM) += fw/paging.o fw/smem.o fw/init.o fw/dbg.o
|
||||
iwlwifi-$(CONFIG_IWLMVM) += fw/common_rx.o fw/nvm.o
|
||||
iwlwifi-$(CONFIG_ACPI) += fw/acpi.o
|
||||
|
||||
iwlwifi-objs += $(iwlwifi-m)
|
||||
|
||||
|
||||
@@ -309,6 +309,7 @@ const struct iwl_cfg iwl3168_2ac_cfg = {
|
||||
.nvm_calib_ver = IWL3168_TX_POWER_VERSION,
|
||||
.pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
|
||||
.dccm_len = IWL7265_DCCM_LEN,
|
||||
.nvm_type = IWL_NVM_SDP,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwl7265_2ac_cfg = {
|
||||
|
||||
@@ -164,7 +164,7 @@ static const struct iwl_tt_params iwl8000_tt_params = {
|
||||
.default_nvm_file_C_step = DEFAULT_NVM_FILE_FAMILY_8000C, \
|
||||
.thermal_params = &iwl8000_tt_params, \
|
||||
.apmg_not_supported = true, \
|
||||
.ext_nvm = true, \
|
||||
.nvm_type = IWL_NVM_EXT, \
|
||||
.dbgc_supported = true
|
||||
|
||||
#define IWL_DEVICE_8000 \
|
||||
|
||||
@@ -148,7 +148,7 @@ static const struct iwl_tt_params iwl9000_tt_params = {
|
||||
.vht_mu_mimo_supported = true, \
|
||||
.mac_addr_from_csr = true, \
|
||||
.rf_id = true, \
|
||||
.ext_nvm = true, \
|
||||
.nvm_type = IWL_NVM_EXT, \
|
||||
.dbgc_supported = true
|
||||
|
||||
const struct iwl_cfg iwl9160_2ac_cfg = {
|
||||
|
||||
@@ -133,78 +133,79 @@ static const struct iwl_ht_params iwl_a000_ht_params = {
|
||||
.use_tfh = true, \
|
||||
.rf_id = true, \
|
||||
.gen2 = true, \
|
||||
.ext_nvm = true, \
|
||||
.dbgc_supported = true
|
||||
.nvm_type = IWL_NVM_EXT, \
|
||||
.dbgc_supported = true, \
|
||||
.tx_cmd_queue_size = 32
|
||||
|
||||
const struct iwl_cfg iwla000_2ac_cfg_hr = {
|
||||
.name = "Intel(R) Dual Band Wireless AC a000",
|
||||
.fw_name_pre = IWL_A000_HR_FW_PRE,
|
||||
IWL_DEVICE_A000,
|
||||
.ht_params = &iwl_a000_ht_params,
|
||||
.nvm_ver = IWL_A000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.name = "Intel(R) Dual Band Wireless AC a000",
|
||||
.fw_name_pre = IWL_A000_HR_FW_PRE,
|
||||
IWL_DEVICE_A000,
|
||||
.ht_params = &iwl_a000_ht_params,
|
||||
.nvm_ver = IWL_A000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwla000_2ac_cfg_hr_cdb = {
|
||||
.name = "Intel(R) Dual Band Wireless AC a000",
|
||||
.fw_name_pre = IWL_A000_HR_CDB_FW_PRE,
|
||||
IWL_DEVICE_A000,
|
||||
.ht_params = &iwl_a000_ht_params,
|
||||
.nvm_ver = IWL_A000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.cdb = true,
|
||||
.name = "Intel(R) Dual Band Wireless AC a000",
|
||||
.fw_name_pre = IWL_A000_HR_CDB_FW_PRE,
|
||||
IWL_DEVICE_A000,
|
||||
.ht_params = &iwl_a000_ht_params,
|
||||
.nvm_ver = IWL_A000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.cdb = true,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwla000_2ac_cfg_jf = {
|
||||
.name = "Intel(R) Dual Band Wireless AC a000",
|
||||
.fw_name_pre = IWL_A000_JF_FW_PRE,
|
||||
IWL_DEVICE_A000,
|
||||
.ht_params = &iwl_a000_ht_params,
|
||||
.nvm_ver = IWL_A000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.name = "Intel(R) Dual Band Wireless AC a000",
|
||||
.fw_name_pre = IWL_A000_JF_FW_PRE,
|
||||
IWL_DEVICE_A000,
|
||||
.ht_params = &iwl_a000_ht_params,
|
||||
.nvm_ver = IWL_A000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwla000_2ax_cfg_hr = {
|
||||
.name = "Intel(R) Dual Band Wireless AX a000",
|
||||
.fw_name_pre = IWL_A000_HR_FW_PRE,
|
||||
IWL_DEVICE_A000,
|
||||
.ht_params = &iwl_a000_ht_params,
|
||||
.nvm_ver = IWL_A000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.name = "Intel(R) Dual Band Wireless AX a000",
|
||||
.fw_name_pre = IWL_A000_HR_FW_PRE,
|
||||
IWL_DEVICE_A000,
|
||||
.ht_params = &iwl_a000_ht_params,
|
||||
.nvm_ver = IWL_A000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_f0 = {
|
||||
.name = "Intel(R) Dual Band Wireless AX a000",
|
||||
.fw_name_pre = IWL_A000_HR_F0_FW_PRE,
|
||||
IWL_DEVICE_A000,
|
||||
.ht_params = &iwl_a000_ht_params,
|
||||
.nvm_ver = IWL_A000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.name = "Intel(R) Dual Band Wireless AX a000",
|
||||
.fw_name_pre = IWL_A000_HR_F0_FW_PRE,
|
||||
IWL_DEVICE_A000,
|
||||
.ht_params = &iwl_a000_ht_params,
|
||||
.nvm_ver = IWL_A000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwla000_2ax_cfg_qnj_jf_b0 = {
|
||||
.name = "Intel(R) Dual Band Wireless AX a000",
|
||||
.fw_name_pre = IWL_A000_JF_B0_FW_PRE,
|
||||
IWL_DEVICE_A000,
|
||||
.ht_params = &iwl_a000_ht_params,
|
||||
.nvm_ver = IWL_A000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.name = "Intel(R) Dual Band Wireless AX a000",
|
||||
.fw_name_pre = IWL_A000_JF_B0_FW_PRE,
|
||||
IWL_DEVICE_A000,
|
||||
.ht_params = &iwl_a000_ht_params,
|
||||
.nvm_ver = IWL_A000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
const struct iwl_cfg iwla000_2ax_cfg_qnj_hr_a0 = {
|
||||
.name = "Intel(R) Dual Band Wireless AX a000",
|
||||
.fw_name_pre = IWL_A000_HR_A0_FW_PRE,
|
||||
IWL_DEVICE_A000,
|
||||
.ht_params = &iwl_a000_ht_params,
|
||||
.nvm_ver = IWL_A000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
.name = "Intel(R) Dual Band Wireless AX a000",
|
||||
.fw_name_pre = IWL_A000_HR_A0_FW_PRE,
|
||||
IWL_DEVICE_A000,
|
||||
.ht_params = &iwl_a000_ht_params,
|
||||
.nvm_ver = IWL_A000_NVM_VERSION,
|
||||
.nvm_calib_ver = IWL_A000_TX_POWER_VERSION,
|
||||
.max_ht_ampdu_exponent = IEEE80211_HT_MAX_AMPDU_64K,
|
||||
};
|
||||
|
||||
MODULE_FIRMWARE(IWL_A000_HR_MODULE_FIRMWARE(IWL_A000_UCODE_API_MAX));
|
||||
|
||||
210
drivers/net/wireless/intel/iwlwifi/fw/acpi.c
Normal file
210
drivers/net/wireless/intel/iwlwifi/fw/acpi.c
Normal file
@@ -0,0 +1,210 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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;
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "iwl-drv.h"
|
||||
#include "iwl-debug.h"
|
||||
#include "acpi.h"
|
||||
|
||||
void *iwl_acpi_get_object(struct device *dev, acpi_string method)
|
||||
{
|
||||
acpi_handle root_handle;
|
||||
acpi_handle handle;
|
||||
struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
|
||||
acpi_status status;
|
||||
|
||||
root_handle = ACPI_HANDLE(dev);
|
||||
if (!root_handle) {
|
||||
IWL_DEBUG_DEV_RADIO(dev,
|
||||
"Could not retrieve root port ACPI handle\n");
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
/* Get the method's handle */
|
||||
status = acpi_get_handle(root_handle, method, &handle);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
IWL_DEBUG_DEV_RADIO(dev, "%s method not found\n", method);
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
/* Call the method with no arguments */
|
||||
status = acpi_evaluate_object(handle, NULL, NULL, &buf);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
IWL_DEBUG_DEV_RADIO(dev, "%s invocation failed (0x%x)\n",
|
||||
method, status);
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
return buf.pointer;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_acpi_get_object);
|
||||
|
||||
union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
|
||||
union acpi_object *data,
|
||||
int data_size)
|
||||
{
|
||||
int i;
|
||||
union acpi_object *wifi_pkg;
|
||||
|
||||
/*
|
||||
* We need at least one entry in the wifi package that
|
||||
* describes the domain, and one more entry, otherwise there's
|
||||
* no point in reading it.
|
||||
*/
|
||||
if (WARN_ON_ONCE(data_size < 2))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/*
|
||||
* We need at least two packages, one for the revision and one
|
||||
* for the data itself. Also check that the revision is valid
|
||||
* (i.e. it is an integer set to 0).
|
||||
*/
|
||||
if (data->type != ACPI_TYPE_PACKAGE ||
|
||||
data->package.count < 2 ||
|
||||
data->package.elements[0].type != ACPI_TYPE_INTEGER ||
|
||||
data->package.elements[0].integer.value != 0) {
|
||||
IWL_DEBUG_DEV_RADIO(dev, "Unsupported packages structure\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
/* loop through all the packages to find the one for WiFi */
|
||||
for (i = 1; i < data->package.count; i++) {
|
||||
union acpi_object *domain;
|
||||
|
||||
wifi_pkg = &data->package.elements[i];
|
||||
|
||||
/* skip entries that are not a package with the right size */
|
||||
if (wifi_pkg->type != ACPI_TYPE_PACKAGE ||
|
||||
wifi_pkg->package.count != data_size)
|
||||
continue;
|
||||
|
||||
domain = &wifi_pkg->package.elements[0];
|
||||
if (domain->type == ACPI_TYPE_INTEGER &&
|
||||
domain->integer.value == ACPI_WIFI_DOMAIN)
|
||||
goto found;
|
||||
}
|
||||
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
||||
found:
|
||||
return wifi_pkg;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_acpi_get_wifi_pkg);
|
||||
|
||||
int iwl_acpi_get_mcc(struct device *dev, char *mcc)
|
||||
{
|
||||
union acpi_object *wifi_pkg, *data;
|
||||
u32 mcc_val;
|
||||
int ret;
|
||||
|
||||
data = iwl_acpi_get_object(dev, ACPI_WRDD_METHOD);
|
||||
if (IS_ERR(data))
|
||||
return PTR_ERR(data);
|
||||
|
||||
wifi_pkg = iwl_acpi_get_wifi_pkg(dev, data, ACPI_WRDD_WIFI_DATA_SIZE);
|
||||
if (IS_ERR(wifi_pkg)) {
|
||||
ret = PTR_ERR(wifi_pkg);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) {
|
||||
ret = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
mcc_val = wifi_pkg->package.elements[1].integer.value;
|
||||
|
||||
mcc[0] = (mcc_val >> 8) & 0xff;
|
||||
mcc[1] = mcc_val & 0xff;
|
||||
mcc[2] = '\0';
|
||||
|
||||
ret = 0;
|
||||
out_free:
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_acpi_get_mcc);
|
||||
|
||||
u64 iwl_acpi_get_pwr_limit(struct device *dev)
|
||||
{
|
||||
union acpi_object *data, *wifi_pkg;
|
||||
u64 dflt_pwr_limit;
|
||||
|
||||
data = iwl_acpi_get_object(dev, ACPI_SPLC_METHOD);
|
||||
if (IS_ERR(data)) {
|
||||
dflt_pwr_limit = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
wifi_pkg = iwl_acpi_get_wifi_pkg(dev, data,
|
||||
ACPI_SPLC_WIFI_DATA_SIZE);
|
||||
if (IS_ERR(wifi_pkg) ||
|
||||
wifi_pkg->package.elements[1].integer.value != ACPI_TYPE_INTEGER) {
|
||||
dflt_pwr_limit = 0;
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
dflt_pwr_limit = wifi_pkg->package.elements[1].integer.value;
|
||||
out_free:
|
||||
kfree(data);
|
||||
out:
|
||||
return dflt_pwr_limit;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_acpi_get_pwr_limit);
|
||||
138
drivers/net/wireless/intel/iwlwifi/fw/acpi.h
Normal file
138
drivers/net/wireless/intel/iwlwifi/fw/acpi.h
Normal file
@@ -0,0 +1,138 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file is provided under a dual BSD/GPLv2 license. When using or
|
||||
* redistributing this file, you may do so under either license.
|
||||
*
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* 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;
|
||||
*
|
||||
* The full GNU General Public License is included in this distribution
|
||||
* in the file called COPYING.
|
||||
*
|
||||
* Contact Information:
|
||||
* Intel Linux Wireless <linuxwifi@intel.com>
|
||||
* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
|
||||
*
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2017 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Intel Corporation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#ifndef __iwl_fw_acpi__
|
||||
#define __iwl_fw_acpi__
|
||||
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#define ACPI_WRDS_METHOD "WRDS"
|
||||
#define ACPI_EWRD_METHOD "EWRD"
|
||||
#define ACPI_WGDS_METHOD "WGDS"
|
||||
#define ACPI_WRDD_METHOD "WRDD"
|
||||
#define ACPI_SPLC_METHOD "SPLC"
|
||||
|
||||
#define ACPI_WIFI_DOMAIN (0x07)
|
||||
|
||||
#define ACPI_SAR_TABLE_SIZE 10
|
||||
#define ACPI_SAR_PROFILE_NUM 4
|
||||
|
||||
#define ACPI_GEO_TABLE_SIZE 6
|
||||
#define ACPI_NUM_GEO_PROFILES 3
|
||||
#define ACPI_GEO_PER_CHAIN_SIZE 3
|
||||
|
||||
#define ACPI_SAR_NUM_CHAIN_LIMITS 2
|
||||
#define ACPI_SAR_NUM_SUB_BANDS 5
|
||||
|
||||
#define ACPI_WRDS_WIFI_DATA_SIZE (ACPI_SAR_TABLE_SIZE + 2)
|
||||
#define ACPI_EWRD_WIFI_DATA_SIZE ((ACPI_SAR_PROFILE_NUM - 1) * \
|
||||
ACPI_SAR_TABLE_SIZE + 3)
|
||||
#define ACPI_WGDS_WIFI_DATA_SIZE 18
|
||||
#define ACPI_WRDD_WIFI_DATA_SIZE 2
|
||||
#define ACPI_SPLC_WIFI_DATA_SIZE 2
|
||||
|
||||
#define ACPI_WGDS_NUM_BANDS 2
|
||||
#define ACPI_WGDS_TABLE_SIZE 3
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
|
||||
void *iwl_acpi_get_object(struct device *dev, acpi_string method);
|
||||
union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
|
||||
union acpi_object *data,
|
||||
int data_size);
|
||||
|
||||
/**
|
||||
* iwl_acpi_get_mcc - read MCC from ACPI, if available
|
||||
*
|
||||
* @dev: the struct device
|
||||
* @mcc: output buffer (3 bytes) that will get the MCC
|
||||
*
|
||||
* This function tries to read the current MCC from ACPI if available.
|
||||
*/
|
||||
int iwl_acpi_get_mcc(struct device *dev, char *mcc);
|
||||
|
||||
u64 iwl_acpi_get_pwr_limit(struct device *dev);
|
||||
|
||||
#else /* CONFIG_ACPI */
|
||||
|
||||
static inline void *iwl_acpi_get_object(struct device *dev, acpi_string method)
|
||||
{
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
static inline union acpi_object *iwl_acpi_get_wifi_pkg(struct device *dev,
|
||||
union acpi_object *data,
|
||||
int data_size)
|
||||
{
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
static inline int iwl_acpi_get_mcc(struct device *dev, char *mcc)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static inline u64 iwl_acpi_get_pwr_limit(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ACPI */
|
||||
#endif /* __iwl_fw_acpi__ */
|
||||
@@ -116,14 +116,14 @@ struct iwl_binding_cmd {
|
||||
#define IWL_MVM_MAX_QUOTA 128
|
||||
|
||||
/**
|
||||
* struct iwl_time_quota_data - configuration of time quota per binding
|
||||
* struct iwl_time_quota_data_v1 - configuration of time quota per binding
|
||||
* @id_and_color: ID and color of the relevant Binding,
|
||||
* &enum iwl_ctxt_id_and_color
|
||||
* @quota: absolute time quota in TU. The scheduler will try to divide the
|
||||
* remainig quota (after Time Events) according to this quota.
|
||||
* @max_duration: max uninterrupted context duration in TU
|
||||
*/
|
||||
struct iwl_time_quota_data {
|
||||
struct iwl_time_quota_data_v1 {
|
||||
__le32 id_and_color;
|
||||
__le32 quota;
|
||||
__le32 max_duration;
|
||||
@@ -137,8 +137,43 @@ struct iwl_time_quota_data {
|
||||
* essentially zero.
|
||||
* On CDB the fourth one is a regular binding.
|
||||
*/
|
||||
struct iwl_time_quota_cmd {
|
||||
struct iwl_time_quota_data quotas[MAX_BINDINGS];
|
||||
struct iwl_time_quota_cmd_v1 {
|
||||
struct iwl_time_quota_data_v1 quotas[MAX_BINDINGS];
|
||||
} __packed; /* TIME_QUOTA_ALLOCATION_CMD_API_S_VER_1 */
|
||||
|
||||
enum iwl_quota_low_latency {
|
||||
IWL_QUOTA_LOW_LATENCY_NONE = 0,
|
||||
IWL_QUOTA_LOW_LATENCY_TX = BIT(0),
|
||||
IWL_QUOTA_LOW_LATENCY_RX = BIT(1),
|
||||
IWL_QUOTA_LOW_LATENCY_TX_RX =
|
||||
IWL_QUOTA_LOW_LATENCY_TX | IWL_QUOTA_LOW_LATENCY_RX,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_time_quota_data - configuration of time quota per binding
|
||||
* @id_and_color: ID and color of the relevant Binding.
|
||||
* @quota: absolute time quota in TU. The scheduler will try to divide the
|
||||
* remainig quota (after Time Events) according to this quota.
|
||||
* @max_duration: max uninterrupted context duration in TU
|
||||
* @low_latency: low latency status, &enum iwl_quota_low_latency
|
||||
*/
|
||||
struct iwl_time_quota_data {
|
||||
__le32 id_and_color;
|
||||
__le32 quota;
|
||||
__le32 max_duration;
|
||||
__le32 low_latency;
|
||||
} __packed; /* TIME_QUOTA_DATA_API_S_VER_2 */
|
||||
|
||||
/**
|
||||
* struct iwl_time_quota_cmd - configuration of time quota between bindings
|
||||
* ( TIME_QUOTA_CMD = 0x2c )
|
||||
* Note: on non-CDB the fourth one is the auxilary mac and is essentially zero.
|
||||
* On CDB the fourth one is a regular binding.
|
||||
*
|
||||
* @quotas: allocations per binding
|
||||
*/
|
||||
struct iwl_time_quota_cmd {
|
||||
struct iwl_time_quota_data quotas[MAX_BINDINGS];
|
||||
} __packed; /* TIME_QUOTA_ALLOCATION_CMD_API_S_VER_2 */
|
||||
|
||||
#endif /* __iwl_fw_api_binding_h__ */
|
||||
|
||||
@@ -504,6 +504,7 @@ enum iwl_legacy_cmds {
|
||||
|
||||
/**
|
||||
* @MARKER_CMD: trace marker command, uses &struct iwl_mvm_marker
|
||||
* with &struct iwl_mvm_marker_rsp
|
||||
*/
|
||||
MARKER_CMD = 0xcb,
|
||||
|
||||
|
||||
@@ -278,6 +278,15 @@ struct iwl_mvm_marker {
|
||||
__le32 metadata[0];
|
||||
} __packed; /* MARKER_API_S_VER_1 */
|
||||
|
||||
/**
|
||||
* struct iwl_mvm_marker_rsp - Response to marker cmd
|
||||
*
|
||||
* @gp2: The gp2 clock value in the FW
|
||||
*/
|
||||
struct iwl_mvm_marker_rsp {
|
||||
__le32 gp2;
|
||||
} __packed;
|
||||
|
||||
/* Operation types for the debug mem access */
|
||||
enum {
|
||||
DEBUG_MEM_OP_READ = 0,
|
||||
|
||||
@@ -67,79 +67,12 @@
|
||||
* enum iwl_mac_conf_subcmd_ids - mac configuration command IDs
|
||||
*/
|
||||
enum iwl_mac_conf_subcmd_ids {
|
||||
/**
|
||||
* @LINK_QUALITY_MEASUREMENT_CMD: &struct iwl_link_qual_msrmnt_cmd
|
||||
*/
|
||||
LINK_QUALITY_MEASUREMENT_CMD = 0x1,
|
||||
|
||||
/**
|
||||
* @LINK_QUALITY_MEASUREMENT_COMPLETE_NOTIF:
|
||||
* &struct iwl_link_qual_msrmnt_notif
|
||||
*/
|
||||
LINK_QUALITY_MEASUREMENT_COMPLETE_NOTIF = 0xFE,
|
||||
|
||||
/**
|
||||
* @CHANNEL_SWITCH_NOA_NOTIF: &struct iwl_channel_switch_noa_notif
|
||||
*/
|
||||
CHANNEL_SWITCH_NOA_NOTIF = 0xFF,
|
||||
};
|
||||
|
||||
#define LQM_NUMBER_OF_STATIONS_IN_REPORT 16
|
||||
|
||||
enum iwl_lqm_cmd_operatrions {
|
||||
LQM_CMD_OPERATION_START_MEASUREMENT = 0x01,
|
||||
LQM_CMD_OPERATION_STOP_MEASUREMENT = 0x02,
|
||||
};
|
||||
|
||||
enum iwl_lqm_status {
|
||||
LQM_STATUS_SUCCESS = 0,
|
||||
LQM_STATUS_TIMEOUT = 1,
|
||||
LQM_STATUS_ABORT = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct iwl_link_qual_msrmnt_cmd - Link Quality Measurement command
|
||||
* @cmd_operation: command operation to be performed (start or stop)
|
||||
* as defined above.
|
||||
* @mac_id: MAC ID the measurement applies to.
|
||||
* @measurement_time: time of the total measurement to be performed, in uSec.
|
||||
* @timeout: maximum time allowed until a response is sent, in uSec.
|
||||
*/
|
||||
struct iwl_link_qual_msrmnt_cmd {
|
||||
__le32 cmd_operation;
|
||||
__le32 mac_id;
|
||||
__le32 measurement_time;
|
||||
__le32 timeout;
|
||||
} __packed /* LQM_CMD_API_S_VER_1 */;
|
||||
|
||||
/**
|
||||
* struct iwl_link_qual_msrmnt_notif - Link Quality Measurement notification
|
||||
*
|
||||
* @frequent_stations_air_time: an array containing the total air time
|
||||
* (in uSec) used by the most frequently transmitting stations.
|
||||
* @number_of_stations: the number of uniqe stations included in the array
|
||||
* (a number between 0 to 16)
|
||||
* @total_air_time_other_stations: the total air time (uSec) used by all the
|
||||
* stations which are not included in the above report.
|
||||
* @time_in_measurement_window: the total time in uSec in which a measurement
|
||||
* took place.
|
||||
* @tx_frame_dropped: the number of TX frames dropped due to retry limit during
|
||||
* measurement
|
||||
* @mac_id: MAC ID the measurement applies to.
|
||||
* @status: return status. may be one of the LQM_STATUS_* defined above.
|
||||
* @reserved: reserved.
|
||||
*/
|
||||
struct iwl_link_qual_msrmnt_notif {
|
||||
__le32 frequent_stations_air_time[LQM_NUMBER_OF_STATIONS_IN_REPORT];
|
||||
__le32 number_of_stations;
|
||||
__le32 total_air_time_other_stations;
|
||||
__le32 time_in_measurement_window;
|
||||
__le32 tx_frame_dropped;
|
||||
__le32 mac_id;
|
||||
__le32 status;
|
||||
u8 reserved[12];
|
||||
} __packed; /* LQM_MEASUREMENT_COMPLETE_NTF_API_S_VER1 */
|
||||
|
||||
/**
|
||||
* struct iwl_channel_switch_noa_notif - Channel switch NOA notification
|
||||
*
|
||||
|
||||
@@ -108,6 +108,7 @@ enum iwl_nvm_access_target {
|
||||
* @NVM_SECTION_TYPE_REGULATORY: regulatory section
|
||||
* @NVM_SECTION_TYPE_CALIBRATION: calibration section
|
||||
* @NVM_SECTION_TYPE_PRODUCTION: production section
|
||||
* @NVM_SECTION_TYPE_REGULATORY_SDP: regulatory section used by 3168 series
|
||||
* @NVM_SECTION_TYPE_MAC_OVERRIDE: MAC override section
|
||||
* @NVM_SECTION_TYPE_PHY_SKU: PHY SKU section
|
||||
* @NVM_MAX_NUM_SECTIONS: number of sections
|
||||
@@ -117,6 +118,7 @@ enum iwl_nvm_section_type {
|
||||
NVM_SECTION_TYPE_REGULATORY = 3,
|
||||
NVM_SECTION_TYPE_CALIBRATION = 4,
|
||||
NVM_SECTION_TYPE_PRODUCTION = 5,
|
||||
NVM_SECTION_TYPE_REGULATORY_SDP = 8,
|
||||
NVM_SECTION_TYPE_MAC_OVERRIDE = 11,
|
||||
NVM_SECTION_TYPE_PHY_SKU = 12,
|
||||
NVM_MAX_NUM_SECTIONS = 13,
|
||||
|
||||
@@ -357,8 +357,7 @@ struct iwl_dev_tx_power_cmd {
|
||||
u8 reserved[3];
|
||||
} __packed; /* TX_REDUCED_POWER_API_S_VER_4 */
|
||||
|
||||
#define IWL_NUM_GEO_PROFILES 3
|
||||
#define IWL_GEO_PER_CHAIN_SIZE 3
|
||||
#define IWL_NUM_GEO_PROFILES 3
|
||||
|
||||
/**
|
||||
* enum iwl_geo_per_chain_offset_operation - type of operation
|
||||
|
||||
@@ -68,9 +68,6 @@
|
||||
* @STA_FLG_REDUCED_TX_PWR_DATA: reduced TX power (data frames)
|
||||
* @STA_FLG_DISABLE_TX: set if TX should be disabled
|
||||
* @STA_FLG_PS: set if STA is in Power Save
|
||||
* @STA_FLG_INVALID: set if STA is invalid
|
||||
* @STA_FLG_DLP_EN: Direct Link Protocol is enabled
|
||||
* @STA_FLG_SET_ALL_KEYS: the current key applies to all key IDs
|
||||
* @STA_FLG_DRAIN_FLOW: drain flow
|
||||
* @STA_FLG_PAN: STA is for PAN interface
|
||||
* @STA_FLG_CLASS_AUTH: station is authenticated
|
||||
@@ -100,7 +97,6 @@
|
||||
* @STA_FLG_MIMO_EN_SISO: no support for MIMO
|
||||
* @STA_FLG_MIMO_EN_MIMO2: 2 streams supported
|
||||
* @STA_FLG_MIMO_EN_MIMO3: 3 streams supported
|
||||
* @STA_FLG_MFP_EN: Management Frame Protection
|
||||
* @STA_FLG_AGG_MPDU_DENS_MSK: A-MPDU density (mask)
|
||||
* @STA_FLG_AGG_MPDU_DENS_SHIFT: A-MPDU density (bit shift)
|
||||
* @STA_FLG_AGG_MPDU_DENS_2US: A-MPDU density (2 usec gap)
|
||||
|
||||
@@ -93,6 +93,8 @@ static void iwl_read_radio_regs(struct iwl_fw_runtime *fwrt,
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
IWL_DEBUG_INFO(fwrt, "WRT radio registers dump\n");
|
||||
|
||||
if (!iwl_trans_grab_nic_access(fwrt->trans, &flags))
|
||||
return;
|
||||
|
||||
@@ -233,6 +235,8 @@ static void iwl_fw_dump_fifos(struct iwl_fw_runtime *fwrt,
|
||||
unsigned long flags;
|
||||
int i, j;
|
||||
|
||||
IWL_DEBUG_INFO(fwrt, "WRT FIFO dump\n");
|
||||
|
||||
if (!iwl_trans_grab_nic_access(fwrt->trans, &flags))
|
||||
return;
|
||||
|
||||
@@ -476,6 +480,8 @@ static void iwl_dump_prph(struct iwl_trans *trans,
|
||||
unsigned long flags;
|
||||
u32 i;
|
||||
|
||||
IWL_DEBUG_INFO(trans, "WRT PRPH dump\n");
|
||||
|
||||
if (!iwl_trans_grab_nic_access(trans, &flags))
|
||||
return;
|
||||
|
||||
@@ -559,6 +565,8 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
||||
bool monitor_dump_only = false;
|
||||
int i;
|
||||
|
||||
IWL_DEBUG_INFO(fwrt, "WRT dump start\n");
|
||||
|
||||
/* there's no point in fw dump if the bus is dead */
|
||||
if (test_bit(STATUS_TRANS_DEAD, &fwrt->trans->status)) {
|
||||
IWL_ERR(fwrt, "Skip fw error dump since bus is dead\n");
|
||||
@@ -816,6 +824,9 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
||||
dump_mem->type = fw_dbg_mem[i].data_type;
|
||||
dump_mem->offset = cpu_to_le32(ofs);
|
||||
|
||||
IWL_DEBUG_INFO(fwrt, "WRT memory dump. Type=%u\n",
|
||||
dump_mem->type);
|
||||
|
||||
switch (dump_mem->type & cpu_to_le32(FW_DBG_MEM_TYPE_MASK)) {
|
||||
case cpu_to_le32(FW_DBG_MEM_TYPE_REGULAR):
|
||||
iwl_trans_read_mem_bytes(fwrt->trans, ofs,
|
||||
@@ -841,6 +852,7 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
||||
}
|
||||
|
||||
if (smem_len) {
|
||||
IWL_DEBUG_INFO(fwrt, "WRT SMEM dump\n");
|
||||
dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
|
||||
dump_data->len = cpu_to_le32(smem_len + sizeof(*dump_mem));
|
||||
dump_mem = (void *)dump_data->data;
|
||||
@@ -853,6 +865,7 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
||||
}
|
||||
|
||||
if (sram2_len) {
|
||||
IWL_DEBUG_INFO(fwrt, "WRT SRAM dump\n");
|
||||
dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM);
|
||||
dump_data->len = cpu_to_le32(sram2_len + sizeof(*dump_mem));
|
||||
dump_mem = (void *)dump_data->data;
|
||||
@@ -868,6 +881,7 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
||||
if (!fwrt->trans->cfg->gen2 &&
|
||||
fwrt->fw->img[fwrt->cur_fw_img].paging_mem_size &&
|
||||
fwrt->fw_paging_db[0].fw_paging_block) {
|
||||
IWL_DEBUG_INFO(fwrt, "WRT paging dump\n");
|
||||
for (i = 1; i < fwrt->num_of_paging_blk + 1; i++) {
|
||||
struct iwl_fw_error_dump_paging *paging;
|
||||
struct page *pages =
|
||||
@@ -930,6 +944,7 @@ void iwl_fw_error_dump(struct iwl_fw_runtime *fwrt)
|
||||
iwl_fw_free_dump_desc(fwrt);
|
||||
fwrt->dump.trig = NULL;
|
||||
clear_bit(IWL_FWRT_STATUS_DUMPING, &fwrt->status);
|
||||
IWL_DEBUG_INFO(fwrt, "WRT dump done\n");
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_error_dump);
|
||||
|
||||
@@ -1086,7 +1101,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work)
|
||||
|
||||
if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
||||
/* stop recording */
|
||||
iwl_set_bits_prph(fwrt->trans, MON_BUFF_SAMPLE_CTL, 0x100);
|
||||
iwl_fw_dbg_stop_recording(fwrt);
|
||||
|
||||
iwl_fw_error_dump(fwrt);
|
||||
|
||||
@@ -1104,10 +1119,7 @@ void iwl_fw_error_dump_wk(struct work_struct *work)
|
||||
u32 in_sample = iwl_read_prph(fwrt->trans, DBGC_IN_SAMPLE);
|
||||
u32 out_ctrl = iwl_read_prph(fwrt->trans, DBGC_OUT_CTRL);
|
||||
|
||||
/* stop recording */
|
||||
iwl_write_prph(fwrt->trans, DBGC_IN_SAMPLE, 0);
|
||||
udelay(100);
|
||||
iwl_write_prph(fwrt->trans, DBGC_OUT_CTRL, 0);
|
||||
iwl_fw_dbg_stop_recording(fwrt);
|
||||
/* wait before we collect the data till the DBGC stop */
|
||||
udelay(500);
|
||||
|
||||
|
||||
@@ -68,6 +68,8 @@
|
||||
#include <linux/workqueue.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include "runtime.h"
|
||||
#include "iwl-prph.h"
|
||||
#include "iwl-io.h"
|
||||
#include "file.h"
|
||||
#include "error-dump.h"
|
||||
|
||||
@@ -194,8 +196,21 @@ _iwl_fw_dbg_trigger_simple_stop(struct iwl_fw_runtime *fwrt,
|
||||
iwl_fw_dbg_get_trigger((fwrt)->fw,\
|
||||
(trig)))
|
||||
|
||||
static inline void iwl_fw_dbg_stop_recording(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
|
||||
iwl_set_bits_prph(fwrt->trans, MON_BUFF_SAMPLE_CTL, 0x100);
|
||||
} else {
|
||||
iwl_write_prph(fwrt->trans, DBGC_IN_SAMPLE, 0);
|
||||
udelay(100);
|
||||
iwl_write_prph(fwrt->trans, DBGC_OUT_CTRL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void iwl_fw_dump_conf_clear(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
iwl_fw_dbg_stop_recording(fwrt);
|
||||
|
||||
fwrt->dump.conf = FW_DBG_INVALID;
|
||||
}
|
||||
|
||||
|
||||
@@ -248,6 +248,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
|
||||
* @IWL_UCODE_TLV_API_NEW_RX_STATS: should new RX STATISTICS API be used
|
||||
* @IWL_UCODE_TLV_API_ATS_COEX_EXTERNAL: the coex notification is enlared to
|
||||
* include information about ACL time sharing.
|
||||
* @IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY: Quota command includes a field
|
||||
* indicating low latency direction.
|
||||
*
|
||||
* @NUM_IWL_UCODE_TLV_API: number of bits used
|
||||
*/
|
||||
@@ -265,6 +267,7 @@ enum iwl_ucode_tlv_api {
|
||||
IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE = (__force iwl_ucode_tlv_api_t)34,
|
||||
IWL_UCODE_TLV_API_NEW_RX_STATS = (__force iwl_ucode_tlv_api_t)35,
|
||||
IWL_UCODE_TLV_API_COEX_ATS_EXTERNAL = (__force iwl_ucode_tlv_api_t)37,
|
||||
IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY = (__force iwl_ucode_tlv_api_t)38,
|
||||
|
||||
NUM_IWL_UCODE_TLV_API
|
||||
#ifdef __CHECKER__
|
||||
|
||||
@@ -108,6 +108,18 @@ enum iwl_led_mode {
|
||||
IWL_LED_DISABLE,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum iwl_nvm_type - nvm formats
|
||||
* @IWL_NVM: the regular format
|
||||
* @IWL_NVM_EXT: extended NVM format
|
||||
* @IWL_NVM_SDP: NVM format used by 3168 series
|
||||
*/
|
||||
enum iwl_nvm_type {
|
||||
IWL_NVM,
|
||||
IWL_NVM_EXT,
|
||||
IWL_NVM_SDP,
|
||||
};
|
||||
|
||||
/*
|
||||
* This is the threshold value of plcp error rate per 100mSecs. It is
|
||||
* used to set and check for the validity of plcp_delta.
|
||||
@@ -320,7 +332,9 @@ struct iwl_pwr_tx_backoff {
|
||||
* @integrated: discrete or integrated
|
||||
* @gen2: a000 and on transport operation
|
||||
* @cdb: CDB support
|
||||
* @ext_nvm: extended NVM format
|
||||
* @nvm_type: see &enum iwl_nvm_type
|
||||
* @tx_cmd_queue_size: size of the cmd queue. If zero, use the same value as
|
||||
* the regular queues
|
||||
*
|
||||
* We enable the driver to be backward compatible wrt. hardware features.
|
||||
* API differences in uCode shouldn't be handled here but through TLVs
|
||||
@@ -342,6 +356,7 @@ struct iwl_cfg {
|
||||
const struct iwl_tt_params *thermal_params;
|
||||
enum iwl_device_family device_family;
|
||||
enum iwl_led_mode led_mode;
|
||||
enum iwl_nvm_type nvm_type;
|
||||
u32 max_data_size;
|
||||
u32 max_inst_size;
|
||||
netdev_features_t features;
|
||||
@@ -369,8 +384,8 @@ struct iwl_cfg {
|
||||
use_tfh:1,
|
||||
gen2:1,
|
||||
cdb:1,
|
||||
ext_nvm:1,
|
||||
dbgc_supported:1;
|
||||
u16 tx_cmd_queue_size;
|
||||
u8 valid_tx_ant;
|
||||
u8 valid_rx_ant;
|
||||
u8 non_shared_ant;
|
||||
|
||||
@@ -216,6 +216,7 @@ do { \
|
||||
#define IWL_DEBUG_TX_REPLY(p, f, a...) IWL_DEBUG(p, IWL_DL_TX_REPLY, f, ## a)
|
||||
#define IWL_DEBUG_TX_QUEUES(p, f, a...) IWL_DEBUG(p, IWL_DL_TX_QUEUES, f, ## a)
|
||||
#define IWL_DEBUG_RADIO(p, f, a...) IWL_DEBUG(p, IWL_DL_RADIO, f, ## a)
|
||||
#define IWL_DEBUG_DEV_RADIO(p, f, a...) IWL_DEBUG_DEV(p, IWL_DL_RADIO, f, ## a)
|
||||
#define IWL_DEBUG_POWER(p, f, a...) IWL_DEBUG(p, IWL_DL_POWER, f, ## a)
|
||||
#define IWL_DEBUG_11H(p, f, a...) IWL_DEBUG(p, IWL_DL_11H, f, ## a)
|
||||
#define IWL_DEBUG_RPM(p, f, a...) IWL_DEBUG(p, IWL_DL_RPM, f, ## a)
|
||||
|
||||
@@ -832,7 +832,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
capa->standard_phy_calibration_size =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_SEC_RT:
|
||||
case IWL_UCODE_TLV_SEC_RT:
|
||||
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR,
|
||||
tlv_len);
|
||||
drv->fw.type = IWL_FW_MVM;
|
||||
@@ -864,7 +864,7 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv,
|
||||
FW_PHY_CFG_RX_CHAIN) >>
|
||||
FW_PHY_CFG_RX_CHAIN_POS;
|
||||
break;
|
||||
case IWL_UCODE_TLV_SECURE_SEC_RT:
|
||||
case IWL_UCODE_TLV_SECURE_SEC_RT:
|
||||
iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR,
|
||||
tlv_len);
|
||||
drv->fw.type = IWL_FW_MVM;
|
||||
@@ -1335,7 +1335,8 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
|
||||
|
||||
/* Runtime instructions and 2 copies of data:
|
||||
* 1) unmodified from disk
|
||||
* 2) backup cache for save/restore during power-downs */
|
||||
* 2) backup cache for save/restore during power-downs
|
||||
*/
|
||||
for (i = 0; i < IWL_UCODE_TYPE_MAX; i++)
|
||||
if (iwl_alloc_ucode(drv, pieces, i))
|
||||
goto out_free_fw;
|
||||
|
||||
@@ -68,16 +68,17 @@
|
||||
#include <linux/export.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#include "iwl-drv.h"
|
||||
#include "iwl-modparams.h"
|
||||
#include "iwl-nvm-parse.h"
|
||||
#include "iwl-prph.h"
|
||||
#include "iwl-io.h"
|
||||
#include "iwl-csr.h"
|
||||
#include "fw/acpi.h"
|
||||
|
||||
/* NVM offsets (in words) definitions */
|
||||
enum wkp_nvm_offsets {
|
||||
enum nvm_offsets {
|
||||
/* NVM HW-Section offset (in words) definitions */
|
||||
SUBSYSTEM_ID = 0x0A,
|
||||
HW_ADDR = 0x15,
|
||||
@@ -92,7 +93,10 @@ enum wkp_nvm_offsets {
|
||||
|
||||
/* NVM calibration section offset (in words) definitions */
|
||||
NVM_CALIB_SECTION = 0x2B8,
|
||||
XTAL_CALIB = 0x316 - NVM_CALIB_SECTION
|
||||
XTAL_CALIB = 0x316 - NVM_CALIB_SECTION,
|
||||
|
||||
/* NVM REGULATORY -Section offset (in words) definitions */
|
||||
NVM_CHANNELS_SDP = 0,
|
||||
};
|
||||
|
||||
enum ext_nvm_offsets {
|
||||
@@ -206,8 +210,36 @@ enum iwl_nvm_channel_flags {
|
||||
NVM_CHANNEL_DC_HIGH = BIT(12),
|
||||
};
|
||||
|
||||
static inline void iwl_nvm_print_channel_flags(struct device *dev, u32 level,
|
||||
int chan, u16 flags)
|
||||
{
|
||||
#define CHECK_AND_PRINT_I(x) \
|
||||
((ch_flags & NVM_CHANNEL_##x) ? # x " " : "")
|
||||
((flags & NVM_CHANNEL_##x) ? " " #x : "")
|
||||
|
||||
if (!(flags & NVM_CHANNEL_VALID)) {
|
||||
IWL_DEBUG_DEV(dev, level, "Ch. %d: 0x%x: No traffic\n",
|
||||
chan, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Note: already can print up to 101 characters, 110 is the limit! */
|
||||
IWL_DEBUG_DEV(dev, level,
|
||||
"Ch. %d: 0x%x:%s%s%s%s%s%s%s%s%s%s%s%s\n",
|
||||
chan, flags,
|
||||
CHECK_AND_PRINT_I(VALID),
|
||||
CHECK_AND_PRINT_I(IBSS),
|
||||
CHECK_AND_PRINT_I(ACTIVE),
|
||||
CHECK_AND_PRINT_I(RADAR),
|
||||
CHECK_AND_PRINT_I(INDOOR_ONLY),
|
||||
CHECK_AND_PRINT_I(GO_CONCURRENT),
|
||||
CHECK_AND_PRINT_I(UNIFORM),
|
||||
CHECK_AND_PRINT_I(20MHZ),
|
||||
CHECK_AND_PRINT_I(40MHZ),
|
||||
CHECK_AND_PRINT_I(80MHZ),
|
||||
CHECK_AND_PRINT_I(160MHZ),
|
||||
CHECK_AND_PRINT_I(DC_HIGH));
|
||||
#undef CHECK_AND_PRINT_I
|
||||
}
|
||||
|
||||
static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,
|
||||
u16 nvm_flags, const struct iwl_cfg *cfg)
|
||||
@@ -215,7 +247,7 @@ static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,
|
||||
u32 flags = IEEE80211_CHAN_NO_HT40;
|
||||
u32 last_5ghz_ht = LAST_5GHZ_HT;
|
||||
|
||||
if (cfg->ext_nvm)
|
||||
if (cfg->nvm_type == IWL_NVM_EXT)
|
||||
last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
|
||||
|
||||
if (!is_5ghz && (nvm_flags & NVM_CHANNEL_40MHZ)) {
|
||||
@@ -268,7 +300,7 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
|
||||
int num_of_ch, num_2ghz_channels;
|
||||
const u8 *nvm_chan;
|
||||
|
||||
if (!cfg->ext_nvm) {
|
||||
if (cfg->nvm_type != IWL_NVM_EXT) {
|
||||
num_of_ch = IWL_NUM_CHANNELS;
|
||||
nvm_chan = &iwl_nvm_channels[0];
|
||||
num_2ghz_channels = NUM_2GHZ_CHANNELS;
|
||||
@@ -302,12 +334,8 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
|
||||
* supported, hence we still want to add them to
|
||||
* the list of supported channels to cfg80211.
|
||||
*/
|
||||
IWL_DEBUG_EEPROM(dev,
|
||||
"Ch. %d Flags %x [%sGHz] - No traffic\n",
|
||||
nvm_chan[ch_idx],
|
||||
ch_flags,
|
||||
(ch_idx >= num_2ghz_channels) ?
|
||||
"5.2" : "2.4");
|
||||
iwl_nvm_print_channel_flags(dev, IWL_DL_EEPROM,
|
||||
nvm_chan[ch_idx], ch_flags);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -337,27 +365,10 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
|
||||
else
|
||||
channel->flags = 0;
|
||||
|
||||
IWL_DEBUG_EEPROM(dev,
|
||||
"Ch. %d [%sGHz] flags 0x%x %s%s%s%s%s%s%s%s%s%s%s%s(%ddBm): Ad-Hoc %ssupported\n",
|
||||
channel->hw_value,
|
||||
is_5ghz ? "5.2" : "2.4",
|
||||
ch_flags,
|
||||
CHECK_AND_PRINT_I(VALID),
|
||||
CHECK_AND_PRINT_I(IBSS),
|
||||
CHECK_AND_PRINT_I(ACTIVE),
|
||||
CHECK_AND_PRINT_I(RADAR),
|
||||
CHECK_AND_PRINT_I(INDOOR_ONLY),
|
||||
CHECK_AND_PRINT_I(GO_CONCURRENT),
|
||||
CHECK_AND_PRINT_I(UNIFORM),
|
||||
CHECK_AND_PRINT_I(20MHZ),
|
||||
CHECK_AND_PRINT_I(40MHZ),
|
||||
CHECK_AND_PRINT_I(80MHZ),
|
||||
CHECK_AND_PRINT_I(160MHZ),
|
||||
CHECK_AND_PRINT_I(DC_HIGH),
|
||||
channel->max_power,
|
||||
((ch_flags & NVM_CHANNEL_IBSS) &&
|
||||
!(ch_flags & NVM_CHANNEL_RADAR))
|
||||
? "" : "not ");
|
||||
iwl_nvm_print_channel_flags(dev, IWL_DL_EEPROM,
|
||||
channel->hw_value, ch_flags);
|
||||
IWL_DEBUG_EEPROM(dev, "Ch. %d: %ddBm\n",
|
||||
channel->hw_value, channel->max_power);
|
||||
}
|
||||
|
||||
return n_channels;
|
||||
@@ -484,7 +495,7 @@ IWL_EXPORT_SYMBOL(iwl_init_sbands);
|
||||
static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw,
|
||||
const __le16 *phy_sku)
|
||||
{
|
||||
if (!cfg->ext_nvm)
|
||||
if (cfg->nvm_type != IWL_NVM_EXT)
|
||||
return le16_to_cpup(nvm_sw + SKU);
|
||||
|
||||
return le32_to_cpup((__le32 *)(phy_sku + SKU_FAMILY_8000));
|
||||
@@ -492,7 +503,7 @@ static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw,
|
||||
|
||||
static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw)
|
||||
{
|
||||
if (!cfg->ext_nvm)
|
||||
if (cfg->nvm_type != IWL_NVM_EXT)
|
||||
return le16_to_cpup(nvm_sw + NVM_VERSION);
|
||||
else
|
||||
return le32_to_cpup((__le32 *)(nvm_sw +
|
||||
@@ -502,7 +513,7 @@ static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw)
|
||||
static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, const __le16 *nvm_sw,
|
||||
const __le16 *phy_sku)
|
||||
{
|
||||
if (!cfg->ext_nvm)
|
||||
if (cfg->nvm_type != IWL_NVM_EXT)
|
||||
return le16_to_cpup(nvm_sw + RADIO_CFG);
|
||||
|
||||
return le32_to_cpup((__le32 *)(phy_sku + RADIO_CFG_FAMILY_EXT_NVM));
|
||||
@@ -513,7 +524,7 @@ static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg, const __le16 *nvm_sw)
|
||||
{
|
||||
int n_hw_addr;
|
||||
|
||||
if (!cfg->ext_nvm)
|
||||
if (cfg->nvm_type != IWL_NVM_EXT)
|
||||
return le16_to_cpup(nvm_sw + N_HW_ADDRS);
|
||||
|
||||
n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000));
|
||||
@@ -525,7 +536,7 @@ static void iwl_set_radio_cfg(const struct iwl_cfg *cfg,
|
||||
struct iwl_nvm_data *data,
|
||||
u32 radio_cfg)
|
||||
{
|
||||
if (!cfg->ext_nvm) {
|
||||
if (cfg->nvm_type != IWL_NVM_EXT) {
|
||||
data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg);
|
||||
data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg);
|
||||
data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg);
|
||||
@@ -634,7 +645,7 @@ static int iwl_set_hw_address(struct iwl_trans *trans,
|
||||
{
|
||||
if (cfg->mac_addr_from_csr) {
|
||||
iwl_set_hw_address_from_csr(trans, data);
|
||||
} else if (!cfg->ext_nvm) {
|
||||
} else if (cfg->nvm_type != IWL_NVM_EXT) {
|
||||
const u8 *hw_addr = (const u8 *)(nvm_hw + HW_ADDR);
|
||||
|
||||
/* The byte order is little endian 16 bit, meaning 214365 */
|
||||
@@ -706,7 +717,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
u16 lar_config;
|
||||
const __le16 *ch_section;
|
||||
|
||||
if (!cfg->ext_nvm)
|
||||
if (cfg->nvm_type != IWL_NVM_EXT)
|
||||
data = kzalloc(sizeof(*data) +
|
||||
sizeof(struct ieee80211_channel) *
|
||||
IWL_NUM_CHANNELS,
|
||||
@@ -740,7 +751,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
|
||||
data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw);
|
||||
|
||||
if (!cfg->ext_nvm) {
|
||||
if (cfg->nvm_type != IWL_NVM_EXT) {
|
||||
/* Checking for required sections */
|
||||
if (!nvm_calib) {
|
||||
IWL_ERR(trans,
|
||||
@@ -748,11 +759,15 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
kfree(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ch_section = cfg->nvm_type == IWL_NVM_SDP ?
|
||||
®ulatory[NVM_CHANNELS_SDP] :
|
||||
&nvm_sw[NVM_CHANNELS];
|
||||
|
||||
/* in family 8000 Xtal calibration values moved to OTP */
|
||||
data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
|
||||
data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
|
||||
lar_enabled = true;
|
||||
ch_section = &nvm_sw[NVM_CHANNELS];
|
||||
} else {
|
||||
u16 lar_offset = data->nvm_version < 0xE39 ?
|
||||
NVM_LAR_OFFSET_OLD :
|
||||
@@ -786,7 +801,7 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan,
|
||||
u32 flags = NL80211_RRF_NO_HT40;
|
||||
u32 last_5ghz_ht = LAST_5GHZ_HT;
|
||||
|
||||
if (cfg->ext_nvm)
|
||||
if (cfg->nvm_type == IWL_NVM_EXT)
|
||||
last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
|
||||
|
||||
if (ch_idx < NUM_2GHZ_CHANNELS &&
|
||||
@@ -834,7 +849,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
|
||||
int ch_idx;
|
||||
u16 ch_flags;
|
||||
u32 reg_rule_flags, prev_reg_rule_flags = 0;
|
||||
const u8 *nvm_chan = cfg->ext_nvm ?
|
||||
const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ?
|
||||
iwl_ext_nvm_channels : iwl_nvm_channels;
|
||||
struct ieee80211_regdomain *regd;
|
||||
int size_of_regd;
|
||||
@@ -843,7 +858,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
|
||||
int center_freq, prev_center_freq = 0;
|
||||
int valid_rules = 0;
|
||||
bool new_rule;
|
||||
int max_num_ch = cfg->ext_nvm ?
|
||||
int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ?
|
||||
IWL_NUM_CHANNELS_EXT : IWL_NUM_CHANNELS;
|
||||
|
||||
if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES))
|
||||
@@ -873,12 +888,8 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
|
||||
new_rule = false;
|
||||
|
||||
if (!(ch_flags & NVM_CHANNEL_VALID)) {
|
||||
IWL_DEBUG_DEV(dev, IWL_DL_LAR,
|
||||
"Ch. %d Flags %x [%sGHz] - No traffic\n",
|
||||
nvm_chan[ch_idx],
|
||||
ch_flags,
|
||||
(ch_idx >= NUM_2GHZ_CHANNELS) ?
|
||||
"5.2" : "2.4");
|
||||
iwl_nvm_print_channel_flags(dev, IWL_DL_LAR,
|
||||
nvm_chan[ch_idx], ch_flags);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -914,31 +925,8 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
|
||||
prev_center_freq = center_freq;
|
||||
prev_reg_rule_flags = reg_rule_flags;
|
||||
|
||||
IWL_DEBUG_DEV(dev, IWL_DL_LAR,
|
||||
"Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s%s%s%s(0x%02x)\n",
|
||||
center_freq,
|
||||
band == NL80211_BAND_5GHZ ? "5.2" : "2.4",
|
||||
CHECK_AND_PRINT_I(VALID),
|
||||
CHECK_AND_PRINT_I(IBSS),
|
||||
CHECK_AND_PRINT_I(ACTIVE),
|
||||
CHECK_AND_PRINT_I(RADAR),
|
||||
CHECK_AND_PRINT_I(INDOOR_ONLY),
|
||||
CHECK_AND_PRINT_I(GO_CONCURRENT),
|
||||
CHECK_AND_PRINT_I(UNIFORM),
|
||||
CHECK_AND_PRINT_I(20MHZ),
|
||||
CHECK_AND_PRINT_I(40MHZ),
|
||||
CHECK_AND_PRINT_I(80MHZ),
|
||||
CHECK_AND_PRINT_I(160MHZ),
|
||||
CHECK_AND_PRINT_I(DC_HIGH),
|
||||
ch_flags);
|
||||
IWL_DEBUG_DEV(dev, IWL_DL_LAR,
|
||||
"Ch. %d [%sGHz] reg_flags 0x%x: %s\n",
|
||||
center_freq,
|
||||
band == NL80211_BAND_5GHZ ? "5.2" : "2.4",
|
||||
reg_rule_flags,
|
||||
((ch_flags & NVM_CHANNEL_ACTIVE) &&
|
||||
!(ch_flags & NVM_CHANNEL_RADAR))
|
||||
? "Ad-Hoc" : "");
|
||||
iwl_nvm_print_channel_flags(dev, IWL_DL_LAR,
|
||||
nvm_chan[ch_idx], ch_flags);
|
||||
}
|
||||
|
||||
regd->n_reg_rules = valid_rules;
|
||||
@@ -950,91 +938,3 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
|
||||
return regd;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_parse_nvm_mcc_info);
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
#define WRDD_METHOD "WRDD"
|
||||
#define WRDD_WIFI (0x07)
|
||||
#define WRDD_WIGIG (0x10)
|
||||
|
||||
static u32 iwl_wrdd_get_mcc(struct device *dev, union acpi_object *wrdd)
|
||||
{
|
||||
union acpi_object *mcc_pkg, *domain_type, *mcc_value;
|
||||
u32 i;
|
||||
|
||||
if (wrdd->type != ACPI_TYPE_PACKAGE ||
|
||||
wrdd->package.count < 2 ||
|
||||
wrdd->package.elements[0].type != ACPI_TYPE_INTEGER ||
|
||||
wrdd->package.elements[0].integer.value != 0) {
|
||||
IWL_DEBUG_EEPROM(dev, "Unsupported wrdd structure\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 1 ; i < wrdd->package.count ; ++i) {
|
||||
mcc_pkg = &wrdd->package.elements[i];
|
||||
|
||||
if (mcc_pkg->type != ACPI_TYPE_PACKAGE ||
|
||||
mcc_pkg->package.count < 2 ||
|
||||
mcc_pkg->package.elements[0].type != ACPI_TYPE_INTEGER ||
|
||||
mcc_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) {
|
||||
mcc_pkg = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
domain_type = &mcc_pkg->package.elements[0];
|
||||
if (domain_type->integer.value == WRDD_WIFI)
|
||||
break;
|
||||
|
||||
mcc_pkg = NULL;
|
||||
}
|
||||
|
||||
if (mcc_pkg) {
|
||||
mcc_value = &mcc_pkg->package.elements[1];
|
||||
return mcc_value->integer.value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iwl_get_bios_mcc(struct device *dev, char *mcc)
|
||||
{
|
||||
acpi_handle root_handle;
|
||||
acpi_handle handle;
|
||||
struct acpi_buffer wrdd = {ACPI_ALLOCATE_BUFFER, NULL};
|
||||
acpi_status status;
|
||||
u32 mcc_val;
|
||||
|
||||
root_handle = ACPI_HANDLE(dev);
|
||||
if (!root_handle) {
|
||||
IWL_DEBUG_EEPROM(dev,
|
||||
"Could not retrieve root port ACPI handle\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Get the method's handle */
|
||||
status = acpi_get_handle(root_handle, (acpi_string)WRDD_METHOD,
|
||||
&handle);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
IWL_DEBUG_EEPROM(dev, "WRD method not found\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Call WRDD with no arguments */
|
||||
status = acpi_evaluate_object(handle, NULL, NULL, &wrdd);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
IWL_DEBUG_EEPROM(dev, "WRDC invocation failed (0x%x)\n",
|
||||
status);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
mcc_val = iwl_wrdd_get_mcc(dev, wrdd.pointer);
|
||||
kfree(wrdd.pointer);
|
||||
if (!mcc_val)
|
||||
return -ENOENT;
|
||||
|
||||
mcc[0] = (mcc_val >> 8) & 0xff;
|
||||
mcc[1] = mcc_val & 0xff;
|
||||
mcc[2] = '\0';
|
||||
return 0;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_get_bios_mcc);
|
||||
#endif
|
||||
|
||||
@@ -109,21 +109,4 @@ struct ieee80211_regdomain *
|
||||
iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
|
||||
int num_of_ch, __le32 *channels, u16 fw_mcc);
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
/**
|
||||
* iwl_get_bios_mcc - read MCC from BIOS, if available
|
||||
*
|
||||
* @dev: the struct device
|
||||
* @mcc: output buffer (3 bytes) that will get the MCC
|
||||
*
|
||||
* This function tries to read the current MCC from ACPI if available.
|
||||
*/
|
||||
int iwl_get_bios_mcc(struct device *dev, char *mcc);
|
||||
#else
|
||||
static inline int iwl_get_bios_mcc(struct device *dev, char *mcc)
|
||||
{
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __iwl_nvm_parse_h__ */
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
* GPL LICENSE SUMMARY
|
||||
*
|
||||
* Copyright(c) 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@@ -31,6 +32,7 @@
|
||||
* BSD LICENSE
|
||||
*
|
||||
* Copyright(c) 2015 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -205,3 +207,17 @@ int iwl_cmd_groups_verify_sorted(const struct iwl_trans_config *trans)
|
||||
return 0;
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_cmd_groups_verify_sorted);
|
||||
|
||||
void iwl_trans_ref(struct iwl_trans *trans)
|
||||
{
|
||||
if (trans->ops->ref)
|
||||
trans->ops->ref(trans);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_trans_ref);
|
||||
|
||||
void iwl_trans_unref(struct iwl_trans *trans)
|
||||
{
|
||||
if (trans->ops->unref)
|
||||
trans->ops->unref(trans);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_trans_unref);
|
||||
|
||||
@@ -749,8 +749,6 @@ struct iwl_trans {
|
||||
struct lockdep_map sync_cmd_lockdep_map;
|
||||
#endif
|
||||
|
||||
u64 dflt_pwr_limit;
|
||||
|
||||
const struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
|
||||
const struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
|
||||
struct iwl_fw_dbg_trigger_tlv * const *dbg_trigger_tlv;
|
||||
@@ -875,18 +873,6 @@ static inline int iwl_trans_d3_resume(struct iwl_trans *trans,
|
||||
return trans->ops->d3_resume(trans, status, test, reset);
|
||||
}
|
||||
|
||||
static inline void iwl_trans_ref(struct iwl_trans *trans)
|
||||
{
|
||||
if (trans->ops->ref)
|
||||
trans->ops->ref(trans);
|
||||
}
|
||||
|
||||
static inline void iwl_trans_unref(struct iwl_trans *trans)
|
||||
{
|
||||
if (trans->ops->unref)
|
||||
trans->ops->unref(trans);
|
||||
}
|
||||
|
||||
static inline int iwl_trans_suspend(struct iwl_trans *trans)
|
||||
{
|
||||
if (!trans->ops->suspend)
|
||||
@@ -1191,6 +1177,8 @@ struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
|
||||
const struct iwl_cfg *cfg,
|
||||
const struct iwl_trans_ops *ops);
|
||||
void iwl_trans_free(struct iwl_trans *trans);
|
||||
void iwl_trans_ref(struct iwl_trans *trans);
|
||||
void iwl_trans_unref(struct iwl_trans *trans);
|
||||
|
||||
/*****************************************************
|
||||
* driver (transport) register/unregister functions
|
||||
|
||||
@@ -664,6 +664,7 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
int ret, i;
|
||||
struct iwl_binding_cmd binding_cmd = {};
|
||||
struct iwl_time_quota_cmd quota_cmd = {};
|
||||
struct iwl_time_quota_data *quota;
|
||||
u32 status;
|
||||
int size;
|
||||
|
||||
@@ -745,17 +746,20 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
return ret;
|
||||
|
||||
/* and some quota */
|
||||
quota_cmd.quotas[0].id_and_color =
|
||||
quota = iwl_mvm_quota_cmd_get_quota(mvm, "a_cmd, 0);
|
||||
quota->id_and_color =
|
||||
cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->phy_ctxt->id,
|
||||
mvmvif->phy_ctxt->color));
|
||||
quota_cmd.quotas[0].quota = cpu_to_le32(IWL_MVM_MAX_QUOTA);
|
||||
quota_cmd.quotas[0].max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA);
|
||||
quota->quota = cpu_to_le32(IWL_MVM_MAX_QUOTA);
|
||||
quota->max_duration = cpu_to_le32(IWL_MVM_MAX_QUOTA);
|
||||
|
||||
for (i = 1; i < MAX_BINDINGS; i++)
|
||||
quota_cmd.quotas[i].id_and_color = cpu_to_le32(FW_CTXT_INVALID);
|
||||
for (i = 1; i < MAX_BINDINGS; i++) {
|
||||
quota = iwl_mvm_quota_cmd_get_quota(mvm, "a_cmd, i);
|
||||
quota->id_and_color = cpu_to_le32(FW_CTXT_INVALID);
|
||||
}
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0,
|
||||
sizeof(quota_cmd), "a_cmd);
|
||||
iwl_mvm_quota_cmd_size(mvm), "a_cmd);
|
||||
if (ret)
|
||||
IWL_ERR(mvm, "Failed to send quota: %d\n", ret);
|
||||
|
||||
|
||||
@@ -1455,80 +1455,6 @@ static const char * const chanwidths[] = {
|
||||
[NL80211_CHAN_WIDTH_160] = "vht160",
|
||||
};
|
||||
|
||||
static bool iwl_mvm_lqm_notif_wait(struct iwl_notif_wait_data *notif_wait,
|
||||
struct iwl_rx_packet *pkt, void *data)
|
||||
{
|
||||
struct ieee80211_vif *vif = data;
|
||||
struct iwl_mvm *mvm =
|
||||
container_of(notif_wait, struct iwl_mvm, notif_wait);
|
||||
struct iwl_link_qual_msrmnt_notif *report = (void *)pkt->data;
|
||||
u32 num_of_stations = le32_to_cpu(report->number_of_stations);
|
||||
int i;
|
||||
|
||||
IWL_INFO(mvm, "LQM report:\n");
|
||||
IWL_INFO(mvm, "\tstatus: %d\n", report->status);
|
||||
IWL_INFO(mvm, "\tmacID: %d\n", le32_to_cpu(report->mac_id));
|
||||
IWL_INFO(mvm, "\ttx_frame_dropped: %d\n",
|
||||
le32_to_cpu(report->tx_frame_dropped));
|
||||
IWL_INFO(mvm, "\ttime_in_measurement_window: %d us\n",
|
||||
le32_to_cpu(report->time_in_measurement_window));
|
||||
IWL_INFO(mvm, "\ttotal_air_time_other_stations: %d\n",
|
||||
le32_to_cpu(report->total_air_time_other_stations));
|
||||
IWL_INFO(mvm, "\tchannel_freq: %d\n",
|
||||
vif->bss_conf.chandef.center_freq1);
|
||||
IWL_INFO(mvm, "\tchannel_width: %s\n",
|
||||
chanwidths[vif->bss_conf.chandef.width]);
|
||||
IWL_INFO(mvm, "\tnumber_of_stations: %d\n", num_of_stations);
|
||||
for (i = 0; i < num_of_stations; i++)
|
||||
IWL_INFO(mvm, "\t\tsta[%d]: %d\n", i,
|
||||
report->frequent_stations_air_time[i]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_lqm_send_cmd_write(struct ieee80211_vif *vif,
|
||||
char *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_mvm *mvm = mvmvif->mvm;
|
||||
struct iwl_notification_wait wait_lqm_notif;
|
||||
static u16 lqm_notif[] = {
|
||||
WIDE_ID(MAC_CONF_GROUP,
|
||||
LINK_QUALITY_MEASUREMENT_COMPLETE_NOTIF)
|
||||
};
|
||||
int err;
|
||||
u32 duration;
|
||||
u32 timeout;
|
||||
|
||||
if (sscanf(buf, "%d,%d", &duration, &timeout) != 2)
|
||||
return -EINVAL;
|
||||
|
||||
iwl_init_notification_wait(&mvm->notif_wait, &wait_lqm_notif,
|
||||
lqm_notif, ARRAY_SIZE(lqm_notif),
|
||||
iwl_mvm_lqm_notif_wait, vif);
|
||||
mutex_lock(&mvm->mutex);
|
||||
err = iwl_mvm_send_lqm_cmd(vif, LQM_CMD_OPERATION_START_MEASUREMENT,
|
||||
duration, timeout);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
if (err) {
|
||||
IWL_ERR(mvm, "Failed to send lqm cmdf(err=%d)\n", err);
|
||||
iwl_remove_notification(&mvm->notif_wait, &wait_lqm_notif);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* wait for 2 * timeout (safety guard) and convert to jiffies*/
|
||||
timeout = msecs_to_jiffies((timeout * 2) / 1000);
|
||||
|
||||
err = iwl_wait_notification(&mvm->notif_wait, &wait_lqm_notif,
|
||||
timeout);
|
||||
if (err)
|
||||
IWL_ERR(mvm, "Getting lqm notif timed out\n");
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \
|
||||
_MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_vif)
|
||||
#define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \
|
||||
@@ -1553,7 +1479,6 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(tof_range_abort, 32);
|
||||
MVM_DEBUGFS_READ_FILE_OPS(tof_range_response);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(tof_responder_params, 32);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(quota_min, 32);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(lqm_send_cmd, 64);
|
||||
MVM_DEBUGFS_READ_FILE_OPS(os_device_timediff);
|
||||
|
||||
|
||||
@@ -1594,7 +1519,6 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
|
||||
S_IRUSR | S_IWUSR);
|
||||
MVM_DEBUGFS_ADD_FILE_VIF(quota_min, mvmvif->dbgfs_dir,
|
||||
S_IRUSR | S_IWUSR);
|
||||
MVM_DEBUGFS_ADD_FILE_VIF(lqm_send_cmd, mvmvif->dbgfs_dir, S_IWUSR);
|
||||
MVM_DEBUGFS_ADD_FILE_VIF(os_device_timediff,
|
||||
mvmvif->dbgfs_dir, S_IRUSR);
|
||||
|
||||
|
||||
@@ -660,6 +660,36 @@ iwl_dbgfs_bt_force_ant_write(struct iwl_mvm *mvm, char *buf,
|
||||
return ret ?: count;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_fw_ver_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_mvm *mvm = file->private_data;
|
||||
char *buff, *pos, *endpos;
|
||||
static const size_t bufsz = 1024;
|
||||
int ret;
|
||||
|
||||
buff = kmalloc(bufsz, GFP_KERNEL);
|
||||
if (!buff)
|
||||
return -ENOMEM;
|
||||
|
||||
pos = buff;
|
||||
endpos = pos + bufsz;
|
||||
|
||||
pos += scnprintf(pos, endpos - pos, "FW prefix: %s\n",
|
||||
mvm->trans->cfg->fw_name_pre);
|
||||
pos += scnprintf(pos, endpos - pos, "FW: %s\n",
|
||||
mvm->fwrt.fw->human_readable);
|
||||
pos += scnprintf(pos, endpos - pos, "Device: %s\n",
|
||||
mvm->fwrt.trans->cfg->name);
|
||||
pos += scnprintf(pos, endpos - pos, "Bus: %s\n",
|
||||
mvm->fwrt.dev->bus->name);
|
||||
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff);
|
||||
kfree(buff);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define PRINT_STATS_LE32(_struct, _memb) \
|
||||
pos += scnprintf(buf + pos, bufsz - pos, \
|
||||
fmt_table, #_memb, \
|
||||
@@ -1662,6 +1692,7 @@ MVM_DEBUGFS_READ_FILE_OPS(bt_cmd);
|
||||
MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64);
|
||||
MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats);
|
||||
MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats);
|
||||
MVM_DEBUGFS_READ_FILE_OPS(fw_ver);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10);
|
||||
MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio, 10);
|
||||
@@ -1843,6 +1874,7 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
|
||||
MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir,
|
||||
S_IRUSR | S_IWUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(fw_ver, mvm->debugfs_dir, S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(drv_rx_stats, mvm->debugfs_dir, S_IRUSR);
|
||||
MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR);
|
||||
|
||||
@@ -66,7 +66,6 @@
|
||||
*****************************************************************************/
|
||||
#include <net/mac80211.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#include "iwl-trans.h"
|
||||
#include "iwl-op-mode.h"
|
||||
@@ -75,7 +74,7 @@
|
||||
#include "iwl-csr.h" /* for iwl_mvm_rx_card_state_notif */
|
||||
#include "iwl-io.h" /* for iwl_mvm_rx_card_state_notif */
|
||||
#include "iwl-prph.h"
|
||||
#include "iwl-eeprom-parse.h"
|
||||
#include "fw/acpi.h"
|
||||
|
||||
#include "mvm.h"
|
||||
#include "fw/dbg.h"
|
||||
@@ -579,17 +578,6 @@ static int iwl_mvm_config_ltr(struct iwl_mvm *mvm)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
#define ACPI_WRDS_METHOD "WRDS"
|
||||
#define ACPI_EWRD_METHOD "EWRD"
|
||||
#define ACPI_WGDS_METHOD "WGDS"
|
||||
#define ACPI_WIFI_DOMAIN (0x07)
|
||||
#define ACPI_WRDS_WIFI_DATA_SIZE (IWL_MVM_SAR_TABLE_SIZE + 2)
|
||||
#define ACPI_EWRD_WIFI_DATA_SIZE ((IWL_MVM_SAR_PROFILE_NUM - 1) * \
|
||||
IWL_MVM_SAR_TABLE_SIZE + 3)
|
||||
#define ACPI_WGDS_WIFI_DATA_SIZE 18
|
||||
#define ACPI_WGDS_NUM_BANDS 2
|
||||
#define ACPI_WGDS_TABLE_SIZE 3
|
||||
|
||||
static int iwl_mvm_sar_set_profile(struct iwl_mvm *mvm,
|
||||
union acpi_object *table,
|
||||
struct iwl_mvm_sar_profile *profile,
|
||||
@@ -599,7 +587,7 @@ static int iwl_mvm_sar_set_profile(struct iwl_mvm *mvm,
|
||||
|
||||
profile->enabled = enabled;
|
||||
|
||||
for (i = 0; i < IWL_MVM_SAR_TABLE_SIZE; i++) {
|
||||
for (i = 0; i < ACPI_SAR_TABLE_SIZE; i++) {
|
||||
if ((table[i].type != ACPI_TYPE_INTEGER) ||
|
||||
(table[i].integer.value > U8_MAX))
|
||||
return -EINVAL;
|
||||
@@ -610,88 +598,18 @@ static int iwl_mvm_sar_set_profile(struct iwl_mvm *mvm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static union acpi_object *iwl_mvm_sar_find_wifi_pkg(struct iwl_mvm *mvm,
|
||||
union acpi_object *data,
|
||||
int data_size)
|
||||
{
|
||||
union acpi_object *wifi_pkg = NULL;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* We need at least two packages, one for the revision and one
|
||||
* for the data itself. Also check that the revision is valid
|
||||
* (i.e. it is an integer set to 0).
|
||||
*/
|
||||
if (data->type != ACPI_TYPE_PACKAGE ||
|
||||
data->package.count < 2 ||
|
||||
data->package.elements[0].type != ACPI_TYPE_INTEGER ||
|
||||
data->package.elements[0].integer.value != 0) {
|
||||
IWL_DEBUG_RADIO(mvm, "Unsupported packages structure\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
/* loop through all the packages to find the one for WiFi */
|
||||
for (i = 1; i < data->package.count; i++) {
|
||||
union acpi_object *domain;
|
||||
|
||||
wifi_pkg = &data->package.elements[i];
|
||||
|
||||
/* Skip anything that is not a package with the right
|
||||
* amount of elements (i.e. domain_type,
|
||||
* enabled/disabled plus the actual data size.
|
||||
*/
|
||||
if (wifi_pkg->type != ACPI_TYPE_PACKAGE ||
|
||||
wifi_pkg->package.count != data_size)
|
||||
continue;
|
||||
|
||||
domain = &wifi_pkg->package.elements[0];
|
||||
if (domain->type == ACPI_TYPE_INTEGER &&
|
||||
domain->integer.value == ACPI_WIFI_DOMAIN)
|
||||
break;
|
||||
|
||||
wifi_pkg = NULL;
|
||||
}
|
||||
|
||||
if (!wifi_pkg)
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
||||
return wifi_pkg;
|
||||
}
|
||||
|
||||
static int iwl_mvm_sar_get_wrds_table(struct iwl_mvm *mvm)
|
||||
{
|
||||
union acpi_object *wifi_pkg, *table;
|
||||
acpi_handle root_handle;
|
||||
acpi_handle handle;
|
||||
struct acpi_buffer wrds = {ACPI_ALLOCATE_BUFFER, NULL};
|
||||
acpi_status status;
|
||||
union acpi_object *wifi_pkg, *table, *data;
|
||||
bool enabled;
|
||||
int ret;
|
||||
|
||||
root_handle = ACPI_HANDLE(mvm->dev);
|
||||
if (!root_handle) {
|
||||
IWL_DEBUG_RADIO(mvm,
|
||||
"Could not retrieve root port ACPI handle\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
data = iwl_acpi_get_object(mvm->dev, ACPI_WRDS_METHOD);
|
||||
if (IS_ERR(data))
|
||||
return PTR_ERR(data);
|
||||
|
||||
/* Get the method's handle */
|
||||
status = acpi_get_handle(root_handle, (acpi_string)ACPI_WRDS_METHOD,
|
||||
&handle);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
IWL_DEBUG_RADIO(mvm, "WRDS method not found\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Call WRDS with no arguments */
|
||||
status = acpi_evaluate_object(handle, NULL, NULL, &wrds);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
IWL_DEBUG_RADIO(mvm, "WRDS invocation failed (0x%x)\n", status);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
wifi_pkg = iwl_mvm_sar_find_wifi_pkg(mvm, wrds.pointer,
|
||||
ACPI_WRDS_WIFI_DATA_SIZE);
|
||||
wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data,
|
||||
ACPI_WRDS_WIFI_DATA_SIZE);
|
||||
if (IS_ERR(wifi_pkg)) {
|
||||
ret = PTR_ERR(wifi_pkg);
|
||||
goto out_free;
|
||||
@@ -712,46 +630,23 @@ static int iwl_mvm_sar_get_wrds_table(struct iwl_mvm *mvm)
|
||||
*/
|
||||
ret = iwl_mvm_sar_set_profile(mvm, table, &mvm->sar_profiles[0],
|
||||
enabled);
|
||||
|
||||
out_free:
|
||||
kfree(wrds.pointer);
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwl_mvm_sar_get_ewrd_table(struct iwl_mvm *mvm)
|
||||
{
|
||||
union acpi_object *wifi_pkg;
|
||||
acpi_handle root_handle;
|
||||
acpi_handle handle;
|
||||
struct acpi_buffer ewrd = {ACPI_ALLOCATE_BUFFER, NULL};
|
||||
acpi_status status;
|
||||
union acpi_object *wifi_pkg, *data;
|
||||
bool enabled;
|
||||
int i, n_profiles, ret;
|
||||
|
||||
root_handle = ACPI_HANDLE(mvm->dev);
|
||||
if (!root_handle) {
|
||||
IWL_DEBUG_RADIO(mvm,
|
||||
"Could not retrieve root port ACPI handle\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
data = iwl_acpi_get_object(mvm->dev, ACPI_EWRD_METHOD);
|
||||
if (IS_ERR(data))
|
||||
return PTR_ERR(data);
|
||||
|
||||
/* Get the method's handle */
|
||||
status = acpi_get_handle(root_handle, (acpi_string)ACPI_EWRD_METHOD,
|
||||
&handle);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
IWL_DEBUG_RADIO(mvm, "EWRD method not found\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Call EWRD with no arguments */
|
||||
status = acpi_evaluate_object(handle, NULL, NULL, &ewrd);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
IWL_DEBUG_RADIO(mvm, "EWRD invocation failed (0x%x)\n", status);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
wifi_pkg = iwl_mvm_sar_find_wifi_pkg(mvm, ewrd.pointer,
|
||||
ACPI_EWRD_WIFI_DATA_SIZE);
|
||||
wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data,
|
||||
ACPI_EWRD_WIFI_DATA_SIZE);
|
||||
if (IS_ERR(wifi_pkg)) {
|
||||
ret = PTR_ERR(wifi_pkg);
|
||||
goto out_free;
|
||||
@@ -788,55 +683,33 @@ static int iwl_mvm_sar_get_ewrd_table(struct iwl_mvm *mvm)
|
||||
break;
|
||||
|
||||
/* go to the next table */
|
||||
pos += IWL_MVM_SAR_TABLE_SIZE;
|
||||
pos += ACPI_SAR_TABLE_SIZE;
|
||||
}
|
||||
|
||||
out_free:
|
||||
kfree(ewrd.pointer);
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm)
|
||||
{
|
||||
union acpi_object *wifi_pkg;
|
||||
acpi_handle root_handle;
|
||||
acpi_handle handle;
|
||||
struct acpi_buffer wgds = {ACPI_ALLOCATE_BUFFER, NULL};
|
||||
acpi_status status;
|
||||
union acpi_object *wifi_pkg, *data;
|
||||
int i, j, ret;
|
||||
int idx = 1;
|
||||
|
||||
root_handle = ACPI_HANDLE(mvm->dev);
|
||||
if (!root_handle) {
|
||||
IWL_DEBUG_RADIO(mvm,
|
||||
"Could not retrieve root port ACPI handle\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
data = iwl_acpi_get_object(mvm->dev, ACPI_WGDS_METHOD);
|
||||
if (IS_ERR(data))
|
||||
return PTR_ERR(data);
|
||||
|
||||
/* Get the method's handle */
|
||||
status = acpi_get_handle(root_handle, (acpi_string)ACPI_WGDS_METHOD,
|
||||
&handle);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
IWL_DEBUG_RADIO(mvm, "WGDS method not found\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Call WGDS with no arguments */
|
||||
status = acpi_evaluate_object(handle, NULL, NULL, &wgds);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
IWL_DEBUG_RADIO(mvm, "WGDS invocation failed (0x%x)\n", status);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
wifi_pkg = iwl_mvm_sar_find_wifi_pkg(mvm, wgds.pointer,
|
||||
ACPI_WGDS_WIFI_DATA_SIZE);
|
||||
wifi_pkg = iwl_acpi_get_wifi_pkg(mvm->dev, data,
|
||||
ACPI_WGDS_WIFI_DATA_SIZE);
|
||||
if (IS_ERR(wifi_pkg)) {
|
||||
ret = PTR_ERR(wifi_pkg);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
for (i = 0; i < IWL_NUM_GEO_PROFILES; i++) {
|
||||
for (j = 0; j < IWL_MVM_GEO_TABLE_SIZE; j++) {
|
||||
for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) {
|
||||
for (j = 0; j < ACPI_GEO_TABLE_SIZE; j++) {
|
||||
union acpi_object *entry;
|
||||
|
||||
entry = &wifi_pkg->package.elements[idx++];
|
||||
@@ -851,7 +724,7 @@ static int iwl_mvm_sar_get_wgds_table(struct iwl_mvm *mvm)
|
||||
}
|
||||
ret = 0;
|
||||
out_free:
|
||||
kfree(wgds.pointer);
|
||||
kfree(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -861,25 +734,25 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
|
||||
.v3.set_mode = cpu_to_le32(IWL_TX_POWER_MODE_SET_CHAINS),
|
||||
};
|
||||
int i, j, idx;
|
||||
int profs[IWL_NUM_CHAIN_LIMITS] = { prof_a, prof_b };
|
||||
int profs[ACPI_SAR_NUM_CHAIN_LIMITS] = { prof_a, prof_b };
|
||||
int len = sizeof(cmd);
|
||||
|
||||
BUILD_BUG_ON(IWL_NUM_CHAIN_LIMITS < 2);
|
||||
BUILD_BUG_ON(IWL_NUM_CHAIN_LIMITS * IWL_NUM_SUB_BANDS !=
|
||||
IWL_MVM_SAR_TABLE_SIZE);
|
||||
BUILD_BUG_ON(ACPI_SAR_NUM_CHAIN_LIMITS < 2);
|
||||
BUILD_BUG_ON(ACPI_SAR_NUM_CHAIN_LIMITS * ACPI_SAR_NUM_SUB_BANDS !=
|
||||
ACPI_SAR_TABLE_SIZE);
|
||||
|
||||
if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_TX_POWER_ACK))
|
||||
len = sizeof(cmd.v3);
|
||||
|
||||
for (i = 0; i < IWL_NUM_CHAIN_LIMITS; i++) {
|
||||
for (i = 0; i < ACPI_SAR_NUM_CHAIN_LIMITS; i++) {
|
||||
struct iwl_mvm_sar_profile *prof;
|
||||
|
||||
/* don't allow SAR to be disabled (profile 0 means disable) */
|
||||
if (profs[i] == 0)
|
||||
return -EPERM;
|
||||
|
||||
/* we are off by one, so allow up to IWL_MVM_SAR_PROFILE_NUM */
|
||||
if (profs[i] > IWL_MVM_SAR_PROFILE_NUM)
|
||||
/* we are off by one, so allow up to ACPI_SAR_PROFILE_NUM */
|
||||
if (profs[i] > ACPI_SAR_PROFILE_NUM)
|
||||
return -EINVAL;
|
||||
|
||||
/* profiles go from 1 to 4, so decrement to access the array */
|
||||
@@ -894,8 +767,8 @@ int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b)
|
||||
}
|
||||
|
||||
IWL_DEBUG_RADIO(mvm, " Chain[%d]:\n", i);
|
||||
for (j = 0; j < IWL_NUM_SUB_BANDS; j++) {
|
||||
idx = (i * IWL_NUM_SUB_BANDS) + j;
|
||||
for (j = 0; j < ACPI_SAR_NUM_SUB_BANDS; j++) {
|
||||
idx = (i * ACPI_SAR_NUM_SUB_BANDS) + j;
|
||||
cmd.v3.per_chain_restriction[i][j] =
|
||||
cpu_to_le16(prof->table[idx]);
|
||||
IWL_DEBUG_RADIO(mvm, " Band[%d] = %d * .125dBm\n",
|
||||
@@ -931,7 +804,7 @@ int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm)
|
||||
|
||||
resp = (void *)cmd.resp_pkt->data;
|
||||
ret = le32_to_cpu(resp->profile_idx);
|
||||
if (WARN_ON(ret > IWL_NUM_GEO_PROFILES)) {
|
||||
if (WARN_ON(ret > ACPI_NUM_GEO_PROFILES)) {
|
||||
ret = -EIO;
|
||||
IWL_WARN(mvm, "Invalid geographic profile idx (%d)\n", ret);
|
||||
}
|
||||
@@ -959,10 +832,12 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
|
||||
|
||||
IWL_DEBUG_RADIO(mvm, "Sending GEO_TX_POWER_LIMIT\n");
|
||||
|
||||
BUILD_BUG_ON(IWL_NUM_GEO_PROFILES * ACPI_WGDS_NUM_BANDS *
|
||||
BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES * ACPI_WGDS_NUM_BANDS *
|
||||
ACPI_WGDS_TABLE_SIZE != ACPI_WGDS_WIFI_DATA_SIZE);
|
||||
|
||||
for (i = 0; i < IWL_NUM_GEO_PROFILES; i++) {
|
||||
BUILD_BUG_ON(ACPI_NUM_GEO_PROFILES > IWL_NUM_GEO_PROFILES);
|
||||
|
||||
for (i = 0; i < ACPI_NUM_GEO_PROFILES; i++) {
|
||||
struct iwl_per_chain_offset *chain =
|
||||
(struct iwl_per_chain_offset *)&cmd.table[i];
|
||||
|
||||
@@ -970,7 +845,7 @@ static int iwl_mvm_sar_geo_init(struct iwl_mvm *mvm)
|
||||
u8 *value;
|
||||
|
||||
value = &mvm->geo_profiles[i].values[j *
|
||||
IWL_GEO_PER_CHAIN_SIZE];
|
||||
ACPI_GEO_PER_CHAIN_SIZE];
|
||||
chain[j].max_tx_power = cpu_to_le16(value[0]);
|
||||
chain[j].chain_a = value[1];
|
||||
chain[j].chain_b = value[2];
|
||||
|
||||
@@ -1077,6 +1077,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
|
||||
mvm->vif_count = 0;
|
||||
mvm->rx_ba_sessions = 0;
|
||||
mvm->fwrt.dump.conf = FW_DBG_INVALID;
|
||||
mvm->monitor_on = false;
|
||||
|
||||
/* keep statistics ticking */
|
||||
iwl_mvm_accu_radio_stats(mvm);
|
||||
@@ -1437,6 +1438,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
|
||||
mvm->p2p_device_vif = vif;
|
||||
}
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_MONITOR)
|
||||
mvm->monitor_on = true;
|
||||
|
||||
iwl_mvm_vif_dbgfs_register(mvm, vif);
|
||||
goto out_unlock;
|
||||
|
||||
@@ -1526,6 +1530,9 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
|
||||
iwl_mvm_power_update_mac(mvm);
|
||||
iwl_mvm_mac_ctxt_remove(mvm, vif);
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_MONITOR)
|
||||
mvm->monitor_on = false;
|
||||
|
||||
out_release:
|
||||
mutex_unlock(&mvm->mutex);
|
||||
}
|
||||
@@ -1892,11 +1899,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
|
||||
if (changes & BSS_CHANGED_ASSOC && bss_conf->assoc)
|
||||
iwl_mvm_mac_ctxt_recalc_tsf_id(mvm, vif);
|
||||
|
||||
if (changes & BSS_CHANGED_ASSOC && !bss_conf->assoc &&
|
||||
mvmvif->lqm_active)
|
||||
iwl_mvm_send_lqm_cmd(vif, LQM_CMD_OPERATION_STOP_MEASUREMENT,
|
||||
0, 0);
|
||||
|
||||
/*
|
||||
* If we're not associated yet, take the (new) BSSID before associating
|
||||
* so the firmware knows. If we're already associated, then use the old
|
||||
@@ -3425,10 +3427,24 @@ static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
|
||||
return;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
/* we are only changing the min_width, may be a noop */
|
||||
if (changed == IEEE80211_CHANCTX_CHANGE_MIN_WIDTH) {
|
||||
if (phy_ctxt->width == ctx->min_def.width)
|
||||
goto out_unlock;
|
||||
|
||||
/* we are just toggling between 20_NOHT and 20 */
|
||||
if (phy_ctxt->width <= NL80211_CHAN_WIDTH_20 &&
|
||||
ctx->min_def.width <= NL80211_CHAN_WIDTH_20)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
iwl_mvm_bt_coex_vif_change(mvm);
|
||||
iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->min_def,
|
||||
ctx->rx_chains_static,
|
||||
ctx->rx_chains_dynamic);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&mvm->mutex);
|
||||
}
|
||||
|
||||
@@ -3893,11 +3909,6 @@ static int iwl_mvm_pre_channel_switch(struct ieee80211_hw *hw,
|
||||
|
||||
break;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
if (mvmvif->lqm_active)
|
||||
iwl_mvm_send_lqm_cmd(vif,
|
||||
LQM_CMD_OPERATION_STOP_MEASUREMENT,
|
||||
0, 0);
|
||||
|
||||
/* Schedule the time event to a bit before beacon 1,
|
||||
* to make sure we're in the new channel when the
|
||||
* GO/AP arrives. In case count <= 1 immediately schedule the
|
||||
@@ -4252,31 +4263,6 @@ static void iwl_mvm_event_bar_rx_callback(struct iwl_mvm *mvm,
|
||||
event->u.ba.ssn);
|
||||
}
|
||||
|
||||
static void
|
||||
iwl_mvm_event_frame_timeout_callback(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
const struct ieee80211_event *event)
|
||||
{
|
||||
struct iwl_fw_dbg_trigger_tlv *trig;
|
||||
struct iwl_fw_dbg_trigger_ba *ba_trig;
|
||||
|
||||
if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_BA))
|
||||
return;
|
||||
|
||||
trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_BA);
|
||||
ba_trig = (void *)trig->data;
|
||||
if (!iwl_fw_dbg_trigger_check_stop(&mvm->fwrt,
|
||||
ieee80211_vif_to_wdev(vif), trig))
|
||||
return;
|
||||
|
||||
if (!(le16_to_cpu(ba_trig->frame_timeout) & BIT(event->u.ba.tid)))
|
||||
return;
|
||||
|
||||
iwl_fw_dbg_collect_trig(&mvm->fwrt, trig,
|
||||
"Frame from %pM timed out, tid %d",
|
||||
event->u.ba.sta->addr, event->u.ba.tid);
|
||||
}
|
||||
|
||||
static void iwl_mvm_mac_event_callback(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
const struct ieee80211_event *event)
|
||||
@@ -4291,7 +4277,8 @@ static void iwl_mvm_mac_event_callback(struct ieee80211_hw *hw,
|
||||
iwl_mvm_event_bar_rx_callback(mvm, vif, event);
|
||||
break;
|
||||
case BA_FRAME_TIMEOUT:
|
||||
iwl_mvm_event_frame_timeout_callback(mvm, vif, event);
|
||||
iwl_mvm_event_frame_timeout_callback(mvm, vif, event->u.ba.sta,
|
||||
event->u.ba.tid);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
#include "tof.h"
|
||||
#include "fw/runtime.h"
|
||||
#include "fw/dbg.h"
|
||||
#include "fw/acpi.h"
|
||||
|
||||
#define IWL_MVM_MAX_ADDRESSES 5
|
||||
/* RSSI offset for WkP */
|
||||
@@ -147,6 +148,8 @@ struct iwl_mvm_phy_ctxt {
|
||||
u16 color;
|
||||
u32 ref;
|
||||
|
||||
enum nl80211_chan_width width;
|
||||
|
||||
/*
|
||||
* TODO: This should probably be removed. Currently here only for rate
|
||||
* scaling algorithm
|
||||
@@ -436,12 +439,6 @@ struct iwl_mvm_vif {
|
||||
|
||||
/* TCP Checksum Offload */
|
||||
netdev_features_t features;
|
||||
|
||||
/*
|
||||
* link quality measurement - used to check whether this interface
|
||||
* is in the middle of a link quality measurement
|
||||
*/
|
||||
bool lqm_active;
|
||||
};
|
||||
|
||||
static inline struct iwl_mvm_vif *
|
||||
@@ -592,6 +589,7 @@ enum iwl_mvm_tdls_cs_state {
|
||||
* @queue: queue of this reorder buffer
|
||||
* @last_amsdu: track last ASMDU SN for duplication detection
|
||||
* @last_sub_index: track ASMDU sub frame index for duplication detection
|
||||
* @tid: the tid
|
||||
* @entries: list of skbs stored
|
||||
* @reorder_time: time the packet was stored in the reorder buffer
|
||||
* @reorder_timer: timer for frames are in the reorder buffer. For AMSDU
|
||||
@@ -609,6 +607,7 @@ struct iwl_mvm_reorder_buffer {
|
||||
int queue;
|
||||
u16 last_amsdu;
|
||||
u8 last_sub_index;
|
||||
u8 tid;
|
||||
struct sk_buff_head entries[IEEE80211_MAX_AMPDU_BUF];
|
||||
unsigned long reorder_time[IEEE80211_MAX_AMPDU_BUF];
|
||||
struct timer_list reorder_timer;
|
||||
@@ -685,20 +684,14 @@ enum iwl_mvm_queue_status {
|
||||
|
||||
#define IWL_MVM_NUM_CIPHERS 10
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
#define IWL_MVM_SAR_TABLE_SIZE 10
|
||||
#define IWL_MVM_SAR_PROFILE_NUM 4
|
||||
#define IWL_MVM_GEO_TABLE_SIZE 6
|
||||
|
||||
struct iwl_mvm_sar_profile {
|
||||
bool enabled;
|
||||
u8 table[IWL_MVM_SAR_TABLE_SIZE];
|
||||
u8 table[ACPI_SAR_TABLE_SIZE];
|
||||
};
|
||||
|
||||
struct iwl_mvm_geo_profile {
|
||||
u8 values[IWL_MVM_GEO_TABLE_SIZE];
|
||||
u8 values[ACPI_GEO_TABLE_SIZE];
|
||||
};
|
||||
#endif
|
||||
|
||||
struct iwl_mvm {
|
||||
/* for logger access */
|
||||
@@ -1015,9 +1008,12 @@ struct iwl_mvm {
|
||||
bool drop_bcn_ap_mode;
|
||||
|
||||
struct delayed_work cs_tx_unblock_dwork;
|
||||
|
||||
/* does a monitor vif exist (only one can exist hence bool) */
|
||||
bool monitor_on;
|
||||
#ifdef CONFIG_ACPI
|
||||
struct iwl_mvm_sar_profile sar_profiles[IWL_MVM_SAR_PROFILE_NUM];
|
||||
struct iwl_mvm_geo_profile geo_profiles[IWL_NUM_GEO_PROFILES];
|
||||
struct iwl_mvm_sar_profile sar_profiles[ACPI_SAR_PROFILE_NUM];
|
||||
struct iwl_mvm_geo_profile geo_profiles[ACPI_NUM_GEO_PROFILES];
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1159,7 +1155,7 @@ static inline bool iwl_mvm_is_lar_supported(struct iwl_mvm *mvm)
|
||||
* Enable LAR only if it is supported by the FW (TLV) &&
|
||||
* enabled in the NVM
|
||||
*/
|
||||
if (mvm->cfg->ext_nvm)
|
||||
if (mvm->cfg->nvm_type == IWL_NVM_EXT)
|
||||
return nvm_lar && tlv_lar;
|
||||
else
|
||||
return tlv_lar;
|
||||
@@ -1248,6 +1244,12 @@ static inline bool iwl_mvm_has_new_ats_coex_api(struct iwl_mvm *mvm)
|
||||
IWL_UCODE_TLV_API_COEX_ATS_EXTERNAL);
|
||||
}
|
||||
|
||||
static inline bool iwl_mvm_has_quota_low_latency(struct iwl_mvm *mvm)
|
||||
{
|
||||
return fw_has_api(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_API_QUOTA_LOW_LATENCY);
|
||||
}
|
||||
|
||||
static inline struct agg_tx_status *
|
||||
iwl_mvm_get_agg_status(struct iwl_mvm *mvm, void *tx_resp)
|
||||
{
|
||||
@@ -1486,6 +1488,27 @@ int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||
int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
|
||||
|
||||
/* Quota management */
|
||||
static inline size_t iwl_mvm_quota_cmd_size(struct iwl_mvm *mvm)
|
||||
{
|
||||
return iwl_mvm_has_quota_low_latency(mvm) ?
|
||||
sizeof(struct iwl_time_quota_cmd) :
|
||||
sizeof(struct iwl_time_quota_cmd_v1);
|
||||
}
|
||||
|
||||
static inline struct iwl_time_quota_data
|
||||
*iwl_mvm_quota_cmd_get_quota(struct iwl_mvm *mvm,
|
||||
struct iwl_time_quota_cmd *cmd,
|
||||
int i)
|
||||
{
|
||||
struct iwl_time_quota_data_v1 *quotas;
|
||||
|
||||
if (iwl_mvm_has_quota_low_latency(mvm))
|
||||
return &cmd->quotas[i];
|
||||
|
||||
quotas = (struct iwl_time_quota_data_v1 *)cmd->quotas;
|
||||
return (struct iwl_time_quota_data *)"as[i];
|
||||
}
|
||||
|
||||
int iwl_mvm_update_quotas(struct iwl_mvm *mvm, bool force_upload,
|
||||
struct ieee80211_vif *disabled_vif);
|
||||
|
||||
@@ -1818,12 +1841,10 @@ unsigned int iwl_mvm_get_wd_timeout(struct iwl_mvm *mvm,
|
||||
bool tdls, bool cmd_q);
|
||||
void iwl_mvm_connection_loss(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
||||
const char *errmsg);
|
||||
|
||||
/* Link Quality Measurement */
|
||||
int iwl_mvm_send_lqm_cmd(struct ieee80211_vif *vif,
|
||||
enum iwl_lqm_cmd_operatrions operation,
|
||||
u32 duration, u32 timeout);
|
||||
bool iwl_mvm_lqm_active(struct iwl_mvm *mvm);
|
||||
void iwl_mvm_event_frame_timeout_callback(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
const struct ieee80211_sta *sta,
|
||||
u16 tid);
|
||||
|
||||
int iwl_mvm_sar_select_profile(struct iwl_mvm *mvm, int prof_a, int prof_b);
|
||||
int iwl_mvm_get_sar_geo_profile(struct iwl_mvm *mvm);
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
#include "iwl-eeprom-read.h"
|
||||
#include "iwl-nvm-parse.h"
|
||||
#include "iwl-prph.h"
|
||||
#include "fw/acpi.h"
|
||||
|
||||
/* Default NVM size to read */
|
||||
#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024)
|
||||
@@ -295,18 +296,24 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
|
||||
const __be16 *hw;
|
||||
const __le16 *sw, *calib, *regulatory, *mac_override, *phy_sku;
|
||||
bool lar_enabled;
|
||||
int regulatory_type;
|
||||
|
||||
/* Checking for required sections */
|
||||
if (!mvm->trans->cfg->ext_nvm) {
|
||||
if (mvm->trans->cfg->nvm_type != IWL_NVM_EXT) {
|
||||
if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
|
||||
!mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data) {
|
||||
IWL_ERR(mvm, "Can't parse empty OTP/NVM sections\n");
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (mvm->trans->cfg->nvm_type == IWL_NVM_SDP)
|
||||
regulatory_type = NVM_SECTION_TYPE_REGULATORY_SDP;
|
||||
else
|
||||
regulatory_type = NVM_SECTION_TYPE_REGULATORY;
|
||||
|
||||
/* SW and REGULATORY sections are mandatory */
|
||||
if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
|
||||
!mvm->nvm_sections[NVM_SECTION_TYPE_REGULATORY].data) {
|
||||
!mvm->nvm_sections[regulatory_type].data) {
|
||||
IWL_ERR(mvm,
|
||||
"Can't parse empty family 8000 OTP/NVM sections\n");
|
||||
return NULL;
|
||||
@@ -330,11 +337,14 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
|
||||
hw = (const __be16 *)sections[mvm->cfg->nvm_hw_section_num].data;
|
||||
sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
|
||||
calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data;
|
||||
regulatory = (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data;
|
||||
mac_override =
|
||||
(const __le16 *)sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data;
|
||||
phy_sku = (const __le16 *)sections[NVM_SECTION_TYPE_PHY_SKU].data;
|
||||
|
||||
regulatory = mvm->trans->cfg->nvm_type == IWL_NVM_SDP ?
|
||||
(const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY_SDP].data :
|
||||
(const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data;
|
||||
|
||||
lar_enabled = !iwlwifi_mod_params.lar_disable &&
|
||||
fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_LAR_SUPPORT);
|
||||
@@ -394,7 +404,7 @@ int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
|
||||
IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n");
|
||||
|
||||
/* Maximal size depends on NVM version */
|
||||
if (!mvm->trans->cfg->ext_nvm)
|
||||
if (mvm->trans->cfg->nvm_type != IWL_NVM_EXT)
|
||||
max_section_size = IWL_MAX_NVM_SECTION_SIZE;
|
||||
else
|
||||
max_section_size = IWL_MAX_EXT_NVM_SECTION_SIZE;
|
||||
@@ -465,7 +475,7 @@ int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!mvm->trans->cfg->ext_nvm) {
|
||||
if (mvm->trans->cfg->nvm_type != IWL_NVM_EXT) {
|
||||
section_size =
|
||||
2 * NVM_WORD1_LEN(le16_to_cpu(file_sec->word1));
|
||||
section_id = NVM_WORD2_ID(le16_to_cpu(file_sec->word2));
|
||||
@@ -740,7 +750,7 @@ int iwl_mvm_init_mcc(struct iwl_mvm *mvm)
|
||||
struct ieee80211_regdomain *regd;
|
||||
char mcc[3];
|
||||
|
||||
if (mvm->cfg->ext_nvm) {
|
||||
if (mvm->cfg->nvm_type == IWL_NVM_EXT) {
|
||||
tlv_lar = fw_has_capa(&mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_LAR_SUPPORT);
|
||||
nvm_lar = mvm->nvm_data->lar_enabled;
|
||||
@@ -775,7 +785,7 @@ int iwl_mvm_init_mcc(struct iwl_mvm *mvm)
|
||||
return -EIO;
|
||||
|
||||
if (iwl_mvm_is_wifi_mcc_supported(mvm) &&
|
||||
!iwl_get_bios_mcc(mvm->dev, mcc)) {
|
||||
!iwl_acpi_get_mcc(mvm->dev, mcc)) {
|
||||
kfree(regd);
|
||||
regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, mcc,
|
||||
MCC_SOURCE_BIOS, NULL);
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
#include "time-event.h"
|
||||
#include "fw-api.h"
|
||||
#include "fw/api/scan.h"
|
||||
#include "fw/acpi.h"
|
||||
|
||||
#define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux"
|
||||
MODULE_DESCRIPTION(DRV_DESCRIPTION);
|
||||
@@ -423,8 +424,6 @@ static const struct iwl_hcmd_names iwl_mvm_system_names[] = {
|
||||
* Access is done through binary search
|
||||
*/
|
||||
static const struct iwl_hcmd_names iwl_mvm_mac_conf_names[] = {
|
||||
HCMD_NAME(LINK_QUALITY_MEASUREMENT_CMD),
|
||||
HCMD_NAME(LINK_QUALITY_MEASUREMENT_COMPLETE_NOTIF),
|
||||
HCMD_NAME(CHANNEL_SWITCH_NOA_NOTIF),
|
||||
};
|
||||
|
||||
@@ -490,18 +489,21 @@ static const struct iwl_hcmd_arr iwl_mvm_groups[] = {
|
||||
static void iwl_mvm_async_handlers_wk(struct work_struct *wk);
|
||||
static void iwl_mvm_d0i3_exit_work(struct work_struct *wk);
|
||||
|
||||
static u32 calc_min_backoff(struct iwl_trans *trans, const struct iwl_cfg *cfg)
|
||||
static u32 iwl_mvm_min_backoff(struct iwl_mvm *mvm)
|
||||
{
|
||||
const struct iwl_pwr_tx_backoff *pwr_tx_backoff = cfg->pwr_tx_backoffs;
|
||||
const struct iwl_pwr_tx_backoff *backoff = mvm->cfg->pwr_tx_backoffs;
|
||||
u64 dflt_pwr_limit;
|
||||
|
||||
if (!pwr_tx_backoff)
|
||||
if (!backoff)
|
||||
return 0;
|
||||
|
||||
while (pwr_tx_backoff->pwr) {
|
||||
if (trans->dflt_pwr_limit >= pwr_tx_backoff->pwr)
|
||||
return pwr_tx_backoff->backoff;
|
||||
dflt_pwr_limit = iwl_acpi_get_pwr_limit(mvm->dev);
|
||||
|
||||
pwr_tx_backoff++;
|
||||
while (backoff->pwr) {
|
||||
if (dflt_pwr_limit >= backoff->pwr)
|
||||
return backoff->backoff;
|
||||
|
||||
backoff++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -771,7 +773,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
|
||||
goto out_free;
|
||||
mvm->hw_registered = true;
|
||||
|
||||
min_backoff = calc_min_backoff(trans, cfg);
|
||||
min_backoff = iwl_mvm_min_backoff(mvm);
|
||||
iwl_mvm_thermal_initialize(mvm, min_backoff);
|
||||
|
||||
err = iwl_mvm_dbgfs_register(mvm, dbgfs_dir);
|
||||
|
||||
@@ -272,6 +272,7 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
|
||||
}
|
||||
|
||||
ctxt->channel = chandef->chan;
|
||||
ctxt->width = chandef->width;
|
||||
return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
|
||||
chains_static, chains_dynamic,
|
||||
action, 0);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of version 2 of the GNU General Public License as
|
||||
@@ -34,7 +34,7 @@
|
||||
*
|
||||
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
|
||||
* Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2016 Intel Deutschland GmbH
|
||||
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -164,9 +164,12 @@ static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm,
|
||||
beacon_int = mvm->noa_vif->bss_conf.beacon_int;
|
||||
|
||||
for (i = 0; i < MAX_BINDINGS; i++) {
|
||||
u32 id_n_c = le32_to_cpu(cmd->quotas[i].id_and_color);
|
||||
struct iwl_time_quota_data *data =
|
||||
iwl_mvm_quota_cmd_get_quota(mvm, cmd,
|
||||
i);
|
||||
u32 id_n_c = le32_to_cpu(data->id_and_color);
|
||||
u32 id = (id_n_c & FW_CTXT_ID_MSK) >> FW_CTXT_ID_POS;
|
||||
u32 quota = le32_to_cpu(cmd->quotas[i].quota);
|
||||
u32 quota = le32_to_cpu(data->quota);
|
||||
|
||||
if (id != phy_id)
|
||||
continue;
|
||||
@@ -175,9 +178,9 @@ static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm,
|
||||
quota /= beacon_int;
|
||||
|
||||
IWL_DEBUG_QUOTA(mvm, "quota: adjust for NoA from %d to %d\n",
|
||||
le32_to_cpu(cmd->quotas[i].quota), quota);
|
||||
le32_to_cpu(data->quota), quota);
|
||||
|
||||
cmd->quotas[i].quota = cpu_to_le32(quota);
|
||||
data->quota = cpu_to_le32(quota);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -194,6 +197,7 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
|
||||
.disabled_vif = disabled_vif,
|
||||
};
|
||||
struct iwl_time_quota_cmd *last = &mvm->last_quota_cmd;
|
||||
struct iwl_time_quota_data *qdata, *last_data;
|
||||
bool send = false;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
@@ -216,7 +220,8 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
|
||||
*/
|
||||
num_active_macs = 0;
|
||||
for (i = 0; i < MAX_BINDINGS; i++) {
|
||||
cmd.quotas[i].id_and_color = cpu_to_le32(FW_CTXT_INVALID);
|
||||
qdata = iwl_mvm_quota_cmd_get_quota(mvm, &cmd, i);
|
||||
qdata->id_and_color = cpu_to_le32(FW_CTXT_INVALID);
|
||||
num_active_macs += data.n_interfaces[i];
|
||||
}
|
||||
|
||||
@@ -265,14 +270,16 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
|
||||
if (data.colors[i] < 0)
|
||||
continue;
|
||||
|
||||
cmd.quotas[idx].id_and_color =
|
||||
qdata = iwl_mvm_quota_cmd_get_quota(mvm, &cmd, idx);
|
||||
|
||||
qdata->id_and_color =
|
||||
cpu_to_le32(FW_CMD_ID_AND_COLOR(i, data.colors[i]));
|
||||
|
||||
if (data.n_interfaces[i] <= 0)
|
||||
cmd.quotas[idx].quota = cpu_to_le32(0);
|
||||
qdata->quota = cpu_to_le32(0);
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
else if (data.dbgfs_min[i])
|
||||
cmd.quotas[idx].quota =
|
||||
qdata->quota =
|
||||
cpu_to_le32(data.dbgfs_min[i] * QUOTA_100 / 100);
|
||||
#endif
|
||||
else if (data.n_low_latency_bindings == 1 && n_non_lowlat &&
|
||||
@@ -283,24 +290,25 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
|
||||
* the minimal required quota for the low latency
|
||||
* binding.
|
||||
*/
|
||||
cmd.quotas[idx].quota = cpu_to_le32(QUOTA_LOWLAT_MIN);
|
||||
qdata->quota = cpu_to_le32(QUOTA_LOWLAT_MIN);
|
||||
else
|
||||
cmd.quotas[idx].quota =
|
||||
qdata->quota =
|
||||
cpu_to_le32(quota * data.n_interfaces[i]);
|
||||
|
||||
WARN_ONCE(le32_to_cpu(cmd.quotas[idx].quota) > QUOTA_100,
|
||||
WARN_ONCE(le32_to_cpu(qdata->quota) > QUOTA_100,
|
||||
"Binding=%d, quota=%u > max=%u\n",
|
||||
idx, le32_to_cpu(cmd.quotas[idx].quota), QUOTA_100);
|
||||
idx, le32_to_cpu(qdata->quota), QUOTA_100);
|
||||
|
||||
cmd.quotas[idx].max_duration = cpu_to_le32(0);
|
||||
qdata->max_duration = cpu_to_le32(0);
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
/* Give the remainder of the session to the first data binding */
|
||||
for (i = 0; i < MAX_BINDINGS; i++) {
|
||||
if (le32_to_cpu(cmd.quotas[i].quota) != 0) {
|
||||
le32_add_cpu(&cmd.quotas[i].quota, quota_rem);
|
||||
qdata = iwl_mvm_quota_cmd_get_quota(mvm, &cmd, i);
|
||||
if (le32_to_cpu(qdata->quota) != 0) {
|
||||
le32_add_cpu(&qdata->quota, quota_rem);
|
||||
IWL_DEBUG_QUOTA(mvm,
|
||||
"quota: giving remainder of %d to binding %d\n",
|
||||
quota_rem, i);
|
||||
@@ -312,17 +320,19 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
|
||||
|
||||
/* check that we have non-zero quota for all valid bindings */
|
||||
for (i = 0; i < MAX_BINDINGS; i++) {
|
||||
if (cmd.quotas[i].id_and_color != last->quotas[i].id_and_color)
|
||||
qdata = iwl_mvm_quota_cmd_get_quota(mvm, &cmd, i);
|
||||
last_data = iwl_mvm_quota_cmd_get_quota(mvm, last, i);
|
||||
if (qdata->id_and_color != last_data->id_and_color)
|
||||
send = true;
|
||||
if (cmd.quotas[i].max_duration != last->quotas[i].max_duration)
|
||||
if (qdata->max_duration != last_data->max_duration)
|
||||
send = true;
|
||||
if (abs((int)le32_to_cpu(cmd.quotas[i].quota) -
|
||||
(int)le32_to_cpu(last->quotas[i].quota))
|
||||
if (abs((int)le32_to_cpu(qdata->quota) -
|
||||
(int)le32_to_cpu(last_data->quota))
|
||||
> IWL_MVM_QUOTA_THRESHOLD)
|
||||
send = true;
|
||||
if (cmd.quotas[i].id_and_color == cpu_to_le32(FW_CTXT_INVALID))
|
||||
if (qdata->id_and_color == cpu_to_le32(FW_CTXT_INVALID))
|
||||
continue;
|
||||
WARN_ONCE(cmd.quotas[i].quota == 0,
|
||||
WARN_ONCE(qdata->quota == 0,
|
||||
"zero quota on binding %d\n", i);
|
||||
}
|
||||
|
||||
@@ -334,7 +344,8 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0, sizeof(cmd), &cmd);
|
||||
err = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0,
|
||||
iwl_mvm_quota_cmd_size(mvm), &cmd);
|
||||
|
||||
if (err)
|
||||
IWL_ERR(mvm, "Failed to send quota: %d\n", err);
|
||||
|
||||
@@ -244,7 +244,9 @@ static u32 iwl_mvm_set_mac80211_rx_flag(struct iwl_mvm *mvm,
|
||||
return 0;
|
||||
|
||||
default:
|
||||
IWL_ERR(mvm, "Unhandled alg: 0x%x\n", rx_pkt_status);
|
||||
/* Expected in monitor (not having the keys) */
|
||||
if (!mvm->monitor_on)
|
||||
IWL_ERR(mvm, "Unhandled alg: 0x%x\n", rx_pkt_status);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -661,11 +663,10 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm,
|
||||
expected_size = sizeof(struct iwl_notif_statistics_cdb);
|
||||
}
|
||||
|
||||
if (iwl_rx_packet_payload_len(pkt) != expected_size) {
|
||||
IWL_ERR(mvm, "received invalid statistics size (%d)!\n",
|
||||
iwl_rx_packet_payload_len(pkt));
|
||||
if (WARN_ONCE(iwl_rx_packet_payload_len(pkt) != expected_size,
|
||||
"received invalid statistics size (%d)!\n",
|
||||
iwl_rx_packet_payload_len(pkt)))
|
||||
return;
|
||||
}
|
||||
|
||||
if (!iwl_mvm_has_new_rx_stats_api(mvm)) {
|
||||
struct iwl_notif_statistics_v11 *stats = (void *)&pkt->data;
|
||||
|
||||
@@ -277,7 +277,9 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_hdr *hdr,
|
||||
stats->flag |= RX_FLAG_DECRYPTED;
|
||||
return 0;
|
||||
default:
|
||||
IWL_ERR(mvm, "Unhandled alg: 0x%x\n", status);
|
||||
/* Expected in monitor (not having the keys) */
|
||||
if (!mvm->monitor_on)
|
||||
IWL_ERR(mvm, "Unhandled alg: 0x%x\n", status);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -492,13 +494,18 @@ void iwl_mvm_reorder_timer_expired(unsigned long data)
|
||||
|
||||
if (expired) {
|
||||
struct ieee80211_sta *sta;
|
||||
struct iwl_mvm_sta *mvmsta;
|
||||
|
||||
rcu_read_lock();
|
||||
sta = rcu_dereference(buf->mvm->fw_id_to_mac_id[buf->sta_id]);
|
||||
mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||
|
||||
/* SN is set to the last expired frame + 1 */
|
||||
IWL_DEBUG_HT(buf->mvm,
|
||||
"Releasing expired frames for sta %u, sn %d\n",
|
||||
buf->sta_id, sn);
|
||||
iwl_mvm_event_frame_timeout_callback(buf->mvm, mvmsta->vif,
|
||||
sta, buf->tid);
|
||||
iwl_mvm_release_frames(buf->mvm, sta, NULL, buf, sn);
|
||||
rcu_read_unlock();
|
||||
} else {
|
||||
@@ -619,7 +626,8 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
|
||||
return false;
|
||||
|
||||
/* no sta yet */
|
||||
if (WARN_ON(IS_ERR_OR_NULL(sta)))
|
||||
if (WARN_ONCE(IS_ERR_OR_NULL(sta),
|
||||
"Got valid BAID without a valid station assigned\n"))
|
||||
return false;
|
||||
|
||||
mvm_sta = iwl_mvm_sta_from_mac80211(sta);
|
||||
|
||||
@@ -2158,6 +2158,7 @@ static void iwl_mvm_init_reorder_buffer(struct iwl_mvm *mvm,
|
||||
reorder_buf->mvm = mvm;
|
||||
reorder_buf->queue = i;
|
||||
reorder_buf->sta_id = sta_id;
|
||||
reorder_buf->tid = data->tid;
|
||||
reorder_buf->valid = false;
|
||||
for (j = 0; j < reorder_buf->buf_size; j++)
|
||||
__skb_queue_head_init(&reorder_buf->entries[j]);
|
||||
|
||||
@@ -631,7 +631,7 @@ static int iwl_mvm_tzone_get_temp(struct thermal_zone_device *device,
|
||||
|
||||
if (!iwl_mvm_firmware_running(mvm) ||
|
||||
mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) {
|
||||
ret = -EIO;
|
||||
ret = -ENODATA;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
@@ -1368,6 +1368,31 @@ void iwl_mvm_inactivity_check(struct iwl_mvm *mvm)
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
void iwl_mvm_event_frame_timeout_callback(struct iwl_mvm *mvm,
|
||||
struct ieee80211_vif *vif,
|
||||
const struct ieee80211_sta *sta,
|
||||
u16 tid)
|
||||
{
|
||||
struct iwl_fw_dbg_trigger_tlv *trig;
|
||||
struct iwl_fw_dbg_trigger_ba *ba_trig;
|
||||
|
||||
if (!iwl_fw_dbg_trigger_enabled(mvm->fw, FW_DBG_TRIGGER_BA))
|
||||
return;
|
||||
|
||||
trig = iwl_fw_dbg_get_trigger(mvm->fw, FW_DBG_TRIGGER_BA);
|
||||
ba_trig = (void *)trig->data;
|
||||
if (!iwl_fw_dbg_trigger_check_stop(&mvm->fwrt,
|
||||
ieee80211_vif_to_wdev(vif), trig))
|
||||
return;
|
||||
|
||||
if (!(le16_to_cpu(ba_trig->frame_timeout) & BIT(tid)))
|
||||
return;
|
||||
|
||||
iwl_fw_dbg_collect_trig(&mvm->fwrt, trig,
|
||||
"Frame from %pM timed out, tid %d",
|
||||
sta->addr, tid);
|
||||
}
|
||||
|
||||
void iwl_mvm_get_sync_time(struct iwl_mvm *mvm, u32 *gp2, u64 *boottime)
|
||||
{
|
||||
bool ps_disabled;
|
||||
@@ -1389,74 +1414,3 @@ void iwl_mvm_get_sync_time(struct iwl_mvm *mvm, u32 *gp2, u64 *boottime)
|
||||
iwl_mvm_power_update_device(mvm);
|
||||
}
|
||||
}
|
||||
|
||||
int iwl_mvm_send_lqm_cmd(struct ieee80211_vif *vif,
|
||||
enum iwl_lqm_cmd_operatrions operation,
|
||||
u32 duration, u32 timeout)
|
||||
{
|
||||
struct iwl_mvm_vif *mvm_vif = iwl_mvm_vif_from_mac80211(vif);
|
||||
struct iwl_link_qual_msrmnt_cmd cmd = {
|
||||
.cmd_operation = cpu_to_le32(operation),
|
||||
.mac_id = cpu_to_le32(mvm_vif->id),
|
||||
.measurement_time = cpu_to_le32(duration),
|
||||
.timeout = cpu_to_le32(timeout),
|
||||
};
|
||||
u32 cmdid =
|
||||
iwl_cmd_id(LINK_QUALITY_MEASUREMENT_CMD, MAC_CONF_GROUP, 0);
|
||||
int ret;
|
||||
|
||||
if (!fw_has_capa(&mvm_vif->mvm->fw->ucode_capa,
|
||||
IWL_UCODE_TLV_CAPA_LQM_SUPPORT))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
|
||||
return -EINVAL;
|
||||
|
||||
switch (operation) {
|
||||
case LQM_CMD_OPERATION_START_MEASUREMENT:
|
||||
if (iwl_mvm_lqm_active(mvm_vif->mvm))
|
||||
return -EBUSY;
|
||||
if (!vif->bss_conf.assoc)
|
||||
return -EINVAL;
|
||||
mvm_vif->lqm_active = true;
|
||||
break;
|
||||
case LQM_CMD_OPERATION_STOP_MEASUREMENT:
|
||||
if (!iwl_mvm_lqm_active(mvm_vif->mvm))
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = iwl_mvm_send_cmd_pdu(mvm_vif->mvm, cmdid, 0, sizeof(cmd),
|
||||
&cmd);
|
||||
|
||||
/* command failed - roll back lqm_active state */
|
||||
if (ret) {
|
||||
mvm_vif->lqm_active =
|
||||
operation == LQM_CMD_OPERATION_STOP_MEASUREMENT;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void iwl_mvm_lqm_active_iterator(void *_data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct iwl_mvm_vif *mvm_vif = iwl_mvm_vif_from_mac80211(vif);
|
||||
bool *lqm_active = _data;
|
||||
|
||||
*lqm_active = *lqm_active || mvm_vif->lqm_active;
|
||||
}
|
||||
|
||||
bool iwl_mvm_lqm_active(struct iwl_mvm *mvm)
|
||||
{
|
||||
bool ret = false;
|
||||
|
||||
lockdep_assert_held(&mvm->mutex);
|
||||
ieee80211_iterate_active_interfaces_atomic(
|
||||
mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
|
||||
iwl_mvm_lqm_active_iterator, &ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -244,7 +244,7 @@ int iwl_pcie_ctxt_info_init(struct iwl_trans *trans,
|
||||
ctxt_info->hcmd_cfg.cmd_queue_addr =
|
||||
cpu_to_le64(trans_pcie->txq[trans_pcie->cmd_queue]->dma_addr);
|
||||
ctxt_info->hcmd_cfg.cmd_queue_size =
|
||||
TFD_QUEUE_CB_SIZE(TFD_CMD_SLOTS);
|
||||
TFD_QUEUE_CB_SIZE(trans_pcie->tx_cmd_queue_size);
|
||||
|
||||
/* allocate ucode sections in dram and set addresses */
|
||||
ret = iwl_pcie_ctxt_info_init_fw_sec(trans, fw, ctxt_info);
|
||||
|
||||
@@ -73,6 +73,8 @@
|
||||
#include <linux/pci-aspm.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
#include "fw/acpi.h"
|
||||
|
||||
#include "iwl-trans.h"
|
||||
#include "iwl-drv.h"
|
||||
#include "internal.h"
|
||||
@@ -576,7 +578,8 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
|
||||
{IWL_PCI_DEVICE(0x2720, 0x0000, iwla000_2ax_cfg_hr)},
|
||||
{IWL_PCI_DEVICE(0x34F0, 0x0070, iwla000_2ax_cfg_hr)},
|
||||
{IWL_PCI_DEVICE(0x2720, 0x0078, iwla000_2ax_cfg_hr)},
|
||||
{IWL_PCI_DEVICE(0x2720, 0x0070, iwla000_2ax_cfg_hr)},
|
||||
{IWL_PCI_DEVICE(0x2720, 0x0070, iwla000_2ac_cfg_hr_cdb)},
|
||||
{IWL_PCI_DEVICE(0x2720, 0x0030, iwla000_2ac_cfg_hr_cdb)},
|
||||
{IWL_PCI_DEVICE(0x2720, 0x1080, iwla000_2ax_cfg_hr)},
|
||||
#endif /* CONFIG_IWLMVM */
|
||||
|
||||
@@ -584,99 +587,6 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
#define ACPI_SPLC_METHOD "SPLC"
|
||||
#define ACPI_SPLC_DOMAIN_WIFI (0x07)
|
||||
|
||||
static u64 splc_get_pwr_limit(struct iwl_trans *trans, union acpi_object *splc)
|
||||
{
|
||||
union acpi_object *data_pkg, *dflt_pwr_limit;
|
||||
int i;
|
||||
|
||||
/* We need at least two elements, one for the revision and one
|
||||
* for the data itself. Also check that the revision is
|
||||
* supported (currently only revision 0).
|
||||
*/
|
||||
if (splc->type != ACPI_TYPE_PACKAGE ||
|
||||
splc->package.count < 2 ||
|
||||
splc->package.elements[0].type != ACPI_TYPE_INTEGER ||
|
||||
splc->package.elements[0].integer.value != 0) {
|
||||
IWL_DEBUG_INFO(trans,
|
||||
"Unsupported structure returned by the SPLC method. Ignoring.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* loop through all the packages to find the one for WiFi */
|
||||
for (i = 1; i < splc->package.count; i++) {
|
||||
union acpi_object *domain;
|
||||
|
||||
data_pkg = &splc->package.elements[i];
|
||||
|
||||
/* Skip anything that is not a package with the right
|
||||
* amount of elements (i.e. at least 2 integers).
|
||||
*/
|
||||
if (data_pkg->type != ACPI_TYPE_PACKAGE ||
|
||||
data_pkg->package.count < 2 ||
|
||||
data_pkg->package.elements[0].type != ACPI_TYPE_INTEGER ||
|
||||
data_pkg->package.elements[1].type != ACPI_TYPE_INTEGER)
|
||||
continue;
|
||||
|
||||
domain = &data_pkg->package.elements[0];
|
||||
if (domain->integer.value == ACPI_SPLC_DOMAIN_WIFI)
|
||||
break;
|
||||
|
||||
data_pkg = NULL;
|
||||
}
|
||||
|
||||
if (!data_pkg) {
|
||||
IWL_DEBUG_INFO(trans,
|
||||
"No element for the WiFi domain returned by the SPLC method.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
dflt_pwr_limit = &data_pkg->package.elements[1];
|
||||
return dflt_pwr_limit->integer.value;
|
||||
}
|
||||
|
||||
static void set_dflt_pwr_limit(struct iwl_trans *trans, struct pci_dev *pdev)
|
||||
{
|
||||
acpi_handle pxsx_handle;
|
||||
acpi_handle handle;
|
||||
struct acpi_buffer splc = {ACPI_ALLOCATE_BUFFER, NULL};
|
||||
acpi_status status;
|
||||
|
||||
pxsx_handle = ACPI_HANDLE(&pdev->dev);
|
||||
if (!pxsx_handle) {
|
||||
IWL_DEBUG_INFO(trans,
|
||||
"Could not retrieve root port ACPI handle\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the method's handle */
|
||||
status = acpi_get_handle(pxsx_handle, (acpi_string)ACPI_SPLC_METHOD,
|
||||
&handle);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
IWL_DEBUG_INFO(trans, "SPLC method not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Call SPLC with no arguments */
|
||||
status = acpi_evaluate_object(handle, NULL, NULL, &splc);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
IWL_ERR(trans, "SPLC invocation failed (0x%x)\n", status);
|
||||
return;
|
||||
}
|
||||
|
||||
trans->dflt_pwr_limit = splc_get_pwr_limit(trans, splc.pointer);
|
||||
IWL_DEBUG_INFO(trans, "Default power limit set to %lld\n",
|
||||
trans->dflt_pwr_limit);
|
||||
kfree(splc.pointer);
|
||||
}
|
||||
|
||||
#else /* CONFIG_ACPI */
|
||||
static void set_dflt_pwr_limit(struct iwl_trans *trans, struct pci_dev *pdev) {}
|
||||
#endif
|
||||
|
||||
/* PCI registers */
|
||||
#define PCI_CFG_RETRY_TIMEOUT 0x041
|
||||
|
||||
@@ -740,8 +650,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
goto out_free_trans;
|
||||
}
|
||||
|
||||
set_dflt_pwr_limit(iwl_trans, pdev);
|
||||
|
||||
/* register transport layer debugfs here */
|
||||
ret = iwl_trans_pcie_dbgfs_register(iwl_trans);
|
||||
if (ret)
|
||||
|
||||
@@ -383,6 +383,7 @@ struct iwl_self_init_dram {
|
||||
* @hw_init_mask: initial unmasked hw causes
|
||||
* @fh_mask: current unmasked fh causes
|
||||
* @hw_mask: current unmasked hw causes
|
||||
* @tx_cmd_queue_size: the size of the tx command queue
|
||||
*/
|
||||
struct iwl_trans_pcie {
|
||||
struct iwl_rxq *rxq;
|
||||
@@ -442,6 +443,7 @@ struct iwl_trans_pcie {
|
||||
bool bc_table_dword;
|
||||
bool scd_set_active;
|
||||
bool sw_csum_tx;
|
||||
bool pcie_dbg_dumped_once;
|
||||
u32 rx_page_order;
|
||||
|
||||
/*protect hw register */
|
||||
@@ -463,6 +465,7 @@ struct iwl_trans_pcie {
|
||||
u32 fh_mask;
|
||||
u32 hw_mask;
|
||||
cpumask_t affinity_mask[IWL_MAX_RX_HW_QUEUES];
|
||||
u16 tx_cmd_queue_size;
|
||||
};
|
||||
|
||||
static inline struct iwl_trans_pcie *
|
||||
@@ -534,6 +537,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
|
||||
void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
|
||||
struct sk_buff_head *skbs);
|
||||
void iwl_trans_pcie_tx_reset(struct iwl_trans *trans);
|
||||
void iwl_pcie_set_tx_cmd_queue_size(struct iwl_trans *trans);
|
||||
|
||||
static inline u16 iwl_pcie_tfd_tb_get_len(struct iwl_trans *trans, void *_tfd,
|
||||
u8 idx)
|
||||
|
||||
@@ -88,6 +88,93 @@
|
||||
#define IWL_FW_MEM_EXTENDED_START 0x40000
|
||||
#define IWL_FW_MEM_EXTENDED_END 0x57FFF
|
||||
|
||||
static void iwl_trans_pcie_err_dump(struct iwl_trans *trans)
|
||||
{
|
||||
#define PCI_DUMP_SIZE 64
|
||||
#define PREFIX_LEN 32
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
struct pci_dev *pdev = trans_pcie->pci_dev;
|
||||
u32 i, pos, alloc_size, *ptr, *buf;
|
||||
char *prefix;
|
||||
|
||||
if (trans_pcie->pcie_dbg_dumped_once)
|
||||
return;
|
||||
|
||||
/* Should be a multiple of 4 */
|
||||
BUILD_BUG_ON(PCI_DUMP_SIZE > 4096 || PCI_DUMP_SIZE & 0x3);
|
||||
/* Alloc a max size buffer */
|
||||
if (PCI_ERR_ROOT_ERR_SRC + 4 > PCI_DUMP_SIZE)
|
||||
alloc_size = PCI_ERR_ROOT_ERR_SRC + 4 + PREFIX_LEN;
|
||||
else
|
||||
alloc_size = PCI_DUMP_SIZE + PREFIX_LEN;
|
||||
buf = kmalloc(alloc_size, GFP_ATOMIC);
|
||||
if (!buf)
|
||||
return;
|
||||
prefix = (char *)buf + alloc_size - PREFIX_LEN;
|
||||
|
||||
IWL_ERR(trans, "iwlwifi transaction failed, dumping registers\n");
|
||||
|
||||
/* Print wifi device registers */
|
||||
sprintf(prefix, "iwlwifi %s: ", pci_name(pdev));
|
||||
IWL_ERR(trans, "iwlwifi device config registers:\n");
|
||||
for (i = 0, ptr = buf; i < PCI_DUMP_SIZE; i += 4, ptr++)
|
||||
if (pci_read_config_dword(pdev, i, ptr))
|
||||
goto err_read;
|
||||
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0);
|
||||
|
||||
IWL_ERR(trans, "iwlwifi device memory mapped registers:\n");
|
||||
for (i = 0, ptr = buf; i < PCI_DUMP_SIZE; i += 4, ptr++)
|
||||
*ptr = iwl_read32(trans, i);
|
||||
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0);
|
||||
|
||||
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
|
||||
if (pos) {
|
||||
IWL_ERR(trans, "iwlwifi device AER capability structure:\n");
|
||||
for (i = 0, ptr = buf; i < PCI_ERR_ROOT_COMMAND; i += 4, ptr++)
|
||||
if (pci_read_config_dword(pdev, pos + i, ptr))
|
||||
goto err_read;
|
||||
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET,
|
||||
32, 4, buf, i, 0);
|
||||
}
|
||||
|
||||
/* Print parent device registers next */
|
||||
if (!pdev->bus->self)
|
||||
goto out;
|
||||
|
||||
pdev = pdev->bus->self;
|
||||
sprintf(prefix, "iwlwifi %s: ", pci_name(pdev));
|
||||
|
||||
IWL_ERR(trans, "iwlwifi parent port (%s) config registers:\n",
|
||||
pci_name(pdev));
|
||||
for (i = 0, ptr = buf; i < PCI_DUMP_SIZE; i += 4, ptr++)
|
||||
if (pci_read_config_dword(pdev, i, ptr))
|
||||
goto err_read;
|
||||
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0);
|
||||
|
||||
/* Print root port AER registers */
|
||||
pos = 0;
|
||||
pdev = pcie_find_root_port(pdev);
|
||||
if (pdev)
|
||||
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR);
|
||||
if (pos) {
|
||||
IWL_ERR(trans, "iwlwifi root port (%s) AER cap structure:\n",
|
||||
pci_name(pdev));
|
||||
sprintf(prefix, "iwlwifi %s: ", pci_name(pdev));
|
||||
for (i = 0, ptr = buf; i <= PCI_ERR_ROOT_ERR_SRC; i += 4, ptr++)
|
||||
if (pci_read_config_dword(pdev, pos + i, ptr))
|
||||
goto err_read;
|
||||
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32,
|
||||
4, buf, i, 0);
|
||||
}
|
||||
|
||||
err_read:
|
||||
print_hex_dump(KERN_ERR, prefix, DUMP_PREFIX_OFFSET, 32, 4, buf, i, 0);
|
||||
IWL_ERR(trans, "Read failed at 0x%X\n", i);
|
||||
out:
|
||||
trans_pcie->pcie_dbg_dumped_once = 1;
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
static void iwl_pcie_free_fw_monitor(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
@@ -649,6 +736,7 @@ static int iwl_pcie_load_firmware_chunk(struct iwl_trans *trans,
|
||||
trans_pcie->ucode_write_complete, 5 * HZ);
|
||||
if (!ret) {
|
||||
IWL_ERR(trans, "Failed to load firmware chunk!\n");
|
||||
iwl_trans_pcie_err_dump(trans);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
@@ -1868,6 +1956,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans,
|
||||
(CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
|
||||
CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
|
||||
if (unlikely(ret < 0)) {
|
||||
iwl_trans_pcie_err_dump(trans);
|
||||
iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
|
||||
WARN_ONCE(1,
|
||||
"Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n",
|
||||
|
||||
@@ -1160,6 +1160,8 @@ int iwl_pcie_gen2_tx_init(struct iwl_trans *trans)
|
||||
struct iwl_txq *cmd_queue;
|
||||
int txq_id = trans_pcie->cmd_queue, ret;
|
||||
|
||||
iwl_pcie_set_tx_cmd_queue_size(trans);
|
||||
|
||||
/* alloc and init the command queue */
|
||||
if (!trans_pcie->txq[txq_id]) {
|
||||
cmd_queue = kzalloc(sizeof(*cmd_queue), GFP_KERNEL);
|
||||
@@ -1168,7 +1170,8 @@ int iwl_pcie_gen2_tx_init(struct iwl_trans *trans)
|
||||
return -ENOMEM;
|
||||
}
|
||||
trans_pcie->txq[txq_id] = cmd_queue;
|
||||
ret = iwl_pcie_txq_alloc(trans, cmd_queue, TFD_CMD_SLOTS, true);
|
||||
ret = iwl_pcie_txq_alloc(trans, cmd_queue,
|
||||
trans_pcie->tx_cmd_queue_size, true);
|
||||
if (ret) {
|
||||
IWL_ERR(trans, "Tx %d queue init failed\n", txq_id);
|
||||
goto error;
|
||||
@@ -1177,7 +1180,8 @@ int iwl_pcie_gen2_tx_init(struct iwl_trans *trans)
|
||||
cmd_queue = trans_pcie->txq[txq_id];
|
||||
}
|
||||
|
||||
ret = iwl_pcie_txq_init(trans, cmd_queue, TFD_CMD_SLOTS, true);
|
||||
ret = iwl_pcie_txq_init(trans, cmd_queue,
|
||||
trans_pcie->tx_cmd_queue_size, true);
|
||||
if (ret) {
|
||||
IWL_ERR(trans, "Tx %d queue alloc failed\n", txq_id);
|
||||
goto error;
|
||||
|
||||
@@ -951,7 +951,8 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans)
|
||||
txq_id++) {
|
||||
bool cmd_queue = (txq_id == trans_pcie->cmd_queue);
|
||||
|
||||
slots_num = cmd_queue ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
|
||||
slots_num = cmd_queue ? trans_pcie->tx_cmd_queue_size :
|
||||
TFD_TX_CMD_SLOTS;
|
||||
trans_pcie->txq[txq_id] = &trans_pcie->txq_memory[txq_id];
|
||||
ret = iwl_pcie_txq_alloc(trans, trans_pcie->txq[txq_id],
|
||||
slots_num, cmd_queue);
|
||||
@@ -970,6 +971,21 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void iwl_pcie_set_tx_cmd_queue_size(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
int queue_size = TFD_CMD_SLOTS;
|
||||
|
||||
if (trans->cfg->tx_cmd_queue_size)
|
||||
queue_size = trans->cfg->tx_cmd_queue_size;
|
||||
|
||||
if (WARN_ON(!(is_power_of_2(queue_size) &&
|
||||
TFD_QUEUE_CB_SIZE(queue_size) > 0)))
|
||||
trans_pcie->tx_cmd_queue_size = TFD_CMD_SLOTS;
|
||||
else
|
||||
trans_pcie->tx_cmd_queue_size = queue_size;
|
||||
}
|
||||
|
||||
int iwl_pcie_tx_init(struct iwl_trans *trans)
|
||||
{
|
||||
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
|
||||
@@ -977,6 +993,8 @@ int iwl_pcie_tx_init(struct iwl_trans *trans)
|
||||
int txq_id, slots_num;
|
||||
bool alloc = false;
|
||||
|
||||
iwl_pcie_set_tx_cmd_queue_size(trans);
|
||||
|
||||
if (!trans_pcie->txq_memory) {
|
||||
ret = iwl_pcie_tx_alloc(trans);
|
||||
if (ret)
|
||||
@@ -1000,7 +1018,8 @@ int iwl_pcie_tx_init(struct iwl_trans *trans)
|
||||
txq_id++) {
|
||||
bool cmd_queue = (txq_id == trans_pcie->cmd_queue);
|
||||
|
||||
slots_num = cmd_queue ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
|
||||
slots_num = cmd_queue ? trans_pcie->tx_cmd_queue_size :
|
||||
TFD_TX_CMD_SLOTS;
|
||||
ret = iwl_pcie_txq_init(trans, trans_pcie->txq[txq_id],
|
||||
slots_num, cmd_queue);
|
||||
if (ret) {
|
||||
|
||||
@@ -852,12 +852,11 @@ void p54_unregister_common(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct p54_common *priv = dev->priv;
|
||||
|
||||
#ifdef CONFIG_P54_LEDS
|
||||
p54_unregister_leds(priv);
|
||||
#endif /* CONFIG_P54_LEDS */
|
||||
|
||||
if (priv->registered) {
|
||||
priv->registered = false;
|
||||
#ifdef CONFIG_P54_LEDS
|
||||
p54_unregister_leds(priv);
|
||||
#endif /* CONFIG_P54_LEDS */
|
||||
ieee80211_unregister_hw(dev);
|
||||
}
|
||||
|
||||
|
||||
@@ -658,12 +658,6 @@ void mwifiex_11n_delba(struct mwifiex_private *priv, int tid)
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
|
||||
if (list_empty(&priv->rx_reorder_tbl_ptr)) {
|
||||
dev_dbg(priv->adapter->dev,
|
||||
"mwifiex_11n_delba: rx_reorder_tbl_ptr empty\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
list_for_each_entry(rx_reor_tbl_ptr, &priv->rx_reorder_tbl_ptr, list) {
|
||||
if (rx_reor_tbl_ptr->tid == tid) {
|
||||
dev_dbg(priv->adapter->dev,
|
||||
@@ -854,9 +848,6 @@ mwifiex_send_delba_txbastream_tbl(struct mwifiex_private *priv, u8 tid)
|
||||
struct mwifiex_adapter *adapter = priv->adapter;
|
||||
struct mwifiex_tx_ba_stream_tbl *tx_ba_stream_tbl_ptr;
|
||||
|
||||
if (list_empty(&priv->tx_ba_stream_tbl_ptr))
|
||||
return;
|
||||
|
||||
list_for_each_entry(tx_ba_stream_tbl_ptr,
|
||||
&priv->tx_ba_stream_tbl_ptr, list) {
|
||||
if (tx_ba_stream_tbl_ptr->ba_status == BA_SETUP_COMPLETE) {
|
||||
|
||||
@@ -835,12 +835,6 @@ void mwifiex_update_rxreor_flags(struct mwifiex_adapter *adapter, u8 flags)
|
||||
continue;
|
||||
|
||||
spin_lock_irqsave(&priv->rx_reorder_tbl_lock, lock_flags);
|
||||
if (list_empty(&priv->rx_reorder_tbl_ptr)) {
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
|
||||
lock_flags);
|
||||
continue;
|
||||
}
|
||||
|
||||
list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list)
|
||||
tbl->flags = flags;
|
||||
spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, lock_flags);
|
||||
|
||||
@@ -142,7 +142,7 @@ mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
u8 key_index, bool pairwise, const u8 *mac_addr)
|
||||
{
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
|
||||
const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
static const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
|
||||
|
||||
if (mwifiex_set_encode(priv, NULL, NULL, 0, key_index, peer_mac, 1)) {
|
||||
@@ -454,7 +454,7 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
{
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev);
|
||||
struct mwifiex_wep_key *wep_key;
|
||||
const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
static const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
const u8 *peer_mac = pairwise ? mac_addr : bc_mac;
|
||||
|
||||
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP &&
|
||||
@@ -2503,6 +2503,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
|
||||
struct ieee80211_channel *chan;
|
||||
struct ieee_types_header *ie;
|
||||
struct mwifiex_user_scan_cfg *user_scan_cfg;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
|
||||
mwifiex_dbg(priv->adapter, CMD,
|
||||
"info: received scan request on %s\n", dev->name);
|
||||
@@ -2529,15 +2530,10 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
|
||||
priv->scan_request = request;
|
||||
|
||||
if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
|
||||
ether_addr_copy(priv->random_mac, request->mac_addr);
|
||||
for (i = 0; i < ETH_ALEN; i++) {
|
||||
priv->random_mac[i] &= request->mac_addr_mask[i];
|
||||
priv->random_mac[i] |= get_random_int() &
|
||||
~(request->mac_addr_mask[i]);
|
||||
}
|
||||
ether_addr_copy(user_scan_cfg->random_mac, priv->random_mac);
|
||||
} else {
|
||||
eth_zero_addr(priv->random_mac);
|
||||
get_random_mask_addr(mac_addr, request->mac_addr,
|
||||
request->mac_addr_mask);
|
||||
ether_addr_copy(request->mac_addr, mac_addr);
|
||||
ether_addr_copy(user_scan_cfg->random_mac, mac_addr);
|
||||
}
|
||||
|
||||
user_scan_cfg->num_ssids = request->n_ssids;
|
||||
@@ -2959,18 +2955,21 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
|
||||
}
|
||||
|
||||
mwifiex_init_priv_params(priv, dev);
|
||||
mwifiex_set_mac_address(priv, dev);
|
||||
|
||||
priv->netdev = dev;
|
||||
|
||||
ret = mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
|
||||
HostCmd_ACT_GEN_SET, 0, NULL, true);
|
||||
if (ret)
|
||||
goto err_set_bss_mode;
|
||||
if (!adapter->mfg_mode) {
|
||||
mwifiex_set_mac_address(priv, dev);
|
||||
|
||||
ret = mwifiex_sta_init_cmd(priv, false, false);
|
||||
if (ret)
|
||||
goto err_sta_init;
|
||||
ret = mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
|
||||
HostCmd_ACT_GEN_SET, 0, NULL, true);
|
||||
if (ret)
|
||||
goto err_set_bss_mode;
|
||||
|
||||
ret = mwifiex_sta_init_cmd(priv, false, false);
|
||||
if (ret)
|
||||
goto err_sta_init;
|
||||
}
|
||||
|
||||
mwifiex_setup_ht_caps(&wiphy->bands[NL80211_BAND_2GHZ]->ht_cap, priv);
|
||||
if (adapter->is_hw_11ac_capable)
|
||||
@@ -3250,8 +3249,8 @@ static int mwifiex_set_wowlan_mef_entry(struct mwifiex_private *priv,
|
||||
int i, filt_num = 0, ret = 0;
|
||||
bool first_pat = true;
|
||||
u8 byte_seq[MWIFIEX_MEF_MAX_BYTESEQ + 1];
|
||||
const u8 ipv4_mc_mac[] = {0x33, 0x33};
|
||||
const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
|
||||
static const u8 ipv4_mc_mac[] = {0x33, 0x33};
|
||||
static const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
|
||||
|
||||
mef_entry->mode = MEF_MODE_HOST_SLEEP;
|
||||
mef_entry->action = MEF_ACTION_ALLOW_AND_WAKEUP_HOST;
|
||||
@@ -3544,9 +3543,9 @@ static int mwifiex_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
static int mwifiex_get_coalesce_pkt_type(u8 *byte_seq)
|
||||
{
|
||||
const u8 ipv4_mc_mac[] = {0x33, 0x33};
|
||||
const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
|
||||
const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff};
|
||||
static const u8 ipv4_mc_mac[] = {0x33, 0x33};
|
||||
static const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
|
||||
static const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff};
|
||||
|
||||
if ((byte_seq[0] & 0x01) &&
|
||||
(byte_seq[MWIFIEX_COALESCE_MAX_BYTESEQ] == 1))
|
||||
@@ -3795,9 +3794,8 @@ mwifiex_cfg80211_tdls_chan_switch(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
spin_lock_irqsave(&priv->sta_list_spinlock, flags);
|
||||
sta_ptr = mwifiex_get_sta_entry(priv, addr);
|
||||
spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
|
||||
|
||||
if (!sta_ptr) {
|
||||
spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
|
||||
wiphy_err(wiphy, "%s: Invalid TDLS peer %pM\n",
|
||||
__func__, addr);
|
||||
return -ENOENT;
|
||||
@@ -3805,15 +3803,18 @@ mwifiex_cfg80211_tdls_chan_switch(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
if (!(sta_ptr->tdls_cap.extcap.ext_capab[3] &
|
||||
WLAN_EXT_CAPA4_TDLS_CHAN_SWITCH)) {
|
||||
spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
|
||||
wiphy_err(wiphy, "%pM do not support tdls cs\n", addr);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (sta_ptr->tdls_status == TDLS_CHAN_SWITCHING ||
|
||||
sta_ptr->tdls_status == TDLS_IN_OFF_CHAN) {
|
||||
spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
|
||||
wiphy_err(wiphy, "channel switch is running, abort request\n");
|
||||
return -EALREADY;
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
|
||||
|
||||
chan = chandef->chan->hw_value;
|
||||
second_chan_offset = mwifiex_get_sec_chan_offset(chan);
|
||||
@@ -3834,18 +3835,20 @@ mwifiex_cfg80211_tdls_cancel_chan_switch(struct wiphy *wiphy,
|
||||
|
||||
spin_lock_irqsave(&priv->sta_list_spinlock, flags);
|
||||
sta_ptr = mwifiex_get_sta_entry(priv, addr);
|
||||
spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
|
||||
|
||||
if (!sta_ptr) {
|
||||
spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
|
||||
wiphy_err(wiphy, "%s: Invalid TDLS peer %pM\n",
|
||||
__func__, addr);
|
||||
} else if (!(sta_ptr->tdls_status == TDLS_CHAN_SWITCHING ||
|
||||
sta_ptr->tdls_status == TDLS_IN_BASE_CHAN ||
|
||||
sta_ptr->tdls_status == TDLS_IN_OFF_CHAN)) {
|
||||
spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
|
||||
wiphy_err(wiphy, "tdls chan switch not initialize by %pM\n",
|
||||
addr);
|
||||
} else
|
||||
} else {
|
||||
spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
|
||||
mwifiex_stop_tdls_cs(priv, addr);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -4202,7 +4205,10 @@ int mwifiex_init_channel_scan_gap(struct mwifiex_adapter *adapter)
|
||||
if (adapter->config_bands & BAND_A)
|
||||
n_channels_a = mwifiex_band_5ghz.n_channels;
|
||||
|
||||
adapter->num_in_chan_stats = n_channels_bg + n_channels_a;
|
||||
/* allocate twice the number total channels, since the driver issues an
|
||||
* additional active scan request for hidden SSIDs on passive channels.
|
||||
*/
|
||||
adapter->num_in_chan_stats = 2 * (n_channels_bg + n_channels_a);
|
||||
adapter->chan_stats = vmalloc(sizeof(*adapter->chan_stats) *
|
||||
adapter->num_in_chan_stats);
|
||||
|
||||
@@ -4306,10 +4312,12 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
|
||||
wiphy->features |= NL80211_FEATURE_HT_IBSS |
|
||||
NL80211_FEATURE_INACTIVITY_TIMER |
|
||||
NL80211_FEATURE_LOW_PRIORITY_SCAN |
|
||||
NL80211_FEATURE_NEED_OBSS_SCAN |
|
||||
NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR |
|
||||
NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
|
||||
NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
|
||||
NL80211_FEATURE_NEED_OBSS_SCAN;
|
||||
|
||||
if (ISSUPP_RANDOM_MAC(adapter->fw_cap_info))
|
||||
wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR |
|
||||
NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
|
||||
NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
|
||||
|
||||
if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info))
|
||||
wiphy->features |= NL80211_FEATURE_TDLS_CHANNEL_SWITCH;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
* this warranty disclaimer.
|
||||
*/
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
#include "decl.h"
|
||||
#include "ioctl.h"
|
||||
#include "util.h"
|
||||
@@ -183,7 +184,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
|
||||
uint16_t cmd_code;
|
||||
uint16_t cmd_size;
|
||||
unsigned long flags;
|
||||
__le32 tmp;
|
||||
|
||||
if (!adapter || !cmd_node)
|
||||
return -1;
|
||||
@@ -249,9 +249,9 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
|
||||
mwifiex_dbg_dump(adapter, CMD_D, "cmd buffer:", host_cmd, cmd_size);
|
||||
|
||||
if (adapter->iface_type == MWIFIEX_USB) {
|
||||
tmp = cpu_to_le32(MWIFIEX_USB_TYPE_CMD);
|
||||
skb_push(cmd_node->cmd_skb, MWIFIEX_TYPE_LEN);
|
||||
memcpy(cmd_node->cmd_skb->data, &tmp, MWIFIEX_TYPE_LEN);
|
||||
put_unaligned_le32(MWIFIEX_USB_TYPE_CMD,
|
||||
cmd_node->cmd_skb->data);
|
||||
adapter->cmd_sent = true;
|
||||
ret = adapter->if_ops.host_to_card(adapter,
|
||||
MWIFIEX_USB_EP_CMD_EVENT,
|
||||
@@ -317,7 +317,6 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
|
||||
(struct mwifiex_opt_sleep_confirm *)
|
||||
adapter->sleep_cfm->data;
|
||||
struct sk_buff *sleep_cfm_tmp;
|
||||
__le32 tmp;
|
||||
|
||||
priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
|
||||
|
||||
@@ -342,8 +341,7 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
|
||||
+ MWIFIEX_TYPE_LEN);
|
||||
skb_put(sleep_cfm_tmp, sizeof(struct mwifiex_opt_sleep_confirm)
|
||||
+ MWIFIEX_TYPE_LEN);
|
||||
tmp = cpu_to_le32(MWIFIEX_USB_TYPE_CMD);
|
||||
memcpy(sleep_cfm_tmp->data, &tmp, MWIFIEX_TYPE_LEN);
|
||||
put_unaligned_le32(MWIFIEX_USB_TYPE_CMD, sleep_cfm_tmp->data);
|
||||
memcpy(sleep_cfm_tmp->data + MWIFIEX_TYPE_LEN,
|
||||
adapter->sleep_cfm->data,
|
||||
sizeof(struct mwifiex_opt_sleep_confirm));
|
||||
|
||||
@@ -238,6 +238,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
|
||||
#define ISSUPP_DRCS_ENABLED(FwCapInfo) (FwCapInfo & BIT(15))
|
||||
#define ISSUPP_SDIO_SPA_ENABLED(FwCapInfo) (FwCapInfo & BIT(16))
|
||||
#define ISSUPP_ADHOC_ENABLED(FwCapInfo) (FwCapInfo & BIT(25))
|
||||
#define ISSUPP_RANDOM_MAC(FwCapInfo) (FwCapInfo & BIT(27))
|
||||
|
||||
#define MWIFIEX_DEF_HT_CAP (IEEE80211_HT_CAP_DSSSCCK40 | \
|
||||
(1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) | \
|
||||
|
||||
@@ -579,10 +579,6 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv)
|
||||
|
||||
{
|
||||
spin_lock_irqsave(lock, flags);
|
||||
if (list_empty(head)) {
|
||||
spin_unlock_irqrestore(lock, flags);
|
||||
continue;
|
||||
}
|
||||
list_for_each_entry_safe(bssprio_node, tmp_node, head,
|
||||
list) {
|
||||
if (bssprio_node->priv == priv) {
|
||||
|
||||
@@ -680,7 +680,6 @@ struct mwifiex_private {
|
||||
struct mwifiex_user_scan_chan hidden_chan[MWIFIEX_USER_SCAN_CHAN_MAX];
|
||||
u8 assoc_resp_ht_param;
|
||||
bool ht_param_present;
|
||||
u8 random_mac[ETH_ALEN];
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1936,8 +1936,6 @@ mwifiex_active_scan_req_for_passive_chan(struct mwifiex_private *priv)
|
||||
if (!user_scan_cfg)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(user_scan_cfg, 0, sizeof(*user_scan_cfg));
|
||||
|
||||
for (id = 0; id < MWIFIEX_USER_SCAN_CHAN_MAX; id++) {
|
||||
if (!priv->hidden_chan[id].chan_number)
|
||||
break;
|
||||
@@ -1948,7 +1946,8 @@ mwifiex_active_scan_req_for_passive_chan(struct mwifiex_private *priv)
|
||||
|
||||
adapter->active_scan_triggered = true;
|
||||
if (priv->scan_request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
|
||||
ether_addr_copy(user_scan_cfg->random_mac, priv->random_mac);
|
||||
ether_addr_copy(user_scan_cfg->random_mac,
|
||||
priv->scan_request->mac_addr);
|
||||
user_scan_cfg->num_ssids = priv->scan_request->n_ssids;
|
||||
user_scan_cfg->ssid_list = priv->scan_request->ssids;
|
||||
|
||||
|
||||
@@ -70,11 +70,7 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
|
||||
break;
|
||||
case HostCmd_CMD_802_11_SCAN:
|
||||
case HostCmd_CMD_802_11_SCAN_EXT:
|
||||
mwifiex_cancel_pending_scan_cmd(adapter);
|
||||
|
||||
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
|
||||
adapter->scan_processing = false;
|
||||
spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
|
||||
mwifiex_cancel_scan(adapter);
|
||||
break;
|
||||
|
||||
case HostCmd_CMD_MAC_CONTROL:
|
||||
|
||||
@@ -359,13 +359,12 @@ static void mwifiex_process_uap_tx_pause(struct mwifiex_private *priv,
|
||||
} else {
|
||||
spin_lock_irqsave(&priv->sta_list_spinlock, flags);
|
||||
sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac);
|
||||
spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
|
||||
|
||||
if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) {
|
||||
sta_ptr->tx_pause = tp->tx_pause;
|
||||
mwifiex_update_ralist_tx_pause(priv, tp->peermac,
|
||||
tp->tx_pause);
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,14 +395,13 @@ static void mwifiex_process_sta_tx_pause(struct mwifiex_private *priv,
|
||||
if (mwifiex_is_tdls_link_setup(status)) {
|
||||
spin_lock_irqsave(&priv->sta_list_spinlock, flags);
|
||||
sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac);
|
||||
spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
|
||||
|
||||
if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) {
|
||||
sta_ptr->tx_pause = tp->tx_pause;
|
||||
mwifiex_update_ralist_tx_pause(priv,
|
||||
tp->peermac,
|
||||
tp->tx_pause);
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->sta_list_spinlock, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1413,13 +1413,6 @@ void mwifiex_check_auto_tdls(unsigned long context)
|
||||
|
||||
priv->check_tdls_tx = false;
|
||||
|
||||
if (list_empty(&priv->auto_tdls_list)) {
|
||||
mod_timer(&priv->auto_tdls_timer,
|
||||
jiffies +
|
||||
msecs_to_jiffies(MWIFIEX_TIMER_10S));
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->auto_tdls_lock, flags);
|
||||
list_for_each_entry(tdls_peer, &priv->auto_tdls_list, list) {
|
||||
if ((jiffies - tdls_peer->rssi_jiffies) >
|
||||
|
||||
@@ -359,7 +359,8 @@ static enum mwifiex_wmm_ac_e
|
||||
mwifiex_wmm_convert_tos_to_ac(struct mwifiex_adapter *adapter, u32 tos)
|
||||
{
|
||||
/* Map of TOS UP values to WMM AC */
|
||||
const enum mwifiex_wmm_ac_e tos_to_ac[] = { WMM_AC_BE,
|
||||
static const enum mwifiex_wmm_ac_e tos_to_ac[] = {
|
||||
WMM_AC_BE,
|
||||
WMM_AC_BK,
|
||||
WMM_AC_BK,
|
||||
WMM_AC_BE,
|
||||
|
||||
@@ -133,6 +133,7 @@ int qtnf_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
|
||||
vif->netdev = NULL;
|
||||
vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
|
||||
eth_zero_addr(vif->mac_addr);
|
||||
eth_zero_addr(vif->bssid);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -201,6 +202,8 @@ static struct wireless_dev *qtnf_add_virtual_intf(struct wiphy *wiphy,
|
||||
qtnf_cmd_send_del_intf(vif);
|
||||
err_cmd:
|
||||
vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
|
||||
eth_zero_addr(vif->mac_addr);
|
||||
eth_zero_addr(vif->bssid);
|
||||
|
||||
return ERR_PTR(-EFAULT);
|
||||
}
|
||||
@@ -256,11 +259,6 @@ static int qtnf_change_beacon(struct wiphy *wiphy, struct net_device *dev,
|
||||
{
|
||||
struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
|
||||
|
||||
if (!(vif->bss_status & QTNF_STATE_AP_START)) {
|
||||
pr_err("VIF%u.%u: not started\n", vif->mac->macid, vif->vifid);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return qtnf_mgmt_set_appie(vif, info);
|
||||
}
|
||||
|
||||
@@ -268,46 +266,15 @@ static int qtnf_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_ap_settings *settings)
|
||||
{
|
||||
struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
|
||||
struct qtnf_wmac *mac = wiphy_priv(wiphy);
|
||||
struct qtnf_bss_config *bss_cfg;
|
||||
int ret;
|
||||
|
||||
if (!cfg80211_chandef_identical(&mac->chandef, &settings->chandef)) {
|
||||
memcpy(&mac->chandef, &settings->chandef, sizeof(mac->chandef));
|
||||
if (vif->vifid != 0)
|
||||
pr_warn("%s: unexpected chan %u (%u MHz)\n", dev->name,
|
||||
settings->chandef.chan->hw_value,
|
||||
settings->chandef.chan->center_freq);
|
||||
}
|
||||
|
||||
bss_cfg = &vif->bss_cfg;
|
||||
memset(bss_cfg, 0, sizeof(*bss_cfg));
|
||||
|
||||
bss_cfg->bcn_period = settings->beacon_interval;
|
||||
bss_cfg->dtim = settings->dtim_period;
|
||||
bss_cfg->auth_type = settings->auth_type;
|
||||
bss_cfg->privacy = settings->privacy;
|
||||
|
||||
bss_cfg->ssid_len = settings->ssid_len;
|
||||
memcpy(&bss_cfg->ssid, settings->ssid, bss_cfg->ssid_len);
|
||||
|
||||
memcpy(&bss_cfg->crypto, &settings->crypto,
|
||||
sizeof(struct cfg80211_crypto_settings));
|
||||
|
||||
ret = qtnf_cmd_send_config_ap(vif);
|
||||
ret = qtnf_cmd_send_config_ap(vif, settings);
|
||||
if (ret) {
|
||||
pr_err("VIF%u.%u: failed to push config to FW\n",
|
||||
vif->mac->macid, vif->vifid);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(vif->bss_status & QTNF_STATE_AP_CONFIG)) {
|
||||
pr_err("VIF%u.%u: AP config failed in FW\n", vif->mac->macid,
|
||||
vif->vifid);
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = qtnf_mgmt_set_appie(vif, &settings->beacon);
|
||||
if (ret) {
|
||||
pr_err("VIF%u.%u: failed to add IEs to beacon\n",
|
||||
@@ -316,17 +283,9 @@ static int qtnf_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
||||
}
|
||||
|
||||
ret = qtnf_cmd_send_start_ap(vif);
|
||||
if (ret) {
|
||||
if (ret)
|
||||
pr_err("VIF%u.%u: failed to start AP\n", vif->mac->macid,
|
||||
vif->vifid);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(vif->bss_status & QTNF_STATE_AP_START)) {
|
||||
pr_err("VIF%u.%u: FW failed to start AP operation\n",
|
||||
vif->mac->macid, vif->vifid);
|
||||
ret = -EFAULT;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
@@ -343,8 +302,6 @@ static int qtnf_stop_ap(struct wiphy *wiphy, struct net_device *dev)
|
||||
if (ret) {
|
||||
pr_err("VIF%u.%u: failed to stop AP operation in FW\n",
|
||||
vif->mac->macid, vif->vifid);
|
||||
vif->bss_status &= ~QTNF_STATE_AP_START;
|
||||
vif->bss_status &= ~QTNF_STATE_AP_CONFIG;
|
||||
|
||||
netif_carrier_off(vif->netdev);
|
||||
}
|
||||
@@ -615,9 +572,6 @@ qtnf_connect(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_connect_params *sme)
|
||||
{
|
||||
struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
|
||||
struct qtnf_wmac *mac = wiphy_priv(wiphy);
|
||||
struct cfg80211_chan_def chandef;
|
||||
struct qtnf_bss_config *bss_cfg;
|
||||
int ret;
|
||||
|
||||
if (vif->wdev.iftype != NL80211_IFTYPE_STATION)
|
||||
@@ -626,49 +580,10 @@ qtnf_connect(struct wiphy *wiphy, struct net_device *dev,
|
||||
if (vif->sta_state != QTNF_STA_DISCONNECTED)
|
||||
return -EBUSY;
|
||||
|
||||
bss_cfg = &vif->bss_cfg;
|
||||
memset(bss_cfg, 0, sizeof(*bss_cfg));
|
||||
|
||||
if (sme->channel) {
|
||||
/* FIXME: need to set proper nl80211_channel_type value */
|
||||
cfg80211_chandef_create(&chandef, sme->channel,
|
||||
NL80211_CHAN_HT20);
|
||||
/* fall-back to minimal safe chandef description */
|
||||
if (!cfg80211_chandef_valid(&chandef))
|
||||
cfg80211_chandef_create(&chandef, sme->channel,
|
||||
NL80211_CHAN_HT20);
|
||||
|
||||
memcpy(&mac->chandef, &chandef, sizeof(mac->chandef));
|
||||
}
|
||||
|
||||
bss_cfg->ssid_len = sme->ssid_len;
|
||||
memcpy(&bss_cfg->ssid, sme->ssid, bss_cfg->ssid_len);
|
||||
bss_cfg->auth_type = sme->auth_type;
|
||||
bss_cfg->privacy = sme->privacy;
|
||||
bss_cfg->mfp = sme->mfp;
|
||||
|
||||
if ((sme->bg_scan_period > 0) &&
|
||||
(sme->bg_scan_period <= QTNF_MAX_BG_SCAN_PERIOD))
|
||||
bss_cfg->bg_scan_period = sme->bg_scan_period;
|
||||
else if (sme->bg_scan_period == -1)
|
||||
bss_cfg->bg_scan_period = QTNF_DEFAULT_BG_SCAN_PERIOD;
|
||||
else
|
||||
bss_cfg->bg_scan_period = 0; /* disabled */
|
||||
|
||||
bss_cfg->connect_flags = 0;
|
||||
|
||||
if (sme->flags & ASSOC_REQ_DISABLE_HT)
|
||||
bss_cfg->connect_flags |= QLINK_STA_CONNECT_DISABLE_HT;
|
||||
if (sme->flags & ASSOC_REQ_DISABLE_VHT)
|
||||
bss_cfg->connect_flags |= QLINK_STA_CONNECT_DISABLE_VHT;
|
||||
if (sme->flags & ASSOC_REQ_USE_RRM)
|
||||
bss_cfg->connect_flags |= QLINK_STA_CONNECT_USE_RRM;
|
||||
|
||||
memcpy(&bss_cfg->crypto, &sme->crypto, sizeof(bss_cfg->crypto));
|
||||
if (sme->bssid)
|
||||
ether_addr_copy(bss_cfg->bssid, sme->bssid);
|
||||
ether_addr_copy(vif->bssid, sme->bssid);
|
||||
else
|
||||
eth_zero_addr(bss_cfg->bssid);
|
||||
eth_zero_addr(vif->bssid);
|
||||
|
||||
ret = qtnf_cmd_send_connect(vif, sme);
|
||||
if (ret) {
|
||||
@@ -717,15 +632,15 @@ qtnf_dump_survey(struct wiphy *wiphy, struct net_device *dev,
|
||||
int idx, struct survey_info *survey)
|
||||
{
|
||||
struct qtnf_wmac *mac = wiphy_priv(wiphy);
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct cfg80211_chan_def *chandef;
|
||||
const struct cfg80211_chan_def *chandef = &wdev->chandef;
|
||||
struct ieee80211_channel *chan;
|
||||
struct qtnf_chan_stats stats;
|
||||
struct qtnf_vif *vif;
|
||||
int ret;
|
||||
|
||||
vif = qtnf_netdev_get_priv(dev);
|
||||
chandef = &mac->chandef;
|
||||
|
||||
sband = wiphy->bands[NL80211_BAND_2GHZ];
|
||||
if (sband && idx >= sband->n_channels) {
|
||||
@@ -792,46 +707,35 @@ static int
|
||||
qtnf_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct qtnf_wmac *mac = wiphy_priv(wiphy);
|
||||
struct net_device *ndev = wdev->netdev;
|
||||
struct qtnf_vif *vif;
|
||||
int ret;
|
||||
|
||||
if (!ndev)
|
||||
return -ENODEV;
|
||||
|
||||
vif = qtnf_netdev_get_priv(wdev->netdev);
|
||||
|
||||
switch (vif->wdev.iftype) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
if (vif->sta_state == QTNF_STA_DISCONNECTED) {
|
||||
pr_warn("%s: STA disconnected\n", ndev->name);
|
||||
return -ENODATA;
|
||||
}
|
||||
break;
|
||||
case NL80211_IFTYPE_AP:
|
||||
if (!(vif->bss_status & QTNF_STATE_AP_START)) {
|
||||
pr_warn("%s: AP not started\n", ndev->name);
|
||||
return -ENODATA;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_err("unsupported vif type (%d)\n", vif->wdev.iftype);
|
||||
return -ENODATA;
|
||||
ret = qtnf_cmd_get_channel(vif, chandef);
|
||||
if (ret) {
|
||||
pr_err("%s: failed to get channel: %d\n", ndev->name, ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!cfg80211_chandef_valid(&mac->chandef)) {
|
||||
pr_err("invalid channel settings on %s\n", ndev->name);
|
||||
return -ENODATA;
|
||||
if (!cfg80211_chandef_valid(chandef)) {
|
||||
pr_err("%s: bad chan freq1=%u freq2=%u bw=%u\n", ndev->name,
|
||||
chandef->center_freq1, chandef->center_freq2,
|
||||
chandef->width);
|
||||
ret = -ENODATA;
|
||||
}
|
||||
|
||||
memcpy(chandef, &mac->chandef, sizeof(*chandef));
|
||||
return 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qtnf_channel_switch(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_csa_settings *params)
|
||||
{
|
||||
struct qtnf_wmac *mac = wiphy_priv(wiphy);
|
||||
struct qtnf_vif *vif = qtnf_netdev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
@@ -839,41 +743,12 @@ static int qtnf_channel_switch(struct wiphy *wiphy, struct net_device *dev,
|
||||
params->chandef.chan->hw_value, params->count,
|
||||
params->radar_required, params->block_tx);
|
||||
|
||||
switch (vif->wdev.iftype) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
if (!(vif->bss_status & QTNF_STATE_AP_START)) {
|
||||
pr_warn("AP not started on %s\n", dev->name);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
pr_err("unsupported vif type (%d) on %s\n",
|
||||
vif->wdev.iftype, dev->name);
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (vif->vifid != 0) {
|
||||
if (!(mac->status & QTNF_MAC_CSA_ACTIVE))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!cfg80211_chandef_identical(¶ms->chandef,
|
||||
&mac->csa_chandef))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!cfg80211_chandef_valid(¶ms->chandef)) {
|
||||
pr_err("%s: invalid channel\n", dev->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cfg80211_chandef_identical(¶ms->chandef, &mac->chandef)) {
|
||||
pr_err("%s: switch request to the same channel\n", dev->name);
|
||||
return -EALREADY;
|
||||
}
|
||||
|
||||
ret = qtnf_cmd_send_chan_switch(mac, params);
|
||||
ret = qtnf_cmd_send_chan_switch(vif, params);
|
||||
if (ret)
|
||||
pr_warn("%s: failed to switch to channel (%u)\n",
|
||||
dev->name, params->chandef.chan->hw_value);
|
||||
@@ -1119,7 +994,7 @@ void qtnf_virtual_intf_cleanup(struct net_device *ndev)
|
||||
break;
|
||||
case QTNF_STA_CONNECTING:
|
||||
cfg80211_connect_result(vif->netdev,
|
||||
vif->bss_cfg.bssid, NULL, 0,
|
||||
vif->bssid, NULL, 0,
|
||||
NULL, 0,
|
||||
WLAN_STATUS_UNSPECIFIED_FAILURE,
|
||||
GFP_KERNEL);
|
||||
@@ -1147,7 +1022,7 @@ void qtnf_cfg80211_vif_reset(struct qtnf_vif *vif)
|
||||
switch (vif->sta_state) {
|
||||
case QTNF_STA_CONNECTING:
|
||||
cfg80211_connect_result(vif->netdev,
|
||||
vif->bss_cfg.bssid, NULL, 0,
|
||||
vif->bssid, NULL, 0,
|
||||
NULL, 0,
|
||||
WLAN_STATUS_UNSPECIFIED_FAILURE,
|
||||
GFP_KERNEL);
|
||||
|
||||
@@ -173,7 +173,6 @@ int qtnf_cmd_send_start_ap(struct qtnf_vif *vif)
|
||||
goto out;
|
||||
}
|
||||
|
||||
vif->bss_status |= QTNF_STATE_AP_START;
|
||||
netif_carrier_on(vif->netdev);
|
||||
|
||||
out:
|
||||
@@ -181,62 +180,68 @@ int qtnf_cmd_send_start_ap(struct qtnf_vif *vif)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qtnf_cmd_send_config_ap(struct qtnf_vif *vif)
|
||||
int qtnf_cmd_send_config_ap(struct qtnf_vif *vif,
|
||||
const struct cfg80211_ap_settings *s)
|
||||
{
|
||||
struct sk_buff *cmd_skb;
|
||||
struct qtnf_bss_config *bss_cfg = &vif->bss_cfg;
|
||||
struct cfg80211_chan_def *chandef = &vif->mac->chandef;
|
||||
struct qlink_tlv_channel *qchan;
|
||||
struct qlink_auth_encr aen;
|
||||
struct qlink_cmd_config_ap *cmd;
|
||||
struct qlink_auth_encr *aen;
|
||||
u16 res_code = QLINK_CMD_RESULT_OK;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
|
||||
QLINK_CMD_CONFIG_AP,
|
||||
sizeof(struct qlink_cmd));
|
||||
sizeof(*cmd));
|
||||
if (unlikely(!cmd_skb))
|
||||
return -ENOMEM;
|
||||
|
||||
qtnf_bus_lock(vif->mac->bus);
|
||||
cmd = (struct qlink_cmd_config_ap *)cmd_skb->data;
|
||||
cmd->dtim_period = s->dtim_period;
|
||||
cmd->beacon_interval = cpu_to_le16(s->beacon_interval);
|
||||
cmd->hidden_ssid = qlink_hidden_ssid_nl2q(s->hidden_ssid);
|
||||
cmd->inactivity_timeout = cpu_to_le16(s->inactivity_timeout);
|
||||
cmd->smps_mode = s->smps_mode;
|
||||
cmd->p2p_ctwindow = s->p2p_ctwindow;
|
||||
cmd->p2p_opp_ps = s->p2p_opp_ps;
|
||||
cmd->pbss = s->pbss;
|
||||
cmd->ht_required = s->ht_required;
|
||||
cmd->vht_required = s->vht_required;
|
||||
|
||||
qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, bss_cfg->ssid,
|
||||
bss_cfg->ssid_len);
|
||||
qtnf_cmd_skb_put_tlv_u16(cmd_skb, QTN_TLV_ID_BCN_PERIOD,
|
||||
bss_cfg->bcn_period);
|
||||
qtnf_cmd_skb_put_tlv_u8(cmd_skb, QTN_TLV_ID_DTIM, bss_cfg->dtim);
|
||||
|
||||
qchan = skb_put_zero(cmd_skb, sizeof(*qchan));
|
||||
qchan->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANNEL);
|
||||
qchan->hdr.len = cpu_to_le16(sizeof(*qchan) -
|
||||
sizeof(struct qlink_tlv_hdr));
|
||||
qchan->hw_value = cpu_to_le16(
|
||||
ieee80211_frequency_to_channel(chandef->chan->center_freq));
|
||||
|
||||
memset(&aen, 0, sizeof(aen));
|
||||
aen.auth_type = bss_cfg->auth_type;
|
||||
aen.privacy = !!bss_cfg->privacy;
|
||||
aen.mfp = bss_cfg->mfp;
|
||||
aen.wpa_versions = cpu_to_le32(bss_cfg->crypto.wpa_versions);
|
||||
aen.cipher_group = cpu_to_le32(bss_cfg->crypto.cipher_group);
|
||||
aen.n_ciphers_pairwise = cpu_to_le32(
|
||||
bss_cfg->crypto.n_ciphers_pairwise);
|
||||
aen = &cmd->aen;
|
||||
aen->auth_type = s->auth_type;
|
||||
aen->privacy = !!s->privacy;
|
||||
aen->mfp = 0;
|
||||
aen->wpa_versions = cpu_to_le32(s->crypto.wpa_versions);
|
||||
aen->cipher_group = cpu_to_le32(s->crypto.cipher_group);
|
||||
aen->n_ciphers_pairwise = cpu_to_le32(s->crypto.n_ciphers_pairwise);
|
||||
for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++)
|
||||
aen.ciphers_pairwise[i] = cpu_to_le32(
|
||||
bss_cfg->crypto.ciphers_pairwise[i]);
|
||||
aen.n_akm_suites = cpu_to_le32(
|
||||
bss_cfg->crypto.n_akm_suites);
|
||||
aen->ciphers_pairwise[i] =
|
||||
cpu_to_le32(s->crypto.ciphers_pairwise[i]);
|
||||
aen->n_akm_suites = cpu_to_le32(s->crypto.n_akm_suites);
|
||||
for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++)
|
||||
aen.akm_suites[i] = cpu_to_le32(
|
||||
bss_cfg->crypto.akm_suites[i]);
|
||||
aen.control_port = bss_cfg->crypto.control_port;
|
||||
aen.control_port_no_encrypt =
|
||||
bss_cfg->crypto.control_port_no_encrypt;
|
||||
aen.control_port_ethertype = cpu_to_le16(be16_to_cpu(
|
||||
bss_cfg->crypto.control_port_ethertype));
|
||||
aen->akm_suites[i] = cpu_to_le32(s->crypto.akm_suites[i]);
|
||||
aen->control_port = s->crypto.control_port;
|
||||
aen->control_port_no_encrypt = s->crypto.control_port_no_encrypt;
|
||||
aen->control_port_ethertype =
|
||||
cpu_to_le16(be16_to_cpu(s->crypto.control_port_ethertype));
|
||||
|
||||
qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_CRYPTO, (u8 *)&aen,
|
||||
sizeof(aen));
|
||||
if (s->ssid && s->ssid_len > 0 && s->ssid_len <= IEEE80211_MAX_SSID_LEN)
|
||||
qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, s->ssid,
|
||||
s->ssid_len);
|
||||
|
||||
if (cfg80211_chandef_valid(&s->chandef)) {
|
||||
struct qlink_tlv_chandef *chtlv =
|
||||
(struct qlink_tlv_chandef *)skb_put(cmd_skb,
|
||||
sizeof(*chtlv));
|
||||
|
||||
chtlv->hdr.type = cpu_to_le16(QTN_TLV_ID_CHANDEF);
|
||||
chtlv->hdr.len = cpu_to_le16(sizeof(*chtlv) -
|
||||
sizeof(chtlv->hdr));
|
||||
qlink_chandef_cfg2q(&s->chandef, &chtlv->chan);
|
||||
}
|
||||
|
||||
qtnf_bus_lock(vif->mac->bus);
|
||||
|
||||
ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
|
||||
|
||||
@@ -250,8 +255,6 @@ int qtnf_cmd_send_config_ap(struct qtnf_vif *vif)
|
||||
goto out;
|
||||
}
|
||||
|
||||
vif->bss_status |= QTNF_STATE_AP_CONFIG;
|
||||
|
||||
out:
|
||||
qtnf_bus_unlock(vif->mac->bus);
|
||||
return ret;
|
||||
@@ -283,9 +286,6 @@ int qtnf_cmd_send_stop_ap(struct qtnf_vif *vif)
|
||||
goto out;
|
||||
}
|
||||
|
||||
vif->bss_status &= ~QTNF_STATE_AP_START;
|
||||
vif->bss_status &= ~QTNF_STATE_AP_CONFIG;
|
||||
|
||||
netif_carrier_off(vif->netdev);
|
||||
|
||||
out:
|
||||
@@ -2037,11 +2037,11 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif,
|
||||
{
|
||||
struct sk_buff *cmd_skb;
|
||||
struct qlink_cmd_connect *cmd;
|
||||
struct qtnf_bss_config *bss_cfg = &vif->bss_cfg;
|
||||
struct qlink_auth_encr aen;
|
||||
struct qlink_auth_encr *aen;
|
||||
u16 res_code = QLINK_CMD_RESULT_OK;
|
||||
int ret;
|
||||
int i;
|
||||
u32 connect_flags = 0;
|
||||
|
||||
cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
|
||||
QLINK_CMD_CONNECT,
|
||||
@@ -2049,52 +2049,65 @@ int qtnf_cmd_send_connect(struct qtnf_vif *vif,
|
||||
if (unlikely(!cmd_skb))
|
||||
return -ENOMEM;
|
||||
|
||||
qtnf_bus_lock(vif->mac->bus);
|
||||
|
||||
cmd = (struct qlink_cmd_connect *)cmd_skb->data;
|
||||
|
||||
ether_addr_copy(cmd->bssid, bss_cfg->bssid);
|
||||
ether_addr_copy(cmd->bssid, vif->bssid);
|
||||
|
||||
if (vif->mac->chandef.chan)
|
||||
cmd->channel = cpu_to_le16(vif->mac->chandef.chan->hw_value);
|
||||
if (sme->channel)
|
||||
cmd->channel = cpu_to_le16(sme->channel->hw_value);
|
||||
else
|
||||
cmd->channel = 0;
|
||||
|
||||
cmd->bg_scan_period = cpu_to_le16(bss_cfg->bg_scan_period);
|
||||
if ((sme->bg_scan_period > 0) &&
|
||||
(sme->bg_scan_period <= QTNF_MAX_BG_SCAN_PERIOD))
|
||||
cmd->bg_scan_period = cpu_to_le16(sme->bg_scan_period);
|
||||
else if (sme->bg_scan_period == -1)
|
||||
cmd->bg_scan_period = cpu_to_le16(QTNF_DEFAULT_BG_SCAN_PERIOD);
|
||||
else
|
||||
cmd->bg_scan_period = 0; /* disabled */
|
||||
|
||||
memset(&aen, 0, sizeof(aen));
|
||||
aen.auth_type = bss_cfg->auth_type;
|
||||
aen.privacy = !!bss_cfg->privacy;
|
||||
aen.mfp = bss_cfg->mfp;
|
||||
aen.wpa_versions = cpu_to_le32(bss_cfg->crypto.wpa_versions);
|
||||
aen.cipher_group = cpu_to_le32(bss_cfg->crypto.cipher_group);
|
||||
aen.n_ciphers_pairwise = cpu_to_le32(
|
||||
bss_cfg->crypto.n_ciphers_pairwise);
|
||||
if (sme->flags & ASSOC_REQ_DISABLE_HT)
|
||||
connect_flags |= QLINK_STA_CONNECT_DISABLE_HT;
|
||||
if (sme->flags & ASSOC_REQ_DISABLE_VHT)
|
||||
connect_flags |= QLINK_STA_CONNECT_DISABLE_VHT;
|
||||
if (sme->flags & ASSOC_REQ_USE_RRM)
|
||||
connect_flags |= QLINK_STA_CONNECT_USE_RRM;
|
||||
|
||||
cmd->flags = cpu_to_le32(connect_flags);
|
||||
|
||||
aen = &cmd->aen;
|
||||
aen->auth_type = sme->auth_type;
|
||||
aen->privacy = !!sme->privacy;
|
||||
aen->mfp = sme->mfp;
|
||||
aen->wpa_versions = cpu_to_le32(sme->crypto.wpa_versions);
|
||||
aen->cipher_group = cpu_to_le32(sme->crypto.cipher_group);
|
||||
aen->n_ciphers_pairwise = cpu_to_le32(sme->crypto.n_ciphers_pairwise);
|
||||
|
||||
for (i = 0; i < QLINK_MAX_NR_CIPHER_SUITES; i++)
|
||||
aen.ciphers_pairwise[i] = cpu_to_le32(
|
||||
bss_cfg->crypto.ciphers_pairwise[i]);
|
||||
aen->ciphers_pairwise[i] =
|
||||
cpu_to_le32(sme->crypto.ciphers_pairwise[i]);
|
||||
|
||||
aen.n_akm_suites = cpu_to_le32(bss_cfg->crypto.n_akm_suites);
|
||||
aen->n_akm_suites = cpu_to_le32(sme->crypto.n_akm_suites);
|
||||
|
||||
for (i = 0; i < QLINK_MAX_NR_AKM_SUITES; i++)
|
||||
aen.akm_suites[i] = cpu_to_le32(
|
||||
bss_cfg->crypto.akm_suites[i]);
|
||||
aen->akm_suites[i] = cpu_to_le32(sme->crypto.akm_suites[i]);
|
||||
|
||||
aen.control_port = bss_cfg->crypto.control_port;
|
||||
aen.control_port_no_encrypt =
|
||||
bss_cfg->crypto.control_port_no_encrypt;
|
||||
aen.control_port_ethertype = cpu_to_le16(be16_to_cpu(
|
||||
bss_cfg->crypto.control_port_ethertype));
|
||||
aen->control_port = sme->crypto.control_port;
|
||||
aen->control_port_no_encrypt =
|
||||
sme->crypto.control_port_no_encrypt;
|
||||
aen->control_port_ethertype =
|
||||
cpu_to_le16(be16_to_cpu(sme->crypto.control_port_ethertype));
|
||||
|
||||
qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, bss_cfg->ssid,
|
||||
bss_cfg->ssid_len);
|
||||
qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_CRYPTO, (u8 *)&aen,
|
||||
sizeof(aen));
|
||||
qtnf_cmd_skb_put_tlv_arr(cmd_skb, WLAN_EID_SSID, sme->ssid,
|
||||
sme->ssid_len);
|
||||
|
||||
if (sme->ie_len != 0)
|
||||
qtnf_cmd_skb_put_tlv_arr(cmd_skb, QTN_TLV_ID_IE_SET,
|
||||
sme->ie,
|
||||
sme->ie_len);
|
||||
|
||||
qtnf_bus_lock(vif->mac->bus);
|
||||
|
||||
ret = qtnf_cmd_send(vif->mac->bus, cmd_skb, &res_code);
|
||||
|
||||
if (unlikely(ret))
|
||||
@@ -2304,15 +2317,16 @@ int qtnf_cmd_get_chan_stats(struct qtnf_wmac *mac, u16 channel,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qtnf_cmd_send_chan_switch(struct qtnf_wmac *mac,
|
||||
int qtnf_cmd_send_chan_switch(struct qtnf_vif *vif,
|
||||
struct cfg80211_csa_settings *params)
|
||||
{
|
||||
struct qtnf_wmac *mac = vif->mac;
|
||||
struct qlink_cmd_chan_switch *cmd;
|
||||
struct sk_buff *cmd_skb;
|
||||
u16 res_code = QLINK_CMD_RESULT_OK;
|
||||
int ret;
|
||||
|
||||
cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, 0x0,
|
||||
cmd_skb = qtnf_cmd_alloc_new_cmdskb(mac->macid, vif->vifid,
|
||||
QLINK_CMD_CHAN_SWITCH,
|
||||
sizeof(*cmd));
|
||||
|
||||
@@ -2334,9 +2348,6 @@ int qtnf_cmd_send_chan_switch(struct qtnf_wmac *mac,
|
||||
|
||||
switch (res_code) {
|
||||
case QLINK_CMD_RESULT_OK:
|
||||
memcpy(&mac->csa_chandef, ¶ms->chandef,
|
||||
sizeof(mac->csa_chandef));
|
||||
mac->status |= QTNF_MAC_CSA_ACTIVE;
|
||||
ret = 0;
|
||||
break;
|
||||
case QLINK_CMD_RESULT_ENOTFOUND:
|
||||
@@ -2358,3 +2369,41 @@ int qtnf_cmd_send_chan_switch(struct qtnf_wmac *mac,
|
||||
qtnf_bus_unlock(mac->bus);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qtnf_cmd_get_channel(struct qtnf_vif *vif, struct cfg80211_chan_def *chdef)
|
||||
{
|
||||
struct qtnf_bus *bus = vif->mac->bus;
|
||||
const struct qlink_resp_channel_get *resp;
|
||||
struct sk_buff *cmd_skb;
|
||||
struct sk_buff *resp_skb = NULL;
|
||||
u16 res_code = QLINK_CMD_RESULT_OK;
|
||||
int ret;
|
||||
|
||||
cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
|
||||
QLINK_CMD_CHAN_GET,
|
||||
sizeof(struct qlink_cmd));
|
||||
if (unlikely(!cmd_skb))
|
||||
return -ENOMEM;
|
||||
|
||||
qtnf_bus_lock(bus);
|
||||
|
||||
ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb, &res_code,
|
||||
sizeof(*resp), NULL);
|
||||
|
||||
qtnf_bus_unlock(bus);
|
||||
|
||||
if (unlikely(ret))
|
||||
goto out;
|
||||
|
||||
if (unlikely(res_code != QLINK_CMD_RESULT_OK)) {
|
||||
ret = -ENODATA;
|
||||
goto out;
|
||||
}
|
||||
|
||||
resp = (const struct qlink_resp_channel_get *)resp_skb->data;
|
||||
qlink_chandef_q2cfg(priv_to_wiphy(vif->mac), &resp->chan, chdef);
|
||||
|
||||
out:
|
||||
consume_skb(resp_skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,8 @@ int qtnf_cmd_send_del_intf(struct qtnf_vif *vif);
|
||||
int qtnf_cmd_get_mac_chan_info(struct qtnf_wmac *mac,
|
||||
struct ieee80211_supported_band *band);
|
||||
int qtnf_cmd_send_regulatory_config(struct qtnf_wmac *mac, const char *alpha2);
|
||||
int qtnf_cmd_send_config_ap(struct qtnf_vif *vif);
|
||||
int qtnf_cmd_send_config_ap(struct qtnf_vif *vif,
|
||||
const struct cfg80211_ap_settings *s);
|
||||
int qtnf_cmd_send_start_ap(struct qtnf_vif *vif);
|
||||
int qtnf_cmd_send_stop_ap(struct qtnf_vif *vif);
|
||||
int qtnf_cmd_send_register_mgmt(struct qtnf_vif *vif, u16 frame_type, bool reg);
|
||||
@@ -73,7 +74,8 @@ int qtnf_cmd_send_updown_intf(struct qtnf_vif *vif,
|
||||
int qtnf_cmd_reg_notify(struct qtnf_bus *bus, struct regulatory_request *req);
|
||||
int qtnf_cmd_get_chan_stats(struct qtnf_wmac *mac, u16 channel,
|
||||
struct qtnf_chan_stats *stats);
|
||||
int qtnf_cmd_send_chan_switch(struct qtnf_wmac *mac,
|
||||
int qtnf_cmd_send_chan_switch(struct qtnf_vif *vif,
|
||||
struct cfg80211_csa_settings *params);
|
||||
int qtnf_cmd_get_channel(struct qtnf_vif *vif, struct cfg80211_chan_def *chdef);
|
||||
|
||||
#endif /* QLINK_COMMANDS_H_ */
|
||||
|
||||
@@ -52,27 +52,11 @@
|
||||
#define QTNF_DEF_WDOG_TIMEOUT 5
|
||||
#define QTNF_TX_TIMEOUT_TRSHLD 100
|
||||
|
||||
#define QTNF_STATE_AP_CONFIG BIT(2)
|
||||
#define QTNF_STATE_AP_START BIT(1)
|
||||
|
||||
extern const struct net_device_ops qtnf_netdev_ops;
|
||||
|
||||
struct qtnf_bus;
|
||||
struct qtnf_vif;
|
||||
|
||||
struct qtnf_bss_config {
|
||||
u8 ssid[IEEE80211_MAX_SSID_LEN];
|
||||
u8 bssid[ETH_ALEN];
|
||||
size_t ssid_len;
|
||||
u8 dtim;
|
||||
u16 bcn_period;
|
||||
u16 auth_type;
|
||||
bool privacy;
|
||||
enum nl80211_mfp mfp;
|
||||
struct cfg80211_crypto_settings crypto;
|
||||
u16 bg_scan_period;
|
||||
u32 connect_flags;
|
||||
};
|
||||
|
||||
struct qtnf_sta_node {
|
||||
struct list_head list;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
@@ -89,12 +73,10 @@ enum qtnf_sta_state {
|
||||
QTNF_STA_CONNECTED
|
||||
};
|
||||
|
||||
enum qtnf_mac_status {
|
||||
QTNF_MAC_CSA_ACTIVE = BIT(0)
|
||||
};
|
||||
|
||||
struct qtnf_vif {
|
||||
struct wireless_dev wdev;
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 vifid;
|
||||
u8 bss_priority;
|
||||
u8 bss_status;
|
||||
@@ -102,9 +84,8 @@ struct qtnf_vif {
|
||||
u16 mgmt_frames_bitmask;
|
||||
struct net_device *netdev;
|
||||
struct qtnf_wmac *mac;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
|
||||
struct work_struct reset_work;
|
||||
struct qtnf_bss_config bss_cfg;
|
||||
struct qtnf_sta_list sta_list;
|
||||
unsigned long cons_tx_timeout_cnt;
|
||||
};
|
||||
@@ -141,13 +122,10 @@ struct qtnf_wmac {
|
||||
u8 macid;
|
||||
u8 wiphy_registered;
|
||||
u8 macaddr[ETH_ALEN];
|
||||
u32 status;
|
||||
struct qtnf_bus *bus;
|
||||
struct qtnf_mac_info macinfo;
|
||||
struct qtnf_vif iflist[QTNF_MAX_INTF];
|
||||
struct cfg80211_scan_request *scan_req;
|
||||
struct cfg80211_chan_def chandef;
|
||||
struct cfg80211_chan_def csa_chandef;
|
||||
struct mutex mac_lock; /* lock during wmac speicific ops */
|
||||
struct timer_list scan_timeout;
|
||||
};
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "trans.h"
|
||||
#include "util.h"
|
||||
#include "event.h"
|
||||
#include "qlink_util.h"
|
||||
|
||||
static int
|
||||
qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif,
|
||||
@@ -52,12 +53,6 @@ qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif,
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
if (!(vif->bss_status & QTNF_STATE_AP_START)) {
|
||||
pr_err("VIF%u.%u: STA_ASSOC event when AP is not started\n",
|
||||
mac->macid, vif->vifid);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
sta_addr = sta_assoc->sta_addr;
|
||||
frame_control = le16_to_cpu(sta_assoc->frame_control);
|
||||
|
||||
@@ -126,12 +121,6 @@ qtnf_event_handle_sta_deauth(struct qtnf_wmac *mac, struct qtnf_vif *vif,
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
if (!(vif->bss_status & QTNF_STATE_AP_START)) {
|
||||
pr_err("VIF%u.%u: STA_DEAUTH event when AP is not started\n",
|
||||
mac->macid, vif->vifid);
|
||||
return -EPROTO;
|
||||
}
|
||||
|
||||
sta_addr = sta_deauth->sta_addr;
|
||||
reason = le16_to_cpu(sta_deauth->reason);
|
||||
|
||||
@@ -357,40 +346,29 @@ qtnf_event_handle_freq_change(struct qtnf_wmac *mac,
|
||||
{
|
||||
struct wiphy *wiphy = priv_to_wiphy(mac);
|
||||
struct cfg80211_chan_def chandef;
|
||||
struct ieee80211_channel *chan;
|
||||
struct qtnf_vif *vif;
|
||||
int freq;
|
||||
int i;
|
||||
|
||||
if (len < sizeof(*data)) {
|
||||
pr_err("payload is too short\n");
|
||||
pr_err("MAC%u: payload is too short\n", mac->macid);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
freq = le32_to_cpu(data->freq);
|
||||
chan = ieee80211_get_channel(wiphy, freq);
|
||||
if (!chan) {
|
||||
pr_err("channel at %d MHz not found\n", freq);
|
||||
if (!wiphy->registered)
|
||||
return 0;
|
||||
|
||||
qlink_chandef_q2cfg(wiphy, &data->chan, &chandef);
|
||||
|
||||
if (!cfg80211_chandef_valid(&chandef)) {
|
||||
pr_err("MAC%u: bad channel f1=%u f2=%u bw=%u\n", mac->macid,
|
||||
chandef.center_freq1, chandef.center_freq2,
|
||||
chandef.width);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
pr_debug("MAC%d switch to new channel %u MHz\n", mac->macid, freq);
|
||||
|
||||
if (mac->status & QTNF_MAC_CSA_ACTIVE) {
|
||||
mac->status &= ~QTNF_MAC_CSA_ACTIVE;
|
||||
if (chan->hw_value != mac->csa_chandef.chan->hw_value)
|
||||
pr_warn("unexpected switch to %u during CSA to %u\n",
|
||||
chan->hw_value,
|
||||
mac->csa_chandef.chan->hw_value);
|
||||
}
|
||||
|
||||
/* FIXME: need to figure out proper nl80211_channel_type value */
|
||||
cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20);
|
||||
/* fall-back to minimal safe chandef description */
|
||||
if (!cfg80211_chandef_valid(&chandef))
|
||||
cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20);
|
||||
|
||||
memcpy(&mac->chandef, &chandef, sizeof(mac->chandef));
|
||||
pr_debug("MAC%d: new channel ieee=%u freq1=%u freq2=%u bw=%u\n",
|
||||
mac->macid, chandef.chan->hw_value, chandef.center_freq1,
|
||||
chandef.center_freq2, chandef.width);
|
||||
|
||||
for (i = 0; i < QTNF_MAX_INTF; i++) {
|
||||
vif = &mac->iflist[i];
|
||||
|
||||
@@ -108,16 +108,48 @@ enum qlink_sta_flags {
|
||||
};
|
||||
|
||||
enum qlink_channel_width {
|
||||
QLINK_CHAN_WIDTH_5 = BIT(0),
|
||||
QLINK_CHAN_WIDTH_10 = BIT(1),
|
||||
QLINK_CHAN_WIDTH_20_NOHT = BIT(2),
|
||||
QLINK_CHAN_WIDTH_20 = BIT(3),
|
||||
QLINK_CHAN_WIDTH_40 = BIT(4),
|
||||
QLINK_CHAN_WIDTH_80 = BIT(5),
|
||||
QLINK_CHAN_WIDTH_80P80 = BIT(6),
|
||||
QLINK_CHAN_WIDTH_160 = BIT(7),
|
||||
QLINK_CHAN_WIDTH_5 = 0,
|
||||
QLINK_CHAN_WIDTH_10,
|
||||
QLINK_CHAN_WIDTH_20_NOHT,
|
||||
QLINK_CHAN_WIDTH_20,
|
||||
QLINK_CHAN_WIDTH_40,
|
||||
QLINK_CHAN_WIDTH_80,
|
||||
QLINK_CHAN_WIDTH_80P80,
|
||||
QLINK_CHAN_WIDTH_160,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct qlink_chandef - qlink channel definition
|
||||
*
|
||||
* @center_freq1: center frequency of first segment
|
||||
* @center_freq2: center frequency of second segment (80+80 only)
|
||||
* @width: channel width, one of @enum qlink_channel_width
|
||||
*/
|
||||
struct qlink_chandef {
|
||||
__le16 center_freq1;
|
||||
__le16 center_freq2;
|
||||
u8 width;
|
||||
u8 rsvd[3];
|
||||
} __packed;
|
||||
|
||||
#define QLINK_MAX_NR_CIPHER_SUITES 5
|
||||
#define QLINK_MAX_NR_AKM_SUITES 2
|
||||
|
||||
struct qlink_auth_encr {
|
||||
__le32 wpa_versions;
|
||||
__le32 cipher_group;
|
||||
__le32 n_ciphers_pairwise;
|
||||
__le32 ciphers_pairwise[QLINK_MAX_NR_CIPHER_SUITES];
|
||||
__le32 n_akm_suites;
|
||||
__le32 akm_suites[QLINK_MAX_NR_AKM_SUITES];
|
||||
__le16 control_port_ethertype;
|
||||
u8 auth_type;
|
||||
u8 privacy;
|
||||
u8 mfp;
|
||||
u8 control_port;
|
||||
u8 control_port_no_encrypt;
|
||||
} __packed;
|
||||
|
||||
/* QLINK Command messages related definitions
|
||||
*/
|
||||
|
||||
@@ -155,6 +187,7 @@ enum qlink_cmd_type {
|
||||
QLINK_CMD_REG_NOTIFY = 0x0019,
|
||||
QLINK_CMD_CHANS_INFO_GET = 0x001A,
|
||||
QLINK_CMD_CHAN_SWITCH = 0x001B,
|
||||
QLINK_CMD_CHAN_GET = 0x001C,
|
||||
QLINK_CMD_CONFIG_AP = 0x0020,
|
||||
QLINK_CMD_START_AP = 0x0021,
|
||||
QLINK_CMD_STOP_AP = 0x0022,
|
||||
@@ -384,8 +417,9 @@ enum qlink_sta_connect_flags {
|
||||
* struct qlink_cmd_connect - data for QLINK_CMD_CONNECT command
|
||||
*
|
||||
* @flags: for future use.
|
||||
* @freq: center frequence of a channel which should be used to connect.
|
||||
* @channel: channel which should be used to connect.
|
||||
* @bg_scan_period: period of background scan.
|
||||
* @aen: authentication information.
|
||||
* @bssid: BSSID of the BSS to connect to.
|
||||
* @payload: variable portion of connection request.
|
||||
*/
|
||||
@@ -394,6 +428,7 @@ struct qlink_cmd_connect {
|
||||
__le32 flags;
|
||||
__le16 channel;
|
||||
__le16 bg_scan_period;
|
||||
struct qlink_auth_encr aen;
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 payload[0];
|
||||
} __packed;
|
||||
@@ -506,6 +541,46 @@ struct qlink_cmd_chan_switch {
|
||||
u8 beacon_count;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* enum qlink_hidden_ssid - values for %NL80211_ATTR_HIDDEN_SSID
|
||||
*
|
||||
* Refer to &enum nl80211_hidden_ssid
|
||||
*/
|
||||
enum qlink_hidden_ssid {
|
||||
QLINK_HIDDEN_SSID_NOT_IN_USE,
|
||||
QLINK_HIDDEN_SSID_ZERO_LEN,
|
||||
QLINK_HIDDEN_SSID_ZERO_CONTENTS
|
||||
};
|
||||
|
||||
/**
|
||||
* struct qlink_cmd_config_ap - data for QLINK_CMD_CONFIG_AP command
|
||||
*
|
||||
* @beacon_interval: beacon interval
|
||||
* @inactivity_timeout: station's inactivity period in seconds
|
||||
* @dtim_period: DTIM period
|
||||
* @hidden_ssid: whether to hide the SSID, one of &enum qlink_hidden_ssid
|
||||
* @smps_mode: SMPS mode
|
||||
* @ht_required: stations must support HT
|
||||
* @vht_required: stations must support VHT
|
||||
* @aen: encryption info
|
||||
* @info: variable configurations
|
||||
*/
|
||||
struct qlink_cmd_config_ap {
|
||||
struct qlink_cmd chdr;
|
||||
__le16 beacon_interval;
|
||||
__le16 inactivity_timeout;
|
||||
u8 dtim_period;
|
||||
u8 hidden_ssid;
|
||||
u8 smps_mode;
|
||||
u8 p2p_ctwindow;
|
||||
u8 p2p_opp_ps;
|
||||
u8 pbss;
|
||||
u8 ht_required;
|
||||
u8 vht_required;
|
||||
struct qlink_auth_encr aen;
|
||||
u8 info[0];
|
||||
} __packed;
|
||||
|
||||
/* QLINK Command Responses messages related definitions
|
||||
*/
|
||||
|
||||
@@ -680,6 +755,16 @@ struct qlink_resp_get_chan_stats {
|
||||
u8 info[0];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct qlink_resp_channel_get - response for QLINK_CMD_CHAN_GET command
|
||||
*
|
||||
* @chan: definition of current operating channel.
|
||||
*/
|
||||
struct qlink_resp_channel_get {
|
||||
struct qlink_resp rhdr;
|
||||
struct qlink_chandef chan;
|
||||
} __packed;
|
||||
|
||||
/* QLINK Events messages related definitions
|
||||
*/
|
||||
|
||||
@@ -764,11 +849,11 @@ struct qlink_event_bss_leave {
|
||||
/**
|
||||
* struct qlink_event_freq_change - data for QLINK_EVENT_FREQ_CHANGE event
|
||||
*
|
||||
* @freq: new operating frequency in MHz
|
||||
* @chan: new operating channel definition
|
||||
*/
|
||||
struct qlink_event_freq_change {
|
||||
struct qlink_event ehdr;
|
||||
__le32 freq;
|
||||
struct qlink_chandef chan;
|
||||
} __packed;
|
||||
|
||||
enum qlink_rxmgmt_flags {
|
||||
@@ -856,10 +941,9 @@ enum qlink_tlv_id {
|
||||
QTN_TLV_ID_RTS_THRESH = 0x0202,
|
||||
QTN_TLV_ID_SRETRY_LIMIT = 0x0203,
|
||||
QTN_TLV_ID_LRETRY_LIMIT = 0x0204,
|
||||
QTN_TLV_ID_BCN_PERIOD = 0x0205,
|
||||
QTN_TLV_ID_DTIM = 0x0206,
|
||||
QTN_TLV_ID_REG_RULE = 0x0207,
|
||||
QTN_TLV_ID_CHANNEL = 0x020F,
|
||||
QTN_TLV_ID_CHANDEF = 0x0210,
|
||||
QTN_TLV_ID_COVERAGE_CLASS = 0x0213,
|
||||
QTN_TLV_ID_IFACE_LIMIT = 0x0214,
|
||||
QTN_TLV_ID_NUM_IFACE_COMB = 0x0215,
|
||||
@@ -868,7 +952,6 @@ enum qlink_tlv_id {
|
||||
QTN_TLV_ID_STA_GENERIC_INFO = 0x0301,
|
||||
QTN_TLV_ID_KEY = 0x0302,
|
||||
QTN_TLV_ID_SEQ = 0x0303,
|
||||
QTN_TLV_ID_CRYPTO = 0x0304,
|
||||
QTN_TLV_ID_IE_SET = 0x0305,
|
||||
};
|
||||
|
||||
@@ -1047,22 +1130,16 @@ struct qlink_tlv_channel {
|
||||
u8 rsvd[2];
|
||||
} __packed;
|
||||
|
||||
#define QLINK_MAX_NR_CIPHER_SUITES 5
|
||||
#define QLINK_MAX_NR_AKM_SUITES 2
|
||||
|
||||
struct qlink_auth_encr {
|
||||
__le32 wpa_versions;
|
||||
__le32 cipher_group;
|
||||
__le32 n_ciphers_pairwise;
|
||||
__le32 ciphers_pairwise[QLINK_MAX_NR_CIPHER_SUITES];
|
||||
__le32 n_akm_suites;
|
||||
__le32 akm_suites[QLINK_MAX_NR_AKM_SUITES];
|
||||
__le16 control_port_ethertype;
|
||||
u8 auth_type;
|
||||
u8 privacy;
|
||||
u8 mfp;
|
||||
u8 control_port;
|
||||
u8 control_port_no_encrypt;
|
||||
/**
|
||||
* struct qlink_tlv_chandef - data for QTN_TLV_ID_CHANDEF TLV
|
||||
*
|
||||
* Channel definition.
|
||||
*
|
||||
* @chan: channel definition data.
|
||||
*/
|
||||
struct qlink_tlv_chandef {
|
||||
struct qlink_tlv_hdr hdr;
|
||||
struct qlink_chandef chan;
|
||||
} __packed;
|
||||
|
||||
struct qlink_chan_stats {
|
||||
|
||||
@@ -49,29 +49,126 @@ u8 qlink_chan_width_mask_to_nl(u16 qlink_mask)
|
||||
{
|
||||
u8 result = 0;
|
||||
|
||||
if (qlink_mask & QLINK_CHAN_WIDTH_5)
|
||||
if (qlink_mask & BIT(QLINK_CHAN_WIDTH_5))
|
||||
result |= BIT(NL80211_CHAN_WIDTH_5);
|
||||
|
||||
if (qlink_mask & QLINK_CHAN_WIDTH_10)
|
||||
if (qlink_mask & BIT(QLINK_CHAN_WIDTH_10))
|
||||
result |= BIT(NL80211_CHAN_WIDTH_10);
|
||||
|
||||
if (qlink_mask & QLINK_CHAN_WIDTH_20_NOHT)
|
||||
if (qlink_mask & BIT(QLINK_CHAN_WIDTH_20_NOHT))
|
||||
result |= BIT(NL80211_CHAN_WIDTH_20_NOHT);
|
||||
|
||||
if (qlink_mask & QLINK_CHAN_WIDTH_20)
|
||||
if (qlink_mask & BIT(QLINK_CHAN_WIDTH_20))
|
||||
result |= BIT(NL80211_CHAN_WIDTH_20);
|
||||
|
||||
if (qlink_mask & QLINK_CHAN_WIDTH_40)
|
||||
if (qlink_mask & BIT(QLINK_CHAN_WIDTH_40))
|
||||
result |= BIT(NL80211_CHAN_WIDTH_40);
|
||||
|
||||
if (qlink_mask & QLINK_CHAN_WIDTH_80)
|
||||
if (qlink_mask & BIT(QLINK_CHAN_WIDTH_80))
|
||||
result |= BIT(NL80211_CHAN_WIDTH_80);
|
||||
|
||||
if (qlink_mask & QLINK_CHAN_WIDTH_80P80)
|
||||
if (qlink_mask & BIT(QLINK_CHAN_WIDTH_80P80))
|
||||
result |= BIT(NL80211_CHAN_WIDTH_80P80);
|
||||
|
||||
if (qlink_mask & QLINK_CHAN_WIDTH_160)
|
||||
if (qlink_mask & BIT(QLINK_CHAN_WIDTH_160))
|
||||
result |= BIT(NL80211_CHAN_WIDTH_160);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static enum nl80211_chan_width qlink_chanwidth_to_nl(u8 qlw)
|
||||
{
|
||||
switch (qlw) {
|
||||
case QLINK_CHAN_WIDTH_20_NOHT:
|
||||
return NL80211_CHAN_WIDTH_20_NOHT;
|
||||
case QLINK_CHAN_WIDTH_20:
|
||||
return NL80211_CHAN_WIDTH_20;
|
||||
case QLINK_CHAN_WIDTH_40:
|
||||
return NL80211_CHAN_WIDTH_40;
|
||||
case QLINK_CHAN_WIDTH_80:
|
||||
return NL80211_CHAN_WIDTH_80;
|
||||
case QLINK_CHAN_WIDTH_80P80:
|
||||
return NL80211_CHAN_WIDTH_80P80;
|
||||
case QLINK_CHAN_WIDTH_160:
|
||||
return NL80211_CHAN_WIDTH_160;
|
||||
case QLINK_CHAN_WIDTH_5:
|
||||
return NL80211_CHAN_WIDTH_5;
|
||||
case QLINK_CHAN_WIDTH_10:
|
||||
return NL80211_CHAN_WIDTH_10;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void qlink_chandef_q2cfg(struct wiphy *wiphy,
|
||||
const struct qlink_chandef *qch,
|
||||
struct cfg80211_chan_def *chdef)
|
||||
{
|
||||
chdef->center_freq1 = le16_to_cpu(qch->center_freq1);
|
||||
chdef->center_freq2 = le16_to_cpu(qch->center_freq2);
|
||||
chdef->width = qlink_chanwidth_to_nl(qch->width);
|
||||
|
||||
switch (chdef->width) {
|
||||
case NL80211_CHAN_WIDTH_20_NOHT:
|
||||
case NL80211_CHAN_WIDTH_20:
|
||||
case NL80211_CHAN_WIDTH_5:
|
||||
case NL80211_CHAN_WIDTH_10:
|
||||
chdef->chan = ieee80211_get_channel(wiphy, chdef->center_freq1);
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
case NL80211_CHAN_WIDTH_80:
|
||||
case NL80211_CHAN_WIDTH_80P80:
|
||||
case NL80211_CHAN_WIDTH_160:
|
||||
chdef->chan = ieee80211_get_channel(wiphy,
|
||||
chdef->center_freq1 - 10);
|
||||
break;
|
||||
default:
|
||||
chdef->chan = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static u8 qlink_chanwidth_nl_to_qlink(enum nl80211_chan_width nlwidth)
|
||||
{
|
||||
switch (nlwidth) {
|
||||
case NL80211_CHAN_WIDTH_20_NOHT:
|
||||
return QLINK_CHAN_WIDTH_20_NOHT;
|
||||
case NL80211_CHAN_WIDTH_20:
|
||||
return QLINK_CHAN_WIDTH_20;
|
||||
case NL80211_CHAN_WIDTH_40:
|
||||
return QLINK_CHAN_WIDTH_40;
|
||||
case NL80211_CHAN_WIDTH_80:
|
||||
return QLINK_CHAN_WIDTH_80;
|
||||
case NL80211_CHAN_WIDTH_80P80:
|
||||
return QLINK_CHAN_WIDTH_80P80;
|
||||
case NL80211_CHAN_WIDTH_160:
|
||||
return QLINK_CHAN_WIDTH_160;
|
||||
case NL80211_CHAN_WIDTH_5:
|
||||
return QLINK_CHAN_WIDTH_5;
|
||||
case NL80211_CHAN_WIDTH_10:
|
||||
return QLINK_CHAN_WIDTH_10;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void qlink_chandef_cfg2q(const struct cfg80211_chan_def *chdef,
|
||||
struct qlink_chandef *qch)
|
||||
{
|
||||
qch->center_freq1 = cpu_to_le16(chdef->center_freq1);
|
||||
qch->center_freq2 = cpu_to_le16(chdef->center_freq2);
|
||||
qch->width = qlink_chanwidth_nl_to_qlink(chdef->width);
|
||||
}
|
||||
|
||||
enum qlink_hidden_ssid qlink_hidden_ssid_nl2q(enum nl80211_hidden_ssid nl_val)
|
||||
{
|
||||
switch (nl_val) {
|
||||
case NL80211_HIDDEN_SSID_ZERO_LEN:
|
||||
return QLINK_HIDDEN_SSID_ZERO_LEN;
|
||||
case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
|
||||
return QLINK_HIDDEN_SSID_ZERO_CONTENTS;
|
||||
case NL80211_HIDDEN_SSID_NOT_IN_USE:
|
||||
default:
|
||||
return QLINK_HIDDEN_SSID_NOT_IN_USE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <net/cfg80211.h>
|
||||
|
||||
#include "qlink.h"
|
||||
|
||||
@@ -62,5 +63,11 @@ static inline void qtnf_cmd_skb_put_tlv_u16(struct sk_buff *skb,
|
||||
|
||||
u16 qlink_iface_type_to_nl_mask(u16 qlink_type);
|
||||
u8 qlink_chan_width_mask_to_nl(u16 qlink_mask);
|
||||
void qlink_chandef_q2cfg(struct wiphy *wiphy,
|
||||
const struct qlink_chandef *qch,
|
||||
struct cfg80211_chan_def *chdef);
|
||||
void qlink_chandef_cfg2q(const struct cfg80211_chan_def *chdef,
|
||||
struct qlink_chandef *qch);
|
||||
enum qlink_hidden_ssid qlink_hidden_ssid_nl2q(enum nl80211_hidden_ssid nl_val);
|
||||
|
||||
#endif /* _QTN_FMAC_QLINK_UTIL_H_ */
|
||||
|
||||
@@ -614,7 +614,10 @@ static int rtl8192eu_parse_efuse(struct rtl8xxxu_priv *priv)
|
||||
|
||||
dev_info(&priv->udev->dev, "Vendor: %.7s\n", efuse->vendor_name);
|
||||
dev_info(&priv->udev->dev, "Product: %.11s\n", efuse->device_name);
|
||||
dev_info(&priv->udev->dev, "Serial: %.11s\n", efuse->serial);
|
||||
if (memchr_inv(efuse->serial, 0xff, 11))
|
||||
dev_info(&priv->udev->dev, "Serial: %.11s\n", efuse->serial);
|
||||
else
|
||||
dev_info(&priv->udev->dev, "Serial not available.\n");
|
||||
|
||||
if (rtl8xxxu_debug & RTL8XXXU_DEBUG_EFUSE) {
|
||||
unsigned char *raw = priv->efuse_wifi.raw;
|
||||
|
||||
@@ -249,8 +249,6 @@ static void _rtl_init_hw_vht_capab(struct ieee80211_hw *hw,
|
||||
|
||||
vht_cap->vht_supported = true;
|
||||
vht_cap->cap =
|
||||
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 |
|
||||
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 |
|
||||
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
|
||||
IEEE80211_VHT_CAP_SHORT_GI_80 |
|
||||
IEEE80211_VHT_CAP_TXSTBC |
|
||||
@@ -283,8 +281,6 @@ static void _rtl_init_hw_vht_capab(struct ieee80211_hw *hw,
|
||||
|
||||
vht_cap->vht_supported = true;
|
||||
vht_cap->cap =
|
||||
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 |
|
||||
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 |
|
||||
IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 |
|
||||
IEEE80211_VHT_CAP_SHORT_GI_80 |
|
||||
IEEE80211_VHT_CAP_TXSTBC |
|
||||
@@ -835,7 +831,7 @@ static u8 _rtl_get_vht_highest_n_rate(struct ieee80211_hw *hw,
|
||||
else if ((tx_mcs_map & 0x000c) >> 2 ==
|
||||
IEEE80211_VHT_MCS_SUPPORT_0_8)
|
||||
hw_rate =
|
||||
rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS9];
|
||||
rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS8];
|
||||
else
|
||||
hw_rate =
|
||||
rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS9];
|
||||
@@ -847,7 +843,7 @@ static u8 _rtl_get_vht_highest_n_rate(struct ieee80211_hw *hw,
|
||||
else if ((tx_mcs_map & 0x0003) ==
|
||||
IEEE80211_VHT_MCS_SUPPORT_0_8)
|
||||
hw_rate =
|
||||
rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS9];
|
||||
rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS8];
|
||||
else
|
||||
hw_rate =
|
||||
rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS9];
|
||||
@@ -1103,6 +1099,42 @@ int rtlwifi_rate_mapping(struct ieee80211_hw *hw, bool isht, bool isvht,
|
||||
}
|
||||
EXPORT_SYMBOL(rtlwifi_rate_mapping);
|
||||
|
||||
static u8 _rtl_get_tx_hw_rate(struct ieee80211_hw *hw,
|
||||
struct ieee80211_tx_info *info)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct ieee80211_tx_rate *r = &info->status.rates[0];
|
||||
struct ieee80211_rate *txrate;
|
||||
u8 hw_value = 0x0;
|
||||
|
||||
if (r->flags & IEEE80211_TX_RC_MCS) {
|
||||
/* HT MCS0-15 */
|
||||
hw_value = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15] - 15 +
|
||||
r->idx;
|
||||
} else if (r->flags & IEEE80211_TX_RC_VHT_MCS) {
|
||||
/* VHT MCS0-9, NSS */
|
||||
if (ieee80211_rate_get_vht_nss(r) == 2)
|
||||
hw_value = rtlpriv->cfg->maps[RTL_RC_VHT_RATE_2SS_MCS9];
|
||||
else
|
||||
hw_value = rtlpriv->cfg->maps[RTL_RC_VHT_RATE_1SS_MCS9];
|
||||
|
||||
hw_value = hw_value - 9 + ieee80211_rate_get_vht_mcs(r);
|
||||
} else {
|
||||
/* legacy */
|
||||
txrate = ieee80211_get_tx_rate(hw, info);
|
||||
|
||||
if (txrate)
|
||||
hw_value = txrate->hw_value;
|
||||
}
|
||||
|
||||
/* check 5G band */
|
||||
if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G &&
|
||||
hw_value < rtlpriv->cfg->maps[RTL_RC_OFDM_RATE6M])
|
||||
hw_value = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE6M];
|
||||
|
||||
return hw_value;
|
||||
}
|
||||
|
||||
void rtl_get_tcb_desc(struct ieee80211_hw *hw,
|
||||
struct ieee80211_tx_info *info,
|
||||
struct ieee80211_sta *sta,
|
||||
@@ -1111,12 +1143,10 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw,
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
|
||||
struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
|
||||
struct ieee80211_rate *txrate;
|
||||
|
||||
__le16 fc = rtl_get_fc(skb);
|
||||
|
||||
txrate = ieee80211_get_tx_rate(hw, info);
|
||||
if (txrate)
|
||||
tcb_desc->hw_rate = txrate->hw_value;
|
||||
tcb_desc->hw_rate = _rtl_get_tx_hw_rate(hw, info);
|
||||
|
||||
if (rtl_is_tx_report_skb(hw, skb))
|
||||
tcb_desc->use_spe_rpt = 1;
|
||||
@@ -1527,6 +1557,42 @@ void rtl_wait_tx_report_acked(struct ieee80211_hw *hw, u32 wait_ms)
|
||||
"Wait 1ms (%d/%d) to disable key.\n", i, wait_ms);
|
||||
}
|
||||
}
|
||||
|
||||
u32 rtl_get_hal_edca_param(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum wireless_mode wirelessmode,
|
||||
struct ieee80211_tx_queue_params *param)
|
||||
{
|
||||
u32 reg = 0;
|
||||
u8 sifstime = 10;
|
||||
u8 slottime = 20;
|
||||
|
||||
/* AIFS = AIFSN * slot time + SIFS */
|
||||
switch (wirelessmode) {
|
||||
case WIRELESS_MODE_A:
|
||||
case WIRELESS_MODE_N_24G:
|
||||
case WIRELESS_MODE_N_5G:
|
||||
case WIRELESS_MODE_AC_5G:
|
||||
case WIRELESS_MODE_AC_24G:
|
||||
sifstime = 16;
|
||||
slottime = 9;
|
||||
break;
|
||||
case WIRELESS_MODE_G:
|
||||
slottime = (vif->bss_conf.use_short_slot ? 9 : 20);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
reg |= (param->txop & 0x7FF) << 16;
|
||||
reg |= (fls(param->cw_max) & 0xF) << 12;
|
||||
reg |= (fls(param->cw_min) & 0xF) << 8;
|
||||
reg |= (param->aifs & 0x0F) * slottime + sifstime;
|
||||
|
||||
return reg;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rtl_get_hal_edca_param);
|
||||
|
||||
/*********************************************************
|
||||
*
|
||||
* functions called by core.c
|
||||
@@ -1932,6 +1998,22 @@ void rtl_watchdog_wq_callback(void *data)
|
||||
rtlpriv->link_info.tx_busy_traffic = tx_busy_traffic;
|
||||
rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic;
|
||||
|
||||
rtlpriv->stats.txbytesunicast_inperiod =
|
||||
rtlpriv->stats.txbytesunicast -
|
||||
rtlpriv->stats.txbytesunicast_last;
|
||||
rtlpriv->stats.rxbytesunicast_inperiod =
|
||||
rtlpriv->stats.rxbytesunicast -
|
||||
rtlpriv->stats.rxbytesunicast_last;
|
||||
rtlpriv->stats.txbytesunicast_last = rtlpriv->stats.txbytesunicast;
|
||||
rtlpriv->stats.rxbytesunicast_last = rtlpriv->stats.rxbytesunicast;
|
||||
|
||||
rtlpriv->stats.txbytesunicast_inperiod_tp =
|
||||
(u32)(rtlpriv->stats.txbytesunicast_inperiod * 8 / 2 /
|
||||
1024 / 1024);
|
||||
rtlpriv->stats.rxbytesunicast_inperiod_tp =
|
||||
(u32)(rtlpriv->stats.rxbytesunicast_inperiod * 8 / 2 /
|
||||
1024 / 1024);
|
||||
|
||||
/* <3> DM */
|
||||
if (!rtlpriv->cfg->mod_params->disable_watchdog)
|
||||
rtlpriv->cfg->ops->dm_watchdog(hw);
|
||||
@@ -2204,7 +2286,7 @@ int rtl_send_smps_action(struct ieee80211_hw *hw,
|
||||
struct rtl_sta_info *sta_entry =
|
||||
(struct rtl_sta_info *) sta->drv_priv;
|
||||
sta_entry->mimo_ps = smps;
|
||||
/* rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); */
|
||||
/* rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0, true); */
|
||||
|
||||
info->control.rates[0].idx = 0;
|
||||
info->band = hw->conf.chandef.chan->band;
|
||||
|
||||
@@ -137,6 +137,10 @@ void rtl_tx_report_handler(struct ieee80211_hw *hw, u8 *tmp_buf,
|
||||
u8 c2h_cmd_len);
|
||||
bool rtl_check_tx_report_acked(struct ieee80211_hw *hw);
|
||||
void rtl_wait_tx_report_acked(struct ieee80211_hw *hw, u32 wait_ms);
|
||||
u32 rtl_get_hal_edca_param(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
enum wireless_mode wirelessmode,
|
||||
struct ieee80211_tx_queue_params *param);
|
||||
|
||||
void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||
void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||
|
||||
@@ -2260,14 +2260,11 @@ static void halbtc8723b1ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
|
||||
|
||||
if (iot_peer != BTC_IOT_PEER_CISCO &&
|
||||
iot_peer != BTC_IOT_PEER_BROADCOM) {
|
||||
if (bt_link_info->sco_exist)
|
||||
halbtc8723b1ant_limited_rx(btcoexist,
|
||||
NORMAL_EXEC, false,
|
||||
false, 0x5);
|
||||
else
|
||||
halbtc8723b1ant_limited_rx(btcoexist,
|
||||
NORMAL_EXEC, false,
|
||||
false, 0x5);
|
||||
bool sco_exist = bt_link_info->sco_exist;
|
||||
|
||||
halbtc8723b1ant_limited_rx(btcoexist,
|
||||
NORMAL_EXEC, sco_exist,
|
||||
false, 0x5);
|
||||
} else {
|
||||
if (bt_link_info->sco_exist) {
|
||||
halbtc8723b1ant_limited_rx(btcoexist,
|
||||
|
||||
@@ -453,7 +453,8 @@ static void _rtl_add_wowlan_patterns(struct ieee80211_hw *hw,
|
||||
for (i = 0; i < wow->n_patterns; i++) {
|
||||
memset(&rtl_pattern, 0, sizeof(struct rtl_wow_pattern));
|
||||
memset(mask, 0, MAX_WOL_BIT_MASK_SIZE);
|
||||
if (patterns[i].pattern_len > MAX_WOL_PATTERN_SIZE) {
|
||||
if (patterns[i].pattern_len < 0 ||
|
||||
patterns[i].pattern_len > MAX_WOL_PATTERN_SIZE) {
|
||||
RT_TRACE(rtlpriv, COMP_POWER, DBG_WARNING,
|
||||
"Pattern[%d] is too long\n", i);
|
||||
continue;
|
||||
@@ -945,7 +946,7 @@ static int rtl_op_sta_add(struct ieee80211_hw *hw,
|
||||
memcpy(sta_entry->mac_addr, sta->addr, ETH_ALEN);
|
||||
RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
|
||||
"Add sta addr is %pM\n", sta->addr);
|
||||
rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
|
||||
rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1151,7 +1152,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION)
|
||||
rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
|
||||
rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0,
|
||||
true);
|
||||
rcu_read_unlock();
|
||||
|
||||
/* to avoid AP Disassociation caused by inactivity */
|
||||
|
||||
@@ -586,7 +586,7 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
|
||||
skb = __skb_dequeue(&ring->queue);
|
||||
pci_unmap_single(rtlpci->pdev,
|
||||
rtlpriv->cfg->ops->
|
||||
get_desc((u8 *)entry, true,
|
||||
get_desc(hw, (u8 *)entry, true,
|
||||
HW_DESC_TXBUFF_ADDR),
|
||||
skb->len, PCI_DMA_TODEVICE);
|
||||
|
||||
@@ -691,9 +691,10 @@ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
|
||||
return 0;
|
||||
rtlpci->rx_ring[rxring_idx].rx_buf[desc_idx] = skb;
|
||||
if (rtlpriv->use_new_trx_flow) {
|
||||
/* skb->cb may be 64 bit address */
|
||||
rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
|
||||
HW_DESC_RX_PREPARE,
|
||||
(u8 *)&bufferaddress);
|
||||
(u8 *)(dma_addr_t *)skb->cb);
|
||||
} else {
|
||||
rtlpriv->cfg->ops->set_desc(hw, (u8 *)entry, false,
|
||||
HW_DESC_RXBUFF_ADDR,
|
||||
@@ -798,7 +799,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
|
||||
pdesc = &rtlpci->rx_ring[rxring_idx].desc[
|
||||
rtlpci->rx_ring[rxring_idx].idx];
|
||||
|
||||
own = (u8)rtlpriv->cfg->ops->get_desc((u8 *)pdesc,
|
||||
own = (u8)rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc,
|
||||
false,
|
||||
HW_DESC_OWN);
|
||||
if (own) /* wait data to be filled by hardware */
|
||||
@@ -825,7 +826,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw)
|
||||
(u8 *)buffer_desc,
|
||||
hw_queue);
|
||||
|
||||
len = rtlpriv->cfg->ops->get_desc((u8 *)pdesc, false,
|
||||
len = rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc, false,
|
||||
HW_DESC_RXPKT_LEN);
|
||||
|
||||
if (skb->end - skb->tail > len) {
|
||||
@@ -1122,7 +1123,7 @@ static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
|
||||
if (pskb) {
|
||||
pci_unmap_single(rtlpci->pdev,
|
||||
rtlpriv->cfg->ops->get_desc(
|
||||
(u8 *)entry, true, HW_DESC_TXBUFF_ADDR),
|
||||
hw, (u8 *)entry, true, HW_DESC_TXBUFF_ADDR),
|
||||
pskb->len, PCI_DMA_TODEVICE);
|
||||
kfree_skb(pskb);
|
||||
}
|
||||
@@ -1378,7 +1379,8 @@ static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw,
|
||||
|
||||
pci_unmap_single(rtlpci->pdev,
|
||||
rtlpriv->cfg->
|
||||
ops->get_desc((u8 *)entry, true,
|
||||
ops->get_desc(hw, (u8 *)entry,
|
||||
true,
|
||||
HW_DESC_TXBUFF_ADDR),
|
||||
skb->len, PCI_DMA_TODEVICE);
|
||||
kfree_skb(skb);
|
||||
@@ -1507,7 +1509,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
|
||||
for (i = 0; i < rtlpci->rxringcount; i++) {
|
||||
entry = &rtlpci->rx_ring[rxring_idx].desc[i];
|
||||
bufferaddress =
|
||||
rtlpriv->cfg->ops->get_desc((u8 *)entry,
|
||||
rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry,
|
||||
false , HW_DESC_RXBUFF_ADDR);
|
||||
memset((u8 *)entry , 0 ,
|
||||
sizeof(*rtlpci->rx_ring
|
||||
@@ -1560,7 +1562,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
|
||||
|
||||
pci_unmap_single(rtlpci->pdev,
|
||||
rtlpriv->cfg->ops->
|
||||
get_desc((u8 *)
|
||||
get_desc(hw, (u8 *)
|
||||
entry,
|
||||
true,
|
||||
HW_DESC_TXBUFF_ADDR),
|
||||
@@ -1673,7 +1675,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw,
|
||||
if (rtlpriv->use_new_trx_flow) {
|
||||
ptx_bd_desc = &ring->buffer_desc[idx];
|
||||
} else {
|
||||
own = (u8) rtlpriv->cfg->ops->get_desc((u8 *)pdesc,
|
||||
own = (u8)rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc,
|
||||
true, HW_DESC_OWN);
|
||||
|
||||
if ((own == 1) && (hw_queue != BEACON_QUEUE)) {
|
||||
@@ -2163,6 +2165,21 @@ static int rtl_pci_intr_mode_decide(struct ieee80211_hw *hw)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void platform_enable_dma64(struct pci_dev *pdev, bool dma64)
|
||||
{
|
||||
u8 value;
|
||||
|
||||
pci_read_config_byte(pdev, 0x719, &value);
|
||||
|
||||
/* 0x719 Bit5 is DMA64 bit fetch. */
|
||||
if (dma64)
|
||||
value |= BIT(5);
|
||||
else
|
||||
value &= ~BIT(5);
|
||||
|
||||
pci_write_config_byte(pdev, 0x719, value);
|
||||
}
|
||||
|
||||
int rtl_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
@@ -2181,13 +2198,25 @@ int rtl_pci_probe(struct pci_dev *pdev,
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
|
||||
if (((struct rtl_hal_cfg *)id->driver_data)->mod_params->dma64 &&
|
||||
!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
|
||||
if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
|
||||
WARN_ONCE(true,
|
||||
"Unable to obtain 64bit DMA for consistent allocations\n");
|
||||
err = -ENOMEM;
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
platform_enable_dma64(pdev, true);
|
||||
} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
|
||||
if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
|
||||
WARN_ONCE(true,
|
||||
"rtlwifi: Unable to obtain 32bit DMA for consistent allocations\n");
|
||||
err = -ENOMEM;
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
platform_enable_dma64(pdev, false);
|
||||
}
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
@@ -143,13 +143,7 @@ struct rtl_pci_capabilities_header {
|
||||
* RX wifi info == RX descriptor in old flow
|
||||
*/
|
||||
struct rtl_tx_buffer_desc {
|
||||
#if (RTL8192EE_SEG_NUM == 2)
|
||||
u32 dword[2*(DMA_IS_64BIT + 1)*8]; /*seg = 8*/
|
||||
#elif (RTL8192EE_SEG_NUM == 1)
|
||||
u32 dword[2*(DMA_IS_64BIT + 1)*4]; /*seg = 4*/
|
||||
#elif (RTL8192EE_SEG_NUM == 0)
|
||||
u32 dword[2*(DMA_IS_64BIT + 1)*2]; /*seg = 2*/
|
||||
#endif
|
||||
u32 dword[4 * (1 << (BUFDESC_SEG_NUM + 1))];
|
||||
} __packed;
|
||||
|
||||
struct rtl_tx_desc {
|
||||
@@ -157,7 +151,7 @@ struct rtl_tx_desc {
|
||||
} __packed;
|
||||
|
||||
struct rtl_rx_buffer_desc { /*rx buffer desc*/
|
||||
u32 dword[2];
|
||||
u32 dword[4];
|
||||
} __packed;
|
||||
|
||||
struct rtl_rx_desc { /*old: rx desc new: rx wifi info*/
|
||||
|
||||
@@ -1221,7 +1221,8 @@ static void rtl88e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
|
||||
sta = rtl_find_sta(hw, mac->bssid);
|
||||
if (sta)
|
||||
rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
|
||||
p_ra->ratr_state);
|
||||
p_ra->ratr_state,
|
||||
true);
|
||||
rcu_read_unlock();
|
||||
|
||||
p_ra->pre_ratr_state = p_ra->ratr_state;
|
||||
|
||||
@@ -99,6 +99,7 @@ static void _rtl88ee_return_beacon_queue_skb(struct ieee80211_hw *hw)
|
||||
|
||||
pci_unmap_single(rtlpci->pdev,
|
||||
rtlpriv->cfg->ops->get_desc(
|
||||
hw,
|
||||
(u8 *)entry, true, HW_DESC_TXBUFF_ADDR),
|
||||
skb->len, PCI_DMA_TODEVICE);
|
||||
kfree_skb(skb);
|
||||
@@ -2076,7 +2077,7 @@ static void rtl88ee_update_hal_rate_table(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
static void rtl88ee_update_hal_rate_mask(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta, u8 rssi_level)
|
||||
struct ieee80211_sta *sta, u8 rssi_level, bool update_bw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
@@ -2207,12 +2208,12 @@ static void rtl88ee_update_hal_rate_mask(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
void rtl88ee_update_hal_rate_tbl(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta, u8 rssi_level)
|
||||
struct ieee80211_sta *sta, u8 rssi_level, bool update_bw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
if (rtlpriv->dm.useramask)
|
||||
rtl88ee_update_hal_rate_mask(hw, sta, rssi_level);
|
||||
rtl88ee_update_hal_rate_mask(hw, sta, rssi_level, update_bw);
|
||||
else
|
||||
rtl88ee_update_hal_rate_table(hw, sta);
|
||||
}
|
||||
@@ -2235,7 +2236,7 @@ bool rtl88ee_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
|
||||
enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
|
||||
enum rf_pwrstate e_rfpowerstate_toset;
|
||||
u32 u4tmp;
|
||||
bool b_actuallyset = false;
|
||||
|
||||
@@ -2254,8 +2255,6 @@ bool rtl88ee_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
|
||||
spin_unlock(&rtlpriv->locks.rf_ps_lock);
|
||||
}
|
||||
|
||||
cur_rfstate = ppsc->rfpwr_state;
|
||||
|
||||
u4tmp = rtl_read_dword(rtlpriv, REG_GPIO_OUTPUT);
|
||||
e_rfpowerstate_toset = (u4tmp & BIT(31)) ? ERFON : ERFOFF;
|
||||
|
||||
|
||||
@@ -43,7 +43,8 @@ void rtl88ee_update_interrupt_mask(struct ieee80211_hw *hw,
|
||||
u32 add_msr, u32 rm_msr);
|
||||
void rtl88ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
|
||||
void rtl88ee_update_hal_rate_tbl(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta, u8 rssi_level);
|
||||
struct ieee80211_sta *sta, u8 rssi_level,
|
||||
bool update_bw);
|
||||
void rtl88ee_update_channel_access_setting(struct ieee80211_hw *hw);
|
||||
bool rtl88ee_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
|
||||
void rtl88ee_enable_hw_security_config(struct ieee80211_hw *hw);
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
static void rtl88e_init_aspm_vars(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
|
||||
|
||||
/*close ASPM for AMD defaultly */
|
||||
@@ -77,7 +78,7 @@ static void rtl88e_init_aspm_vars(struct ieee80211_hw *hw)
|
||||
* 1 - Support ASPM,
|
||||
* 2 - According to chipset.
|
||||
*/
|
||||
rtlpci->const_support_pciaspm = 1;
|
||||
rtlpci->const_support_pciaspm = rtlpriv->cfg->mod_params->aspm_support;
|
||||
}
|
||||
|
||||
int rtl88e_init_sw_vars(struct ieee80211_hw *hw)
|
||||
@@ -276,6 +277,7 @@ static struct rtl_mod_params rtl88ee_mod_params = {
|
||||
.swctrl_lps = false,
|
||||
.fwctrl_lps = false,
|
||||
.msi_support = true,
|
||||
.aspm_support = 1,
|
||||
.debug_level = 0,
|
||||
.debug_mask = 0,
|
||||
};
|
||||
@@ -399,6 +401,7 @@ module_param_named(ips, rtl88ee_mod_params.inactiveps, bool, 0444);
|
||||
module_param_named(swlps, rtl88ee_mod_params.swctrl_lps, bool, 0444);
|
||||
module_param_named(fwlps, rtl88ee_mod_params.fwctrl_lps, bool, 0444);
|
||||
module_param_named(msi, rtl88ee_mod_params.msi_support, bool, 0444);
|
||||
module_param_named(aspm, rtl88ee_mod_params.aspm_support, int, 0444);
|
||||
module_param_named(disable_watchdog, rtl88ee_mod_params.disable_watchdog,
|
||||
bool, 0444);
|
||||
MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
|
||||
@@ -406,6 +409,7 @@ MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
|
||||
MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
|
||||
MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
|
||||
MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n");
|
||||
MODULE_PARM_DESC(aspm, "Set to 1 to enable ASPM (default 1)\n");
|
||||
MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
|
||||
MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
|
||||
MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n");
|
||||
|
||||
@@ -786,7 +786,8 @@ void rtl88ee_set_desc(struct ieee80211_hw *hw, u8 *pdesc,
|
||||
}
|
||||
}
|
||||
|
||||
u32 rtl88ee_get_desc(u8 *pdesc, bool istx, u8 desc_name)
|
||||
u64 rtl88ee_get_desc(struct ieee80211_hw *hw,
|
||||
u8 *pdesc, bool istx, u8 desc_name)
|
||||
{
|
||||
u32 ret = 0;
|
||||
|
||||
@@ -828,7 +829,7 @@ bool rtl88ee_is_tx_desc_closed(struct ieee80211_hw *hw, u8 hw_queue, u16 index)
|
||||
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
|
||||
struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
|
||||
u8 *entry = (u8 *)(&ring->desc[ring->idx]);
|
||||
u8 own = (u8)rtl88ee_get_desc(entry, true, HW_DESC_OWN);
|
||||
u8 own = (u8)rtl88ee_get_desc(hw, entry, true, HW_DESC_OWN);
|
||||
|
||||
/*beacon packet will only use the first
|
||||
*descriptor defautly,and the own may not
|
||||
|
||||
@@ -782,7 +782,8 @@ bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw,
|
||||
u8 *pdesc, struct sk_buff *skb);
|
||||
void rtl88ee_set_desc(struct ieee80211_hw *hw, u8 *pdesc,
|
||||
bool istx, u8 desc_name, u8 *val);
|
||||
u32 rtl88ee_get_desc(u8 *pdesc, bool istx, u8 desc_name);
|
||||
u64 rtl88ee_get_desc(struct ieee80211_hw *hw,
|
||||
u8 *pdesc, bool istx, u8 desc_name);
|
||||
bool rtl88ee_is_tx_desc_closed(struct ieee80211_hw *hw,
|
||||
u8 hw_queue, u16 index);
|
||||
void rtl88ee_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
|
||||
|
||||
@@ -1865,7 +1865,7 @@ static void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta, u8 rssi_level)
|
||||
struct ieee80211_sta *sta, u8 rssi_level, bool update_bw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
@@ -1995,12 +1995,12 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta, u8 rssi_level)
|
||||
struct ieee80211_sta *sta, u8 rssi_level, bool update_bw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
if (rtlpriv->dm.useramask)
|
||||
rtl92ce_update_hal_rate_mask(hw, sta, rssi_level);
|
||||
rtl92ce_update_hal_rate_mask(hw, sta, rssi_level, update_bw);
|
||||
else
|
||||
rtl92ce_update_hal_rate_table(hw, sta);
|
||||
}
|
||||
|
||||
@@ -56,9 +56,8 @@ void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw,
|
||||
u32 add_msr, u32 rm_msr);
|
||||
void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
|
||||
void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta, u8 rssi_level);
|
||||
void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta, u8 rssi_level);
|
||||
struct ieee80211_sta *sta, u8 rssi_level,
|
||||
bool update_bw);
|
||||
void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw);
|
||||
bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
|
||||
void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw);
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
static void rtl92c_init_aspm_vars(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
|
||||
|
||||
/*close ASPM for AMD defaultly */
|
||||
@@ -83,7 +84,7 @@ static void rtl92c_init_aspm_vars(struct ieee80211_hw *hw)
|
||||
* 1 - Support ASPM,
|
||||
* 2 - According to chipset.
|
||||
*/
|
||||
rtlpci->const_support_pciaspm = 1;
|
||||
rtlpci->const_support_pciaspm = rtlpriv->cfg->mod_params->aspm_support;
|
||||
}
|
||||
|
||||
int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
|
||||
@@ -252,6 +253,7 @@ static struct rtl_mod_params rtl92ce_mod_params = {
|
||||
.inactiveps = true,
|
||||
.swctrl_lps = false,
|
||||
.fwctrl_lps = true,
|
||||
.aspm_support = 1,
|
||||
.debug_level = 0,
|
||||
.debug_mask = 0,
|
||||
};
|
||||
@@ -375,10 +377,12 @@ module_param_named(debug_mask, rtl92ce_mod_params.debug_mask, ullong, 0644);
|
||||
module_param_named(ips, rtl92ce_mod_params.inactiveps, bool, 0444);
|
||||
module_param_named(swlps, rtl92ce_mod_params.swctrl_lps, bool, 0444);
|
||||
module_param_named(fwlps, rtl92ce_mod_params.fwctrl_lps, bool, 0444);
|
||||
module_param_named(aspm, rtl92ce_mod_params.aspm_support, int, 0444);
|
||||
MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
|
||||
MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
|
||||
MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
|
||||
MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
|
||||
MODULE_PARM_DESC(aspm, "Set to 1 to enable ASPM (default 1)\n");
|
||||
MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)");
|
||||
MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)");
|
||||
|
||||
|
||||
@@ -697,7 +697,8 @@ void rtl92ce_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
|
||||
}
|
||||
}
|
||||
|
||||
u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
|
||||
u64 rtl92ce_get_desc(struct ieee80211_hw *hw, u8 *p_desc,
|
||||
bool istx, u8 desc_name)
|
||||
{
|
||||
u32 ret = 0;
|
||||
|
||||
@@ -740,7 +741,7 @@ bool rtl92ce_is_tx_desc_closed(struct ieee80211_hw *hw,
|
||||
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
|
||||
struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
|
||||
u8 *entry = (u8 *)(&ring->desc[ring->idx]);
|
||||
u8 own = (u8)rtl92ce_get_desc(entry, true, HW_DESC_OWN);
|
||||
u8 own = (u8)rtl92ce_get_desc(hw, entry, true, HW_DESC_OWN);
|
||||
|
||||
/*beacon packet will only use the first
|
||||
*descriptor defautly,and the own may not
|
||||
|
||||
@@ -718,7 +718,8 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
|
||||
u8 *pdesc, struct sk_buff *skb);
|
||||
void rtl92ce_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
|
||||
u8 desc_name, u8 *val);
|
||||
u32 rtl92ce_get_desc(u8 *pdesc, bool istx, u8 desc_name);
|
||||
u64 rtl92ce_get_desc(struct ieee80211_hw *hw, u8 *p_desc,
|
||||
bool istx, u8 desc_name);
|
||||
bool rtl92ce_is_tx_desc_closed(struct ieee80211_hw *hw,
|
||||
u8 hw_queue, u16 index);
|
||||
void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
|
||||
|
||||
@@ -2006,7 +2006,7 @@ static void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
|
||||
|
||||
static void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta,
|
||||
u8 rssi_level)
|
||||
u8 rssi_level, bool update_bw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
@@ -2153,12 +2153,12 @@ static void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw,
|
||||
|
||||
void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta,
|
||||
u8 rssi_level)
|
||||
u8 rssi_level, bool update_bw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
if (rtlpriv->dm.useramask)
|
||||
rtl92cu_update_hal_rate_mask(hw, sta, rssi_level);
|
||||
rtl92cu_update_hal_rate_mask(hw, sta, rssi_level, update_bw);
|
||||
else
|
||||
rtl92cu_update_hal_rate_table(hw, sta);
|
||||
}
|
||||
|
||||
@@ -104,6 +104,6 @@ void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
|
||||
bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw);
|
||||
void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta,
|
||||
u8 rssi_level);
|
||||
u8 rssi_level, bool update_bw);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -490,7 +490,7 @@ static bool _rtl92d_cmd_send_packet(struct ieee80211_hw *hw,
|
||||
spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
|
||||
pdesc = &ring->desc[idx];
|
||||
/* discard output from call below */
|
||||
rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
|
||||
rtlpriv->cfg->ops->get_desc(hw, (u8 *)pdesc, true, HW_DESC_OWN);
|
||||
rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
|
||||
__skb_queue_tail(&ring->queue, skb);
|
||||
spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
|
||||
|
||||
@@ -1897,7 +1897,7 @@ static void rtl92de_update_hal_rate_table(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta, u8 rssi_level)
|
||||
struct ieee80211_sta *sta, u8 rssi_level, bool update_bw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
||||
@@ -2033,12 +2033,12 @@ static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
void rtl92de_update_hal_rate_tbl(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta, u8 rssi_level)
|
||||
struct ieee80211_sta *sta, u8 rssi_level, bool update_bw)
|
||||
{
|
||||
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
||||
|
||||
if (rtlpriv->dm.useramask)
|
||||
rtl92de_update_hal_rate_mask(hw, sta, rssi_level);
|
||||
rtl92de_update_hal_rate_mask(hw, sta, rssi_level, update_bw);
|
||||
else
|
||||
rtl92de_update_hal_rate_table(hw, sta);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,8 @@ void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw,
|
||||
u32 add_msr, u32 rm_msr);
|
||||
void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
|
||||
void rtl92de_update_hal_rate_tbl(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta, u8 rssi_level);
|
||||
struct ieee80211_sta *sta, u8 rssi_level,
|
||||
bool update_bw);
|
||||
void rtl92de_update_channel_access_setting(struct ieee80211_hw *hw);
|
||||
bool rtl92de_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
|
||||
void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user