diff options
Diffstat (limited to 'drivers/net/wireless')
330 files changed, 7667 insertions, 24389 deletions
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index cfce83e..f9a24e5 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c @@ -1924,6 +1924,7 @@ static int adm8211_probe(struct pci_dev *pdev, pci_iounmap(pdev, priv->map); err_free_dev: + pci_set_drvdata(pdev, NULL); ieee80211_free_hw(dev); err_free_reg: diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index edf4b57..7fe1964 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -5570,6 +5570,7 @@ static void airo_pci_remove(struct pci_dev *pdev) airo_print_info(dev->name, "Unregistering..."); stop_airo_card(dev, 1); pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); } static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state) diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig index c63d115..1abf1d4 100644 --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig @@ -25,23 +25,6 @@ config ATH_DEBUG Say Y, if you want to debug atheros wireless drivers. Right now only ath9k makes use of this. -config ATH_REG_DYNAMIC_USER_REG_HINTS - bool "Atheros dynamic user regulatory hints" - depends on CFG80211_CERTIFICATION_ONUS - default n - ---help--- - Say N. This should only be enabled in countries where - this feature is explicitly allowed and only on cards that - specifically have been tested for this. - -config ATH_REG_DYNAMIC_USER_CERT_TESTING - bool "Atheros dynamic user regulatory testing" - depends on ATH_REG_DYNAMIC_USER_REG_HINTS && CFG80211_CERTIFICATION_ONUS - default n - ---help--- - Say N. This should only be enabled on systems - undergoing certification testing. - source "drivers/net/wireless/ath/ath5k/Kconfig" source "drivers/net/wireless/ath/ath9k/Kconfig" source "drivers/net/wireless/ath/carl9170/Kconfig" @@ -49,6 +32,5 @@ source "drivers/net/wireless/ath/ath6kl/Kconfig" source "drivers/net/wireless/ath/ar5523/Kconfig" source "drivers/net/wireless/ath/wil6210/Kconfig" source "drivers/net/wireless/ath/ath10k/Kconfig" -source "drivers/net/wireless/ath/wcn36xx/Kconfig" endif diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile index 7d023b0..fb05cfd 100644 --- a/drivers/net/wireless/ath/Makefile +++ b/drivers/net/wireless/ath/Makefile @@ -5,16 +5,13 @@ obj-$(CONFIG_ATH6KL) += ath6kl/ obj-$(CONFIG_AR5523) += ar5523/ obj-$(CONFIG_WIL6210) += wil6210/ obj-$(CONFIG_ATH10K) += ath10k/ -obj-$(CONFIG_WCN36XX) += wcn36xx/ obj-$(CONFIG_ATH_COMMON) += ath.o ath-objs := main.o \ regd.o \ hw.o \ - key.o \ - dfs_pattern_detector.o \ - dfs_pri_detector.o + key.o ath-$(CONFIG_ATH_DEBUG) += debug.o ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c index 280fc3d..17d7fec 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c @@ -1762,7 +1762,6 @@ static struct usb_device_id ar5523_id_table[] = { AR5523_DEVICE_UX(0x2001, 0x3a00), /* Dlink / DWLAG132 */ AR5523_DEVICE_UG(0x2001, 0x3a02), /* Dlink / DWLG132 */ AR5523_DEVICE_UX(0x2001, 0x3a04), /* Dlink / DWLAG122 */ - AR5523_DEVICE_UG(0x07d1, 0x3a07), /* D-Link / WUA-2340 rev A1 */ AR5523_DEVICE_UG(0x1690, 0x0712), /* Gigaset / AR5523 */ AR5523_DEVICE_UG(0x1690, 0x0710), /* Gigaset / SMCWUSBTG */ AR5523_DEVICE_UG(0x129b, 0x160c), /* Gigaset / USB stick 108 diff --git a/drivers/net/wireless/ath/ath10k/bmi.c b/drivers/net/wireless/ath/ath10k/bmi.c index a1f0996..744da6d 100644 --- a/drivers/net/wireless/ath/ath10k/bmi.c +++ b/drivers/net/wireless/ath/ath10k/bmi.c @@ -22,8 +22,7 @@ void ath10k_bmi_start(struct ath10k *ar) { - ath10k_dbg(ATH10K_DBG_BMI, "bmi start\n"); - + ath10k_dbg(ATH10K_DBG_CORE, "BMI started\n"); ar->bmi.done_sent = false; } @@ -33,10 +32,8 @@ int ath10k_bmi_done(struct ath10k *ar) u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.done); int ret; - ath10k_dbg(ATH10K_DBG_BMI, "bmi done\n"); - if (ar->bmi.done_sent) { - ath10k_dbg(ATH10K_DBG_BMI, "bmi skipped\n"); + ath10k_dbg(ATH10K_DBG_CORE, "%s skipped\n", __func__); return 0; } @@ -49,6 +46,7 @@ int ath10k_bmi_done(struct ath10k *ar) return ret; } + ath10k_dbg(ATH10K_DBG_CORE, "BMI done\n"); return 0; } @@ -61,8 +59,6 @@ int ath10k_bmi_get_target_info(struct ath10k *ar, u32 resplen = sizeof(resp.get_target_info); int ret; - ath10k_dbg(ATH10K_DBG_BMI, "bmi get target info\n"); - if (ar->bmi.done_sent) { ath10k_warn("BMI Get Target Info Command disallowed\n"); return -EBUSY; @@ -84,7 +80,6 @@ int ath10k_bmi_get_target_info(struct ath10k *ar, target_info->version = __le32_to_cpu(resp.get_target_info.version); target_info->type = __le32_to_cpu(resp.get_target_info.type); - return 0; } @@ -97,14 +92,15 @@ int ath10k_bmi_read_memory(struct ath10k *ar, u32 rxlen; int ret; - ath10k_dbg(ATH10K_DBG_BMI, "bmi read address 0x%x length %d\n", - address, length); - if (ar->bmi.done_sent) { ath10k_warn("command disallowed\n"); return -EBUSY; } + ath10k_dbg(ATH10K_DBG_CORE, + "%s: (device: 0x%p, address: 0x%x, length: %d)\n", + __func__, ar, address, length); + while (length) { rxlen = min_t(u32, length, BMI_MAX_DATA_SIZE); @@ -137,14 +133,15 @@ int ath10k_bmi_write_memory(struct ath10k *ar, u32 txlen; int ret; - ath10k_dbg(ATH10K_DBG_BMI, "bmi write address 0x%x length %d\n", - address, length); - if (ar->bmi.done_sent) { ath10k_warn("command disallowed\n"); return -EBUSY; } + ath10k_dbg(ATH10K_DBG_CORE, + "%s: (device: 0x%p, address: 0x%x, length: %d)\n", + __func__, ar, address, length); + while (length) { txlen = min(length, BMI_MAX_DATA_SIZE - hdrlen); @@ -183,14 +180,15 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param) u32 resplen = sizeof(resp.execute); int ret; - ath10k_dbg(ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n", - address, *param); - if (ar->bmi.done_sent) { ath10k_warn("command disallowed\n"); return -EBUSY; } + ath10k_dbg(ATH10K_DBG_CORE, + "%s: (device: 0x%p, address: 0x%x, param: %d)\n", + __func__, ar, address, *param); + cmd.id = __cpu_to_le32(BMI_EXECUTE); cmd.execute.addr = __cpu_to_le32(address); cmd.execute.param = __cpu_to_le32(*param); @@ -218,9 +216,6 @@ int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length) u32 txlen; int ret; - ath10k_dbg(ATH10K_DBG_BMI, "bmi lz data buffer 0x%p length %d\n", - buffer, length); - if (ar->bmi.done_sent) { ath10k_warn("command disallowed\n"); return -EBUSY; @@ -255,9 +250,6 @@ int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address) u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.lz_start); int ret; - ath10k_dbg(ATH10K_DBG_BMI, "bmi lz stream start address 0x%x\n", - address); - if (ar->bmi.done_sent) { ath10k_warn("command disallowed\n"); return -EBUSY; @@ -283,10 +275,6 @@ int ath10k_bmi_fast_download(struct ath10k *ar, u32 trailer_len = length - head_len; int ret; - ath10k_dbg(ATH10K_DBG_BMI, - "bmi fast download address 0x%x buffer 0x%p length %d\n", - address, buffer, length); - ret = ath10k_bmi_lz_stream_start(ar, address); if (ret) return ret; diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index e46951b..f8b969f 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c @@ -76,7 +76,36 @@ static inline void ath10k_ce_src_ring_write_index_set(struct ath10k *ar, u32 ce_ctrl_addr, unsigned int n) { - ath10k_pci_write32(ar, ce_ctrl_addr + SR_WR_INDEX_ADDRESS, n); + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); + void __iomem *indicator_addr; + + if (!test_bit(ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND, ar_pci->features)) { + ath10k_pci_write32(ar, ce_ctrl_addr + SR_WR_INDEX_ADDRESS, n); + return; + } + + /* workaround for QCA988x_1.0 HW CE */ + indicator_addr = ar_pci->mem + ce_ctrl_addr + DST_WATERMARK_ADDRESS; + + if (ce_ctrl_addr == ath10k_ce_base_address(CDC_WAR_DATA_CE)) { + iowrite32((CDC_WAR_MAGIC_STR | n), indicator_addr); + } else { + unsigned long irq_flags; + local_irq_save(irq_flags); + iowrite32(1, indicator_addr); + + /* + * PCIE write waits for ACK in IPQ8K, there is no + * need to read back value. + */ + (void)ioread32(indicator_addr); + (void)ioread32(indicator_addr); /* conservative */ + + ath10k_pci_write32(ar, ce_ctrl_addr + SR_WR_INDEX_ADDRESS, n); + + iowrite32(0, indicator_addr); + local_irq_restore(irq_flags); + } } static inline u32 ath10k_ce_src_ring_write_index_get(struct ath10k *ar, @@ -256,7 +285,7 @@ static inline void ath10k_ce_engine_int_status_clear(struct ath10k *ar, * ath10k_ce_sendlist_send. * The caller takes responsibility for any needed locking. */ -static int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state, +static int ath10k_ce_send_nolock(struct ce_state *ce_state, void *per_transfer_context, u32 buffer, unsigned int nbytes, @@ -264,7 +293,7 @@ static int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state, unsigned int flags) { struct ath10k *ar = ce_state->ar; - struct ath10k_ce_ring *src_ring = ce_state->src_ring; + struct ce_ring_state *src_ring = ce_state->src_ring; struct ce_desc *desc, *sdesc; unsigned int nentries_mask = src_ring->nentries_mask; unsigned int sw_index = src_ring->sw_index; @@ -277,13 +306,11 @@ static int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state, ath10k_warn("%s: send more we can (nbytes: %d, max: %d)\n", __func__, nbytes, ce_state->src_sz_max); - ret = ath10k_pci_wake(ar); - if (ret) - return ret; + ath10k_pci_wake(ar); if (unlikely(CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) <= 0)) { - ret = -ENOSR; + ret = -EIO; goto exit; } @@ -319,7 +346,7 @@ exit: return ret; } -int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_send(struct ce_state *ce_state, void *per_transfer_context, u32 buffer, unsigned int nbytes, @@ -338,26 +365,77 @@ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, return ret; } -int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe) +void ath10k_ce_sendlist_buf_add(struct ce_sendlist *sendlist, u32 buffer, + unsigned int nbytes, u32 flags) { - struct ath10k *ar = pipe->ar; + unsigned int num_items = sendlist->num_items; + struct ce_sendlist_item *item; + + item = &sendlist->item[num_items]; + item->data = buffer; + item->u.nbytes = nbytes; + item->flags = flags; + sendlist->num_items++; +} + +int ath10k_ce_sendlist_send(struct ce_state *ce_state, + void *per_transfer_context, + struct ce_sendlist *sendlist, + unsigned int transfer_id) +{ + struct ce_ring_state *src_ring = ce_state->src_ring; + struct ce_sendlist_item *item; + struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - int delta; + unsigned int nentries_mask = src_ring->nentries_mask; + unsigned int num_items = sendlist->num_items; + unsigned int sw_index; + unsigned int write_index; + int i, delta, ret = -ENOMEM; spin_lock_bh(&ar_pci->ce_lock); - delta = CE_RING_DELTA(pipe->src_ring->nentries_mask, - pipe->src_ring->write_index, - pipe->src_ring->sw_index - 1); + + sw_index = src_ring->sw_index; + write_index = src_ring->write_index; + + delta = CE_RING_DELTA(nentries_mask, write_index, sw_index - 1); + + if (delta >= num_items) { + /* + * Handle all but the last item uniformly. + */ + for (i = 0; i < num_items - 1; i++) { + item = &sendlist->item[i]; + ret = ath10k_ce_send_nolock(ce_state, + CE_SENDLIST_ITEM_CTXT, + (u32) item->data, + item->u.nbytes, transfer_id, + item->flags | + CE_SEND_FLAG_GATHER); + if (ret) + ath10k_warn("CE send failed for item: %d\n", i); + } + /* + * Provide valid context pointer for final item. + */ + item = &sendlist->item[i]; + ret = ath10k_ce_send_nolock(ce_state, per_transfer_context, + (u32) item->data, item->u.nbytes, + transfer_id, item->flags); + if (ret) + ath10k_warn("CE send failed for last item: %d\n", i); + } + spin_unlock_bh(&ar_pci->ce_lock); - return delta; + return ret; } -int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_recv_buf_enqueue(struct ce_state *ce_state, void *per_recv_context, u32 buffer) { - struct ath10k_ce_ring *dest_ring = ce_state->dest_ring; + struct ce_ring_state *dest_ring = ce_state->dest_ring; u32 ctrl_addr = ce_state->ctrl_addr; struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); @@ -370,9 +448,7 @@ int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state, write_index = dest_ring->write_index; sw_index = dest_ring->sw_index; - ret = ath10k_pci_wake(ar); - if (ret) - goto out; + ath10k_pci_wake(ar); if (CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) > 0) { struct ce_desc *base = dest_ring->base_addr_owner_space; @@ -394,8 +470,6 @@ int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state, ret = -EIO; } ath10k_pci_sleep(ar); - -out: spin_unlock_bh(&ar_pci->ce_lock); return ret; @@ -405,14 +479,14 @@ out: * Guts of ath10k_ce_completed_recv_next. * The caller takes responsibility for any necessary locking. */ -static int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state, +static int ath10k_ce_completed_recv_next_nolock(struct ce_state *ce_state, void **per_transfer_contextp, u32 *bufferp, unsigned int *nbytesp, unsigned int *transfer_idp, unsigned int *flagsp) { - struct ath10k_ce_ring *dest_ring = ce_state->dest_ring; + struct ce_ring_state *dest_ring = ce_state->dest_ring; unsigned int nentries_mask = dest_ring->nentries_mask; unsigned int sw_index = dest_ring->sw_index; @@ -461,7 +535,7 @@ static int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state, return 0; } -int ath10k_ce_completed_recv_next(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_completed_recv_next(struct ce_state *ce_state, void **per_transfer_contextp, u32 *bufferp, unsigned int *nbytesp, @@ -482,11 +556,11 @@ int ath10k_ce_completed_recv_next(struct ath10k_ce_pipe *ce_state, return ret; } -int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_revoke_recv_next(struct ce_state *ce_state, void **per_transfer_contextp, u32 *bufferp) { - struct ath10k_ce_ring *dest_ring; + struct ce_ring_state *dest_ring; unsigned int nentries_mask; unsigned int sw_index; unsigned int write_index; @@ -538,20 +612,19 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, * Guts of ath10k_ce_completed_send_next. * The caller takes responsibility for any necessary locking. */ -static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state, +static int ath10k_ce_completed_send_next_nolock(struct ce_state *ce_state, void **per_transfer_contextp, u32 *bufferp, unsigned int *nbytesp, unsigned int *transfer_idp) { - struct ath10k_ce_ring *src_ring = ce_state->src_ring; + struct ce_ring_state *src_ring = ce_state->src_ring; u32 ctrl_addr = ce_state->ctrl_addr; struct ath10k *ar = ce_state->ar; unsigned int nentries_mask = src_ring->nentries_mask; unsigned int sw_index = src_ring->sw_index; - struct ce_desc *sdesc, *sbase; unsigned int read_index; - int ret; + int ret = -EIO; if (src_ring->hw_index == sw_index) { /* @@ -561,54 +634,48 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state, * the SW has really caught up to the HW, or if the cached * value of the HW index has become stale. */ - - ret = ath10k_pci_wake(ar); - if (ret) - return ret; - + ath10k_pci_wake(ar); src_ring->hw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr); src_ring->hw_index &= nentries_mask; - ath10k_pci_sleep(ar); } - read_index = src_ring->hw_index; - if ((read_index == sw_index) || (read_index == 0xffffffff)) - return -EIO; - - sbase = src_ring->shadow_base; - sdesc = CE_SRC_RING_TO_DESC(sbase, sw_index); + if ((read_index != sw_index) && (read_index != 0xffffffff)) { + struct ce_desc *sbase = src_ring->shadow_base; + struct ce_desc *sdesc = CE_SRC_RING_TO_DESC(sbase, sw_index); - /* Return data from completed source descriptor */ - *bufferp = __le32_to_cpu(sdesc->addr); - *nbytesp = __le16_to_cpu(sdesc->nbytes); - *transfer_idp = MS(__le16_to_cpu(sdesc->flags), - CE_DESC_FLAGS_META_DATA); + /* Return data from completed source descriptor */ + *bufferp = __le32_to_cpu(sdesc->addr); + *nbytesp = __le16_to_cpu(sdesc->nbytes); + *transfer_idp = MS(__le16_to_cpu(sdesc->flags), + CE_DESC_FLAGS_META_DATA); - if (per_transfer_contextp) - *per_transfer_contextp = - src_ring->per_transfer_context[sw_index]; + if (per_transfer_contextp) + *per_transfer_contextp = + src_ring->per_transfer_context[sw_index]; - /* sanity */ - src_ring->per_transfer_context[sw_index] = NULL; + /* sanity */ + src_ring->per_transfer_context[sw_index] = NULL; - /* Update sw_index */ - sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index); - src_ring->sw_index = sw_index; + /* Update sw_index */ + sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index); + src_ring->sw_index = sw_index; + ret = 0; + } - return 0; + return ret; } /* NB: Modeled after ath10k_ce_completed_send_next */ -int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_cancel_send_next(struct ce_state *ce_state, void **per_transfer_contextp, u32 *bufferp, unsigned int *nbytesp, unsigned int *transfer_idp) { - struct ath10k_ce_ring *src_ring; + struct ce_ring_state *src_ring; unsigned int nentries_mask; unsigned int sw_index; unsigned int write_index; @@ -660,7 +727,7 @@ int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state, return ret; } -int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_completed_send_next(struct ce_state *ce_state, void **per_transfer_contextp, u32 *bufferp, unsigned int *nbytesp, @@ -689,29 +756,53 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; + struct ce_state *ce_state = ar_pci->ce_id_to_state[ce_id]; u32 ctrl_addr = ce_state->ctrl_addr; - int ret; - - ret = ath10k_pci_wake(ar); - if (ret) - return; + void *transfer_context; + u32 buf; + unsigned int nbytes; + unsigned int id; + unsigned int flags; + ath10k_pci_wake(ar); spin_lock_bh(&ar_pci->ce_lock); /* Clear the copy-complete interrupts that will be handled here. */ ath10k_ce_engine_int_status_clear(ar, ctrl_addr, HOST_IS_COPY_COMPLETE_MASK); - spin_unlock_bh(&ar_pci->ce_lock); - - if (ce_state->recv_cb) - ce_state->recv_cb(ce_state); - - if (ce_state->send_cb) - ce_state->send_cb(ce_state); + if (ce_state->recv_cb) { + /* + * Pop completed recv buffers and call the registered + * recv callback for each + */ + while (ath10k_ce_completed_recv_next_nolock(ce_state, + &transfer_context, + &buf, &nbytes, + &id, &flags) == 0) { + spin_unlock_bh(&ar_pci->ce_lock); + ce_state->recv_cb(ce_state, transfer_context, buf, + nbytes, id, flags); + spin_lock_bh(&ar_pci->ce_lock); + } + } - spin_lock_bh(&ar_pci->ce_lock); + if (ce_state->send_cb) { + /* + * Pop completed send buffers and call the registered + * send callback for each + */ + while (ath10k_ce_completed_send_next_nolock(ce_state, + &transfer_context, + &buf, + &nbytes, + &id) == 0) { + spin_unlock_bh(&ar_pci->ce_lock); + ce_state->send_cb(ce_state, transfer_context, + buf, nbytes, id); + spin_lock_bh(&ar_pci->ce_lock); + } + } /* * Misc CE interrupts are not being handled, but still need @@ -732,13 +823,10 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) void ath10k_ce_per_engine_service_any(struct ath10k *ar) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - int ce_id, ret; + int ce_id; u32 intr_summary; - ret = ath10k_pci_wake(ar); - if (ret) - return; - + ath10k_pci_wake(ar); intr_summary = CE_INTERRUPT_SUMMARY(ar); for (ce_id = 0; intr_summary && (ce_id < ar_pci->ce_count); ce_id++) { @@ -761,16 +849,13 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar) * * Called with ce_lock held. */ -static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state, +static void ath10k_ce_per_engine_handler_adjust(struct ce_state *ce_state, int disable_copy_compl_intr) { u32 ctrl_addr = ce_state->ctrl_addr; struct ath10k *ar = ce_state->ar; - int ret; - ret = ath10k_pci_wake(ar); - if (ret) - return; + ath10k_pci_wake(ar); if ((!disable_copy_compl_intr) && (ce_state->send_cb || ce_state->recv_cb)) @@ -786,14 +871,11 @@ static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state, void ath10k_ce_disable_interrupts(struct ath10k *ar) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - int ce_id, ret; - - ret = ath10k_pci_wake(ar); - if (ret) - return; + int ce_id; + ath10k_pci_wake(ar); for (ce_id = 0; ce_id < ar_pci->ce_count; ce_id++) { - struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; + struct ce_state *ce_state = ar_pci->ce_id_to_state[ce_id]; u32 ctrl_addr = ce_state->ctrl_addr; ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr); @@ -801,8 +883,12 @@ void ath10k_ce_disable_interrupts(struct ath10k *ar) ath10k_pci_sleep(ar); } -void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, - void (*send_cb)(struct ath10k_ce_pipe *), +void ath10k_ce_send_cb_register(struct ce_state *ce_state, + void (*send_cb) (struct ce_state *ce_state, + void *transfer_context, + u32 buffer, + unsigned int nbytes, + unsigned int transfer_id), int disable_interrupts) { struct ath10k *ar = ce_state->ar; @@ -814,8 +900,13 @@ void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, spin_unlock_bh(&ar_pci->ce_lock); } -void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state, - void (*recv_cb)(struct ath10k_ce_pipe *)) +void ath10k_ce_recv_cb_register(struct ce_state *ce_state, + void (*recv_cb) (struct ce_state *ce_state, + void *transfer_context, + u32 buffer, + unsigned int nbytes, + unsigned int transfer_id, + unsigned int flags)) { struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); @@ -828,11 +919,11 @@ void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state, static int ath10k_ce_init_src_ring(struct ath10k *ar, unsigned int ce_id, - struct ath10k_ce_pipe *ce_state, + struct ce_state *ce_state, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - struct ath10k_ce_ring *src_ring; + struct ce_ring_state *src_ring; unsigned int nentries = attr->src_nentries; unsigned int ce_nbytes; u32 ctrl_addr = ath10k_ce_base_address(ce_id); @@ -846,18 +937,19 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar, return 0; } - ce_nbytes = sizeof(struct ath10k_ce_ring) + (nentries * sizeof(void *)); + ce_nbytes = sizeof(struct ce_ring_state) + (nentries * sizeof(void *)); ptr = kzalloc(ce_nbytes, GFP_KERNEL); if (ptr == NULL) return -ENOMEM; - ce_state->src_ring = (struct ath10k_ce_ring *)ptr; + ce_state->src_ring = (struct ce_ring_state *)ptr; src_ring = ce_state->src_ring; - ptr += sizeof(struct ath10k_ce_ring); + ptr += sizeof(struct ce_ring_state); src_ring->nentries = nentries; src_ring->nentries_mask = nentries - 1; + ath10k_pci_wake(ar); src_ring->sw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr); src_ring->sw_index &= src_ring->nentries_mask; src_ring->hw_index = src_ring->sw_index; @@ -865,6 +957,7 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar, src_ring->write_index = ath10k_ce_src_ring_write_index_get(ar, ctrl_addr); src_ring->write_index &= src_ring->nentries_mask; + ath10k_pci_sleep(ar); src_ring->per_transfer_context = (void **)ptr; @@ -877,12 +970,6 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar, (nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), &base_addr); - if (!src_ring->base_addr_owner_space_unaligned) { - kfree(ce_state->src_ring); - ce_state->src_ring = NULL; - return -ENOMEM; - } - src_ring->base_addr_ce_space_unaligned = base_addr; src_ring->base_addr_owner_space = PTR_ALIGN( @@ -899,21 +986,12 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar, src_ring->shadow_base_unaligned = kmalloc((nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), GFP_KERNEL); - if (!src_ring->shadow_base_unaligned) { - pci_free_consistent(ar_pci->pdev, - (nentries * sizeof(struct ce_desc) + - CE_DESC_RING_ALIGN), - src_ring->base_addr_owner_space, - src_ring->base_addr_ce_space); - kfree(ce_state->src_ring); - ce_state->src_ring = NULL; - return -ENOMEM; - } src_ring->shadow_base = PTR_ALIGN( src_ring->shadow_base_unaligned, CE_DESC_RING_ALIGN); + ath10k_pci_wake(ar); ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr, src_ring->base_addr_ce_space); ath10k_ce_src_ring_size_set(ar, ctrl_addr, nentries); @@ -921,21 +999,18 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar, ath10k_ce_src_ring_byte_swap_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries); - - ath10k_dbg(ATH10K_DBG_BOOT, - "boot ce src ring id %d entries %d base_addr %p\n", - ce_id, nentries, src_ring->base_addr_owner_space); + ath10k_pci_sleep(ar); return 0; } static int ath10k_ce_init_dest_ring(struct ath10k *ar, unsigned int ce_id, - struct ath10k_ce_pipe *ce_state, + struct ce_state *ce_state, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - struct ath10k_ce_ring *dest_ring; + struct ce_ring_state *dest_ring; unsigned int nentries = attr->dest_nentries; unsigned int ce_nbytes; u32 ctrl_addr = ath10k_ce_base_address(ce_id); @@ -949,23 +1024,25 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar, return 0; } - ce_nbytes = sizeof(struct ath10k_ce_ring) + (nentries * sizeof(void *)); + ce_nbytes = sizeof(struct ce_ring_state) + (nentries * sizeof(void *)); ptr = kzalloc(ce_nbytes, GFP_KERNEL); if (ptr == NULL) return -ENOMEM; - ce_state->dest_ring = (struct ath10k_ce_ring *)ptr; + ce_state->dest_ring = (struct ce_ring_state *)ptr; dest_ring = ce_state->dest_ring; - ptr += sizeof(struct ath10k_ce_ring); + ptr += sizeof(struct ce_ring_state); dest_ring->nentries = nentries; dest_ring->nentries_mask = nentries - 1; + ath10k_pci_wake(ar); dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr); dest_ring->sw_index &= dest_ring->nentries_mask; dest_ring->write_index = ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr); dest_ring->write_index &= dest_ring->nentries_mask; + ath10k_pci_sleep(ar); dest_ring->per_transfer_context = (void **)ptr; @@ -978,12 +1055,6 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar, (nentries * sizeof(struct ce_desc) + CE_DESC_RING_ALIGN), &base_addr); - if (!dest_ring->base_addr_owner_space_unaligned) { - kfree(ce_state->dest_ring); - ce_state->dest_ring = NULL; - return -ENOMEM; - } - dest_ring->base_addr_ce_space_unaligned = base_addr; /* @@ -1000,35 +1071,44 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar, dest_ring->base_addr_ce_space_unaligned, CE_DESC_RING_ALIGN); + ath10k_pci_wake(ar); ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr, dest_ring->base_addr_ce_space); ath10k_ce_dest_ring_size_set(ar, ctrl_addr, nentries); ath10k_ce_dest_ring_byte_swap_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries); - - ath10k_dbg(ATH10K_DBG_BOOT, - "boot ce dest ring id %d entries %d base_addr %p\n", - ce_id, nentries, dest_ring->base_addr_owner_space); + ath10k_pci_sleep(ar); return 0; } -static struct ath10k_ce_pipe *ath10k_ce_init_state(struct ath10k *ar, +static struct ce_state *ath10k_ce_init_state(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; + struct ce_state *ce_state = NULL; u32 ctrl_addr = ath10k_ce_base_address(ce_id); spin_lock_bh(&ar_pci->ce_lock); - ce_state->ar = ar; - ce_state->id = ce_id; - ce_state->ctrl_addr = ctrl_addr; - ce_state->attr_flags = attr->flags; - ce_state->src_sz_max = attr->src_sz_max; + if (!ar_pci->ce_id_to_state[ce_id]) { + ce_state = kzalloc(sizeof(*ce_state), GFP_ATOMIC); + if (ce_state == NULL) { + spin_unlock_bh(&ar_pci->ce_lock); + return NULL; + } + + ar_pci->ce_id_to_state[ce_id] = ce_state; + ce_state->ar = ar; + ce_state->id = ce_id; + ce_state->ctrl_addr = ctrl_addr; + ce_state->state = CE_RUNNING; + /* Save attribute flags */ + ce_state->attr_flags = attr->flags; + ce_state->src_sz_max = attr->src_sz_max; + } spin_unlock_bh(&ar_pci->ce_lock); @@ -1042,17 +1122,12 @@ static struct ath10k_ce_pipe *ath10k_ce_init_state(struct ath10k *ar, * initialization. It may be that only one side or the other is * initialized by software/firmware. */ -struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar, +struct ce_state *ath10k_ce_init(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { - struct ath10k_ce_pipe *ce_state; + struct ce_state *ce_state; u32 ctrl_addr = ath10k_ce_base_address(ce_id); - int ret; - - ret = ath10k_pci_wake(ar); - if (ret) - return NULL; ce_state = ath10k_ce_init_state(ar, ce_id, attr); if (!ce_state) { @@ -1061,38 +1136,40 @@ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar, } if (attr->src_nentries) { - ret = ath10k_ce_init_src_ring(ar, ce_id, ce_state, attr); - if (ret) { - ath10k_err("Failed to initialize CE src ring for ID: %d (%d)\n", - ce_id, ret); + if (ath10k_ce_init_src_ring(ar, ce_id, ce_state, attr)) { + ath10k_err("Failed to initialize CE src ring for ID: %d\n", + ce_id); ath10k_ce_deinit(ce_state); return NULL; } } if (attr->dest_nentries) { - ret = ath10k_ce_init_dest_ring(ar, ce_id, ce_state, attr); - if (ret) { - ath10k_err("Failed to initialize CE dest ring for ID: %d (%d)\n", - ce_id, ret); + if (ath10k_ce_init_dest_ring(ar, ce_id, ce_state, attr)) { + ath10k_err("Failed to initialize CE dest ring for ID: %d\n", + ce_id); ath10k_ce_deinit(ce_state); return NULL; } } /* Enable CE error interrupts */ + ath10k_pci_wake(ar); ath10k_ce_error_intr_enable(ar, ctrl_addr); - ath10k_pci_sleep(ar); return ce_state; } -void ath10k_ce_deinit(struct ath10k_ce_pipe *ce_state) +void ath10k_ce_deinit(struct ce_state *ce_state) { + unsigned int ce_id = ce_state->id; struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); + ce_state->state = CE_UNUSED; + ar_pci->ce_id_to_state[ce_id] = NULL; + if (ce_state->src_ring) { kfree(ce_state->src_ring->shadow_base_unaligned); pci_free_consistent(ar_pci->pdev, @@ -1113,7 +1190,5 @@ void ath10k_ce_deinit(struct ath10k_ce_pipe *ce_state) ce_state->dest_ring->base_addr_ce_space); kfree(ce_state->dest_ring); } - - ce_state->src_ring = NULL; - ce_state->dest_ring = NULL; + kfree(ce_state); } diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h index 15d45b5..c17f07c 100644 --- a/drivers/net/wireless/ath/ath10k/ce.h +++ b/drivers/net/wireless/ath/ath10k/ce.h @@ -27,6 +27,7 @@ /* Descriptor rings must be aligned to this boundary */ #define CE_DESC_RING_ALIGN 8 +#define CE_SENDLIST_ITEMS_MAX 12 #define CE_SEND_FLAG_GATHER 0x00010000 /* @@ -35,9 +36,16 @@ * how to use copy engines. */ -struct ath10k_ce_pipe; +struct ce_state; +/* Copy Engine operational state */ +enum ce_op_state { + CE_UNUSED, + CE_PAUSED, + CE_RUNNING, +}; + #define CE_DESC_FLAGS_GATHER (1 << 0) #define CE_DESC_FLAGS_BYTE_SWAP (1 << 1) #define CE_DESC_FLAGS_META_DATA_MASK 0xFFFC @@ -49,7 +57,8 @@ struct ce_desc { __le16 flags; /* %CE_DESC_FLAGS_ */ }; -struct ath10k_ce_ring { +/* Copy Engine Ring internal state */ +struct ce_ring_state { /* Number of entries in this ring; must be power of 2 */ unsigned int nentries; unsigned int nentries_mask; @@ -107,20 +116,49 @@ struct ath10k_ce_ring { void **per_transfer_context; }; -struct ath10k_ce_pipe { +/* Copy Engine internal state */ +struct ce_state { struct ath10k *ar; unsigned int id; unsigned int attr_flags; u32 ctrl_addr; - - void (*send_cb)(struct ath10k_ce_pipe *); - void (*recv_cb)(struct ath10k_ce_pipe *); + enum ce_op_state state; + + void (*send_cb) (struct ce_state *ce_state, + void *per_transfer_send_context, + u32 buffer, + unsigned int nbytes, + unsigned int transfer_id); + void (*recv_cb) (struct ce_state *ce_state, + void *per_transfer_recv_context, + u32 buffer, + unsigned int nbytes, + unsigned int transfer_id, + unsigned int flags); unsigned int src_sz_max; - struct ath10k_ce_ring *src_ring; - struct ath10k_ce_ring *dest_ring; + struct ce_ring_state *src_ring; + struct ce_ring_state *dest_ring; +}; + +struct ce_sendlist_item { + /* e.g. buffer or desc list */ + dma_addr_t data; + union { + /* simple buffer */ + unsigned int nbytes; + /* Rx descriptor list */ + unsigned int ndesc; + } u; + /* externally-specified flags; OR-ed with internal flags */ + u32 flags; +}; + +struct ce_sendlist { + unsigned int num_items; + struct ce_sendlist_item item[CE_SENDLIST_ITEMS_MAX]; }; /* Copy Engine settable attributes */ @@ -144,7 +182,7 @@ struct ce_attr; * * Implementation note: pushes 1 buffer to Source ring */ -int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_send(struct ce_state *ce_state, void *per_transfer_send_context, u32 buffer, unsigned int nbytes, @@ -152,11 +190,36 @@ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, unsigned int transfer_id, unsigned int flags); -void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, - void (*send_cb)(struct ath10k_ce_pipe *), +void ath10k_ce_send_cb_register(struct ce_state *ce_state, + void (*send_cb) (struct ce_state *ce_state, + void *transfer_context, + u32 buffer, + unsigned int nbytes, + unsigned int transfer_id), int disable_interrupts); -int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe); +/* Append a simple buffer (address/length) to a sendlist. */ +void ath10k_ce_sendlist_buf_add(struct ce_sendlist *sendlist, + u32 buffer, + unsigned int nbytes, + /* OR-ed with internal flags */ + u32 flags); + +/* + * Queue a "sendlist" of buffers to be sent using gather to a single + * anonymous destination buffer + * ce - which copy engine to use + * sendlist - list of simple buffers to send using gather + * transfer_id - arbitrary ID; reflected to destination + * Returns 0 on success; otherwise an error status. + * + * Implemenation note: Pushes multiple buffers with Gather to Source ring. + */ +int ath10k_ce_sendlist_send(struct ce_state *ce_state, + void *per_transfer_send_context, + struct ce_sendlist *sendlist, + /* 14 bits */ + unsigned int transfer_id); /*==================Recv=======================*/ @@ -170,12 +233,17 @@ int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe); * * Implemenation note: Pushes a buffer to Dest ring. */ -int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_recv_buf_enqueue(struct ce_state *ce_state, void *per_transfer_recv_context, u32 buffer); -void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state, - void (*recv_cb)(struct ath10k_ce_pipe *)); +void ath10k_ce_recv_cb_register(struct ce_state *ce_state, + void (*recv_cb) (struct ce_state *ce_state, + void *transfer_context, + u32 buffer, + unsigned int nbytes, + unsigned int transfer_id, + unsigned int flags)); /* recv flags */ /* Data is byte-swapped */ @@ -185,7 +253,7 @@ void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state, * Supply data for the next completed unprocessed receive descriptor. * Pops buffer from Dest ring. */ -int ath10k_ce_completed_recv_next(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_completed_recv_next(struct ce_state *ce_state, void **per_transfer_contextp, u32 *bufferp, unsigned int *nbytesp, @@ -195,7 +263,7 @@ int ath10k_ce_completed_recv_next(struct ath10k_ce_pipe *ce_state, * Supply data for the next completed unprocessed send descriptor. * Pops 1 completed send buffer from Source ring. */ -int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_completed_send_next(struct ce_state *ce_state, void **per_transfer_contextp, u32 *bufferp, unsigned int *nbytesp, @@ -204,7 +272,7 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, /*==================CE Engine Initialization=======================*/ /* Initialize an instance of a CE */ -struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar, +struct ce_state *ath10k_ce_init(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr); @@ -214,7 +282,7 @@ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar, * receive buffers. Target DMA must be stopped before using * this API. */ -int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_revoke_recv_next(struct ce_state *ce_state, void **per_transfer_contextp, u32 *bufferp); @@ -223,13 +291,13 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, * pending sends. Target DMA must be stopped before using * this API. */ -int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state, +int ath10k_ce_cancel_send_next(struct ce_state *ce_state, void **per_transfer_contextp, u32 *bufferp, unsigned int *nbytesp, unsigned int *transfer_idp); -void ath10k_ce_deinit(struct ath10k_ce_pipe *ce_state); +void ath10k_ce_deinit(struct ce_state *ce_state); /*==================CE Interrupt Handlers====================*/ void ath10k_ce_per_engine_service_any(struct ath10k *ar); @@ -254,6 +322,9 @@ struct ce_attr { /* CE_ATTR_* values */ unsigned int flags; + /* currently not in use */ + unsigned int priority; + /* #entries in source ring - Must be a power of 2 */ unsigned int src_nentries; @@ -265,8 +336,21 @@ struct ce_attr { /* #entries in destination ring - Must be a power of 2 */ unsigned int dest_nentries; + + /* Future use */ + void *reserved; }; +/* + * When using sendlist_send to transfer multiple buffer fragments, the + * transfer context of each fragment, except last one, will be filled + * with CE_SENDLIST_ITEM_CTXT. ce_completed_send will return success for + * each fragment done with send and the transfer context would be + * CE_SENDLIST_ITEM_CTXT. Upper layer could use this to identify the + * status of a send completion. + */ +#define CE_SENDLIST_ITEM_CTXT ((void *)0xcecebeef) + #define SR_BA_ADDRESS 0x0000 #define SR_SIZE_ADDRESS 0x0004 #define DR_BA_ADDRESS 0x0008 diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 1129994..7226c23 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -39,6 +39,17 @@ MODULE_PARM_DESC(p2p, "Enable ath10k P2P support"); static const struct ath10k_hw_params ath10k_hw_params_list[] = { { + .id = QCA988X_HW_1_0_VERSION, + .name = "qca988x hw1.0", + .patch_load_addr = QCA988X_HW_1_0_PATCH_LOAD_ADDR, + .fw = { + .dir = QCA988X_HW_1_0_FW_DIR, + .fw = QCA988X_HW_1_0_FW_FILE, + .otp = QCA988X_HW_1_0_OTP_FILE, + .board = QCA988X_HW_1_0_BOARD_DATA_FILE, + }, + }, + { .id = QCA988X_HW_2_0_VERSION, .name = "qca988x hw2.0", .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR, @@ -53,12 +64,33 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { static void ath10k_send_suspend_complete(struct ath10k *ar) { - ath10k_dbg(ATH10K_DBG_BOOT, "boot suspend complete\n"); + ath10k_dbg(ATH10K_DBG_CORE, "%s\n", __func__); ar->is_target_paused = true; wake_up(&ar->event_queue); } +static int ath10k_check_fw_version(struct ath10k *ar) +{ + char version[32]; + + if (ar->fw_version_major >= SUPPORTED_FW_MAJOR && + ar->fw_version_minor >= SUPPORTED_FW_MINOR && + ar->fw_version_release >= SUPPORTED_FW_RELEASE && + ar->fw_version_build >= SUPPORTED_FW_BUILD) + return 0; + + snprintf(version, sizeof(version), "%u.%u.%u.%u", + SUPPORTED_FW_MAJOR, SUPPORTED_FW_MINOR, + SUPPORTED_FW_RELEASE, SUPPORTED_FW_BUILD); + + ath10k_warn("WARNING: Firmware version %s is not officially supported.\n", + ar->hw->wiphy->fw_version); + ath10k_warn("Please upgrade to version %s (or newer)\n", version); + + return 0; +} + static int ath10k_init_connect_htc(struct ath10k *ar) { int status; @@ -80,7 +112,7 @@ static int ath10k_init_connect_htc(struct ath10k *ar) goto timeout; } - ath10k_dbg(ATH10K_DBG_BOOT, "boot wmi ready\n"); + ath10k_dbg(ATH10K_DBG_CORE, "core wmi ready\n"); return 0; timeout: @@ -168,7 +200,8 @@ static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar, return fw; } -static int ath10k_push_board_ext_data(struct ath10k *ar) +static int ath10k_push_board_ext_data(struct ath10k *ar, + const struct firmware *fw) { u32 board_data_size = QCA988X_BOARD_DATA_SZ; u32 board_ext_data_size = QCA988X_BOARD_EXT_DATA_SZ; @@ -181,21 +214,21 @@ static int ath10k_push_board_ext_data(struct ath10k *ar) return ret; } - ath10k_dbg(ATH10K_DBG_BOOT, - "boot push board extended data addr 0x%x\n", + ath10k_dbg(ATH10K_DBG_CORE, + "ath10k: Board extended Data download addr: 0x%x\n", board_ext_data_addr); if (board_ext_data_addr == 0) return 0; - if (ar->board_len != (board_data_size + board_ext_data_size)) { + if (fw->size != (board_data_size + board_ext_data_size)) { ath10k_err("invalid board (ext) data sizes %zu != %d+%d\n", - ar->board_len, board_data_size, board_ext_data_size); + fw->size, board_data_size, board_ext_data_size); return -EINVAL; } ret = ath10k_bmi_write_memory(ar, board_ext_data_addr, - ar->board_data + board_data_size, + fw->data + board_data_size, board_ext_data_size); if (ret) { ath10k_err("could not write board ext data (%d)\n", ret); @@ -214,11 +247,12 @@ static int ath10k_push_board_ext_data(struct ath10k *ar) static int ath10k_download_board_data(struct ath10k *ar) { + const struct firmware *fw = ar->board_data; u32 board_data_size = QCA988X_BOARD_DATA_SZ; u32 address; int ret; - ret = ath10k_push_board_ext_data(ar); + ret = ath10k_push_board_ext_data(ar, fw); if (ret) { ath10k_err("could not push board ext data (%d)\n", ret); goto exit; @@ -230,9 +264,8 @@ static int ath10k_download_board_data(struct ath10k *ar) goto exit; } - ret = ath10k_bmi_write_memory(ar, address, ar->board_data, - min_t(u32, board_data_size, - ar->board_len)); + ret = ath10k_bmi_write_memory(ar, address, fw->data, + min_t(u32, board_data_size, fw->size)); if (ret) { ath10k_err("could not write board data (%d)\n", ret); goto exit; @@ -250,16 +283,17 @@ exit: static int ath10k_download_and_run_otp(struct ath10k *ar) { + const struct firmware *fw = ar->otp; u32 address = ar->hw_params.patch_load_addr; u32 exec_param; int ret; /* OTP is optional */ - if (!ar->otp_data || !ar->otp_len) + if (!ar->otp) return 0; - ret = ath10k_bmi_fast_download(ar, address, ar->otp_data, ar->otp_len); + ret = ath10k_bmi_fast_download(ar, address, fw->data, fw->size); if (ret) { ath10k_err("could not write otp (%d)\n", ret); goto exit; @@ -278,13 +312,13 @@ exit: static int ath10k_download_fw(struct ath10k *ar) { + const struct firmware *fw = ar->firmware; u32 address; int ret; address = ar->hw_params.patch_load_addr; - ret = ath10k_bmi_fast_download(ar, address, ar->firmware_data, - ar->firmware_len); + ret = ath10k_bmi_fast_download(ar, address, fw->data, fw->size); if (ret) { ath10k_err("could not write fw (%d)\n", ret); goto exit; @@ -296,8 +330,8 @@ exit: static void ath10k_core_free_firmware_files(struct ath10k *ar) { - if (ar->board && !IS_ERR(ar->board)) - release_firmware(ar->board); + if (ar->board_data && !IS_ERR(ar->board_data)) + release_firmware(ar->board_data); if (ar->otp && !IS_ERR(ar->otp)) release_firmware(ar->otp); @@ -305,20 +339,12 @@ static void ath10k_core_free_firmware_files(struct ath10k *ar) if (ar->firmware && !IS_ERR(ar->firmware)) release_firmware(ar->firmware); - ar->board = NULL; ar->board_data = NULL; - ar->board_len = 0; - ar->otp = NULL; - ar->otp_data = NULL; - ar->otp_len = 0; - ar->firmware = NULL; - ar->firmware_data = NULL; - ar->firmware_len = 0; } -static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar) +static int ath10k_core_fetch_firmware_files(struct ath10k *ar) { int ret = 0; @@ -332,18 +358,15 @@ static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar) return -EINVAL; } - ar->board = ath10k_fetch_fw_file(ar, - ar->hw_params.fw.dir, - ar->hw_params.fw.board); - if (IS_ERR(ar->board)) { - ret = PTR_ERR(ar->board); + ar->board_data = ath10k_fetch_fw_file(ar, + ar->hw_params.fw.dir, + ar->hw_params.fw.board); + if (IS_ERR(ar->board_data)) { + ret = PTR_ERR(ar->board_data); ath10k_err("could not fetch board data (%d)\n", ret); goto err; } - ar->board_data = ar->board->data; - ar->board_len = ar->board->size; - ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, ar->hw_params.fw.fw); @@ -353,9 +376,6 @@ static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar) goto err; } - ar->firmware_data = ar->firmware->data; - ar->firmware_len = ar->firmware->size; - /* OTP may be undefined. If so, don't fetch it at all */ if (ar->hw_params.fw.otp == NULL) return 0; @@ -369,172 +389,6 @@ static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar) goto err; } - ar->otp_data = ar->otp->data; - ar->otp_len = ar->otp->size; - - return 0; - -err: - ath10k_core_free_firmware_files(ar); - return ret; -} - -static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) -{ - size_t magic_len, len, ie_len; - int ie_id, i, index, bit, ret; - struct ath10k_fw_ie *hdr; - const u8 *data; - __le32 *timestamp; - - /* first fetch the firmware file (firmware-*.bin) */ - ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name); - if (IS_ERR(ar->firmware)) { - ath10k_err("Could not fetch firmware file '%s': %ld\n", - name, PTR_ERR(ar->firmware)); - return PTR_ERR(ar->firmware); - } - - data = ar->firmware->data; - len = ar->firmware->size; - - /* magic also includes the null byte, check that as well */ - magic_len = strlen(ATH10K_FIRMWARE_MAGIC) + 1; - - if (len < magic_len) { - ath10k_err("firmware image too small to contain magic: %zu\n", - len); - ret = -EINVAL; - goto err; - } - - if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) { - ath10k_err("Invalid firmware magic\n"); - ret = -EINVAL; - goto err; - } - - /* jump over the padding */ - magic_len = ALIGN(magic_len, 4); - - len -= magic_len; - data += magic_len; - - /* loop elements */ - while (len > sizeof(struct ath10k_fw_ie)) { - hdr = (struct ath10k_fw_ie *)data; - - ie_id = le32_to_cpu(hdr->id); - ie_len = le32_to_cpu(hdr->len); - - len -= sizeof(*hdr); - data += sizeof(*hdr); - - if (len < ie_len) { - ath10k_err("Invalid length for FW IE %d (%zu < %zu)\n", - ie_id, len, ie_len); - ret = -EINVAL; - goto err; - } - - switch (ie_id) { - case ATH10K_FW_IE_FW_VERSION: - if (ie_len > sizeof(ar->hw->wiphy->fw_version) - 1) - break; - - memcpy(ar->hw->wiphy->fw_version, data, ie_len); - ar->hw->wiphy->fw_version[ie_len] = '\0'; - - ath10k_dbg(ATH10K_DBG_BOOT, - "found fw version %s\n", - ar->hw->wiphy->fw_version); - break; - case ATH10K_FW_IE_TIMESTAMP: - if (ie_len != sizeof(u32)) - break; - - timestamp = (__le32 *)data; - - ath10k_dbg(ATH10K_DBG_BOOT, "found fw timestamp %d\n", - le32_to_cpup(timestamp)); - break; - case ATH10K_FW_IE_FEATURES: - ath10k_dbg(ATH10K_DBG_BOOT, - "found firmware features ie (%zd B)\n", - ie_len); - - for (i = 0; i < ATH10K_FW_FEATURE_COUNT; i++) { - index = i / 8; - bit = i % 8; - - if (index == ie_len) - break; - - if (data[index] & (1 << bit)) - __set_bit(i, ar->fw_features); - } - - ath10k_dbg_dump(ATH10K_DBG_BOOT, "features", "", - ar->fw_features, - sizeof(ar->fw_features)); - break; - case ATH10K_FW_IE_FW_IMAGE: - ath10k_dbg(ATH10K_DBG_BOOT, - "found fw image ie (%zd B)\n", - ie_len); - - ar->firmware_data = data; - ar->firmware_len = ie_len; - - break; - case ATH10K_FW_IE_OTP_IMAGE: - ath10k_dbg(ATH10K_DBG_BOOT, - "found otp image ie (%zd B)\n", - ie_len); - - ar->otp_data = data; - ar->otp_len = ie_len; - - break; - default: - ath10k_warn("Unknown FW IE: %u\n", - le32_to_cpu(hdr->id)); - break; - } - - /* jump over the padding */ - ie_len = ALIGN(ie_len, 4); - - len -= ie_len; - data += ie_len; - } - - if (!ar->firmware_data || !ar->firmware_len) { - ath10k_warn("No ATH10K_FW_IE_FW_IMAGE found from %s, skipping\n", - name); - ret = -ENOMEDIUM; - goto err; - } - - /* now fetch the board file */ - if (ar->hw_params.fw.board == NULL) { - ath10k_err("board data file not defined"); - ret = -EINVAL; - goto err; - } - - ar->board = ath10k_fetch_fw_file(ar, - ar->hw_params.fw.dir, - ar->hw_params.fw.board); - if (IS_ERR(ar->board)) { - ret = PTR_ERR(ar->board); - ath10k_err("could not fetch board data (%d)\n", ret); - goto err; - } - - ar->board_data = ar->board->data; - ar->board_len = ar->board->size; - return 0; err: @@ -542,28 +396,6 @@ err: return ret; } -static int ath10k_core_fetch_firmware_files(struct ath10k *ar) -{ - int ret; - - ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API2_FILE); - if (ret == 0) { - ar->fw_api = 2; - goto out; - } - - ret = ath10k_core_fetch_firmware_api_1(ar); - if (ret) - return ret; - - ar->fw_api = 1; - -out: - ath10k_dbg(ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api); - - return 0; -} - static int ath10k_init_download_firmware(struct ath10k *ar) { int ret; @@ -614,13 +446,6 @@ static int ath10k_init_uart(struct ath10k *ar) return ret; } - /* Set the UART baud rate to 19200. */ - ret = ath10k_bmi_write32(ar, hi_desired_baud_rate, 19200); - if (ret) { - ath10k_warn("could not set the baud rate (%d)\n", ret); - return ret; - } - ath10k_info("UART prints enabled\n"); return 0; } @@ -720,9 +545,6 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work); skb_queue_head_init(&ar->offchan_tx_queue); - INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work); - skb_queue_head_init(&ar->wmi_mgmt_tx_queue); - init_waitqueue_head(&ar->event_queue); INIT_WORK(&ar->restart_work, ath10k_core_restart); @@ -737,8 +559,6 @@ EXPORT_SYMBOL(ath10k_core_create); void ath10k_core_destroy(struct ath10k *ar) { - ath10k_debug_destroy(ar); - flush_workqueue(ar->workqueue); destroy_workqueue(ar->workqueue); @@ -750,8 +570,6 @@ int ath10k_core_start(struct ath10k *ar) { int status; - lockdep_assert_held(&ar->conf_mutex); - ath10k_bmi_start(ar); if (ath10k_init_configure_target(ar)) { @@ -802,6 +620,10 @@ int ath10k_core_start(struct ath10k *ar) ath10k_info("firmware %s booted\n", ar->hw->wiphy->fw_version); + status = ath10k_check_fw_version(ar); + if (status) + goto err_disconnect_htc; + status = ath10k_wmi_cmd_init(ar); if (status) { ath10k_err("could not send WMI init command (%d)\n", status); @@ -819,12 +641,7 @@ int ath10k_core_start(struct ath10k *ar) if (status) goto err_disconnect_htc; - status = ath10k_debug_start(ar); - if (status) - goto err_disconnect_htc; - ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1; - INIT_LIST_HEAD(&ar->arvifs); return 0; @@ -841,9 +658,6 @@ EXPORT_SYMBOL(ath10k_core_start); void ath10k_core_stop(struct ath10k *ar) { - lockdep_assert_held(&ar->conf_mutex); - - ath10k_debug_stop(ar); ath10k_htc_stop(&ar->htc); ath10k_htt_detach(&ar->htt); ath10k_wmi_detach(ar); @@ -890,65 +704,23 @@ static int ath10k_core_probe_fw(struct ath10k *ar) return ret; } - mutex_lock(&ar->conf_mutex); - ret = ath10k_core_start(ar); if (ret) { ath10k_err("could not init core (%d)\n", ret); ath10k_core_free_firmware_files(ar); ath10k_hif_power_down(ar); - mutex_unlock(&ar->conf_mutex); return ret; } ath10k_core_stop(ar); - - mutex_unlock(&ar->conf_mutex); - ath10k_hif_power_down(ar); return 0; } -static int ath10k_core_check_chip_id(struct ath10k *ar) -{ - u32 hw_revision = MS(ar->chip_id, SOC_CHIP_ID_REV); - - ath10k_dbg(ATH10K_DBG_BOOT, "boot chip_id 0x%08x hw_revision 0x%x\n", - ar->chip_id, hw_revision); - - /* Check that we are not using hw1.0 (some of them have same pci id - * as hw2.0) before doing anything else as ath10k crashes horribly - * due to missing hw1.0 workarounds. */ - switch (hw_revision) { - case QCA988X_HW_1_0_CHIP_ID_REV: - ath10k_err("ERROR: qca988x hw1.0 is not supported\n"); - return -EOPNOTSUPP; - - case QCA988X_HW_2_0_CHIP_ID_REV: - /* known hardware revision, continue normally */ - return 0; - - default: - ath10k_warn("Warning: hardware revision unknown (0x%x), expect problems\n", - ar->chip_id); - return 0; - } - - return 0; -} - -int ath10k_core_register(struct ath10k *ar, u32 chip_id) +int ath10k_core_register(struct ath10k *ar) { int status; - ar->chip_id = chip_id; - - status = ath10k_core_check_chip_id(ar); - if (status) { - ath10k_err("Unsupported chip id 0x%08x\n", ar->chip_id); - return status; - } - status = ath10k_core_probe_fw(ar); if (status) { ath10k_err("could not probe fw (%d)\n", status); @@ -983,7 +755,6 @@ void ath10k_core_unregister(struct ath10k *ar) * Otherwise we will fail to submit commands to FW and mac80211 will be * unhappy about callback failures. */ ath10k_mac_unregister(ar); - ath10k_core_free_firmware_files(ar); } EXPORT_SYMBOL(ath10k_core_unregister); diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 0934f76..e4bba56 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -43,23 +43,27 @@ /* Antenna noise floor */ #define ATH10K_DEFAULT_NOISE_FLOOR -95 -#define ATH10K_MAX_NUM_MGMT_PENDING 16 - struct ath10k; struct ath10k_skb_cb { dma_addr_t paddr; bool is_mapped; bool is_aborted; - u8 vdev_id; struct { + u8 vdev_id; + u16 msdu_id; u8 tid; bool is_offchan; - - u8 frag_len; - u8 pad_len; + bool is_conf; + bool discard; + bool no_ack; + u8 refcount; + struct sk_buff *txfrag; + struct sk_buff *msdu; } __packed htt; + + /* 4 bytes left on 64bit arch */ } __packed; static inline struct ath10k_skb_cb *ATH10K_SKB_CB(struct sk_buff *skb) @@ -104,26 +108,15 @@ struct ath10k_bmi { bool done_sent; }; -#define ATH10K_MAX_MEM_REQS 16 - -struct ath10k_mem_chunk { - void *vaddr; - dma_addr_t paddr; - u32 len; - u32 req_id; -}; - struct ath10k_wmi { enum ath10k_htc_ep_id eid; struct completion service_ready; struct completion unified_ready; - wait_queue_head_t tx_credits_wq; - struct wmi_cmd_map *cmd; - struct wmi_vdev_param_map *vdev_param; - struct wmi_pdev_param_map *pdev_param; + atomic_t pending_tx_count; + wait_queue_head_t wq; - u32 num_mem_chunks; - struct ath10k_mem_chunk mem_chunks[ATH10K_MAX_MEM_REQS]; + struct sk_buff_head wmi_event_list; + struct work_struct wmi_event_work; }; struct ath10k_peer_stat { @@ -205,22 +198,17 @@ struct ath10k_peer { #define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5*HZ) struct ath10k_vif { - struct list_head list; - u32 vdev_id; enum wmi_vdev_type vdev_type; enum wmi_vdev_subtype vdev_subtype; u32 beacon_interval; u32 dtim_period; - struct sk_buff *beacon; struct ath10k *ar; struct ieee80211_vif *vif; - struct work_struct wep_key_work; struct ieee80211_key_conf *wep_keys[WMI_MAX_KEY_INDEX + 1]; - u8 def_wep_key_idx; - u8 def_wep_key_newidx; + u8 def_wep_key_index; u16 tx_seq_no; @@ -258,9 +246,6 @@ struct ath10k_debug { u32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE]; struct completion event_stats_compl; - - unsigned long htt_stats_mask; - struct delayed_work htt_stats_dwork; }; enum ath10k_state { @@ -285,27 +270,12 @@ enum ath10k_state { ATH10K_STATE_WEDGED, }; -enum ath10k_fw_features { - /* wmi_mgmt_rx_hdr contains extra RSSI information */ - ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX = 0, - - /* firmware from 10X branch */ - ATH10K_FW_FEATURE_WMI_10X = 1, - - /* firmware support tx frame management over WMI, otherwise it's HTT */ - ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX = 2, - - /* keep last */ - ATH10K_FW_FEATURE_COUNT, -}; - struct ath10k { struct ath_common ath_common; struct ieee80211_hw *hw; struct device *dev; u8 mac_addr[ETH_ALEN]; - u32 chip_id; u32 target_version; u8 fw_version_major; u32 fw_version_minor; @@ -318,8 +288,6 @@ struct ath10k { u32 vht_cap_info; u32 num_rf_chains; - DECLARE_BITMAP(fw_features, ATH10K_FW_FEATURE_COUNT); - struct targetdef *targetdef; struct hostdef *hostdef; @@ -351,19 +319,9 @@ struct ath10k { } fw; } hw_params; - const struct firmware *board; - const void *board_data; - size_t board_len; - + const struct firmware *board_data; const struct firmware *otp; - const void *otp_data; - size_t otp_len; - const struct firmware *firmware; - const void *firmware_data; - size_t firmware_len; - - int fw_api; struct { struct completion started; @@ -406,7 +364,6 @@ struct ath10k { /* protects shared structure data */ spinlock_t data_lock; - struct list_head arvifs; struct list_head peers; wait_queue_head_t peer_mapping_wq; @@ -415,9 +372,6 @@ struct ath10k { struct completion offchan_tx_completed; struct sk_buff *offchan_tx_skb; - struct work_struct wmi_mgmt_tx_work; - struct sk_buff_head wmi_mgmt_tx_queue; - enum ath10k_state state; struct work_struct restart_work; @@ -439,7 +393,7 @@ void ath10k_core_destroy(struct ath10k *ar); int ath10k_core_start(struct ath10k *ar); void ath10k_core_stop(struct ath10k *ar); -int ath10k_core_register(struct ath10k *ar, u32 chip_id); +int ath10k_core_register(struct ath10k *ar); void ath10k_core_unregister(struct ath10k *ar); #endif /* _CORE_H_ */ diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 760ff22..3d65594 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -21,9 +21,6 @@ #include "core.h" #include "debug.h" -/* ms */ -#define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000 - static int ath10k_printk(const char *level, const char *fmt, ...) { struct va_format vaf; @@ -263,6 +260,7 @@ void ath10k_debug_read_target_stats(struct ath10k *ar, } spin_unlock_bh(&ar->data_lock); + mutex_unlock(&ar->conf_mutex); complete(&ar->debug.event_stats_compl); } @@ -501,144 +499,6 @@ static const struct file_operations fops_simulate_fw_crash = { .llseek = default_llseek, }; -static ssize_t ath10k_read_chip_id(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath10k *ar = file->private_data; - unsigned int len; - char buf[50]; - - len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->chip_id); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static const struct file_operations fops_chip_id = { - .read = ath10k_read_chip_id, - .open = simple_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -static int ath10k_debug_htt_stats_req(struct ath10k *ar) -{ - u64 cookie; - int ret; - - lockdep_assert_held(&ar->conf_mutex); - - if (ar->debug.htt_stats_mask == 0) - /* htt stats are disabled */ - return 0; - - if (ar->state != ATH10K_STATE_ON) - return 0; - - cookie = get_jiffies_64(); - - ret = ath10k_htt_h2t_stats_req(&ar->htt, ar->debug.htt_stats_mask, - cookie); - if (ret) { - ath10k_warn("failed to send htt stats request: %d\n", ret); - return ret; - } - - queue_delayed_work(ar->workqueue, &ar->debug.htt_stats_dwork, - msecs_to_jiffies(ATH10K_DEBUG_HTT_STATS_INTERVAL)); - - return 0; -} - -static void ath10k_debug_htt_stats_dwork(struct work_struct *work) -{ - struct ath10k *ar = container_of(work, struct ath10k, - debug.htt_stats_dwork.work); - - mutex_lock(&ar->conf_mutex); - - ath10k_debug_htt_stats_req(ar); - - mutex_unlock(&ar->conf_mutex); -} - -static ssize_t ath10k_read_htt_stats_mask(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath10k *ar = file->private_data; - char buf[32]; - unsigned int len; - - len = scnprintf(buf, sizeof(buf), "%lu\n", ar->debug.htt_stats_mask); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static ssize_t ath10k_write_htt_stats_mask(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath10k *ar = file->private_data; - unsigned long mask; - int ret; - - ret = kstrtoul_from_user(user_buf, count, 0, &mask); - if (ret) - return ret; - - /* max 8 bit masks (for now) */ - if (mask > 0xff) - return -E2BIG; - - mutex_lock(&ar->conf_mutex); - - ar->debug.htt_stats_mask = mask; - - ret = ath10k_debug_htt_stats_req(ar); - if (ret) - goto out; - - ret = count; - -out: - mutex_unlock(&ar->conf_mutex); - - return ret; -} - -static const struct file_operations fops_htt_stats_mask = { - .read = ath10k_read_htt_stats_mask, - .write = ath10k_write_htt_stats_mask, - .open = simple_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -int ath10k_debug_start(struct ath10k *ar) -{ - int ret; - - lockdep_assert_held(&ar->conf_mutex); - - ret = ath10k_debug_htt_stats_req(ar); - if (ret) - /* continue normally anyway, this isn't serious */ - ath10k_warn("failed to start htt stats workqueue: %d\n", ret); - - return 0; -} - -void ath10k_debug_stop(struct ath10k *ar) -{ - lockdep_assert_held(&ar->conf_mutex); - - /* Must not use _sync to avoid deadlock, we do that in - * ath10k_debug_destroy(). The check for htt_stats_mask is to avoid - * warning from del_timer(). */ - if (ar->debug.htt_stats_mask != 0) - cancel_delayed_work(&ar->debug.htt_stats_dwork); -} - int ath10k_debug_create(struct ath10k *ar) { ar->debug.debugfs_phy = debugfs_create_dir("ath10k", @@ -647,9 +507,6 @@ int ath10k_debug_create(struct ath10k *ar) if (!ar->debug.debugfs_phy) return -ENOMEM; - INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork, - ath10k_debug_htt_stats_dwork); - init_completion(&ar->debug.event_stats_compl); debugfs_create_file("fw_stats", S_IRUSR, ar->debug.debugfs_phy, ar, @@ -661,20 +518,8 @@ int ath10k_debug_create(struct ath10k *ar) debugfs_create_file("simulate_fw_crash", S_IRUSR, ar->debug.debugfs_phy, ar, &fops_simulate_fw_crash); - debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy, - ar, &fops_chip_id); - - debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy, - ar, &fops_htt_stats_mask); - return 0; } - -void ath10k_debug_destroy(struct ath10k *ar) -{ - cancel_delayed_work_sync(&ar->debug.htt_stats_dwork); -} - #endif /* CONFIG_ATH10K_DEBUGFS */ #ifdef CONFIG_ATH10K_DEBUG diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h index 3cfe3ee..168140c 100644 --- a/drivers/net/wireless/ath/ath10k/debug.h +++ b/drivers/net/wireless/ath/ath10k/debug.h @@ -27,26 +27,22 @@ enum ath10k_debug_mask { ATH10K_DBG_HTC = 0x00000004, ATH10K_DBG_HTT = 0x00000008, ATH10K_DBG_MAC = 0x00000010, - ATH10K_DBG_BOOT = 0x00000020, + ATH10K_DBG_CORE = 0x00000020, ATH10K_DBG_PCI_DUMP = 0x00000040, ATH10K_DBG_HTT_DUMP = 0x00000080, ATH10K_DBG_MGMT = 0x00000100, ATH10K_DBG_DATA = 0x00000200, - ATH10K_DBG_BMI = 0x00000400, ATH10K_DBG_ANY = 0xffffffff, }; extern unsigned int ath10k_debug_mask; -__printf(1, 2) int ath10k_info(const char *fmt, ...); -__printf(1, 2) int ath10k_err(const char *fmt, ...); -__printf(1, 2) int ath10k_warn(const char *fmt, ...); +extern __printf(1, 2) int ath10k_info(const char *fmt, ...); +extern __printf(1, 2) int ath10k_err(const char *fmt, ...); +extern __printf(1, 2) int ath10k_warn(const char *fmt, ...); #ifdef CONFIG_ATH10K_DEBUGFS -int ath10k_debug_start(struct ath10k *ar); -void ath10k_debug_stop(struct ath10k *ar); int ath10k_debug_create(struct ath10k *ar); -void ath10k_debug_destroy(struct ath10k *ar); void ath10k_debug_read_service_map(struct ath10k *ar, void *service_map, size_t map_size); @@ -54,24 +50,11 @@ void ath10k_debug_read_target_stats(struct ath10k *ar, struct wmi_stats_event *ev); #else -static inline int ath10k_debug_start(struct ath10k *ar) -{ - return 0; -} - -static inline void ath10k_debug_stop(struct ath10k *ar) -{ -} - static inline int ath10k_debug_create(struct ath10k *ar) { return 0; } -static inline void ath10k_debug_destroy(struct ath10k *ar) -{ -} - static inline void ath10k_debug_read_service_map(struct ath10k *ar, void *service_map, size_t map_size) @@ -85,7 +68,7 @@ static inline void ath10k_debug_read_target_stats(struct ath10k *ar, #endif /* CONFIG_ATH10K_DEBUGFS */ #ifdef CONFIG_ATH10K_DEBUG -__printf(2, 3) void ath10k_dbg(enum ath10k_debug_mask mask, +extern __printf(2, 3) void ath10k_dbg(enum ath10k_debug_mask mask, const char *fmt, ...); void ath10k_dbg_dump(enum ath10k_debug_mask mask, const char *msg, const char *prefix, diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c index edae50b..ef3329e 100644 --- a/drivers/net/wireless/ath/ath10k/htc.c +++ b/drivers/net/wireless/ath/ath10k/htc.c @@ -103,10 +103,10 @@ static void ath10k_htc_prepare_tx_skb(struct ath10k_htc_ep *ep, struct ath10k_htc_hdr *hdr; hdr = (struct ath10k_htc_hdr *)skb->data; + memset(hdr, 0, sizeof(*hdr)); hdr->eid = ep->eid; hdr->len = __cpu_to_le16(skb->len - sizeof(*hdr)); - hdr->flags = 0; spin_lock_bh(&ep->htc->tx_lock); hdr->seq_no = ep->seq_no++; @@ -117,13 +117,134 @@ static void ath10k_htc_prepare_tx_skb(struct ath10k_htc_ep *ep, spin_unlock_bh(&ep->htc->tx_lock); } +static int ath10k_htc_issue_skb(struct ath10k_htc *htc, + struct ath10k_htc_ep *ep, + struct sk_buff *skb, + u8 credits) +{ + struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb); + int ret; + + ath10k_dbg(ATH10K_DBG_HTC, "%s: ep %d skb %p\n", __func__, + ep->eid, skb); + + ath10k_htc_prepare_tx_skb(ep, skb); + + ret = ath10k_skb_map(htc->ar->dev, skb); + if (ret) + goto err; + + ret = ath10k_hif_send_head(htc->ar, + ep->ul_pipe_id, + ep->eid, + skb->len, + skb); + if (unlikely(ret)) + goto err; + + return 0; +err: + ath10k_warn("HTC issue failed: %d\n", ret); + + spin_lock_bh(&htc->tx_lock); + ep->tx_credits += credits; + spin_unlock_bh(&htc->tx_lock); + + /* this is the simplest way to handle out-of-resources for non-credit + * based endpoints. credit based endpoints can still get -ENOSR, but + * this is highly unlikely as credit reservation should prevent that */ + if (ret == -ENOSR) { + spin_lock_bh(&htc->tx_lock); + __skb_queue_head(&ep->tx_queue, skb); + spin_unlock_bh(&htc->tx_lock); + + return ret; + } + + skb_cb->is_aborted = true; + ath10k_htc_notify_tx_completion(ep, skb); + + return ret; +} + +static struct sk_buff *ath10k_htc_get_skb_credit_based(struct ath10k_htc *htc, + struct ath10k_htc_ep *ep, + u8 *credits) +{ + struct sk_buff *skb; + struct ath10k_skb_cb *skb_cb; + int credits_required; + int remainder; + unsigned int transfer_len; + + lockdep_assert_held(&htc->tx_lock); + + skb = __skb_dequeue(&ep->tx_queue); + if (!skb) + return NULL; + + skb_cb = ATH10K_SKB_CB(skb); + transfer_len = skb->len; + + if (likely(transfer_len <= htc->target_credit_size)) { + credits_required = 1; + } else { + /* figure out how many credits this message requires */ + credits_required = transfer_len / htc->target_credit_size; + remainder = transfer_len % htc->target_credit_size; + + if (remainder) + credits_required++; + } + + ath10k_dbg(ATH10K_DBG_HTC, "Credits required %d got %d\n", + credits_required, ep->tx_credits); + + if (ep->tx_credits < credits_required) { + __skb_queue_head(&ep->tx_queue, skb); + return NULL; + } + + ep->tx_credits -= credits_required; + *credits = credits_required; + return skb; +} + +static void ath10k_htc_send_work(struct work_struct *work) +{ + struct ath10k_htc_ep *ep = container_of(work, + struct ath10k_htc_ep, send_work); + struct ath10k_htc *htc = ep->htc; + struct sk_buff *skb; + u8 credits = 0; + int ret; + + while (true) { + if (ep->ul_is_polled) + ath10k_htc_send_complete_check(ep, 0); + + spin_lock_bh(&htc->tx_lock); + if (ep->tx_credit_flow_enabled) + skb = ath10k_htc_get_skb_credit_based(htc, ep, + &credits); + else + skb = __skb_dequeue(&ep->tx_queue); + spin_unlock_bh(&htc->tx_lock); + + if (!skb) + break; + + ret = ath10k_htc_issue_skb(htc, ep, skb, credits); + if (ret == -ENOSR) + break; + } +} + int ath10k_htc_send(struct ath10k_htc *htc, enum ath10k_htc_ep_id eid, struct sk_buff *skb) { struct ath10k_htc_ep *ep = &htc->endpoint[eid]; - int credits = 0; - int ret; if (htc->ar->state == ATH10K_STATE_WEDGED) return -ECOMM; @@ -133,55 +254,18 @@ int ath10k_htc_send(struct ath10k_htc *htc, return -ENOENT; } - /* FIXME: This looks ugly, can we fix it? */ spin_lock_bh(&htc->tx_lock); if (htc->stopped) { spin_unlock_bh(&htc->tx_lock); return -ESHUTDOWN; } - spin_unlock_bh(&htc->tx_lock); + __skb_queue_tail(&ep->tx_queue, skb); skb_push(skb, sizeof(struct ath10k_htc_hdr)); + spin_unlock_bh(&htc->tx_lock); - if (ep->tx_credit_flow_enabled) { - credits = DIV_ROUND_UP(skb->len, htc->target_credit_size); - spin_lock_bh(&htc->tx_lock); - if (ep->tx_credits < credits) { - spin_unlock_bh(&htc->tx_lock); - ret = -EAGAIN; - goto err_pull; - } - ep->tx_credits -= credits; - spin_unlock_bh(&htc->tx_lock); - } - - ath10k_htc_prepare_tx_skb(ep, skb); - - ret = ath10k_skb_map(htc->ar->dev, skb); - if (ret) - goto err_credits; - - ret = ath10k_hif_send_head(htc->ar, ep->ul_pipe_id, ep->eid, - skb->len, skb); - if (ret) - goto err_unmap; - + queue_work(htc->ar->workqueue, &ep->send_work); return 0; - -err_unmap: - ath10k_skb_unmap(htc->ar->dev, skb); -err_credits: - if (ep->tx_credit_flow_enabled) { - spin_lock_bh(&htc->tx_lock); - ep->tx_credits += credits; - spin_unlock_bh(&htc->tx_lock); - - if (ep->ep_ops.ep_tx_credits) - ep->ep_ops.ep_tx_credits(htc->ar); - } -err_pull: - skb_pull(skb, sizeof(struct ath10k_htc_hdr)); - return ret; } static int ath10k_htc_tx_completion_handler(struct ath10k *ar, @@ -194,9 +278,39 @@ static int ath10k_htc_tx_completion_handler(struct ath10k *ar, ath10k_htc_notify_tx_completion(ep, skb); /* the skb now belongs to the completion handler */ + /* note: when using TX credit flow, the re-checking of queues happens + * when credits flow back from the target. in the non-TX credit case, + * we recheck after the packet completes */ + spin_lock_bh(&htc->tx_lock); + if (!ep->tx_credit_flow_enabled && !htc->stopped) + queue_work(ar->workqueue, &ep->send_work); + spin_unlock_bh(&htc->tx_lock); + return 0; } +/* flush endpoint TX queue */ +static void ath10k_htc_flush_endpoint_tx(struct ath10k_htc *htc, + struct ath10k_htc_ep *ep) +{ + struct sk_buff *skb; + struct ath10k_skb_cb *skb_cb; + + spin_lock_bh(&htc->tx_lock); + for (;;) { + skb = __skb_dequeue(&ep->tx_queue); + if (!skb) + break; + + skb_cb = ATH10K_SKB_CB(skb); + skb_cb->is_aborted = true; + ath10k_htc_notify_tx_completion(ep, skb); + } + spin_unlock_bh(&htc->tx_lock); + + cancel_work_sync(&ep->send_work); +} + /***********/ /* Receive */ /***********/ @@ -226,11 +340,8 @@ ath10k_htc_process_credit_report(struct ath10k_htc *htc, ep = &htc->endpoint[report->eid]; ep->tx_credits += report->credits; - if (ep->ep_ops.ep_tx_credits) { - spin_unlock_bh(&htc->tx_lock); - ep->ep_ops.ep_tx_credits(htc->ar); - spin_lock_bh(&htc->tx_lock); - } + if (ep->tx_credits && !skb_queue_empty(&ep->tx_queue)) + queue_work(htc->ar->workqueue, &ep->send_work); } spin_unlock_bh(&htc->tx_lock); } @@ -488,8 +599,10 @@ static void ath10k_htc_reset_endpoint_states(struct ath10k_htc *htc) ep->max_ep_message_len = 0; ep->max_tx_queue_depth = 0; ep->eid = i; + skb_queue_head_init(&ep->tx_queue); ep->htc = htc; ep->tx_credit_flow_enabled = true; + INIT_WORK(&ep->send_work, ath10k_htc_send_work); } } @@ -534,7 +647,7 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc) u16 credit_count; u16 credit_size; - reinit_completion(&htc->ctl_resp); + INIT_COMPLETION(htc->ctl_resp); status = ath10k_hif_start(htc->ar); if (status) { @@ -639,8 +752,8 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc, tx_alloc = ath10k_htc_get_credit_allocation(htc, conn_req->service_id); if (!tx_alloc) - ath10k_dbg(ATH10K_DBG_BOOT, - "boot htc service %s does not allocate target credits\n", + ath10k_dbg(ATH10K_DBG_HTC, + "HTC Service %s does not allocate target credits\n", htc_service_name(conn_req->service_id)); skb = ath10k_htc_build_tx_ctrl_skb(htc->ar); @@ -659,17 +772,17 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc, flags |= SM(tx_alloc, ATH10K_HTC_CONN_FLAGS_RECV_ALLOC); + req_msg = &msg->connect_service; + req_msg->flags = __cpu_to_le16(flags); + req_msg->service_id = __cpu_to_le16(conn_req->service_id); + /* Only enable credit flow control for WMI ctrl service */ if (conn_req->service_id != ATH10K_HTC_SVC_ID_WMI_CONTROL) { flags |= ATH10K_HTC_CONN_FLAGS_DISABLE_CREDIT_FLOW_CTRL; disable_credit_flow_ctrl = true; } - req_msg = &msg->connect_service; - req_msg->flags = __cpu_to_le16(flags); - req_msg->service_id = __cpu_to_le16(conn_req->service_id); - - reinit_completion(&htc->ctl_resp); + INIT_COMPLETION(htc->ctl_resp); status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb); if (status) { @@ -760,19 +873,19 @@ setup: if (status) return status; - ath10k_dbg(ATH10K_DBG_BOOT, - "boot htc service '%s' ul pipe %d dl pipe %d eid %d ready\n", + ath10k_dbg(ATH10K_DBG_HTC, + "HTC service: %s UL pipe: %d DL pipe: %d eid: %d ready\n", htc_service_name(ep->service_id), ep->ul_pipe_id, ep->dl_pipe_id, ep->eid); - ath10k_dbg(ATH10K_DBG_BOOT, - "boot htc ep %d ul polled %d dl polled %d\n", + ath10k_dbg(ATH10K_DBG_HTC, + "EP %d UL polled: %d, DL polled: %d\n", ep->eid, ep->ul_is_polled, ep->dl_is_polled); if (disable_credit_flow_ctrl && ep->tx_credit_flow_enabled) { ep->tx_credit_flow_enabled = false; - ath10k_dbg(ATH10K_DBG_BOOT, - "boot htc service '%s' eid %d TX flow control disabled\n", + ath10k_dbg(ATH10K_DBG_HTC, + "HTC service: %s eid: %d TX flow control disabled\n", htc_service_name(ep->service_id), assigned_eid); } @@ -832,10 +945,18 @@ int ath10k_htc_start(struct ath10k_htc *htc) */ void ath10k_htc_stop(struct ath10k_htc *htc) { + int i; + struct ath10k_htc_ep *ep; + spin_lock_bh(&htc->tx_lock); htc->stopped = true; spin_unlock_bh(&htc->tx_lock); + for (i = ATH10K_HTC_EP_0; i < ATH10K_HTC_EP_COUNT; i++) { + ep = &htc->endpoint[i]; + ath10k_htc_flush_endpoint_tx(htc, ep); + } + ath10k_hif_stop(htc->ar); } diff --git a/drivers/net/wireless/ath/ath10k/htc.h b/drivers/net/wireless/ath/ath10k/htc.h index 4716d33..e1dd8c7 100644 --- a/drivers/net/wireless/ath/ath10k/htc.h +++ b/drivers/net/wireless/ath/ath10k/htc.h @@ -276,7 +276,6 @@ struct ath10k_htc_ops { struct ath10k_htc_ep_ops { void (*ep_tx_complete)(struct ath10k *, struct sk_buff *); void (*ep_rx_complete)(struct ath10k *, struct sk_buff *); - void (*ep_tx_credits)(struct ath10k *); }; /* service connection information */ @@ -316,11 +315,15 @@ struct ath10k_htc_ep { int ul_is_polled; /* call HIF to get tx completions */ int dl_is_polled; /* call HIF to fetch rx (not implemented) */ + struct sk_buff_head tx_queue; + u8 seq_no; /* for debugging */ int tx_credits; int tx_credit_size; int tx_credits_per_max_message; bool tx_credit_flow_enabled; + + struct work_struct send_work; }; struct ath10k_htc_svc_tx_credits { diff --git a/drivers/net/wireless/ath/ath10k/htt.c b/drivers/net/wireless/ath/ath10k/htt.c index 5f7eeeb..39342c5 100644 --- a/drivers/net/wireless/ath/ath10k/htt.c +++ b/drivers/net/wireless/ath/ath10k/htt.c @@ -104,16 +104,21 @@ err_htc_attach: static int ath10k_htt_verify_version(struct ath10k_htt *htt) { - ath10k_info("htt target version %d.%d\n", - htt->target_version_major, htt->target_version_minor); - - if (htt->target_version_major != 2 && - htt->target_version_major != 3) { - ath10k_err("unsupported htt major version %d. supported versions are 2 and 3\n", - htt->target_version_major); + ath10k_dbg(ATH10K_DBG_HTT, + "htt target version %d.%d; host version %d.%d\n", + htt->target_version_major, + htt->target_version_minor, + HTT_CURRENT_VERSION_MAJOR, + HTT_CURRENT_VERSION_MINOR); + + if (htt->target_version_major != HTT_CURRENT_VERSION_MAJOR) { + ath10k_err("htt major versions are incompatible!\n"); return -ENOTSUPP; } + if (htt->target_version_minor != HTT_CURRENT_VERSION_MINOR) + ath10k_warn("htt minor version differ but still compatible\n"); + return 0; } diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h index 1a337e9..318be46 100644 --- a/drivers/net/wireless/ath/ath10k/htt.h +++ b/drivers/net/wireless/ath/ath10k/htt.h @@ -19,11 +19,13 @@ #define _HTT_H_ #include <linux/bug.h> -#include <linux/interrupt.h> #include "htc.h" #include "rx_desc.h" +#define HTT_CURRENT_VERSION_MAJOR 2 +#define HTT_CURRENT_VERSION_MINOR 1 + enum htt_dbg_stats_type { HTT_DBG_STATS_WAL_PDEV_TXRX = 1 << 0, HTT_DBG_STATS_RX_REORDER = 1 << 1, @@ -43,9 +45,6 @@ enum htt_h2t_msg_type { /* host-to-target */ HTT_H2T_MSG_TYPE_SYNC = 4, HTT_H2T_MSG_TYPE_AGGR_CFG = 5, HTT_H2T_MSG_TYPE_FRAG_DESC_BANK_CFG = 6, - - /* This command is used for sending management frames in HTT < 3.0. - * HTT >= 3.0 uses TX_FRM for everything. */ HTT_H2T_MSG_TYPE_MGMT_TX = 7, HTT_H2T_NUM_MSGS /* keep this last */ @@ -1269,7 +1268,6 @@ struct ath10k_htt { /* set if host-fw communication goes haywire * used to avoid further failures */ bool rx_confused; - struct tasklet_struct rx_replenish_task; }; #define RX_HTT_HDR_STATUS_LEN 64 @@ -1310,10 +1308,6 @@ struct htt_rx_desc { #define HTT_RX_BUF_SIZE 1920 #define HTT_RX_MSDU_SIZE (HTT_RX_BUF_SIZE - (int)sizeof(struct htt_rx_desc)) -/* Refill a bunch of RX buffers for each refill round so that FW/HW can handle - * aggregated traffic more nicely. */ -#define ATH10K_HTT_MAX_NUM_REFILL 16 - /* * DMA_MAP expects the buffer to be an integral number of cache lines. * Rather than checking the actual cache line size, this code makes a @@ -1333,7 +1327,6 @@ void ath10k_htt_rx_detach(struct ath10k_htt *htt); void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb); void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb); int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt); -int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie); int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt); void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt); diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 90d4f74..e784c40 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -20,7 +20,6 @@ #include "htt.h" #include "txrx.h" #include "debug.h" -#include "trace.h" #include <linux/log2.h> @@ -41,10 +40,6 @@ /* when under memory pressure rx ring refill may fail and needs a retry */ #define HTT_RX_RING_REFILL_RETRY_MS 50 - -static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb); - - static int ath10k_htt_rx_ring_size(struct ath10k_htt *htt) { int size; @@ -182,27 +177,10 @@ static int ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num) static void ath10k_htt_rx_msdu_buff_replenish(struct ath10k_htt *htt) { - int ret, num_deficit, num_to_fill; + int ret, num_to_fill; - /* Refilling the whole RX ring buffer proves to be a bad idea. The - * reason is RX may take up significant amount of CPU cycles and starve - * other tasks, e.g. TX on an ethernet device while acting as a bridge - * with ath10k wlan interface. This ended up with very poor performance - * once CPU the host system was overwhelmed with RX on ath10k. - * - * By limiting the number of refills the replenishing occurs - * progressively. This in turns makes use of the fact tasklets are - * processed in FIFO order. This means actual RX processing can starve - * out refilling. If there's not enough buffers on RX ring FW will not - * report RX until it is refilled with enough buffers. This - * automatically balances load wrt to CPU power. - * - * This probably comes at a cost of lower maximum throughput but - * improves the avarage and stability. */ spin_lock_bh(&htt->rx_ring.lock); - num_deficit = htt->rx_ring.fill_level - htt->rx_ring.fill_cnt; - num_to_fill = min(ATH10K_HTT_MAX_NUM_REFILL, num_deficit); - num_deficit -= num_to_fill; + num_to_fill = htt->rx_ring.fill_level - htt->rx_ring.fill_cnt; ret = ath10k_htt_rx_ring_fill_n(htt, num_to_fill); if (ret == -ENOMEM) { /* @@ -213,8 +191,6 @@ static void ath10k_htt_rx_msdu_buff_replenish(struct ath10k_htt *htt) */ mod_timer(&htt->rx_ring.refill_retry_timer, jiffies + msecs_to_jiffies(HTT_RX_RING_REFILL_RETRY_MS)); - } else if (num_deficit > 0) { - tasklet_schedule(&htt->rx_replenish_task); } spin_unlock_bh(&htt->rx_ring.lock); } @@ -236,7 +212,6 @@ void ath10k_htt_rx_detach(struct ath10k_htt *htt) int sw_rd_idx = htt->rx_ring.sw_rd_idx.msdu_payld; del_timer_sync(&htt->rx_ring.refill_retry_timer); - tasklet_kill(&htt->rx_replenish_task); while (sw_rd_idx != __le32_to_cpu(*(htt->rx_ring.alloc_idx.vaddr))) { struct sk_buff *skb = @@ -466,12 +441,6 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, return msdu_chaining; } -static void ath10k_htt_rx_replenish_task(unsigned long ptr) -{ - struct ath10k_htt *htt = (struct ath10k_htt *)ptr; - ath10k_htt_rx_msdu_buff_replenish(htt); -} - int ath10k_htt_rx_attach(struct ath10k_htt *htt) { dma_addr_t paddr; @@ -532,10 +501,7 @@ int ath10k_htt_rx_attach(struct ath10k_htt *htt) if (__ath10k_htt_rx_ring_fill_n(htt, htt->rx_ring.fill_level)) goto err_fill_ring; - tasklet_init(&htt->rx_replenish_task, ath10k_htt_rx_replenish_task, - (unsigned long)htt); - - ath10k_dbg(ATH10K_DBG_BOOT, "htt rx ring size %d fill_level %d\n", + ath10k_dbg(ATH10K_DBG_HTT, "HTT RX ring size: %d, fill_level: %d\n", htt->rx_ring.size, htt->rx_ring.fill_level); return 0; @@ -624,144 +590,134 @@ static bool ath10k_htt_rx_hdr_is_amsdu(struct ieee80211_hdr *hdr) return false; } -struct rfc1042_hdr { - u8 llc_dsap; - u8 llc_ssap; - u8 llc_ctrl; - u8 snap_oui[3]; - __be16 snap_type; -} __packed; - -struct amsdu_subframe_hdr { - u8 dst[ETH_ALEN]; - u8 src[ETH_ALEN]; - __be16 len; -} __packed; - -static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, - struct htt_rx_info *info) +static int ath10k_htt_rx_amsdu(struct ath10k_htt *htt, + struct htt_rx_info *info) { struct htt_rx_desc *rxd; + struct sk_buff *amsdu; struct sk_buff *first; + struct ieee80211_hdr *hdr; struct sk_buff *skb = info->skb; enum rx_msdu_decap_format fmt; enum htt_rx_mpdu_encrypt_type enctype; - struct ieee80211_hdr *hdr; - u8 hdr_buf[64], addr[ETH_ALEN], *qos; unsigned int hdr_len; + int crypto_len; rxd = (void *)skb->data - sizeof(*rxd); + fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), + RX_MSDU_START_INFO1_DECAP_FORMAT); enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), RX_MPDU_START_INFO0_ENCRYPT_TYPE); - hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status; - hdr_len = ieee80211_hdrlen(hdr->frame_control); - memcpy(hdr_buf, hdr, hdr_len); - hdr = (struct ieee80211_hdr *)hdr_buf; + /* FIXME: No idea what assumptions are safe here. Need logs */ + if ((fmt == RX_MSDU_DECAP_RAW && skb->next) || + (fmt == RX_MSDU_DECAP_8023_SNAP_LLC)) { + ath10k_htt_rx_free_msdu_chain(skb->next); + skb->next = NULL; + return -ENOTSUPP; + } - /* FIXME: Hopefully this is a temporary measure. - * - * Reporting individual A-MSDU subframes means each reported frame - * shares the same sequence number. - * - * mac80211 drops frames it recognizes as duplicates, i.e. - * retransmission flag is set and sequence number matches sequence - * number from a previous frame (as per IEEE 802.11-2012: 9.3.2.10 - * "Duplicate detection and recovery") - * - * To avoid frames being dropped clear retransmission flag for all - * received A-MSDUs. - * - * Worst case: actual duplicate frames will be reported but this should - * still be handled gracefully by other OSI/ISO layers. */ - hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_RETRY); + /* A-MSDU max is a little less than 8K */ + amsdu = dev_alloc_skb(8*1024); + if (!amsdu) { + ath10k_warn("A-MSDU allocation failed\n"); + ath10k_htt_rx_free_msdu_chain(skb->next); + skb->next = NULL; + return -ENOMEM; + } + + if (fmt >= RX_MSDU_DECAP_NATIVE_WIFI) { + int hdrlen; + + hdr = (void *)rxd->rx_hdr_status; + hdrlen = ieee80211_hdrlen(hdr->frame_control); + memcpy(skb_put(amsdu, hdrlen), hdr, hdrlen); + } first = skb; while (skb) { void *decap_hdr; - int len; + int decap_len = 0; rxd = (void *)skb->data - sizeof(*rxd); fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), - RX_MSDU_START_INFO1_DECAP_FORMAT); + RX_MSDU_START_INFO1_DECAP_FORMAT); decap_hdr = (void *)rxd->rx_hdr_status; - skb->ip_summed = ath10k_htt_rx_get_csum_state(skb); - - /* First frame in an A-MSDU chain has more decapped data. */ if (skb == first) { - len = round_up(ieee80211_hdrlen(hdr->frame_control), 4); - len += round_up(ath10k_htt_rx_crypto_param_len(enctype), - 4); - decap_hdr += len; - } + /* We receive linked A-MSDU subframe skbuffs. The + * first one contains the original 802.11 header (and + * possible crypto param) in the RX descriptor. The + * A-MSDU subframe header follows that. Each part is + * aligned to 4 byte boundary. */ - switch (fmt) { - case RX_MSDU_DECAP_RAW: - /* remove trailing FCS */ - skb_trim(skb, skb->len - FCS_LEN); - break; - case RX_MSDU_DECAP_NATIVE_WIFI: - /* pull decapped header and copy DA */ - hdr = (struct ieee80211_hdr *)skb->data; + hdr = (void *)amsdu->data; hdr_len = ieee80211_hdrlen(hdr->frame_control); - memcpy(addr, ieee80211_get_DA(hdr), ETH_ALEN); - skb_pull(skb, hdr_len); + crypto_len = ath10k_htt_rx_crypto_param_len(enctype); - /* push original 802.11 header */ - hdr = (struct ieee80211_hdr *)hdr_buf; - hdr_len = ieee80211_hdrlen(hdr->frame_control); - memcpy(skb_push(skb, hdr_len), hdr, hdr_len); + decap_hdr += roundup(hdr_len, 4); + decap_hdr += roundup(crypto_len, 4); + } + + if (fmt == RX_MSDU_DECAP_ETHERNET2_DIX) { + /* Ethernet2 decap inserts ethernet header in place of + * A-MSDU subframe header. */ + skb_pull(skb, 6 + 6 + 2); + + /* A-MSDU subframe header length */ + decap_len += 6 + 6 + 2; + + /* Ethernet2 decap also strips the LLC/SNAP so we need + * to re-insert it. The LLC/SNAP follows A-MSDU + * subframe header. */ + /* FIXME: Not all LLCs are 8 bytes long */ + decap_len += 8; - /* original A-MSDU header has the bit set but we're - * not including A-MSDU subframe header */ + memcpy(skb_put(amsdu, decap_len), decap_hdr, decap_len); + } + + if (fmt == RX_MSDU_DECAP_NATIVE_WIFI) { + /* Native Wifi decap inserts regular 802.11 header + * in place of A-MSDU subframe header. */ hdr = (struct ieee80211_hdr *)skb->data; - qos = ieee80211_get_qos_ctl(hdr); - qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; + skb_pull(skb, ieee80211_hdrlen(hdr->frame_control)); - /* original 802.11 header has a different DA */ - memcpy(ieee80211_get_DA(hdr), addr, ETH_ALEN); - break; - case RX_MSDU_DECAP_ETHERNET2_DIX: - /* strip ethernet header and insert decapped 802.11 - * header, amsdu subframe header and rfc1042 header */ + /* A-MSDU subframe header length */ + decap_len += 6 + 6 + 2; - len = 0; - len += sizeof(struct rfc1042_hdr); - len += sizeof(struct amsdu_subframe_hdr); + memcpy(skb_put(amsdu, decap_len), decap_hdr, decap_len); + } - skb_pull(skb, sizeof(struct ethhdr)); - memcpy(skb_push(skb, len), decap_hdr, len); - memcpy(skb_push(skb, hdr_len), hdr, hdr_len); - break; - case RX_MSDU_DECAP_8023_SNAP_LLC: - /* insert decapped 802.11 header making a singly - * A-MSDU */ - memcpy(skb_push(skb, hdr_len), hdr, hdr_len); - break; + if (fmt == RX_MSDU_DECAP_RAW) + skb_trim(skb, skb->len - 4); /* remove FCS */ + + memcpy(skb_put(amsdu, skb->len), skb->data, skb->len); + + /* A-MSDU subframes are padded to 4bytes + * but relative to first subframe, not the whole MPDU */ + if (skb->next && ((decap_len + skb->len) & 3)) { + int padlen = 4 - ((decap_len + skb->len) & 3); + memset(skb_put(amsdu, padlen), 0, padlen); } - info->skb = skb; - info->encrypt_type = enctype; skb = skb->next; - info->skb->next = NULL; - - ath10k_process_rx(htt->ar, info); } - /* FIXME: It might be nice to re-assemble the A-MSDU when there's a - * monitor interface active for sniffing purposes. */ + info->skb = amsdu; + info->encrypt_type = enctype; + + ath10k_htt_rx_free_msdu_chain(first); + + return 0; } -static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info) +static int ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info) { struct sk_buff *skb = info->skb; struct htt_rx_desc *rxd; struct ieee80211_hdr *hdr; enum rx_msdu_decap_format fmt; enum htt_rx_mpdu_encrypt_type enctype; - int hdr_len; - void *rfc1042; /* This shouldn't happen. If it does than it may be a FW bug. */ if (skb->next) { @@ -775,53 +731,49 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, struct htt_rx_info *info) RX_MSDU_START_INFO1_DECAP_FORMAT); enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), RX_MPDU_START_INFO0_ENCRYPT_TYPE); - hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status; - hdr_len = ieee80211_hdrlen(hdr->frame_control); - - skb->ip_summed = ath10k_htt_rx_get_csum_state(skb); + hdr = (void *)skb->data - RX_HTT_HDR_STATUS_LEN; switch (fmt) { case RX_MSDU_DECAP_RAW: /* remove trailing FCS */ - skb_trim(skb, skb->len - FCS_LEN); + skb_trim(skb, skb->len - 4); break; case RX_MSDU_DECAP_NATIVE_WIFI: - /* Pull decapped header */ - hdr = (struct ieee80211_hdr *)skb->data; - hdr_len = ieee80211_hdrlen(hdr->frame_control); - skb_pull(skb, hdr_len); - - /* Push original header */ - hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status; - hdr_len = ieee80211_hdrlen(hdr->frame_control); - memcpy(skb_push(skb, hdr_len), hdr, hdr_len); + /* nothing to do here */ break; case RX_MSDU_DECAP_ETHERNET2_DIX: - /* strip ethernet header and insert decapped 802.11 header and - * rfc1042 header */ - - rfc1042 = hdr; - rfc1042 += roundup(hdr_len, 4); - rfc1042 += roundup(ath10k_htt_rx_crypto_param_len(enctype), 4); - - skb_pull(skb, sizeof(struct ethhdr)); - memcpy(skb_push(skb, sizeof(struct rfc1042_hdr)), - rfc1042, sizeof(struct rfc1042_hdr)); - memcpy(skb_push(skb, hdr_len), hdr, hdr_len); + /* macaddr[6] + macaddr[6] + ethertype[2] */ + skb_pull(skb, 6 + 6 + 2); break; case RX_MSDU_DECAP_8023_SNAP_LLC: - /* remove A-MSDU subframe header and insert - * decapped 802.11 header. rfc1042 header is already there */ - - skb_pull(skb, sizeof(struct amsdu_subframe_hdr)); - memcpy(skb_push(skb, hdr_len), hdr, hdr_len); + /* macaddr[6] + macaddr[6] + len[2] */ + /* we don't need this for non-A-MSDU */ + skb_pull(skb, 6 + 6 + 2); break; } + if (fmt == RX_MSDU_DECAP_ETHERNET2_DIX) { + void *llc; + int llclen; + + llclen = 8; + llc = hdr; + llc += roundup(ieee80211_hdrlen(hdr->frame_control), 4); + llc += roundup(ath10k_htt_rx_crypto_param_len(enctype), 4); + + skb_push(skb, llclen); + memcpy(skb->data, llc, llclen); + } + + if (fmt >= RX_MSDU_DECAP_ETHERNET2_DIX) { + int len = ieee80211_hdrlen(hdr->frame_control); + skb_push(skb, len); + memcpy(skb->data, hdr, len); + } + info->skb = skb; info->encrypt_type = enctype; - - ath10k_process_rx(htt->ar, info); + return 0; } static bool ath10k_htt_rx_has_decrypt_err(struct sk_buff *skb) @@ -893,6 +845,8 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, int fw_desc_len; u8 *fw_desc; int i, j; + int ret; + int ip_summed; memset(&info, 0, sizeof(info)); @@ -967,6 +921,11 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, continue; } + /* The skb is not yet processed and it may be + * reallocated. Since the offload is in the original + * skb extract the checksum now and assign it later */ + ip_summed = ath10k_htt_rx_get_csum_state(msdu_head); + info.skb = msdu_head; info.fcs_err = ath10k_htt_rx_has_fcs_err(msdu_head); info.signal = ATH10K_DEFAULT_NOISE_FLOOR; @@ -979,13 +938,28 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, hdr = ath10k_htt_rx_skb_get_hdr(msdu_head); if (ath10k_htt_rx_hdr_is_amsdu(hdr)) - ath10k_htt_rx_amsdu(htt, &info); + ret = ath10k_htt_rx_amsdu(htt, &info); else - ath10k_htt_rx_msdu(htt, &info); + ret = ath10k_htt_rx_msdu(htt, &info); + + if (ret && !info.fcs_err) { + ath10k_warn("error processing msdus %d\n", ret); + dev_kfree_skb_any(info.skb); + continue; + } + + if (ath10k_htt_rx_hdr_is_amsdu((void *)info.skb->data)) + ath10k_dbg(ATH10K_DBG_HTT, "htt mpdu is amsdu\n"); + + info.skb->ip_summed = ip_summed; + + ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt mpdu: ", + info.skb->data, info.skb->len); + ath10k_process_rx(htt->ar, &info); } } - tasklet_schedule(&htt->rx_replenish_task); + ath10k_htt_rx_msdu_buff_replenish(htt); } static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, @@ -1157,7 +1131,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) break; } - ath10k_txrx_tx_unref(htt, &tx_done); + ath10k_txrx_tx_completed(htt, &tx_done); break; } case HTT_T2H_MSG_TYPE_TX_COMPL_IND: { @@ -1191,7 +1165,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) for (i = 0; i < resp->data_tx_completion.num_msdus; i++) { msdu_id = resp->data_tx_completion.msdus[i]; tx_done.msdu_id = __le16_to_cpu(msdu_id); - ath10k_txrx_tx_unref(htt, &tx_done); + ath10k_txrx_tx_completed(htt, &tx_done); } break; } @@ -1216,10 +1190,8 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) case HTT_T2H_MSG_TYPE_TEST: /* FIX THIS */ break; - case HTT_T2H_MSG_TYPE_STATS_CONF: - trace_ath10k_htt_stats(skb->data, skb->len); - break; case HTT_T2H_MSG_TYPE_TX_INSPECT_IND: + case HTT_T2H_MSG_TYPE_STATS_CONF: case HTT_T2H_MSG_TYPE_RX_ADDBA: case HTT_T2H_MSG_TYPE_RX_DELBA: case HTT_T2H_MSG_TYPE_RX_FLUSH: diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c index d9335e9..656c254 100644 --- a/drivers/net/wireless/ath/ath10k/htt_tx.c +++ b/drivers/net/wireless/ath/ath10k/htt_tx.c @@ -96,7 +96,7 @@ int ath10k_htt_tx_attach(struct ath10k_htt *htt) htt->max_num_pending_tx = ath10k_hif_get_free_queue_number(htt->ar, pipe); - ath10k_dbg(ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n", + ath10k_dbg(ATH10K_DBG_HTT, "htt tx max num pending tx %d\n", htt->max_num_pending_tx); htt->pending_tx = kzalloc(sizeof(*htt->pending_tx) * @@ -117,7 +117,7 @@ int ath10k_htt_tx_attach(struct ath10k_htt *htt) static void ath10k_htt_tx_cleanup_pending(struct ath10k_htt *htt) { - struct htt_tx_done tx_done = {0}; + struct sk_buff *txdesc; int msdu_id; /* No locks needed. Called after communication with the device has @@ -127,13 +127,18 @@ static void ath10k_htt_tx_cleanup_pending(struct ath10k_htt *htt) if (!test_bit(msdu_id, htt->used_msdu_ids)) continue; + txdesc = htt->pending_tx[msdu_id]; + if (!txdesc) + continue; + ath10k_dbg(ATH10K_DBG_HTT, "force cleanup msdu_id %hu\n", msdu_id); - tx_done.discard = 1; - tx_done.msdu_id = msdu_id; + if (ATH10K_SKB_CB(txdesc)->htt.refcount > 0) + ATH10K_SKB_CB(txdesc)->htt.refcount = 1; - ath10k_txrx_tx_unref(htt, &tx_done); + ATH10K_SKB_CB(txdesc)->htt.discard = true; + ath10k_txrx_tx_unref(htt, txdesc); } } @@ -147,45 +152,37 @@ void ath10k_htt_tx_detach(struct ath10k_htt *htt) void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb) { - dev_kfree_skb_any(skb); -} - -int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt) -{ - struct sk_buff *skb; - struct htt_cmd *cmd; - int len = 0; - int ret; + struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb); + struct ath10k_htt *htt = &ar->htt; - len += sizeof(cmd->hdr); - len += sizeof(cmd->ver_req); + if (skb_cb->htt.is_conf) { + dev_kfree_skb_any(skb); + return; + } - skb = ath10k_htc_alloc_skb(len); - if (!skb) - return -ENOMEM; + if (skb_cb->is_aborted) { + skb_cb->htt.discard = true; - skb_put(skb, len); - cmd = (struct htt_cmd *)skb->data; - cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_VERSION_REQ; - - ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb); - if (ret) { - dev_kfree_skb_any(skb); - return ret; + /* if the skbuff is aborted we need to make sure we'll free up + * the tx resources, we can't simply run tx_unref() 2 times + * because if htt tx completion came in earlier we'd access + * unallocated memory */ + if (skb_cb->htt.refcount > 1) + skb_cb->htt.refcount = 1; } - return 0; + ath10k_txrx_tx_unref(htt, skb); } -int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie) +int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt) { - struct htt_stats_req *req; struct sk_buff *skb; struct htt_cmd *cmd; - int len = 0, ret; + int len = 0; + int ret; len += sizeof(cmd->hdr); - len += sizeof(cmd->stats_req); + len += sizeof(cmd->ver_req); skb = ath10k_htc_alloc_skb(len); if (!skb) @@ -193,23 +190,12 @@ int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie) skb_put(skb, len); cmd = (struct htt_cmd *)skb->data; - cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_STATS_REQ; - - req = &cmd->stats_req; - - memset(req, 0, sizeof(*req)); + cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_VERSION_REQ; - /* currently we support only max 8 bit masks so no need to worry - * about endian support */ - req->upload_types[0] = mask; - req->reset_types[0] = mask; - req->stat_type = HTT_STATS_REQ_CFG_STAT_TYPE_INVALID; - req->cookie_lsb = cpu_to_le32(cookie & 0xffffffff); - req->cookie_msb = cpu_to_le32((cookie & 0xffffffff00000000ULL) >> 32); + ATH10K_SKB_CB(skb)->htt.is_conf = true; ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb); if (ret) { - ath10k_warn("failed to send htt type stats request: %d", ret); dev_kfree_skb_any(skb); return ret; } @@ -293,6 +279,8 @@ int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt) #undef desc_offset + ATH10K_SKB_CB(skb)->htt.is_conf = true; + ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb); if (ret) { dev_kfree_skb_any(skb); @@ -305,10 +293,10 @@ int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt) int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) { struct device *dev = htt->ar->dev; + struct ath10k_skb_cb *skb_cb; struct sk_buff *txdesc = NULL; struct htt_cmd *cmd; - struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu); - u8 vdev_id = skb_cb->vdev_id; + u8 vdev_id = ATH10K_SKB_CB(msdu)->htt.vdev_id; int len = 0; int msdu_id = -1; int res; @@ -316,30 +304,30 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) res = ath10k_htt_tx_inc_pending(htt); if (res) - goto err; + return res; len += sizeof(cmd->hdr); len += sizeof(cmd->mgmt_tx); - spin_lock_bh(&htt->tx_lock); - res = ath10k_htt_tx_alloc_msdu_id(htt); - if (res < 0) { - spin_unlock_bh(&htt->tx_lock); - goto err_tx_dec; - } - msdu_id = res; - htt->pending_tx[msdu_id] = msdu; - spin_unlock_bh(&htt->tx_lock); - txdesc = ath10k_htc_alloc_skb(len); if (!txdesc) { res = -ENOMEM; - goto err_free_msdu_id; + goto err; } + spin_lock_bh(&htt->tx_lock); + msdu_id = ath10k_htt_tx_alloc_msdu_id(htt); + if (msdu_id < 0) { + spin_unlock_bh(&htt->tx_lock); + res = msdu_id; + goto err; + } + htt->pending_tx[msdu_id] = txdesc; + spin_unlock_bh(&htt->tx_lock); + res = ath10k_skb_map(dev, msdu); if (res) - goto err_free_txdesc; + goto err; skb_put(txdesc, len); cmd = (struct htt_cmd *)txdesc->data; @@ -351,27 +339,31 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) memcpy(cmd->mgmt_tx.hdr, msdu->data, min_t(int, msdu->len, HTT_MGMT_FRM_HDR_DOWNLOAD_LEN)); - skb_cb->htt.frag_len = 0; - skb_cb->htt.pad_len = 0; + /* refcount is decremented by HTC and HTT completions until it reaches + * zero and is freed */ + skb_cb = ATH10K_SKB_CB(txdesc); + skb_cb->htt.msdu_id = msdu_id; + skb_cb->htt.refcount = 2; + skb_cb->htt.msdu = msdu; res = ath10k_htc_send(&htt->ar->htc, htt->eid, txdesc); if (res) - goto err_unmap_msdu; + goto err; return 0; -err_unmap_msdu: +err: ath10k_skb_unmap(dev, msdu); -err_free_txdesc: - dev_kfree_skb_any(txdesc); -err_free_msdu_id: - spin_lock_bh(&htt->tx_lock); - htt->pending_tx[msdu_id] = NULL; - ath10k_htt_tx_free_msdu_id(htt, msdu_id); - spin_unlock_bh(&htt->tx_lock); -err_tx_dec: + + if (txdesc) + dev_kfree_skb_any(txdesc); + if (msdu_id >= 0) { + spin_lock_bh(&htt->tx_lock); + htt->pending_tx[msdu_id] = NULL; + ath10k_htt_tx_free_msdu_id(htt, msdu_id); + spin_unlock_bh(&htt->tx_lock); + } ath10k_htt_tx_dec_pending(htt); -err: return res; } @@ -381,12 +373,13 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) struct htt_cmd *cmd; struct htt_data_tx_desc_frag *tx_frags; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; - struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu); + struct ath10k_skb_cb *skb_cb; struct sk_buff *txdesc = NULL; - bool use_frags; - u8 vdev_id = ATH10K_SKB_CB(msdu)->vdev_id; + struct sk_buff *txfrag = NULL; + u8 vdev_id = ATH10K_SKB_CB(msdu)->htt.vdev_id; u8 tid; - int prefetch_len, desc_len; + int prefetch_len, desc_len, frag_len; + dma_addr_t frags_paddr; int msdu_id = -1; int res; u8 flags0; @@ -394,82 +387,69 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) res = ath10k_htt_tx_inc_pending(htt); if (res) - goto err; - - spin_lock_bh(&htt->tx_lock); - res = ath10k_htt_tx_alloc_msdu_id(htt); - if (res < 0) { - spin_unlock_bh(&htt->tx_lock); - goto err_tx_dec; - } - msdu_id = res; - htt->pending_tx[msdu_id] = msdu; - spin_unlock_bh(&htt->tx_lock); + return res; prefetch_len = min(htt->prefetch_len, msdu->len); prefetch_len = roundup(prefetch_len, 4); desc_len = sizeof(cmd->hdr) + sizeof(cmd->data_tx) + prefetch_len; + frag_len = sizeof(*tx_frags) * 2; txdesc = ath10k_htc_alloc_skb(desc_len); if (!txdesc) { res = -ENOMEM; - goto err_free_msdu_id; + goto err; } - /* Since HTT 3.0 there is no separate mgmt tx command. However in case - * of mgmt tx using TX_FRM there is not tx fragment list. Instead of tx - * fragment list host driver specifies directly frame pointer. */ - use_frags = htt->target_version_major < 3 || - !ieee80211_is_mgmt(hdr->frame_control); + txfrag = dev_alloc_skb(frag_len); + if (!txfrag) { + res = -ENOMEM; + goto err; + } if (!IS_ALIGNED((unsigned long)txdesc->data, 4)) { ath10k_warn("htt alignment check failed. dropping packet.\n"); res = -EIO; - goto err_free_txdesc; + goto err; } - if (use_frags) { - skb_cb->htt.frag_len = sizeof(*tx_frags) * 2; - skb_cb->htt.pad_len = (unsigned long)msdu->data - - round_down((unsigned long)msdu->data, 4); - - skb_push(msdu, skb_cb->htt.frag_len + skb_cb->htt.pad_len); - } else { - skb_cb->htt.frag_len = 0; - skb_cb->htt.pad_len = 0; + spin_lock_bh(&htt->tx_lock); + msdu_id = ath10k_htt_tx_alloc_msdu_id(htt); + if (msdu_id < 0) { + spin_unlock_bh(&htt->tx_lock); + res = msdu_id; + goto err; } + htt->pending_tx[msdu_id] = txdesc; + spin_unlock_bh(&htt->tx_lock); res = ath10k_skb_map(dev, msdu); if (res) - goto err_pull_txfrag; - - if (use_frags) { - dma_sync_single_for_cpu(dev, skb_cb->paddr, msdu->len, - DMA_TO_DEVICE); - - /* tx fragment list must be terminated with zero-entry */ - tx_frags = (struct htt_data_tx_desc_frag *)msdu->data; - tx_frags[0].paddr = __cpu_to_le32(skb_cb->paddr + - skb_cb->htt.frag_len + - skb_cb->htt.pad_len); - tx_frags[0].len = __cpu_to_le32(msdu->len - - skb_cb->htt.frag_len - - skb_cb->htt.pad_len); - tx_frags[1].paddr = __cpu_to_le32(0); - tx_frags[1].len = __cpu_to_le32(0); - - dma_sync_single_for_device(dev, skb_cb->paddr, msdu->len, - DMA_TO_DEVICE); - } + goto err; + + /* tx fragment list must be terminated with zero-entry */ + skb_put(txfrag, frag_len); + tx_frags = (struct htt_data_tx_desc_frag *)txfrag->data; + tx_frags[0].paddr = __cpu_to_le32(ATH10K_SKB_CB(msdu)->paddr); + tx_frags[0].len = __cpu_to_le32(msdu->len); + tx_frags[1].paddr = __cpu_to_le32(0); + tx_frags[1].len = __cpu_to_le32(0); - ath10k_dbg(ATH10K_DBG_HTT, "msdu 0x%llx\n", + res = ath10k_skb_map(dev, txfrag); + if (res) + goto err; + + ath10k_dbg(ATH10K_DBG_HTT, "txfrag 0x%llx msdu 0x%llx\n", + (unsigned long long) ATH10K_SKB_CB(txfrag)->paddr, (unsigned long long) ATH10K_SKB_CB(msdu)->paddr); + ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "txfrag: ", + txfrag->data, frag_len); ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "msdu: ", msdu->data, msdu->len); skb_put(txdesc, desc_len); cmd = (struct htt_cmd *)txdesc->data; + memset(cmd, 0, desc_len); tid = ATH10K_SKB_CB(msdu)->htt.tid; @@ -479,13 +459,8 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) if (!ieee80211_has_protected(hdr->frame_control)) flags0 |= HTT_DATA_TX_DESC_FLAGS0_NO_ENCRYPT; flags0 |= HTT_DATA_TX_DESC_FLAGS0_MAC_HDR_PRESENT; - - if (use_frags) - flags0 |= SM(ATH10K_HW_TXRX_NATIVE_WIFI, - HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE); - else - flags0 |= SM(ATH10K_HW_TXRX_MGMT, - HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE); + flags0 |= SM(ATH10K_HW_TXRX_NATIVE_WIFI, + HTT_DATA_TX_DESC_FLAGS0_PKT_TYPE); flags1 = 0; flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID); @@ -493,37 +468,45 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L3_OFFLOAD; flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L4_OFFLOAD; + frags_paddr = ATH10K_SKB_CB(txfrag)->paddr; + cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_TX_FRM; cmd->data_tx.flags0 = flags0; cmd->data_tx.flags1 = __cpu_to_le16(flags1); - cmd->data_tx.len = __cpu_to_le16(msdu->len - - skb_cb->htt.frag_len - - skb_cb->htt.pad_len); + cmd->data_tx.len = __cpu_to_le16(msdu->len); cmd->data_tx.id = __cpu_to_le16(msdu_id); - cmd->data_tx.frags_paddr = __cpu_to_le32(skb_cb->paddr); + cmd->data_tx.frags_paddr = __cpu_to_le32(frags_paddr); cmd->data_tx.peerid = __cpu_to_le32(HTT_INVALID_PEERID); - memcpy(cmd->data_tx.prefetch, hdr, prefetch_len); + memcpy(cmd->data_tx.prefetch, msdu->data, prefetch_len); + + /* refcount is decremented by HTC and HTT completions until it reaches + * zero and is freed */ + skb_cb = ATH10K_SKB_CB(txdesc); + skb_cb->htt.msdu_id = msdu_id; + skb_cb->htt.refcount = 2; + skb_cb->htt.txfrag = txfrag; + skb_cb->htt.msdu = msdu; res = ath10k_htc_send(&htt->ar->htc, htt->eid, txdesc); if (res) - goto err_unmap_msdu; + goto err; return 0; - -err_unmap_msdu: - ath10k_skb_unmap(dev, msdu); -err_pull_txfrag: - skb_pull(msdu, skb_cb->htt.frag_len + skb_cb->htt.pad_len); -err_free_txdesc: - dev_kfree_skb_any(txdesc); -err_free_msdu_id: - spin_lock_bh(&htt->tx_lock); - htt->pending_tx[msdu_id] = NULL; - ath10k_htt_tx_free_msdu_id(htt, msdu_id); - spin_unlock_bh(&htt->tx_lock); -err_tx_dec: - ath10k_htt_tx_dec_pending(htt); err: + if (txfrag) + ath10k_skb_unmap(dev, txfrag); + if (txdesc) + dev_kfree_skb_any(txdesc); + if (txfrag) + dev_kfree_skb_any(txfrag); + if (msdu_id >= 0) { + spin_lock_bh(&htt->tx_lock); + htt->pending_tx[msdu_id] = NULL; + ath10k_htt_tx_free_msdu_id(htt, msdu_id); + spin_unlock_bh(&htt->tx_lock); + } + ath10k_htt_tx_dec_pending(htt); + ath10k_skb_unmap(dev, msdu); return res; } diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 8aeb46d..44ed5af 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -20,37 +20,28 @@ #include "targaddrs.h" -/* QCA988X 1.0 definitions (unsupported) */ -#define QCA988X_HW_1_0_CHIP_ID_REV 0x0 +/* Supported FW version */ +#define SUPPORTED_FW_MAJOR 1 +#define SUPPORTED_FW_MINOR 0 +#define SUPPORTED_FW_RELEASE 0 +#define SUPPORTED_FW_BUILD 629 + +/* QCA988X 1.0 definitions */ +#define QCA988X_HW_1_0_VERSION 0x4000002c +#define QCA988X_HW_1_0_FW_DIR "ath10k/QCA988X/hw1.0" +#define QCA988X_HW_1_0_FW_FILE "firmware.bin" +#define QCA988X_HW_1_0_OTP_FILE "otp.bin" +#define QCA988X_HW_1_0_BOARD_DATA_FILE "board.bin" +#define QCA988X_HW_1_0_PATCH_LOAD_ADDR 0x1234 /* QCA988X 2.0 definitions */ #define QCA988X_HW_2_0_VERSION 0x4100016c -#define QCA988X_HW_2_0_CHIP_ID_REV 0x2 #define QCA988X_HW_2_0_FW_DIR "ath10k/QCA988X/hw2.0" #define QCA988X_HW_2_0_FW_FILE "firmware.bin" #define QCA988X_HW_2_0_OTP_FILE "otp.bin" #define QCA988X_HW_2_0_BOARD_DATA_FILE "board.bin" #define QCA988X_HW_2_0_PATCH_LOAD_ADDR 0x1234 -#define ATH10K_FW_API2_FILE "firmware-2.bin" - -/* includes also the null byte */ -#define ATH10K_FIRMWARE_MAGIC "QCA-ATH10K" - -struct ath10k_fw_ie { - __le32 id; - __le32 len; - u8 data[0]; -}; - -enum ath10k_fw_ie_type { - ATH10K_FW_IE_FW_VERSION = 0, - ATH10K_FW_IE_TIMESTAMP = 1, - ATH10K_FW_IE_FEATURES = 2, - ATH10K_FW_IE_FW_IMAGE = 3, - ATH10K_FW_IE_OTP_IMAGE = 4, -}; - /* Known pecularities: * - current FW doesn't support raw rx mode (last tested v599) * - current FW dumps upon raw tx mode (last tested v599) @@ -62,9 +53,6 @@ enum ath10k_hw_txrx_mode { ATH10K_HW_TXRX_RAW = 0, ATH10K_HW_TXRX_NATIVE_WIFI = 1, ATH10K_HW_TXRX_ETHERNET = 2, - - /* Valid for HTT >= 3.0. Used for management frames in TX_FRM. */ - ATH10K_HW_TXRX_MGMT = 3, }; enum ath10k_mcast2ucast_mode { @@ -72,7 +60,6 @@ enum ath10k_mcast2ucast_mode { ATH10K_MCAST2UCAST_ENABLED = 1, }; -/* Target specific defines for MAIN firmware */ #define TARGET_NUM_VDEVS 8 #define TARGET_NUM_PEER_AST 2 #define TARGET_NUM_WDS_ENTRIES 32 @@ -88,11 +75,7 @@ enum ath10k_mcast2ucast_mode { #define TARGET_RX_CHAIN_MASK (BIT(0) | BIT(1) | BIT(2)) #define TARGET_RX_TIMEOUT_LO_PRI 100 #define TARGET_RX_TIMEOUT_HI_PRI 40 - -/* Native Wifi decap mode is used to align IP frames to 4-byte boundaries and - * avoid a very expensive re-alignment in mac80211. */ -#define TARGET_RX_DECAP_MODE ATH10K_HW_TXRX_NATIVE_WIFI - +#define TARGET_RX_DECAP_MODE ATH10K_HW_TXRX_ETHERNET #define TARGET_SCAN_MAX_PENDING_REQS 4 #define TARGET_BMISS_OFFLOAD_MAX_VDEV 3 #define TARGET_ROAM_OFFLOAD_MAX_VDEV 3 @@ -107,36 +90,6 @@ enum ath10k_mcast2ucast_mode { #define TARGET_NUM_MSDU_DESC (1024 + 400) #define TARGET_MAX_FRAG_ENTRIES 0 -/* Target specific defines for 10.X firmware */ -#define TARGET_10X_NUM_VDEVS 16 -#define TARGET_10X_NUM_PEER_AST 2 -#define TARGET_10X_NUM_WDS_ENTRIES 32 -#define TARGET_10X_DMA_BURST_SIZE 0 -#define TARGET_10X_MAC_AGGR_DELIM 0 -#define TARGET_10X_AST_SKID_LIMIT 16 -#define TARGET_10X_NUM_PEERS (128 + (TARGET_10X_NUM_VDEVS)) -#define TARGET_10X_NUM_OFFLOAD_PEERS 0 -#define TARGET_10X_NUM_OFFLOAD_REORDER_BUFS 0 -#define TARGET_10X_NUM_PEER_KEYS 2 -#define TARGET_10X_NUM_TIDS 256 -#define TARGET_10X_TX_CHAIN_MASK (BIT(0) | BIT(1) | BIT(2)) -#define TARGET_10X_RX_CHAIN_MASK (BIT(0) | BIT(1) | BIT(2)) -#define TARGET_10X_RX_TIMEOUT_LO_PRI 100 -#define TARGET_10X_RX_TIMEOUT_HI_PRI 40 -#define TARGET_10X_RX_DECAP_MODE ATH10K_HW_TXRX_NATIVE_WIFI -#define TARGET_10X_SCAN_MAX_PENDING_REQS 4 -#define TARGET_10X_BMISS_OFFLOAD_MAX_VDEV 2 -#define TARGET_10X_ROAM_OFFLOAD_MAX_VDEV 2 -#define TARGET_10X_ROAM_OFFLOAD_MAX_AP_PROFILES 8 -#define TARGET_10X_GTK_OFFLOAD_MAX_VDEV 3 -#define TARGET_10X_NUM_MCAST_GROUPS 0 -#define TARGET_10X_NUM_MCAST_TABLE_ELEMS 0 -#define TARGET_10X_MCAST2UCAST_MODE ATH10K_MCAST2UCAST_DISABLED -#define TARGET_10X_TX_DBG_LOG_SIZE 1024 -#define TARGET_10X_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK 1 -#define TARGET_10X_VOW_CONFIG 0 -#define TARGET_10X_NUM_MSDU_DESC (1024 + 400) -#define TARGET_10X_MAX_FRAG_ENTRIES 0 /* Number of Copy Engines supported */ #define CE_COUNT 8 @@ -216,10 +169,6 @@ enum ath10k_mcast2ucast_mode { #define SOC_LPO_CAL_ENABLE_LSB 20 #define SOC_LPO_CAL_ENABLE_MASK 0x00100000 -#define SOC_CHIP_ID_ADDRESS 0x000000ec -#define SOC_CHIP_ID_REV_LSB 8 -#define SOC_CHIP_ID_REV_MASK 0x00000f00 - #define WLAN_RESET_CONTROL_COLD_RST_MASK 0x00000008 #define WLAN_RESET_CONTROL_WARM_RST_MASK 0x00000004 #define WLAN_SYSTEM_SLEEP_DISABLE_LSB 0 diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 97ac8c8..cf2ba4d 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -92,7 +92,7 @@ static int ath10k_install_key(struct ath10k_vif *arvif, lockdep_assert_held(&ar->conf_mutex); - reinit_completion(&ar->install_key_done); + INIT_COMPLETION(ar->install_key_done); ret = ath10k_send_key(arvif, key, cmd, macaddr); if (ret) @@ -334,29 +334,25 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr) static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value) { - struct ath10k *ar = arvif->ar; - u32 vdev_param; - if (value != 0xFFFFFFFF) value = min_t(u32, arvif->ar->hw->wiphy->rts_threshold, ATH10K_RTS_MAX); - vdev_param = ar->wmi.vdev_param->rts_threshold; - return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value); + return ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, + WMI_VDEV_PARAM_RTS_THRESHOLD, + value); } static int ath10k_mac_set_frag(struct ath10k_vif *arvif, u32 value) { - struct ath10k *ar = arvif->ar; - u32 vdev_param; - if (value != 0xFFFFFFFF) value = clamp_t(u32, arvif->ar->hw->wiphy->frag_threshold, ATH10K_FRAGMT_THRESHOLD_MIN, ATH10K_FRAGMT_THRESHOLD_MAX); - vdev_param = ar->wmi.vdev_param->fragmentation_threshold; - return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value); + return ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, + WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, + value); } static int ath10k_peer_delete(struct ath10k *ar, u32 vdev_id, const u8 *addr) @@ -438,7 +434,7 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif) lockdep_assert_held(&ar->conf_mutex); - reinit_completion(&ar->vdev_setup_done); + INIT_COMPLETION(ar->vdev_setup_done); arg.vdev_id = arvif->vdev_id; arg.dtim_period = arvif->dtim_period; @@ -464,11 +460,6 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif) arg.ssid_len = arvif->vif->bss_conf.ssid_len; } - ath10k_dbg(ATH10K_DBG_MAC, - "mac vdev %d start center_freq %d phymode %s\n", - arg.vdev_id, arg.channel.freq, - ath10k_wmi_phymode_str(arg.channel.mode)); - ret = ath10k_wmi_vdev_start(ar, &arg); if (ret) { ath10k_warn("WMI vdev start failed: ret %d\n", ret); @@ -491,7 +482,7 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif) lockdep_assert_held(&ar->conf_mutex); - reinit_completion(&ar->vdev_setup_done); + INIT_COMPLETION(ar->vdev_setup_done); ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id); if (ret) { @@ -512,10 +503,13 @@ static int ath10k_monitor_start(struct ath10k *ar, int vdev_id) { struct ieee80211_channel *channel = ar->hw->conf.chandef.chan; struct wmi_vdev_start_request_arg arg = {}; + enum nl80211_channel_type type; int ret = 0; lockdep_assert_held(&ar->conf_mutex); + type = cfg80211_get_chandef_type(&ar->hw->conf.chandef); + arg.vdev_id = vdev_id; arg.channel.freq = channel->center_freq; arg.channel.band_center_freq1 = ar->hw->conf.chandef.center_freq1; @@ -566,9 +560,12 @@ static int ath10k_monitor_stop(struct ath10k *ar) lockdep_assert_held(&ar->conf_mutex); - ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id); - if (ret) - ath10k_warn("Monitor vdev down failed: %d\n", ret); + /* For some reasons, ath10k_wmi_vdev_down() here couse + * often ath10k_wmi_vdev_stop() to fail. Next we could + * not run monitor vdev and driver reload + * required. Don't see such problems we skip + * ath10k_wmi_vdev_down() here. + */ ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id); if (ret) @@ -610,7 +607,7 @@ static int ath10k_monitor_create(struct ath10k *ar) goto vdev_fail; } - ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d created\n", + ath10k_dbg(ATH10K_DBG_MAC, "Monitor interface created, vdev id: %d\n", ar->monitor_vdev_id); ar->monitor_present = true; @@ -642,7 +639,7 @@ static int ath10k_monitor_destroy(struct ath10k *ar) ar->free_vdev_map |= 1 << (ar->monitor_vdev_id); ar->monitor_present = false; - ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n", + ath10k_dbg(ATH10K_DBG_MAC, "Monitor interface destroyed, vdev id: %d\n", ar->monitor_vdev_id); return ret; } @@ -671,14 +668,13 @@ static void ath10k_control_beaconing(struct ath10k_vif *arvif, arvif->vdev_id); return; } - ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id); + ath10k_dbg(ATH10K_DBG_MAC, "VDEV: %d up\n", arvif->vdev_id); } static void ath10k_control_ibss(struct ath10k_vif *arvif, struct ieee80211_bss_conf *info, const u8 self_peer[ETH_ALEN]) { - u32 vdev_param; int ret = 0; lockdep_assert_held(&arvif->ar->conf_mutex); @@ -712,8 +708,8 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif, return; } - vdev_param = arvif->ar->wmi.vdev_param->atim_window; - ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param, + ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, + WMI_VDEV_PARAM_ATIM_WINDOW, ATH10K_DEFAULT_ATIM); if (ret) ath10k_warn("Failed to set IBSS ATIM for VDEV:%d ret:%d\n", @@ -723,45 +719,47 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif, /* * Review this when mac80211 gains per-interface powersave support. */ -static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif) +static void ath10k_ps_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { - struct ath10k *ar = arvif->ar; - struct ieee80211_conf *conf = &ar->hw->conf; + struct ath10k_generic_iter *ar_iter = data; + struct ieee80211_conf *conf = &ar_iter->ar->hw->conf; + struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); enum wmi_sta_powersave_param param; enum wmi_sta_ps_mode psmode; int ret; lockdep_assert_held(&arvif->ar->conf_mutex); - if (arvif->vif->type != NL80211_IFTYPE_STATION) - return 0; + if (vif->type != NL80211_IFTYPE_STATION) + return; if (conf->flags & IEEE80211_CONF_PS) { psmode = WMI_STA_PS_MODE_ENABLED; param = WMI_STA_PS_PARAM_INACTIVITY_TIME; - ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, + ret = ath10k_wmi_set_sta_ps_param(ar_iter->ar, + arvif->vdev_id, + param, conf->dynamic_ps_timeout); if (ret) { ath10k_warn("Failed to set inactivity time for VDEV: %d\n", arvif->vdev_id); - return ret; + return; } + + ar_iter->ret = ret; } else { psmode = WMI_STA_PS_MODE_DISABLED; } - ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d psmode %s\n", - arvif->vdev_id, psmode ? "enable" : "disable"); - - ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode); - if (ret) { + ar_iter->ret = ath10k_wmi_set_psmode(ar_iter->ar, arvif->vdev_id, + psmode); + if (ar_iter->ret) ath10k_warn("Failed to set PS Mode: %d for VDEV: %d\n", psmode, arvif->vdev_id); - return ret; - } - - return 0; + else + ath10k_dbg(ATH10K_DBG_MAC, "Set PS Mode: %d for VDEV: %d\n", + psmode, arvif->vdev_id); } /**********************/ @@ -951,8 +949,7 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar, arg->peer_ht_rates.num_rates = n; arg->peer_num_spatial_streams = max((n+7) / 8, 1); - ath10k_dbg(ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n", - arg->addr, + ath10k_dbg(ATH10K_DBG_MAC, "mcs cnt %d nss %d\n", arg->peer_ht_rates.num_rates, arg->peer_num_spatial_streams); } @@ -972,11 +969,11 @@ static void ath10k_peer_assoc_h_qos_ap(struct ath10k *ar, arg->peer_flags |= WMI_PEER_QOS; if (sta->wme && sta->uapsd_queues) { - ath10k_dbg(ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n", + ath10k_dbg(ATH10K_DBG_MAC, "uapsd_queues: 0x%X, max_sp: %d\n", sta->uapsd_queues, sta->max_sp); arg->peer_flags |= WMI_PEER_APSD; - arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG; + arg->peer_flags |= WMI_RC_UAPSD_FLAG; if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) uapsd |= WMI_AP_PS_UAPSD_AC3_DELIVERY_EN | @@ -1031,26 +1028,13 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar, struct wmi_peer_assoc_complete_arg *arg) { const struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; - u8 ampdu_factor; if (!vht_cap->vht_supported) return; arg->peer_flags |= WMI_PEER_VHT; - arg->peer_vht_caps = vht_cap->cap; - - - ampdu_factor = (vht_cap->cap & - IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >> - IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; - /* Workaround: Some Netgear/Linksys 11ac APs set Rx A-MPDU factor to - * zero in VHT IE. Using it would result in degraded throughput. - * arg->peer_max_mpdu at this point contains HT max_mpdu so keep - * it if VHT max_mpdu is smaller. */ - arg->peer_max_mpdu = max(arg->peer_max_mpdu, - (1U << (IEEE80211_HT_MAX_AMPDU_FACTOR + - ampdu_factor)) - 1); + arg->peer_vht_caps = vht_cap->cap; if (sta->bandwidth == IEEE80211_STA_RX_BW_80) arg->peer_flags |= WMI_PEER_80MHZ; @@ -1064,8 +1048,7 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar, arg->peer_vht_rates.tx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map); - ath10k_dbg(ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n", - sta->addr, arg->peer_max_mpdu, arg->peer_flags); + ath10k_dbg(ATH10K_DBG_MAC, "mac vht peer\n"); } static void ath10k_peer_assoc_h_qos(struct ath10k *ar, @@ -1093,6 +1076,8 @@ static void ath10k_peer_assoc_h_phymode(struct ath10k *ar, { enum wmi_phy_mode phymode = MODE_UNKNOWN; + /* FIXME: add VHT */ + switch (ar->hw->conf.chandef.chan->band) { case IEEE80211_BAND_2GHZ: if (sta->ht_cap.ht_supported) { @@ -1106,17 +1091,7 @@ static void ath10k_peer_assoc_h_phymode(struct ath10k *ar, break; case IEEE80211_BAND_5GHZ: - /* - * Check VHT first. - */ - if (sta->vht_cap.vht_supported) { - if (sta->bandwidth == IEEE80211_STA_RX_BW_80) - phymode = MODE_11AC_VHT80; - else if (sta->bandwidth == IEEE80211_STA_RX_BW_40) - phymode = MODE_11AC_VHT40; - else if (sta->bandwidth == IEEE80211_STA_RX_BW_20) - phymode = MODE_11AC_VHT20; - } else if (sta->ht_cap.ht_supported) { + if (sta->ht_cap.ht_supported) { if (sta->bandwidth == IEEE80211_STA_RX_BW_40) phymode = MODE_11NA_HT40; else @@ -1130,32 +1105,30 @@ static void ath10k_peer_assoc_h_phymode(struct ath10k *ar, break; } - ath10k_dbg(ATH10K_DBG_MAC, "mac peer %pM phymode %s\n", - sta->addr, ath10k_wmi_phymode_str(phymode)); - arg->peer_phymode = phymode; WARN_ON(phymode == MODE_UNKNOWN); } -static int ath10k_peer_assoc_prepare(struct ath10k *ar, - struct ath10k_vif *arvif, - struct ieee80211_sta *sta, - struct ieee80211_bss_conf *bss_conf, - struct wmi_peer_assoc_complete_arg *arg) +static int ath10k_peer_assoc(struct ath10k *ar, + struct ath10k_vif *arvif, + struct ieee80211_sta *sta, + struct ieee80211_bss_conf *bss_conf) { + struct wmi_peer_assoc_complete_arg arg; + lockdep_assert_held(&ar->conf_mutex); - memset(arg, 0, sizeof(*arg)); + memset(&arg, 0, sizeof(struct wmi_peer_assoc_complete_arg)); - ath10k_peer_assoc_h_basic(ar, arvif, sta, bss_conf, arg); - ath10k_peer_assoc_h_crypto(ar, arvif, arg); - ath10k_peer_assoc_h_rates(ar, sta, arg); - ath10k_peer_assoc_h_ht(ar, sta, arg); - ath10k_peer_assoc_h_vht(ar, sta, arg); - ath10k_peer_assoc_h_qos(ar, arvif, sta, bss_conf, arg); - ath10k_peer_assoc_h_phymode(ar, arvif, sta, arg); + ath10k_peer_assoc_h_basic(ar, arvif, sta, bss_conf, &arg); + ath10k_peer_assoc_h_crypto(ar, arvif, &arg); + ath10k_peer_assoc_h_rates(ar, sta, &arg); + ath10k_peer_assoc_h_ht(ar, sta, &arg); + ath10k_peer_assoc_h_vht(ar, sta, &arg); + ath10k_peer_assoc_h_qos(ar, arvif, sta, bss_conf, &arg); + ath10k_peer_assoc_h_phymode(ar, arvif, sta, &arg); - return 0; + return ath10k_wmi_peer_assoc(ar, &arg); } /* can be called only in mac80211 callbacks due to `key_count` usage */ @@ -1165,7 +1138,6 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw, { struct ath10k *ar = hw->priv; struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); - struct wmi_peer_assoc_complete_arg peer_arg; struct ieee80211_sta *ap_sta; int ret; @@ -1181,33 +1153,24 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw, return; } - ret = ath10k_peer_assoc_prepare(ar, arvif, ap_sta, - bss_conf, &peer_arg); + ret = ath10k_peer_assoc(ar, arvif, ap_sta, bss_conf); if (ret) { - ath10k_warn("Peer assoc prepare failed for %pM\n: %d", - bss_conf->bssid, ret); + ath10k_warn("Peer assoc failed for %pM\n", bss_conf->bssid); rcu_read_unlock(); return; } rcu_read_unlock(); - ret = ath10k_wmi_peer_assoc(ar, &peer_arg); - if (ret) { - ath10k_warn("Peer assoc failed for %pM\n: %d", - bss_conf->bssid, ret); - return; - } - - ath10k_dbg(ATH10K_DBG_MAC, - "mac vdev %d up (associated) bssid %pM aid %d\n", - arvif->vdev_id, bss_conf->bssid, bss_conf->aid); - ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, bss_conf->aid, bss_conf->bssid); if (ret) ath10k_warn("VDEV: %d up failed: ret %d\n", arvif->vdev_id, ret); + else + ath10k_dbg(ATH10K_DBG_MAC, + "VDEV: %d associated, BSSID: %pM, AID: %d\n", + arvif->vdev_id, bss_conf->bssid, bss_conf->aid); } /* @@ -1228,11 +1191,10 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw, * No idea why this happens, even though VDEV-DOWN is supposed * to be analogous to link down, so just stop the VDEV. */ - ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d stop (disassociated\n", - arvif->vdev_id); - - /* FIXME: check return value */ ret = ath10k_vdev_stop(arvif); + if (!ret) + ath10k_dbg(ATH10K_DBG_MAC, "VDEV: %d stopped\n", + arvif->vdev_id); /* * If we don't call VDEV-DOWN after VDEV-STOP FW will remain active and @@ -1241,33 +1203,26 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw, * interfaces as it expects there is no rx when no interface is * running. */ - ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d down\n", arvif->vdev_id); - - /* FIXME: why don't we print error if wmi call fails? */ ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id); + if (ret) + ath10k_dbg(ATH10K_DBG_MAC, "VDEV: %d ath10k_wmi_vdev_down failed (%d)\n", + arvif->vdev_id, ret); + + ath10k_wmi_flush_tx(ar); - arvif->def_wep_key_idx = 0; + arvif->def_wep_key_index = 0; } static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif, struct ieee80211_sta *sta) { - struct wmi_peer_assoc_complete_arg peer_arg; int ret = 0; lockdep_assert_held(&ar->conf_mutex); - ret = ath10k_peer_assoc_prepare(ar, arvif, sta, NULL, &peer_arg); - if (ret) { - ath10k_warn("WMI peer assoc prepare failed for %pM\n", - sta->addr); - return ret; - } - - ret = ath10k_wmi_peer_assoc(ar, &peer_arg); + ret = ath10k_peer_assoc(ar, arvif, sta, NULL); if (ret) { - ath10k_warn("Peer assoc failed for STA %pM\n: %d", - sta->addr, ret); + ath10k_warn("WMI peer assoc failed for %pM\n", sta->addr); return ret; } @@ -1378,8 +1333,8 @@ static int ath10k_update_channel_list(struct ath10k *ar) continue; ath10k_dbg(ATH10K_DBG_WMI, - "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n", - ch - arg.channels, arg.n_channels, + "%s: [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n", + __func__, ch - arg.channels, arg.n_channels, ch->freq, ch->max_power, ch->max_reg_power, ch->max_antenna_gain, ch->mode); @@ -1436,33 +1391,6 @@ static void ath10k_reg_notifier(struct wiphy *wiphy, /* TX handlers */ /***************/ -static u8 ath10k_tx_h_get_tid(struct ieee80211_hdr *hdr) -{ - if (ieee80211_is_mgmt(hdr->frame_control)) - return HTT_DATA_TX_EXT_TID_MGMT; - - if (!ieee80211_is_data_qos(hdr->frame_control)) - return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST; - - if (!is_unicast_ether_addr(ieee80211_get_DA(hdr))) - return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST; - - return ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; -} - -static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, - struct ieee80211_tx_info *info) -{ - if (info->control.vif) - return ath10k_vif_to_arvif(info->control.vif)->vdev_id; - - if (ar->monitor_enabled) - return ar->monitor_vdev_id; - - ath10k_warn("could not resolve vdev id\n"); - return 0; -} - /* * Frames sent to the FW have to be in "Native Wifi" format. * Strip the QoS field from the 802.11 header. @@ -1483,30 +1411,6 @@ static void ath10k_tx_h_qos_workaround(struct ieee80211_hw *hw, skb_pull(skb, IEEE80211_QOS_CTL_LEN); } -static void ath10k_tx_wep_key_work(struct work_struct *work) -{ - struct ath10k_vif *arvif = container_of(work, struct ath10k_vif, - wep_key_work); - int ret, keyidx = arvif->def_wep_key_newidx; - - if (arvif->def_wep_key_idx == keyidx) - return; - - ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n", - arvif->vdev_id, keyidx); - - ret = ath10k_wmi_vdev_set_param(arvif->ar, - arvif->vdev_id, - arvif->ar->wmi.vdev_param->def_keyid, - keyidx); - if (ret) { - ath10k_warn("could not update wep keyidx (%d)\n", ret); - return; - } - - arvif->def_wep_key_idx = keyidx; -} - static void ath10k_tx_h_update_wep_key(struct sk_buff *skb) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -1515,6 +1419,11 @@ static void ath10k_tx_h_update_wep_key(struct sk_buff *skb) struct ath10k *ar = arvif->ar; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_key_conf *key = info->control.hw_key; + int ret; + + /* TODO AP mode should be implemented */ + if (vif->type != NL80211_IFTYPE_STATION) + return; if (!ieee80211_has_protected(hdr->frame_control)) return; @@ -1526,14 +1435,20 @@ static void ath10k_tx_h_update_wep_key(struct sk_buff *skb) key->cipher != WLAN_CIPHER_SUITE_WEP104) return; - if (key->keyidx == arvif->def_wep_key_idx) + if (key->keyidx == arvif->def_wep_key_index) return; - /* FIXME: Most likely a few frames will be TXed with an old key. Simply - * queueing frames until key index is updated is not an option because - * sk_buff may need more processing to be done, e.g. offchannel */ - arvif->def_wep_key_newidx = key->keyidx; - ieee80211_queue_work(ar->hw, &arvif->wep_key_work); + ath10k_dbg(ATH10K_DBG_MAC, "new wep keyidx will be %d\n", key->keyidx); + + ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, + WMI_VDEV_PARAM_DEF_KEYID, + key->keyidx); + if (ret) { + ath10k_warn("could not update wep keyidx (%d)\n", ret); + return; + } + + arvif->def_wep_key_index = key->keyidx; } static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar, struct sk_buff *skb) @@ -1563,42 +1478,19 @@ static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar, struct sk_buff *skb) static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - int ret = 0; - - if (ar->htt.target_version_major >= 3) { - /* Since HTT 3.0 there is no separate mgmt tx command */ - ret = ath10k_htt_tx(&ar->htt, skb); - goto exit; - } - - if (ieee80211_is_mgmt(hdr->frame_control)) { - if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, - ar->fw_features)) { - if (skb_queue_len(&ar->wmi_mgmt_tx_queue) >= - ATH10K_MAX_NUM_MGMT_PENDING) { - ath10k_warn("wmi mgmt_tx queue limit reached\n"); - ret = -EBUSY; - goto exit; - } + int ret; - skb_queue_tail(&ar->wmi_mgmt_tx_queue, skb); - ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work); - } else { - ret = ath10k_htt_mgmt_tx(&ar->htt, skb); - } - } else if (!test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, - ar->fw_features) && - ieee80211_is_nullfunc(hdr->frame_control)) { + if (ieee80211_is_mgmt(hdr->frame_control)) + ret = ath10k_htt_mgmt_tx(&ar->htt, skb); + else if (ieee80211_is_nullfunc(hdr->frame_control)) /* FW does not report tx status properly for NullFunc frames * unless they are sent through mgmt tx path. mac80211 sends - * those frames when it detects link/beacon loss and depends - * on the tx status to be correct. */ + * those frames when it detects link/beacon loss and depends on + * the tx status to be correct. */ ret = ath10k_htt_mgmt_tx(&ar->htt, skb); - } else { + else ret = ath10k_htt_tx(&ar->htt, skb); - } -exit: if (ret) { ath10k_warn("tx failed (%d). dropping packet.\n", ret); ieee80211_free_txskb(ar->hw, skb); @@ -1642,19 +1534,18 @@ void ath10k_offchan_tx_work(struct work_struct *work) mutex_lock(&ar->conf_mutex); - ath10k_dbg(ATH10K_DBG_MAC, "mac offchannel skb %p\n", + ath10k_dbg(ATH10K_DBG_MAC, "processing offchannel skb %p\n", skb); hdr = (struct ieee80211_hdr *)skb->data; peer_addr = ieee80211_get_DA(hdr); - vdev_id = ATH10K_SKB_CB(skb)->vdev_id; + vdev_id = ATH10K_SKB_CB(skb)->htt.vdev_id; spin_lock_bh(&ar->data_lock); peer = ath10k_peer_find(ar, vdev_id, peer_addr); spin_unlock_bh(&ar->data_lock); if (peer) - /* FIXME: should this use ath10k_warn()? */ ath10k_dbg(ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n", peer_addr, vdev_id); @@ -1666,7 +1557,7 @@ void ath10k_offchan_tx_work(struct work_struct *work) } spin_lock_bh(&ar->data_lock); - reinit_completion(&ar->offchan_tx_completed); + INIT_COMPLETION(ar->offchan_tx_completed); ar->offchan_tx_skb = skb; spin_unlock_bh(&ar->data_lock); @@ -1689,36 +1580,6 @@ void ath10k_offchan_tx_work(struct work_struct *work) } } -void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar) -{ - struct sk_buff *skb; - - for (;;) { - skb = skb_dequeue(&ar->wmi_mgmt_tx_queue); - if (!skb) - break; - - ieee80211_free_txskb(ar->hw, skb); - } -} - -void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work) -{ - struct ath10k *ar = container_of(work, struct ath10k, wmi_mgmt_tx_work); - struct sk_buff *skb; - int ret; - - for (;;) { - skb = skb_dequeue(&ar->wmi_mgmt_tx_queue); - if (!skb) - break; - - ret = ath10k_wmi_mgmt_tx(ar, skb); - if (ret) - ath10k_warn("wmi mgmt_tx failed (%d)\n", ret); - } -} - /************/ /* Scanning */ /************/ @@ -1782,6 +1643,8 @@ static int ath10k_abort_scan(struct ath10k *ar) return -EIO; } + ath10k_wmi_flush_tx(ar); + ret = wait_for_completion_timeout(&ar->scan.completed, 3*HZ); if (ret == 0) ath10k_warn("timed out while waiting for scan to stop\n"); @@ -1815,6 +1678,10 @@ static int ath10k_start_scan(struct ath10k *ar, if (ret) return ret; + /* make sure we submit the command so the completion + * timeout makes sense */ + ath10k_wmi_flush_tx(ar); + ret = wait_for_completion_timeout(&ar->scan.started, 1*HZ); if (ret == 0) { ath10k_abort_scan(ar); @@ -1842,7 +1709,16 @@ static void ath10k_tx(struct ieee80211_hw *hw, struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ath10k *ar = hw->priv; - u8 tid, vdev_id; + struct ath10k_vif *arvif = NULL; + u32 vdev_id = 0; + u8 tid; + + if (info->control.vif) { + arvif = ath10k_vif_to_arvif(info->control.vif); + vdev_id = arvif->vdev_id; + } else if (ar->monitor_enabled) { + vdev_id = ar->monitor_vdev_id; + } /* We should disable CCK RATE due to P2P */ if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE) @@ -1850,8 +1726,12 @@ static void ath10k_tx(struct ieee80211_hw *hw, /* we must calculate tid before we apply qos workaround * as we'd lose the qos control field */ - tid = ath10k_tx_h_get_tid(hdr); - vdev_id = ath10k_tx_h_get_vdev_id(ar, info); + tid = HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST; + if (ieee80211_is_data_qos(hdr->frame_control) && + is_unicast_ether_addr(ieee80211_get_DA(hdr))) { + u8 *qc = ieee80211_get_qos_ctl(hdr); + tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; + } /* it makes no sense to process injected frames like that */ if (info->control.vif && @@ -1862,14 +1742,14 @@ static void ath10k_tx(struct ieee80211_hw *hw, ath10k_tx_h_seq_no(skb); } - ATH10K_SKB_CB(skb)->vdev_id = vdev_id; - ATH10K_SKB_CB(skb)->htt.is_offchan = false; + memset(ATH10K_SKB_CB(skb), 0, sizeof(*ATH10K_SKB_CB(skb))); + ATH10K_SKB_CB(skb)->htt.vdev_id = vdev_id; ATH10K_SKB_CB(skb)->htt.tid = tid; if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) { spin_lock_bh(&ar->data_lock); ATH10K_SKB_CB(skb)->htt.is_offchan = true; - ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id; + ATH10K_SKB_CB(skb)->htt.vdev_id = ar->scan.vdev_id; spin_unlock_bh(&ar->data_lock); ath10k_dbg(ATH10K_DBG_MAC, "queued offchannel skb %p\n", skb); @@ -1891,7 +1771,6 @@ void ath10k_halt(struct ath10k *ar) del_timer_sync(&ar->scan.timeout); ath10k_offchan_tx_purge(ar); - ath10k_mgmt_over_wmi_tx_purge(ar); ath10k_peer_cleanup_all(ar); ath10k_core_stop(ar); ath10k_hif_power_down(ar); @@ -1938,12 +1817,12 @@ static int ath10k_start(struct ieee80211_hw *hw) else if (ar->state == ATH10K_STATE_RESTARTING) ar->state = ATH10K_STATE_RESTARTED; - ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pmf_qos, 1); + ret = ath10k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_PMF_QOS, 1); if (ret) ath10k_warn("could not enable WMI_PDEV_PARAM_PMF_QOS (%d)\n", ret); - ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->dynamic_bw, 0); + ret = ath10k_wmi_pdev_set_param(ar, WMI_PDEV_PARAM_DYNAMIC_BW, 0); if (ret) ath10k_warn("could not init WMI_PDEV_PARAM_DYNAMIC_BW (%d)\n", ret); @@ -1968,29 +1847,32 @@ static void ath10k_stop(struct ieee80211_hw *hw) ar->state = ATH10K_STATE_OFF; mutex_unlock(&ar->conf_mutex); - ath10k_mgmt_over_wmi_tx_purge(ar); - cancel_work_sync(&ar->offchan_tx_work); - cancel_work_sync(&ar->wmi_mgmt_tx_work); cancel_work_sync(&ar->restart_work); } -static int ath10k_config_ps(struct ath10k *ar) +static void ath10k_config_ps(struct ath10k *ar) { - struct ath10k_vif *arvif; - int ret = 0; + struct ath10k_generic_iter ar_iter; lockdep_assert_held(&ar->conf_mutex); - list_for_each_entry(arvif, &ar->arvifs, list) { - ret = ath10k_mac_vif_setup_ps(arvif); - if (ret) { - ath10k_warn("could not setup powersave (%d)\n", ret); - break; - } - } + /* During HW reconfiguration mac80211 reports all interfaces that were + * running until reconfiguration was started. Since FW doesn't have any + * vdevs at this point we must not iterate over this interface list. + * This setting will be updated upon add_interface(). */ + if (ar->state == ATH10K_STATE_RESTARTED) + return; - return ret; + memset(&ar_iter, 0, sizeof(struct ath10k_generic_iter)); + ar_iter.ar = ar; + + ieee80211_iterate_active_interfaces_atomic( + ar->hw, IEEE80211_IFACE_ITER_NORMAL, + ath10k_ps_iter, &ar_iter); + + if (ar_iter.ret) + ath10k_warn("failed to set ps config (%d)\n", ar_iter.ret); } static int ath10k_config(struct ieee80211_hw *hw, u32 changed) @@ -2002,7 +1884,7 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&ar->conf_mutex); if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - ath10k_dbg(ATH10K_DBG_MAC, "mac config channel %d mhz\n", + ath10k_dbg(ATH10K_DBG_MAC, "Config channel %d mhz\n", conf->chandef.chan->center_freq); spin_lock_bh(&ar->data_lock); ar->rx_channel = conf->chandef.chan; @@ -2019,6 +1901,7 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed) ret = ath10k_monitor_destroy(ar); } + ath10k_wmi_flush_tx(ar); mutex_unlock(&ar->conf_mutex); return ret; } @@ -2039,7 +1922,6 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, int ret = 0; u32 value; int bit; - u32 vdev_param; mutex_lock(&ar->conf_mutex); @@ -2048,22 +1930,21 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, arvif->ar = ar; arvif->vif = vif; - INIT_WORK(&arvif->wep_key_work, ath10k_tx_wep_key_work); - if ((vif->type == NL80211_IFTYPE_MONITOR) && ar->monitor_present) { ath10k_warn("Only one monitor interface allowed\n"); ret = -EBUSY; - goto err; + goto exit; } bit = ffs(ar->free_vdev_map); if (bit == 0) { ret = -EBUSY; - goto err; + goto exit; } arvif->vdev_id = bit - 1; arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE; + ar->free_vdev_map &= ~(1 << arvif->vdev_id); if (ar->p2p) arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE; @@ -2092,41 +1973,32 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, break; } - ath10k_dbg(ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d\n", + ath10k_dbg(ATH10K_DBG_MAC, "Add interface: id %d type %d subtype %d\n", arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype); ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype, vif->addr); if (ret) { ath10k_warn("WMI vdev create failed: ret %d\n", ret); - goto err; + goto exit; } - ar->free_vdev_map &= ~BIT(arvif->vdev_id); - list_add(&arvif->list, &ar->arvifs); - - vdev_param = ar->wmi.vdev_param->def_keyid; - ret = ath10k_wmi_vdev_set_param(ar, 0, vdev_param, - arvif->def_wep_key_idx); - if (ret) { + ret = ath10k_wmi_vdev_set_param(ar, 0, WMI_VDEV_PARAM_DEF_KEYID, + arvif->def_wep_key_index); + if (ret) ath10k_warn("Failed to set default keyid: %d\n", ret); - goto err_vdev_delete; - } - vdev_param = ar->wmi.vdev_param->tx_encap_type; - ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, + ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, + WMI_VDEV_PARAM_TX_ENCAP_TYPE, ATH10K_HW_TXRX_NATIVE_WIFI); - /* 10.X firmware does not support this VDEV parameter. Do not warn */ - if (ret && ret != -EOPNOTSUPP) { + if (ret) ath10k_warn("Failed to set TX encap: %d\n", ret); - goto err_vdev_delete; - } if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr); if (ret) { ath10k_warn("Failed to create peer for AP: %d\n", ret); - goto err_vdev_delete; + goto exit; } } @@ -2135,62 +2007,39 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, value = WMI_STA_PS_RX_WAKE_POLICY_WAKE; ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value); - if (ret) { + if (ret) ath10k_warn("Failed to set RX wake policy: %d\n", ret); - goto err_peer_delete; - } param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD; value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS; ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value); - if (ret) { + if (ret) ath10k_warn("Failed to set TX wake thresh: %d\n", ret); - goto err_peer_delete; - } param = WMI_STA_PS_PARAM_PSPOLL_COUNT; value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX; ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value); - if (ret) { + if (ret) ath10k_warn("Failed to set PSPOLL count: %d\n", ret); - goto err_peer_delete; - } } ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold); - if (ret) { + if (ret) ath10k_warn("failed to set rts threshold for vdev %d (%d)\n", arvif->vdev_id, ret); - goto err_peer_delete; - } ret = ath10k_mac_set_frag(arvif, ar->hw->wiphy->frag_threshold); - if (ret) { + if (ret) ath10k_warn("failed to set frag threshold for vdev %d (%d)\n", arvif->vdev_id, ret); - goto err_peer_delete; - } if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) ar->monitor_present = true; +exit: mutex_unlock(&ar->conf_mutex); - return 0; - -err_peer_delete: - if (arvif->vdev_type == WMI_VDEV_TYPE_AP) - ath10k_wmi_peer_delete(ar, arvif->vdev_id, vif->addr); - -err_vdev_delete: - ath10k_wmi_vdev_delete(ar, arvif->vdev_id); - ar->free_vdev_map &= ~BIT(arvif->vdev_id); - list_del(&arvif->list); - -err: - mutex_unlock(&ar->conf_mutex); - return ret; } @@ -2203,17 +2052,9 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, mutex_lock(&ar->conf_mutex); - cancel_work_sync(&arvif->wep_key_work); - - spin_lock_bh(&ar->data_lock); - if (arvif->beacon) { - dev_kfree_skb_any(arvif->beacon); - arvif->beacon = NULL; - } - spin_unlock_bh(&ar->data_lock); + ath10k_dbg(ATH10K_DBG_MAC, "Remove interface: id %d\n", arvif->vdev_id); ar->free_vdev_map |= 1 << (arvif->vdev_id); - list_del(&arvif->list); if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, vif->addr); @@ -2223,9 +2064,6 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, kfree(arvif->u.ap.noa_data); } - ath10k_dbg(ATH10K_DBG_MAC, "mac vdev delete %d (remove interface)\n", - arvif->vdev_id); - ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id); if (ret) ath10k_warn("WMI vdev delete failed: %d\n", ret); @@ -2267,20 +2105,18 @@ static void ath10k_configure_filter(struct ieee80211_hw *hw, if ((ar->filter_flags & FIF_PROMISC_IN_BSS) && !ar->monitor_enabled) { - ath10k_dbg(ATH10K_DBG_MAC, "mac monitor %d start\n", - ar->monitor_vdev_id); - ret = ath10k_monitor_start(ar, ar->monitor_vdev_id); if (ret) ath10k_warn("Unable to start monitor mode\n"); + else + ath10k_dbg(ATH10K_DBG_MAC, "Monitor mode started\n"); } else if (!(ar->filter_flags & FIF_PROMISC_IN_BSS) && ar->monitor_enabled) { - ath10k_dbg(ATH10K_DBG_MAC, "mac monitor %d stop\n", - ar->monitor_vdev_id); - ret = ath10k_monitor_stop(ar); if (ret) ath10k_warn("Unable to stop monitor mode\n"); + else + ath10k_dbg(ATH10K_DBG_MAC, "Monitor mode stopped\n"); } mutex_unlock(&ar->conf_mutex); @@ -2294,7 +2130,6 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, struct ath10k *ar = hw->priv; struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); int ret = 0; - u32 vdev_param, pdev_param; mutex_lock(&ar->conf_mutex); @@ -2303,44 +2138,44 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_BEACON_INT) { arvif->beacon_interval = info->beacon_int; - vdev_param = ar->wmi.vdev_param->beacon_interval; - ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, + ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, + WMI_VDEV_PARAM_BEACON_INTERVAL, arvif->beacon_interval); - ath10k_dbg(ATH10K_DBG_MAC, - "mac vdev %d beacon_interval %d\n", - arvif->vdev_id, arvif->beacon_interval); - if (ret) ath10k_warn("Failed to set beacon interval for VDEV: %d\n", arvif->vdev_id); + else + ath10k_dbg(ATH10K_DBG_MAC, + "Beacon interval: %d set for VDEV: %d\n", + arvif->beacon_interval, arvif->vdev_id); } if (changed & BSS_CHANGED_BEACON) { - ath10k_dbg(ATH10K_DBG_MAC, - "vdev %d set beacon tx mode to staggered\n", - arvif->vdev_id); - - pdev_param = ar->wmi.pdev_param->beacon_tx_mode; - ret = ath10k_wmi_pdev_set_param(ar, pdev_param, + ret = ath10k_wmi_pdev_set_param(ar, + WMI_PDEV_PARAM_BEACON_TX_MODE, WMI_BEACON_STAGGERED_MODE); if (ret) ath10k_warn("Failed to set beacon mode for VDEV: %d\n", arvif->vdev_id); + else + ath10k_dbg(ATH10K_DBG_MAC, + "Set staggered beacon mode for VDEV: %d\n", + arvif->vdev_id); } if (changed & BSS_CHANGED_BEACON_INFO) { arvif->dtim_period = info->dtim_period; - ath10k_dbg(ATH10K_DBG_MAC, - "mac vdev %d dtim_period %d\n", - arvif->vdev_id, arvif->dtim_period); - - vdev_param = ar->wmi.vdev_param->dtim_period; - ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, + ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, + WMI_VDEV_PARAM_DTIM_PERIOD, arvif->dtim_period); if (ret) ath10k_warn("Failed to set dtim period for VDEV: %d\n", arvif->vdev_id); + else + ath10k_dbg(ATH10K_DBG_MAC, + "Set dtim period: %d for VDEV: %d\n", + arvif->dtim_period, arvif->vdev_id); } if (changed & BSS_CHANGED_SSID && @@ -2353,15 +2188,16 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_BSSID) { if (!is_zero_ether_addr(info->bssid)) { - ath10k_dbg(ATH10K_DBG_MAC, - "mac vdev %d create peer %pM\n", - arvif->vdev_id, info->bssid); - ret = ath10k_peer_create(ar, arvif->vdev_id, info->bssid); if (ret) ath10k_warn("Failed to add peer: %pM for VDEV: %d\n", info->bssid, arvif->vdev_id); + else + ath10k_dbg(ATH10K_DBG_MAC, + "Added peer: %pM for VDEV: %d\n", + info->bssid, arvif->vdev_id); + if (vif->type == NL80211_IFTYPE_STATION) { /* @@ -2371,12 +2207,11 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, memcpy(arvif->u.sta.bssid, info->bssid, ETH_ALEN); - ath10k_dbg(ATH10K_DBG_MAC, - "mac vdev %d start %pM\n", - arvif->vdev_id, info->bssid); - - /* FIXME: check return value */ ret = ath10k_vdev_start(arvif); + if (!ret) + ath10k_dbg(ATH10K_DBG_MAC, + "VDEV: %d started with BSSID: %pM\n", + arvif->vdev_id, info->bssid); } /* @@ -2400,15 +2235,16 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, else cts_prot = 0; - ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n", - arvif->vdev_id, cts_prot); - - vdev_param = ar->wmi.vdev_param->enable_rtscts; - ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, + ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, + WMI_VDEV_PARAM_ENABLE_RTSCTS, cts_prot); if (ret) ath10k_warn("Failed to set CTS prot for VDEV: %d\n", arvif->vdev_id); + else + ath10k_dbg(ATH10K_DBG_MAC, + "Set CTS prot: %d for VDEV: %d\n", + cts_prot, arvif->vdev_id); } if (changed & BSS_CHANGED_ERP_SLOT) { @@ -2419,15 +2255,16 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, else slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */ - ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n", - arvif->vdev_id, slottime); - - vdev_param = ar->wmi.vdev_param->slot_time; - ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, + ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, + WMI_VDEV_PARAM_SLOT_TIME, slottime); if (ret) ath10k_warn("Failed to set erp slot for VDEV: %d\n", arvif->vdev_id); + else + ath10k_dbg(ATH10K_DBG_MAC, + "Set slottime: %d for VDEV: %d\n", + slottime, arvif->vdev_id); } if (changed & BSS_CHANGED_ERP_PREAMBLE) { @@ -2437,16 +2274,16 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, else preamble = WMI_VDEV_PREAMBLE_LONG; - ath10k_dbg(ATH10K_DBG_MAC, - "mac vdev %d preamble %dn", - arvif->vdev_id, preamble); - - vdev_param = ar->wmi.vdev_param->preamble; - ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, + ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, + WMI_VDEV_PARAM_PREAMBLE, preamble); if (ret) ath10k_warn("Failed to set preamble for VDEV: %d\n", arvif->vdev_id); + else + ath10k_dbg(ATH10K_DBG_MAC, + "Set preamble: %d for VDEV: %d\n", + preamble, arvif->vdev_id); } if (changed & BSS_CHANGED_ASSOC) { @@ -2476,8 +2313,8 @@ static int ath10k_hw_scan(struct ieee80211_hw *hw, goto exit; } - reinit_completion(&ar->scan.started); - reinit_completion(&ar->scan.completed); + INIT_COMPLETION(ar->scan.started); + INIT_COMPLETION(ar->scan.completed); ar->scan.in_progress = true; ar->scan.aborting = false; ar->scan.is_roc = false; @@ -2637,26 +2474,27 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, /* * New station addition. */ - ath10k_dbg(ATH10K_DBG_MAC, - "mac vdev %d peer create %pM (new sta)\n", - arvif->vdev_id, sta->addr); - ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr); if (ret) ath10k_warn("Failed to add peer: %pM for VDEV: %d\n", sta->addr, arvif->vdev_id); + else + ath10k_dbg(ATH10K_DBG_MAC, + "Added peer: %pM for VDEV: %d\n", + sta->addr, arvif->vdev_id); } else if ((old_state == IEEE80211_STA_NONE && new_state == IEEE80211_STA_NOTEXIST)) { /* * Existing station deletion. */ - ath10k_dbg(ATH10K_DBG_MAC, - "mac vdev %d peer delete %pM (sta gone)\n", - arvif->vdev_id, sta->addr); ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr); if (ret) ath10k_warn("Failed to delete peer: %pM for VDEV: %d\n", sta->addr, arvif->vdev_id); + else + ath10k_dbg(ATH10K_DBG_MAC, + "Removed peer: %pM for VDEV: %d\n", + sta->addr, arvif->vdev_id); if (vif->type == NL80211_IFTYPE_STATION) ath10k_bss_disassoc(hw, vif); @@ -2667,13 +2505,14 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, /* * New association. */ - ath10k_dbg(ATH10K_DBG_MAC, "mac sta %pM associated\n", - sta->addr); - ret = ath10k_station_assoc(ar, arvif, sta); if (ret) ath10k_warn("Failed to associate station: %pM\n", sta->addr); + else + ath10k_dbg(ATH10K_DBG_MAC, + "Station %pM moved to assoc state\n", + sta->addr); } else if (old_state == IEEE80211_STA_ASSOC && new_state == IEEE80211_STA_AUTH && (vif->type == NL80211_IFTYPE_AP || @@ -2681,13 +2520,14 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, /* * Disassociation. */ - ath10k_dbg(ATH10K_DBG_MAC, "mac sta %pM disassociated\n", - sta->addr); - ret = ath10k_station_disassoc(ar, arvif, sta); if (ret) ath10k_warn("Failed to disassociate station: %pM\n", sta->addr); + else + ath10k_dbg(ATH10K_DBG_MAC, + "Station %pM moved to disassociated state\n", + sta->addr); } mutex_unlock(&ar->conf_mutex); @@ -2832,9 +2672,9 @@ static int ath10k_remain_on_channel(struct ieee80211_hw *hw, goto exit; } - reinit_completion(&ar->scan.started); - reinit_completion(&ar->scan.completed); - reinit_completion(&ar->scan.on_channel); + INIT_COMPLETION(ar->scan.started); + INIT_COMPLETION(ar->scan.completed); + INIT_COMPLETION(ar->scan.on_channel); ar->scan.in_progress = true; ar->scan.aborting = false; ar->scan.is_roc = true; @@ -2892,51 +2732,88 @@ static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw) * Both RTS and Fragmentation threshold are interface-specific * in ath10k, but device-specific in mac80211. */ +static void ath10k_set_rts_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +{ + struct ath10k_generic_iter *ar_iter = data; + struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); + u32 rts = ar_iter->ar->hw->wiphy->rts_threshold; + + lockdep_assert_held(&arvif->ar->conf_mutex); + + /* During HW reconfiguration mac80211 reports all interfaces that were + * running until reconfiguration was started. Since FW doesn't have any + * vdevs at this point we must not iterate over this interface list. + * This setting will be updated upon add_interface(). */ + if (ar_iter->ar->state == ATH10K_STATE_RESTARTED) + return; + + ar_iter->ret = ath10k_mac_set_rts(arvif, rts); + if (ar_iter->ret) + ath10k_warn("Failed to set RTS threshold for VDEV: %d\n", + arvif->vdev_id); + else + ath10k_dbg(ATH10K_DBG_MAC, + "Set RTS threshold: %d for VDEV: %d\n", + rts, arvif->vdev_id); +} static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value) { + struct ath10k_generic_iter ar_iter; struct ath10k *ar = hw->priv; - struct ath10k_vif *arvif; - int ret = 0; - mutex_lock(&ar->conf_mutex); - list_for_each_entry(arvif, &ar->arvifs, list) { - ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n", - arvif->vdev_id, value); + memset(&ar_iter, 0, sizeof(struct ath10k_generic_iter)); + ar_iter.ar = ar; - ret = ath10k_mac_set_rts(arvif, value); - if (ret) { - ath10k_warn("could not set rts threshold for vdev %d (%d)\n", - arvif->vdev_id, ret); - break; - } - } + mutex_lock(&ar->conf_mutex); + ieee80211_iterate_active_interfaces_atomic( + hw, IEEE80211_IFACE_ITER_NORMAL, + ath10k_set_rts_iter, &ar_iter); mutex_unlock(&ar->conf_mutex); - return ret; + return ar_iter.ret; +} + +static void ath10k_set_frag_iter(void *data, u8 *mac, struct ieee80211_vif *vif) +{ + struct ath10k_generic_iter *ar_iter = data; + struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); + u32 frag = ar_iter->ar->hw->wiphy->frag_threshold; + + lockdep_assert_held(&arvif->ar->conf_mutex); + + /* During HW reconfiguration mac80211 reports all interfaces that were + * running until reconfiguration was started. Since FW doesn't have any + * vdevs at this point we must not iterate over this interface list. + * This setting will be updated upon add_interface(). */ + if (ar_iter->ar->state == ATH10K_STATE_RESTARTED) + return; + + ar_iter->ret = ath10k_mac_set_frag(arvif, frag); + if (ar_iter->ret) + ath10k_warn("Failed to set frag threshold for VDEV: %d\n", + arvif->vdev_id); + else + ath10k_dbg(ATH10K_DBG_MAC, + "Set frag threshold: %d for VDEV: %d\n", + frag, arvif->vdev_id); } static int ath10k_set_frag_threshold(struct ieee80211_hw *hw, u32 value) { + struct ath10k_generic_iter ar_iter; struct ath10k *ar = hw->priv; - struct ath10k_vif *arvif; - int ret = 0; - mutex_lock(&ar->conf_mutex); - list_for_each_entry(arvif, &ar->arvifs, list) { - ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d fragmentation threshold %d\n", - arvif->vdev_id, value); + memset(&ar_iter, 0, sizeof(struct ath10k_generic_iter)); + ar_iter.ar = ar; - ret = ath10k_mac_set_rts(arvif, value); - if (ret) { - ath10k_warn("could not set fragmentation threshold for vdev %d (%d)\n", - arvif->vdev_id, ret); - break; - } - } + mutex_lock(&ar->conf_mutex); + ieee80211_iterate_active_interfaces_atomic( + hw, IEEE80211_IFACE_ITER_NORMAL, + ath10k_set_frag_iter, &ar_iter); mutex_unlock(&ar->conf_mutex); - return ret; + return ar_iter.ret; } static void ath10k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) @@ -2959,7 +2836,8 @@ static void ath10k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) bool empty; spin_lock_bh(&ar->htt.tx_lock); - empty = (ar->htt.num_pending_tx == 0); + empty = bitmap_empty(ar->htt.used_msdu_ids, + ar->htt.max_num_pending_tx); spin_unlock_bh(&ar->htt.tx_lock); skip = (ar->state == ATH10K_STATE_WEDGED); @@ -3448,10 +3326,6 @@ int ath10k_mac_register(struct ath10k *ar) IEEE80211_HW_WANT_MONITOR_VIF | IEEE80211_HW_AP_LINK_PS; - /* MSDU can have HTT TX fragment pushed in front. The additional 4 - * bytes is used for padding/alignment if necessary. */ - ar->hw->extra_tx_headroom += sizeof(struct htt_data_tx_desc_frag)*2 + 4; - if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) ar->hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS; diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h index ba10219..6fce9bf 100644 --- a/drivers/net/wireless/ath/ath10k/mac.h +++ b/drivers/net/wireless/ath/ath10k/mac.h @@ -34,8 +34,6 @@ struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id); void ath10k_reset_scan(unsigned long ptr); void ath10k_offchan_tx_purge(struct ath10k *ar); void ath10k_offchan_tx_work(struct work_struct *work); -void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar); -void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work); void ath10k_halt(struct ath10k *ar); static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif) diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 9e86a81..e2f9ef5 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -36,9 +36,11 @@ static unsigned int ath10k_target_ps; module_param(ath10k_target_ps, uint, 0644); MODULE_PARM_DESC(ath10k_target_ps, "Enable ath10k Target (SoC) PS option"); +#define QCA988X_1_0_DEVICE_ID (0xabcd) #define QCA988X_2_0_DEVICE_ID (0x003c) static DEFINE_PCI_DEVICE_TABLE(ath10k_pci_id_table) = { + { PCI_VDEVICE(ATHEROS, QCA988X_1_0_DEVICE_ID) }, /* PCI-E QCA988X V1 */ { PCI_VDEVICE(ATHEROS, QCA988X_2_0_DEVICE_ID) }, /* PCI-E QCA988X V2 */ {0} }; @@ -48,9 +50,9 @@ static int ath10k_pci_diag_read_access(struct ath10k *ar, u32 address, static void ath10k_pci_process_ce(struct ath10k *ar); static int ath10k_pci_post_rx(struct ath10k *ar); -static int ath10k_pci_post_rx_pipe(struct ath10k_pci_pipe *pipe_info, +static int ath10k_pci_post_rx_pipe(struct hif_ce_pipe_info *pipe_info, int num); -static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info); +static void ath10k_pci_rx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info); static void ath10k_pci_stop_ce(struct ath10k *ar); static void ath10k_pci_device_reset(struct ath10k *ar); static int ath10k_pci_reset_target(struct ath10k *ar); @@ -58,145 +60,43 @@ static int ath10k_pci_start_intr(struct ath10k *ar); static void ath10k_pci_stop_intr(struct ath10k *ar); static const struct ce_attr host_ce_config_wlan[] = { - /* CE0: host->target HTC control and raw streams */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 16, - .src_sz_max = 256, - .dest_nentries = 0, - }, - - /* CE1: target->host HTT + HTC control */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 512, - .dest_nentries = 512, - }, - - /* CE2: target->host WMI */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 2048, - .dest_nentries = 32, - }, - - /* CE3: host->target WMI */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 32, - .src_sz_max = 2048, - .dest_nentries = 0, - }, - - /* CE4: host->target HTT */ - { - .flags = CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, - .src_nentries = CE_HTT_H2T_MSG_SRC_NENTRIES, - .src_sz_max = 256, - .dest_nentries = 0, - }, - - /* CE5: unused */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE6: target autonomous hif_memcpy */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 0, - .src_sz_max = 0, - .dest_nentries = 0, - }, - - /* CE7: ce_diag, the Diagnostic Window */ - { - .flags = CE_ATTR_FLAGS, - .src_nentries = 2, - .src_sz_max = DIAG_TRANSFER_LIMIT, - .dest_nentries = 2, - }, + /* host->target HTC control and raw streams */ + { /* CE0 */ CE_ATTR_FLAGS, 0, 16, 256, 0, NULL,}, + /* could be moved to share CE3 */ + /* target->host HTT + HTC control */ + { /* CE1 */ CE_ATTR_FLAGS, 0, 0, 512, 512, NULL,}, + /* target->host WMI */ + { /* CE2 */ CE_ATTR_FLAGS, 0, 0, 2048, 32, NULL,}, + /* host->target WMI */ + { /* CE3 */ CE_ATTR_FLAGS, 0, 32, 2048, 0, NULL,}, + /* host->target HTT */ + { /* CE4 */ CE_ATTR_FLAGS | CE_ATTR_DIS_INTR, 0, + CE_HTT_H2T_MSG_SRC_NENTRIES, 256, 0, NULL,}, + /* unused */ + { /* CE5 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL,}, + /* Target autonomous hif_memcpy */ + { /* CE6 */ CE_ATTR_FLAGS, 0, 0, 0, 0, NULL,}, + /* ce_diag, the Diagnostic Window */ + { /* CE7 */ CE_ATTR_FLAGS, 0, 2, DIAG_TRANSFER_LIMIT, 2, NULL,}, }; /* Target firmware's Copy Engine configuration. */ static const struct ce_pipe_config target_ce_config_wlan[] = { - /* CE0: host->target HTC control and raw streams */ - { - .pipenum = 0, - .pipedir = PIPEDIR_OUT, - .nentries = 32, - .nbytes_max = 256, - .flags = CE_ATTR_FLAGS, - .reserved = 0, - }, - - /* CE1: target->host HTT + HTC control */ - { - .pipenum = 1, - .pipedir = PIPEDIR_IN, - .nentries = 32, - .nbytes_max = 512, - .flags = CE_ATTR_FLAGS, - .reserved = 0, - }, - - /* CE2: target->host WMI */ - { - .pipenum = 2, - .pipedir = PIPEDIR_IN, - .nentries = 32, - .nbytes_max = 2048, - .flags = CE_ATTR_FLAGS, - .reserved = 0, - }, - - /* CE3: host->target WMI */ - { - .pipenum = 3, - .pipedir = PIPEDIR_OUT, - .nentries = 32, - .nbytes_max = 2048, - .flags = CE_ATTR_FLAGS, - .reserved = 0, - }, - - /* CE4: host->target HTT */ - { - .pipenum = 4, - .pipedir = PIPEDIR_OUT, - .nentries = 256, - .nbytes_max = 256, - .flags = CE_ATTR_FLAGS, - .reserved = 0, - }, - + /* host->target HTC control and raw streams */ + { /* CE0 */ 0, PIPEDIR_OUT, 32, 256, CE_ATTR_FLAGS, 0,}, + /* target->host HTT + HTC control */ + { /* CE1 */ 1, PIPEDIR_IN, 32, 512, CE_ATTR_FLAGS, 0,}, + /* target->host WMI */ + { /* CE2 */ 2, PIPEDIR_IN, 32, 2048, CE_ATTR_FLAGS, 0,}, + /* host->target WMI */ + { /* CE3 */ 3, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,}, + /* host->target HTT */ + { /* CE4 */ 4, PIPEDIR_OUT, 256, 256, CE_ATTR_FLAGS, 0,}, /* NB: 50% of src nentries, since tx has 2 frags */ - - /* CE5: unused */ - { - .pipenum = 5, - .pipedir = PIPEDIR_OUT, - .nentries = 32, - .nbytes_max = 2048, - .flags = CE_ATTR_FLAGS, - .reserved = 0, - }, - - /* CE6: Reserved for target autonomous hif_memcpy */ - { - .pipenum = 6, - .pipedir = PIPEDIR_INOUT, - .nentries = 32, - .nbytes_max = 4096, - .flags = CE_ATTR_FLAGS, - .reserved = 0, - }, - + /* unused */ + { /* CE5 */ 5, PIPEDIR_OUT, 32, 2048, CE_ATTR_FLAGS, 0,}, + /* Reserved for target autonomous hif_memcpy */ + { /* CE6 */ 6, PIPEDIR_INOUT, 32, 4096, CE_ATTR_FLAGS, 0,}, /* CE7 used only by Host */ }; @@ -214,7 +114,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, unsigned int completed_nbytes, orig_nbytes, remaining_bytes; unsigned int id; unsigned int flags; - struct ath10k_ce_pipe *ce_diag; + struct ce_state *ce_diag; /* Host buffer address in CE space */ u32 ce_data; dma_addr_t ce_data_base = 0; @@ -378,7 +278,7 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, unsigned int completed_nbytes, orig_nbytes, remaining_bytes; unsigned int id; unsigned int flags; - struct ath10k_ce_pipe *ce_diag; + struct ce_state *ce_diag; void *data_buf = NULL; u32 ce_data; /* Host buffer address in CE space */ dma_addr_t ce_data_base = 0; @@ -537,7 +437,7 @@ static void ath10k_pci_wait(struct ath10k *ar) ath10k_warn("Unable to wakeup target\n"); } -int ath10k_do_pci_wake(struct ath10k *ar) +void ath10k_do_pci_wake(struct ath10k *ar) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); void __iomem *pci_addr = ar_pci->mem; @@ -553,19 +453,18 @@ int ath10k_do_pci_wake(struct ath10k *ar) atomic_inc(&ar_pci->keep_awake_count); if (ar_pci->verified_awake) - return 0; + return; for (;;) { if (ath10k_pci_target_is_awake(ar)) { ar_pci->verified_awake = true; - return 0; + break; } if (tot_delay > PCIE_WAKE_TIMEOUT) { - ath10k_warn("target took longer %d us to wake up (awake count %d)\n", - PCIE_WAKE_TIMEOUT, + ath10k_warn("target takes too long to wake up (awake count %d)\n", atomic_read(&ar_pci->keep_awake_count)); - return -ETIMEDOUT; + break; } udelay(curr_delay); @@ -594,7 +493,7 @@ void ath10k_do_pci_sleep(struct ath10k *ar) * FIXME: Handle OOM properly. */ static inline -struct ath10k_pci_compl *get_free_compl(struct ath10k_pci_pipe *pipe_info) +struct ath10k_pci_compl *get_free_compl(struct hif_ce_pipe_info *pipe_info) { struct ath10k_pci_compl *compl = NULL; @@ -612,28 +511,39 @@ exit: } /* Called by lower (CE) layer when a send to Target completes. */ -static void ath10k_pci_ce_send_done(struct ath10k_ce_pipe *ce_state) +static void ath10k_pci_ce_send_done(struct ce_state *ce_state, + void *transfer_context, + u32 ce_data, + unsigned int nbytes, + unsigned int transfer_id) { struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - struct ath10k_pci_pipe *pipe_info = &ar_pci->pipe_info[ce_state->id]; + struct hif_ce_pipe_info *pipe_info = &ar_pci->pipe_info[ce_state->id]; struct ath10k_pci_compl *compl; - void *transfer_context; - u32 ce_data; - unsigned int nbytes; - unsigned int transfer_id; + bool process = false; + + do { + /* + * For the send completion of an item in sendlist, just + * increment num_sends_allowed. The upper layer callback will + * be triggered when last fragment is done with send. + */ + if (transfer_context == CE_SENDLIST_ITEM_CTXT) { + spin_lock_bh(&pipe_info->pipe_lock); + pipe_info->num_sends_allowed++; + spin_unlock_bh(&pipe_info->pipe_lock); + continue; + } - while (ath10k_ce_completed_send_next(ce_state, &transfer_context, - &ce_data, &nbytes, - &transfer_id) == 0) { compl = get_free_compl(pipe_info); if (!compl) break; - compl->state = ATH10K_PCI_COMPL_SEND; + compl->send_or_recv = HIF_CE_COMPLETE_SEND; compl->ce_state = ce_state; compl->pipe_info = pipe_info; - compl->skb = transfer_context; + compl->transfer_context = transfer_context; compl->nbytes = nbytes; compl->transfer_id = transfer_id; compl->flags = 0; @@ -644,36 +554,46 @@ static void ath10k_pci_ce_send_done(struct ath10k_ce_pipe *ce_state) spin_lock_bh(&ar_pci->compl_lock); list_add_tail(&compl->list, &ar_pci->compl_process); spin_unlock_bh(&ar_pci->compl_lock); - } + + process = true; + } while (ath10k_ce_completed_send_next(ce_state, + &transfer_context, + &ce_data, &nbytes, + &transfer_id) == 0); + + /* + * If only some of the items within a sendlist have completed, + * don't invoke completion processing until the entire sendlist + * has been sent. + */ + if (!process) + return; ath10k_pci_process_ce(ar); } /* Called by lower (CE) layer when data is received from the Target. */ -static void ath10k_pci_ce_recv_data(struct ath10k_ce_pipe *ce_state) +static void ath10k_pci_ce_recv_data(struct ce_state *ce_state, + void *transfer_context, u32 ce_data, + unsigned int nbytes, + unsigned int transfer_id, + unsigned int flags) { struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - struct ath10k_pci_pipe *pipe_info = &ar_pci->pipe_info[ce_state->id]; + struct hif_ce_pipe_info *pipe_info = &ar_pci->pipe_info[ce_state->id]; struct ath10k_pci_compl *compl; struct sk_buff *skb; - void *transfer_context; - u32 ce_data; - unsigned int nbytes; - unsigned int transfer_id; - unsigned int flags; - while (ath10k_ce_completed_recv_next(ce_state, &transfer_context, - &ce_data, &nbytes, &transfer_id, - &flags) == 0) { + do { compl = get_free_compl(pipe_info); if (!compl) break; - compl->state = ATH10K_PCI_COMPL_RECV; + compl->send_or_recv = HIF_CE_COMPLETE_RECV; compl->ce_state = ce_state; compl->pipe_info = pipe_info; - compl->skb = transfer_context; + compl->transfer_context = transfer_context; compl->nbytes = nbytes; compl->transfer_id = transfer_id; compl->flags = flags; @@ -688,7 +608,12 @@ static void ath10k_pci_ce_recv_data(struct ath10k_ce_pipe *ce_state) spin_lock_bh(&ar_pci->compl_lock); list_add_tail(&compl->list, &ar_pci->compl_process); spin_unlock_bh(&ar_pci->compl_lock); - } + + } while (ath10k_ce_completed_recv_next(ce_state, + &transfer_context, + &ce_data, &nbytes, + &transfer_id, + &flags) == 0); ath10k_pci_process_ce(ar); } @@ -700,12 +625,15 @@ static int ath10k_pci_hif_send_head(struct ath10k *ar, u8 pipe_id, { struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(nbuf); struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - struct ath10k_pci_pipe *pipe_info = &(ar_pci->pipe_info[pipe_id]); - struct ath10k_ce_pipe *ce_hdl = pipe_info->ce_hdl; + struct hif_ce_pipe_info *pipe_info = &(ar_pci->pipe_info[pipe_id]); + struct ce_state *ce_hdl = pipe_info->ce_hdl; + struct ce_sendlist sendlist; unsigned int len; u32 flags = 0; int ret; + memset(&sendlist, 0, sizeof(struct ce_sendlist)); + len = min(bytes, nbuf->len); bytes -= len; @@ -720,8 +648,19 @@ static int ath10k_pci_hif_send_head(struct ath10k *ar, u8 pipe_id, "ath10k tx: data: ", nbuf->data, nbuf->len); - ret = ath10k_ce_send(ce_hdl, nbuf, skb_cb->paddr, len, transfer_id, - flags); + ath10k_ce_sendlist_buf_add(&sendlist, skb_cb->paddr, len, flags); + + /* Make sure we have resources to handle this request */ + spin_lock_bh(&pipe_info->pipe_lock); + if (!pipe_info->num_sends_allowed) { + ath10k_warn("Pipe: %d is full\n", pipe_id); + spin_unlock_bh(&pipe_info->pipe_lock); + return -ENOSR; + } + pipe_info->num_sends_allowed--; + spin_unlock_bh(&pipe_info->pipe_lock); + + ret = ath10k_ce_sendlist_send(ce_hdl, nbuf, &sendlist, transfer_id); if (ret) ath10k_warn("CE send failed: %p\n", nbuf); @@ -731,7 +670,14 @@ static int ath10k_pci_hif_send_head(struct ath10k *ar, u8 pipe_id, static u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - return ath10k_ce_num_free_src_entries(ar_pci->pipe_info[pipe].ce_hdl); + struct hif_ce_pipe_info *pipe_info = &(ar_pci->pipe_info[pipe]); + int ret; + + spin_lock_bh(&pipe_info->pipe_lock); + ret = pipe_info->num_sends_allowed; + spin_unlock_bh(&pipe_info->pipe_lock); + + return ret; } static void ath10k_pci_hif_dump_area(struct ath10k *ar) @@ -818,9 +764,9 @@ static void ath10k_pci_hif_set_callbacks(struct ath10k *ar, static int ath10k_pci_start_ce(struct ath10k *ar) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - struct ath10k_ce_pipe *ce_diag = ar_pci->ce_diag; + struct ce_state *ce_diag = ar_pci->ce_diag; const struct ce_attr *attr; - struct ath10k_pci_pipe *pipe_info; + struct hif_ce_pipe_info *pipe_info; struct ath10k_pci_compl *compl; int i, pipe_num, completions, disable_interrupts; @@ -846,6 +792,7 @@ static int ath10k_pci_start_ce(struct ath10k *ar) ath10k_pci_ce_send_done, disable_interrupts); completions += attr->src_nentries; + pipe_info->num_sends_allowed = attr->src_nentries - 1; } if (attr->dest_nentries) { @@ -858,14 +805,15 @@ static int ath10k_pci_start_ce(struct ath10k *ar) continue; for (i = 0; i < completions; i++) { - compl = kmalloc(sizeof(*compl), GFP_KERNEL); + compl = kmalloc(sizeof(struct ath10k_pci_compl), + GFP_KERNEL); if (!compl) { ath10k_warn("No memory for completion state\n"); ath10k_pci_stop_ce(ar); return -ENOMEM; } - compl->state = ATH10K_PCI_COMPL_FREE; + compl->send_or_recv = HIF_CE_COMPLETE_FREE; list_add_tail(&compl->list, &pipe_info->compl_free); } } @@ -892,7 +840,7 @@ static void ath10k_pci_stop_ce(struct ath10k *ar) * their associated resources */ spin_lock_bh(&ar_pci->compl_lock); list_for_each_entry(compl, &ar_pci->compl_process, list) { - skb = compl->skb; + skb = (struct sk_buff *)compl->transfer_context; ATH10K_SKB_CB(skb)->is_aborted = true; } spin_unlock_bh(&ar_pci->compl_lock); @@ -902,7 +850,7 @@ static void ath10k_pci_cleanup_ce(struct ath10k *ar) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_pci_compl *compl, *tmp; - struct ath10k_pci_pipe *pipe_info; + struct hif_ce_pipe_info *pipe_info; struct sk_buff *netbuf; int pipe_num; @@ -913,7 +861,7 @@ static void ath10k_pci_cleanup_ce(struct ath10k *ar) list_for_each_entry_safe(compl, tmp, &ar_pci->compl_process, list) { list_del(&compl->list); - netbuf = compl->skb; + netbuf = (struct sk_buff *)compl->transfer_context; dev_kfree_skb_any(netbuf); kfree(compl); } @@ -964,14 +912,12 @@ static void ath10k_pci_process_ce(struct ath10k *ar) list_del(&compl->list); spin_unlock_bh(&ar_pci->compl_lock); - switch (compl->state) { - case ATH10K_PCI_COMPL_SEND: + if (compl->send_or_recv == HIF_CE_COMPLETE_SEND) { cb->tx_completion(ar, - compl->skb, + compl->transfer_context, compl->transfer_id); send_done = 1; - break; - case ATH10K_PCI_COMPL_RECV: + } else { ret = ath10k_pci_post_rx_pipe(compl->pipe_info, 1); if (ret) { ath10k_warn("Unable to post recv buffer for pipe: %d\n", @@ -979,7 +925,7 @@ static void ath10k_pci_process_ce(struct ath10k *ar) break; } - skb = compl->skb; + skb = (struct sk_buff *)compl->transfer_context; nbytes = compl->nbytes; ath10k_dbg(ATH10K_DBG_PCI, @@ -998,23 +944,16 @@ static void ath10k_pci_process_ce(struct ath10k *ar) nbytes, skb->len + skb_tailroom(skb)); } - break; - case ATH10K_PCI_COMPL_FREE: - ath10k_warn("free completion cannot be processed\n"); - break; - default: - ath10k_warn("invalid completion state (%d)\n", - compl->state); - break; } - compl->state = ATH10K_PCI_COMPL_FREE; + compl->send_or_recv = HIF_CE_COMPLETE_FREE; /* * Add completion back to the pipe's free list. */ spin_lock_bh(&compl->pipe_info->pipe_lock); list_add_tail(&compl->list, &compl->pipe_info->compl_free); + compl->pipe_info->num_sends_allowed += send_done; spin_unlock_bh(&compl->pipe_info->pipe_lock); } @@ -1098,12 +1037,12 @@ static void ath10k_pci_hif_get_default_pipe(struct ath10k *ar, &dl_is_polled); } -static int ath10k_pci_post_rx_pipe(struct ath10k_pci_pipe *pipe_info, +static int ath10k_pci_post_rx_pipe(struct hif_ce_pipe_info *pipe_info, int num) { struct ath10k *ar = pipe_info->hif_ce_state; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - struct ath10k_ce_pipe *ce_state = pipe_info->ce_hdl; + struct ce_state *ce_state = pipe_info->ce_hdl; struct sk_buff *skb; dma_addr_t ce_data; int i, ret = 0; @@ -1158,7 +1097,7 @@ err: static int ath10k_pci_post_rx(struct ath10k *ar) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - struct ath10k_pci_pipe *pipe_info; + struct hif_ce_pipe_info *pipe_info; const struct ce_attr *attr; int pipe_num, ret = 0; @@ -1208,11 +1147,11 @@ static int ath10k_pci_hif_start(struct ath10k *ar) return 0; } -static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info) +static void ath10k_pci_rx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info) { struct ath10k *ar; struct ath10k_pci *ar_pci; - struct ath10k_ce_pipe *ce_hdl; + struct ce_state *ce_hdl; u32 buf_sz; struct sk_buff *netbuf; u32 ce_data; @@ -1240,11 +1179,11 @@ static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info) } } -static void ath10k_pci_tx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info) +static void ath10k_pci_tx_pipe_cleanup(struct hif_ce_pipe_info *pipe_info) { struct ath10k *ar; struct ath10k_pci *ar_pci; - struct ath10k_ce_pipe *ce_hdl; + struct ce_state *ce_hdl; struct sk_buff *netbuf; u32 ce_data; unsigned int nbytes; @@ -1267,14 +1206,15 @@ static void ath10k_pci_tx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info) while (ath10k_ce_cancel_send_next(ce_hdl, (void **)&netbuf, &ce_data, &nbytes, &id) == 0) { - /* - * Indicate the completion to higer layer to free - * the buffer - */ - ATH10K_SKB_CB(netbuf)->is_aborted = true; - ar_pci->msg_callbacks_current.tx_completion(ar, - netbuf, - id); + if (netbuf != CE_SENDLIST_ITEM_CTXT) + /* + * Indicate the completion to higer layer to free + * the buffer + */ + ATH10K_SKB_CB(netbuf)->is_aborted = true; + ar_pci->msg_callbacks_current.tx_completion(ar, + netbuf, + id); } } @@ -1292,7 +1232,7 @@ static void ath10k_pci_buffer_cleanup(struct ath10k *ar) int pipe_num; for (pipe_num = 0; pipe_num < ar_pci->ce_count; pipe_num++) { - struct ath10k_pci_pipe *pipe_info; + struct hif_ce_pipe_info *pipe_info; pipe_info = &ar_pci->pipe_info[pipe_num]; ath10k_pci_rx_pipe_cleanup(pipe_info); @@ -1303,7 +1243,7 @@ static void ath10k_pci_buffer_cleanup(struct ath10k *ar) static void ath10k_pci_ce_deinit(struct ath10k *ar) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - struct ath10k_pci_pipe *pipe_info; + struct hif_ce_pipe_info *pipe_info; int pipe_num; for (pipe_num = 0; pipe_num < ar_pci->ce_count; pipe_num++) { @@ -1353,10 +1293,8 @@ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar, void *resp, u32 *resp_len) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - struct ath10k_pci_pipe *pci_tx = &ar_pci->pipe_info[BMI_CE_NUM_TO_TARG]; - struct ath10k_pci_pipe *pci_rx = &ar_pci->pipe_info[BMI_CE_NUM_TO_HOST]; - struct ath10k_ce_pipe *ce_tx = pci_tx->ce_hdl; - struct ath10k_ce_pipe *ce_rx = pci_rx->ce_hdl; + struct ce_state *ce_tx = ar_pci->pipe_info[BMI_CE_NUM_TO_TARG].ce_hdl; + struct ce_state *ce_rx = ar_pci->pipe_info[BMI_CE_NUM_TO_HOST].ce_hdl; dma_addr_t req_paddr = 0; dma_addr_t resp_paddr = 0; struct bmi_xfer xfer = {}; @@ -1440,16 +1378,13 @@ err_dma: return ret; } -static void ath10k_pci_bmi_send_done(struct ath10k_ce_pipe *ce_state) +static void ath10k_pci_bmi_send_done(struct ce_state *ce_state, + void *transfer_context, + u32 data, + unsigned int nbytes, + unsigned int transfer_id) { - struct bmi_xfer *xfer; - u32 ce_data; - unsigned int nbytes; - unsigned int transfer_id; - - if (ath10k_ce_completed_send_next(ce_state, (void **)&xfer, &ce_data, - &nbytes, &transfer_id)) - return; + struct bmi_xfer *xfer = transfer_context; if (xfer->wait_for_resp) return; @@ -1457,17 +1392,14 @@ static void ath10k_pci_bmi_send_done(struct ath10k_ce_pipe *ce_state) complete(&xfer->done); } -static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state) +static void ath10k_pci_bmi_recv_data(struct ce_state *ce_state, + void *transfer_context, + u32 data, + unsigned int nbytes, + unsigned int transfer_id, + unsigned int flags) { - struct bmi_xfer *xfer; - u32 ce_data; - unsigned int nbytes; - unsigned int transfer_id; - unsigned int flags; - - if (ath10k_ce_completed_recv_next(ce_state, (void **)&xfer, &ce_data, - &nbytes, &transfer_id, &flags)) - return; + struct bmi_xfer *xfer = transfer_context; if (!xfer->wait_for_resp) { ath10k_warn("unexpected: BMI data received; ignoring\n"); @@ -1747,7 +1679,7 @@ static int ath10k_pci_init_config(struct ath10k *ar) static int ath10k_pci_ce_init(struct ath10k *ar) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - struct ath10k_pci_pipe *pipe_info; + struct hif_ce_pipe_info *pipe_info; const struct ce_attr *attr; int pipe_num; @@ -1963,7 +1895,7 @@ static const struct ath10k_hif_ops ath10k_pci_hif_ops = { static void ath10k_pci_ce_tasklet(unsigned long ptr) { - struct ath10k_pci_pipe *pipe = (struct ath10k_pci_pipe *)ptr; + struct hif_ce_pipe_info *pipe = (struct hif_ce_pipe_info *)ptr; struct ath10k_pci *ar_pci = pipe->ar_pci; ath10k_ce_per_engine_service(ar_pci->ar, pipe->pipe_num); @@ -2280,13 +2212,18 @@ static int ath10k_pci_reset_target(struct ath10k *ar) static void ath10k_pci_device_reset(struct ath10k *ar) { + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); + void __iomem *mem = ar_pci->mem; int i; u32 val; if (!SOC_GLOBAL_RESET_ADDRESS) return; - ath10k_pci_reg_write32(ar, PCIE_SOC_WAKE_ADDRESS, + if (!mem) + return; + + ath10k_pci_reg_write32(mem, PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_V_MASK); for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) { if (ath10k_pci_target_is_awake(ar)) @@ -2295,12 +2232,12 @@ static void ath10k_pci_device_reset(struct ath10k *ar) } /* Put Target, including PCIe, into RESET. */ - val = ath10k_pci_reg_read32(ar, SOC_GLOBAL_RESET_ADDRESS); + val = ath10k_pci_reg_read32(mem, SOC_GLOBAL_RESET_ADDRESS); val |= 1; - ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val); + ath10k_pci_reg_write32(mem, SOC_GLOBAL_RESET_ADDRESS, val); for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) { - if (ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) & + if (ath10k_pci_reg_read32(mem, RTC_STATE_ADDRESS) & RTC_STATE_COLD_RESET_MASK) break; msleep(1); @@ -2308,16 +2245,16 @@ static void ath10k_pci_device_reset(struct ath10k *ar) /* Pull Target, including PCIe, out of RESET. */ val &= ~1; - ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val); + ath10k_pci_reg_write32(mem, SOC_GLOBAL_RESET_ADDRESS, val); for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) { - if (!(ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) & + if (!(ath10k_pci_reg_read32(mem, RTC_STATE_ADDRESS) & RTC_STATE_COLD_RESET_MASK)) break; msleep(1); } - ath10k_pci_reg_write32(ar, PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET); + ath10k_pci_reg_write32(mem, PCIE_SOC_WAKE_ADDRESS, PCIE_SOC_WAKE_RESET); } static void ath10k_pci_dump_features(struct ath10k_pci *ar_pci) @@ -2330,10 +2267,13 @@ static void ath10k_pci_dump_features(struct ath10k_pci *ar_pci) switch (i) { case ATH10K_PCI_FEATURE_MSI_X: - ath10k_dbg(ATH10K_DBG_BOOT, "device supports MSI-X\n"); + ath10k_dbg(ATH10K_DBG_PCI, "device supports MSI-X\n"); + break; + case ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND: + ath10k_dbg(ATH10K_DBG_PCI, "QCA988X_1.0 workaround enabled\n"); break; case ATH10K_PCI_FEATURE_SOC_POWER_SAVE: - ath10k_dbg(ATH10K_DBG_BOOT, "QCA98XX SoC power save enabled\n"); + ath10k_dbg(ATH10K_DBG_PCI, "QCA98XX SoC power save enabled\n"); break; } } @@ -2346,7 +2286,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev, int ret = 0; struct ath10k *ar; struct ath10k_pci *ar_pci; - u32 lcr_val, chip_id; + u32 lcr_val; ath10k_dbg(ATH10K_DBG_PCI, "%s\n", __func__); @@ -2358,12 +2298,15 @@ static int ath10k_pci_probe(struct pci_dev *pdev, ar_pci->dev = &pdev->dev; switch (pci_dev->device) { + case QCA988X_1_0_DEVICE_ID: + set_bit(ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND, ar_pci->features); + break; case QCA988X_2_0_DEVICE_ID: set_bit(ATH10K_PCI_FEATURE_MSI_X, ar_pci->features); break; default: ret = -ENODEV; - ath10k_err("Unknown device ID: %d\n", pci_dev->device); + ath10k_err("Unkown device ID: %d\n", pci_dev->device); goto err_ar_pci; } @@ -2379,6 +2322,10 @@ static int ath10k_pci_probe(struct pci_dev *pdev, goto err_ar_pci; } + /* Enable QCA988X_1.0 HW workarounds */ + if (test_bit(ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND, ar_pci->features)) + spin_lock_init(&ar_pci->hw_v1_workaround_lock); + ar_pci->ar = ar; ar_pci->fw_indicator_address = FW_INDICATOR_ADDRESS; atomic_set(&ar_pci->keep_awake_count, 0); @@ -2448,20 +2395,9 @@ static int ath10k_pci_probe(struct pci_dev *pdev, spin_lock_init(&ar_pci->ce_lock); - ret = ath10k_do_pci_wake(ar); - if (ret) { - ath10k_err("Failed to get chip id: %d\n", ret); - return ret; - } - - chip_id = ath10k_pci_read32(ar, - RTC_SOC_BASE_ADDRESS + SOC_CHIP_ID_ADDRESS); - - ath10k_do_pci_sleep(ar); - - ath10k_dbg(ATH10K_DBG_BOOT, "boot pci_mem 0x%p\n", ar_pci->mem); + ar_pci->cacheline_sz = dma_get_cache_alignment(); - ret = ath10k_core_register(ar, chip_id); + ret = ath10k_core_register(ar); if (ret) { ath10k_err("could not register driver core (%d)\n", ret); goto err_iomap; @@ -2478,6 +2414,7 @@ err_region: err_device: pci_disable_device(pdev); err_ar: + pci_set_drvdata(pdev, NULL); ath10k_core_destroy(ar); err_ar_pci: /* call HIF PCI free here */ @@ -2505,6 +2442,7 @@ static void ath10k_pci_remove(struct pci_dev *pdev) ath10k_core_unregister(ar); + pci_set_drvdata(pdev, NULL); pci_iounmap(pdev, ar_pci->mem); pci_release_region(pdev, BAR_NUM); pci_clear_master(pdev); @@ -2545,6 +2483,9 @@ module_exit(ath10k_pci_exit); MODULE_AUTHOR("Qualcomm Atheros"); MODULE_DESCRIPTION("Driver support for Atheros QCA988X PCIe devices"); MODULE_LICENSE("Dual BSD/GPL"); +MODULE_FIRMWARE(QCA988X_HW_1_0_FW_DIR "/" QCA988X_HW_1_0_FW_FILE); +MODULE_FIRMWARE(QCA988X_HW_1_0_FW_DIR "/" QCA988X_HW_1_0_OTP_FILE); +MODULE_FIRMWARE(QCA988X_HW_1_0_FW_DIR "/" QCA988X_HW_1_0_BOARD_DATA_FILE); MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_FW_FILE); MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_OTP_FILE); MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_BOARD_DATA_FILE); diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h index 52fb7b9..871bb33 100644 --- a/drivers/net/wireless/ath/ath10k/pci.h +++ b/drivers/net/wireless/ath/ath10k/pci.h @@ -43,23 +43,22 @@ struct bmi_xfer { u32 resp_len; }; -enum ath10k_pci_compl_state { - ATH10K_PCI_COMPL_FREE = 0, - ATH10K_PCI_COMPL_SEND, - ATH10K_PCI_COMPL_RECV, -}; - struct ath10k_pci_compl { struct list_head list; - enum ath10k_pci_compl_state state; - struct ath10k_ce_pipe *ce_state; - struct ath10k_pci_pipe *pipe_info; - struct sk_buff *skb; + int send_or_recv; + struct ce_state *ce_state; + struct hif_ce_pipe_info *pipe_info; + void *transfer_context; unsigned int nbytes; unsigned int transfer_id; unsigned int flags; }; +/* compl_state.send_or_recv */ +#define HIF_CE_COMPLETE_FREE 0 +#define HIF_CE_COMPLETE_SEND 1 +#define HIF_CE_COMPLETE_RECV 2 + /* * PCI-specific Target state * @@ -153,16 +152,17 @@ struct service_to_pipe { enum ath10k_pci_features { ATH10K_PCI_FEATURE_MSI_X = 0, - ATH10K_PCI_FEATURE_SOC_POWER_SAVE = 1, + ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND = 1, + ATH10K_PCI_FEATURE_SOC_POWER_SAVE = 2, /* keep last */ ATH10K_PCI_FEATURE_COUNT }; /* Per-pipe state. */ -struct ath10k_pci_pipe { +struct hif_ce_pipe_info { /* Handle of underlying Copy Engine */ - struct ath10k_ce_pipe *ce_hdl; + struct ce_state *ce_hdl; /* Our pipe number; facilitiates use of pipe_info ptrs. */ u8 pipe_num; @@ -178,6 +178,9 @@ struct ath10k_pci_pipe { /* List of free CE completion slots */ struct list_head compl_free; + /* Limit the number of outstanding send requests. */ + int num_sends_allowed; + struct ath10k_pci *ar_pci; struct tasklet_struct intr; }; @@ -187,6 +190,7 @@ struct ath10k_pci { struct device *dev; struct ath10k *ar; void __iomem *mem; + int cacheline_sz; DECLARE_BITMAP(features, ATH10K_PCI_FEATURE_COUNT); @@ -215,7 +219,7 @@ struct ath10k_pci { bool compl_processing; - struct ath10k_pci_pipe pipe_info[CE_COUNT_MAX]; + struct hif_ce_pipe_info pipe_info[CE_COUNT_MAX]; struct ath10k_hif_cb msg_callbacks_current; @@ -223,13 +227,16 @@ struct ath10k_pci { u32 fw_indicator_address; /* Copy Engine used for Diagnostic Accesses */ - struct ath10k_ce_pipe *ce_diag; + struct ce_state *ce_diag; /* FIXME: document what this really protects */ spinlock_t ce_lock; /* Map CE id to ce_state */ - struct ath10k_ce_pipe ce_states[CE_COUNT_MAX]; + struct ce_state *ce_id_to_state[CE_COUNT_MAX]; + + /* makes sure that dummy reads are atomic */ + spinlock_t hw_v1_workaround_lock; }; static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar) @@ -237,18 +244,14 @@ static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar) return ar->hif.priv; } -static inline u32 ath10k_pci_reg_read32(struct ath10k *ar, u32 addr) +static inline u32 ath10k_pci_reg_read32(void __iomem *mem, u32 addr) { - struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - - return ioread32(ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr); + return ioread32(mem + PCIE_LOCAL_BASE_ADDRESS + addr); } -static inline void ath10k_pci_reg_write32(struct ath10k *ar, u32 addr, u32 val) +static inline void ath10k_pci_reg_write32(void __iomem *mem, u32 addr, u32 val) { - struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - - iowrite32(val, ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr); + iowrite32(val, mem + PCIE_LOCAL_BASE_ADDRESS + addr); } #define ATH_PCI_RESET_WAIT_MAX 10 /* ms */ @@ -307,8 +310,23 @@ static inline void ath10k_pci_write32(struct ath10k *ar, u32 offset, u32 value) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); + void __iomem *addr = ar_pci->mem; + + if (test_bit(ATH10K_PCI_FEATURE_HW_1_0_WORKAROUND, ar_pci->features)) { + unsigned long irq_flags; - iowrite32(value, ar_pci->mem + offset); + spin_lock_irqsave(&ar_pci->hw_v1_workaround_lock, irq_flags); + + ioread32(addr+offset+4); /* 3rd read prior to write */ + ioread32(addr+offset+4); /* 2nd read prior to write */ + ioread32(addr+offset+4); /* 1st read prior to write */ + iowrite32(value, addr+offset); + + spin_unlock_irqrestore(&ar_pci->hw_v1_workaround_lock, + irq_flags); + } else { + iowrite32(value, addr+offset); + } } static inline u32 ath10k_pci_read32(struct ath10k *ar, u32 offset) @@ -318,17 +336,15 @@ static inline u32 ath10k_pci_read32(struct ath10k *ar, u32 offset) return ioread32(ar_pci->mem + offset); } -int ath10k_do_pci_wake(struct ath10k *ar); +void ath10k_do_pci_wake(struct ath10k *ar); void ath10k_do_pci_sleep(struct ath10k *ar); -static inline int ath10k_pci_wake(struct ath10k *ar) +static inline void ath10k_pci_wake(struct ath10k *ar) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); if (test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) - return ath10k_do_pci_wake(ar); - - return 0; + ath10k_do_pci_wake(ar); } static inline void ath10k_pci_sleep(struct ath10k *ar) diff --git a/drivers/net/wireless/ath/ath10k/rx_desc.h b/drivers/net/wireless/ath/ath10k/rx_desc.h index 1c584c4..bfec6c8 100644 --- a/drivers/net/wireless/ath/ath10k/rx_desc.h +++ b/drivers/net/wireless/ath/ath10k/rx_desc.h @@ -422,30 +422,10 @@ struct rx_mpdu_end { #define RX_MSDU_START_INFO1_IP_FRAG (1 << 14) #define RX_MSDU_START_INFO1_TCP_ONLY_ACK (1 << 15) -/* The decapped header (rx_hdr_status) contains the following: - * a) 802.11 header - * [padding to 4 bytes] - * b) HW crypto parameter - * - 0 bytes for no security - * - 4 bytes for WEP - * - 8 bytes for TKIP, AES - * [padding to 4 bytes] - * c) A-MSDU subframe header (14 bytes) if appliable - * d) LLC/SNAP (RFC1042, 8 bytes) - * - * In case of A-MSDU only first frame in sequence contains (a) and (b). */ enum rx_msdu_decap_format { - RX_MSDU_DECAP_RAW = 0, - - /* Note: QoS frames are reported as non-QoS. The rx_hdr_status in - * htt_rx_desc contains the original decapped 802.11 header. */ - RX_MSDU_DECAP_NATIVE_WIFI = 1, - - /* Payload contains an ethernet header (struct ethhdr). */ + RX_MSDU_DECAP_RAW = 0, + RX_MSDU_DECAP_NATIVE_WIFI = 1, RX_MSDU_DECAP_ETHERNET2_DIX = 2, - - /* Payload contains two 48-bit addresses and 2-byte length (14 bytes - * total), followed by an RFC1042 header (8 bytes). */ RX_MSDU_DECAP_8023_SNAP_LLC = 3 }; diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h index 90817dd..85e806b 100644 --- a/drivers/net/wireless/ath/ath10k/trace.h +++ b/drivers/net/wireless/ath/ath10k/trace.h @@ -111,29 +111,26 @@ TRACE_EVENT(ath10k_log_dbg_dump, ); TRACE_EVENT(ath10k_wmi_cmd, - TP_PROTO(int id, void *buf, size_t buf_len, int ret), + TP_PROTO(int id, void *buf, size_t buf_len), - TP_ARGS(id, buf, buf_len, ret), + TP_ARGS(id, buf, buf_len), TP_STRUCT__entry( __field(unsigned int, id) __field(size_t, buf_len) __dynamic_array(u8, buf, buf_len) - __field(int, ret) ), TP_fast_assign( __entry->id = id; __entry->buf_len = buf_len; - __entry->ret = ret; memcpy(__get_dynamic_array(buf), buf, buf_len); ), TP_printk( - "id %d len %zu ret %d", + "id %d len %zu", __entry->id, - __entry->buf_len, - __entry->ret + __entry->buf_len ) ); @@ -161,27 +158,6 @@ TRACE_EVENT(ath10k_wmi_event, ) ); -TRACE_EVENT(ath10k_htt_stats, - TP_PROTO(void *buf, size_t buf_len), - - TP_ARGS(buf, buf_len), - - TP_STRUCT__entry( - __field(size_t, buf_len) - __dynamic_array(u8, buf, buf_len) - ), - - TP_fast_assign( - __entry->buf_len = buf_len; - memcpy(__get_dynamic_array(buf), buf, buf_len); - ), - - TP_printk( - "len %zu", - __entry->buf_len - ) -); - #endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/ /* we don't want to use include/trace/events */ diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c index 5ae373a..68b6fae 100644 --- a/drivers/net/wireless/ath/ath10k/txrx.c +++ b/drivers/net/wireless/ath/ath10k/txrx.c @@ -44,39 +44,40 @@ out: spin_unlock_bh(&ar->data_lock); } -void ath10k_txrx_tx_unref(struct ath10k_htt *htt, - const struct htt_tx_done *tx_done) +void ath10k_txrx_tx_unref(struct ath10k_htt *htt, struct sk_buff *txdesc) { struct device *dev = htt->ar->dev; struct ieee80211_tx_info *info; - struct ath10k_skb_cb *skb_cb; - struct sk_buff *msdu; + struct sk_buff *txfrag = ATH10K_SKB_CB(txdesc)->htt.txfrag; + struct sk_buff *msdu = ATH10K_SKB_CB(txdesc)->htt.msdu; int ret; - ath10k_dbg(ATH10K_DBG_HTT, "htt tx completion msdu_id %u discard %d no_ack %d\n", - tx_done->msdu_id, !!tx_done->discard, !!tx_done->no_ack); + if (ATH10K_SKB_CB(txdesc)->htt.refcount == 0) + return; - if (tx_done->msdu_id >= htt->max_num_pending_tx) { - ath10k_warn("warning: msdu_id %d too big, ignoring\n", - tx_done->msdu_id); + ATH10K_SKB_CB(txdesc)->htt.refcount--; + + if (ATH10K_SKB_CB(txdesc)->htt.refcount > 0) return; - } - msdu = htt->pending_tx[tx_done->msdu_id]; - skb_cb = ATH10K_SKB_CB(msdu); + if (txfrag) { + ret = ath10k_skb_unmap(dev, txfrag); + if (ret) + ath10k_warn("txfrag unmap failed (%d)\n", ret); + + dev_kfree_skb_any(txfrag); + } ret = ath10k_skb_unmap(dev, msdu); if (ret) ath10k_warn("data skb unmap failed (%d)\n", ret); - if (skb_cb->htt.frag_len) - skb_pull(msdu, skb_cb->htt.frag_len + skb_cb->htt.pad_len); - ath10k_report_offchan_tx(htt->ar, msdu); info = IEEE80211_SKB_CB(msdu); + memset(&info->status, 0, sizeof(info->status)); - if (tx_done->discard) { + if (ATH10K_SKB_CB(txdesc)->htt.discard) { ieee80211_free_txskb(htt->ar->hw, msdu); goto exit; } @@ -84,7 +85,7 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt, if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) info->flags |= IEEE80211_TX_STAT_ACK; - if (tx_done->no_ack) + if (ATH10K_SKB_CB(txdesc)->htt.no_ack) info->flags &= ~IEEE80211_TX_STAT_ACK; ieee80211_tx_status(htt->ar->hw, msdu); @@ -92,12 +93,36 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt, exit: spin_lock_bh(&htt->tx_lock); - htt->pending_tx[tx_done->msdu_id] = NULL; - ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id); + htt->pending_tx[ATH10K_SKB_CB(txdesc)->htt.msdu_id] = NULL; + ath10k_htt_tx_free_msdu_id(htt, ATH10K_SKB_CB(txdesc)->htt.msdu_id); __ath10k_htt_tx_dec_pending(htt); - if (htt->num_pending_tx == 0) + if (bitmap_empty(htt->used_msdu_ids, htt->max_num_pending_tx)) wake_up(&htt->empty_tx_wq); spin_unlock_bh(&htt->tx_lock); + + dev_kfree_skb_any(txdesc); +} + +void ath10k_txrx_tx_completed(struct ath10k_htt *htt, + const struct htt_tx_done *tx_done) +{ + struct sk_buff *txdesc; + + ath10k_dbg(ATH10K_DBG_HTT, "htt tx completion msdu_id %u discard %d no_ack %d\n", + tx_done->msdu_id, !!tx_done->discard, !!tx_done->no_ack); + + if (tx_done->msdu_id >= htt->max_num_pending_tx) { + ath10k_warn("warning: msdu_id %d too big, ignoring\n", + tx_done->msdu_id); + return; + } + + txdesc = htt->pending_tx[tx_done->msdu_id]; + + ATH10K_SKB_CB(txdesc)->htt.discard = tx_done->discard; + ATH10K_SKB_CB(txdesc)->htt.no_ack = tx_done->no_ack; + + ath10k_txrx_tx_unref(htt, txdesc); } static const u8 rx_legacy_rate_idx[] = { @@ -268,8 +293,6 @@ void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info) status->vht_nss, status->freq, status->band); - ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ", - info->skb->data, info->skb->len); ieee80211_rx(ar->hw, info->skb); } diff --git a/drivers/net/wireless/ath/ath10k/txrx.h b/drivers/net/wireless/ath/ath10k/txrx.h index 356dc9c..e78632a 100644 --- a/drivers/net/wireless/ath/ath10k/txrx.h +++ b/drivers/net/wireless/ath/ath10k/txrx.h @@ -19,8 +19,9 @@ #include "htt.h" -void ath10k_txrx_tx_unref(struct ath10k_htt *htt, - const struct htt_tx_done *tx_done); +void ath10k_txrx_tx_unref(struct ath10k_htt *htt, struct sk_buff *txdesc); +void ath10k_txrx_tx_completed(struct ath10k_htt *htt, + const struct htt_tx_done *tx_done); void ath10k_process_rx(struct ath10k *ar, struct htt_rx_info *info); struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id, diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index ccf3597..55f90c7 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -23,470 +23,29 @@ #include "wmi.h" #include "mac.h" -/* MAIN WMI cmd track */ -static struct wmi_cmd_map wmi_cmd_map = { - .init_cmdid = WMI_INIT_CMDID, - .start_scan_cmdid = WMI_START_SCAN_CMDID, - .stop_scan_cmdid = WMI_STOP_SCAN_CMDID, - .scan_chan_list_cmdid = WMI_SCAN_CHAN_LIST_CMDID, - .scan_sch_prio_tbl_cmdid = WMI_SCAN_SCH_PRIO_TBL_CMDID, - .pdev_set_regdomain_cmdid = WMI_PDEV_SET_REGDOMAIN_CMDID, - .pdev_set_channel_cmdid = WMI_PDEV_SET_CHANNEL_CMDID, - .pdev_set_param_cmdid = WMI_PDEV_SET_PARAM_CMDID, - .pdev_pktlog_enable_cmdid = WMI_PDEV_PKTLOG_ENABLE_CMDID, - .pdev_pktlog_disable_cmdid = WMI_PDEV_PKTLOG_DISABLE_CMDID, - .pdev_set_wmm_params_cmdid = WMI_PDEV_SET_WMM_PARAMS_CMDID, - .pdev_set_ht_cap_ie_cmdid = WMI_PDEV_SET_HT_CAP_IE_CMDID, - .pdev_set_vht_cap_ie_cmdid = WMI_PDEV_SET_VHT_CAP_IE_CMDID, - .pdev_set_dscp_tid_map_cmdid = WMI_PDEV_SET_DSCP_TID_MAP_CMDID, - .pdev_set_quiet_mode_cmdid = WMI_PDEV_SET_QUIET_MODE_CMDID, - .pdev_green_ap_ps_enable_cmdid = WMI_PDEV_GREEN_AP_PS_ENABLE_CMDID, - .pdev_get_tpc_config_cmdid = WMI_PDEV_GET_TPC_CONFIG_CMDID, - .pdev_set_base_macaddr_cmdid = WMI_PDEV_SET_BASE_MACADDR_CMDID, - .vdev_create_cmdid = WMI_VDEV_CREATE_CMDID, - .vdev_delete_cmdid = WMI_VDEV_DELETE_CMDID, - .vdev_start_request_cmdid = WMI_VDEV_START_REQUEST_CMDID, - .vdev_restart_request_cmdid = WMI_VDEV_RESTART_REQUEST_CMDID, - .vdev_up_cmdid = WMI_VDEV_UP_CMDID, - .vdev_stop_cmdid = WMI_VDEV_STOP_CMDID, - .vdev_down_cmdid = WMI_VDEV_DOWN_CMDID, - .vdev_set_param_cmdid = WMI_VDEV_SET_PARAM_CMDID, - .vdev_install_key_cmdid = WMI_VDEV_INSTALL_KEY_CMDID, - .peer_create_cmdid = WMI_PEER_CREATE_CMDID, - .peer_delete_cmdid = WMI_PEER_DELETE_CMDID, - .peer_flush_tids_cmdid = WMI_PEER_FLUSH_TIDS_CMDID, - .peer_set_param_cmdid = WMI_PEER_SET_PARAM_CMDID, - .peer_assoc_cmdid = WMI_PEER_ASSOC_CMDID, - .peer_add_wds_entry_cmdid = WMI_PEER_ADD_WDS_ENTRY_CMDID, - .peer_remove_wds_entry_cmdid = WMI_PEER_REMOVE_WDS_ENTRY_CMDID, - .peer_mcast_group_cmdid = WMI_PEER_MCAST_GROUP_CMDID, - .bcn_tx_cmdid = WMI_BCN_TX_CMDID, - .pdev_send_bcn_cmdid = WMI_PDEV_SEND_BCN_CMDID, - .bcn_tmpl_cmdid = WMI_BCN_TMPL_CMDID, - .bcn_filter_rx_cmdid = WMI_BCN_FILTER_RX_CMDID, - .prb_req_filter_rx_cmdid = WMI_PRB_REQ_FILTER_RX_CMDID, - .mgmt_tx_cmdid = WMI_MGMT_TX_CMDID, - .prb_tmpl_cmdid = WMI_PRB_TMPL_CMDID, - .addba_clear_resp_cmdid = WMI_ADDBA_CLEAR_RESP_CMDID, - .addba_send_cmdid = WMI_ADDBA_SEND_CMDID, - .addba_status_cmdid = WMI_ADDBA_STATUS_CMDID, - .delba_send_cmdid = WMI_DELBA_SEND_CMDID, - .addba_set_resp_cmdid = WMI_ADDBA_SET_RESP_CMDID, - .send_singleamsdu_cmdid = WMI_SEND_SINGLEAMSDU_CMDID, - .sta_powersave_mode_cmdid = WMI_STA_POWERSAVE_MODE_CMDID, - .sta_powersave_param_cmdid = WMI_STA_POWERSAVE_PARAM_CMDID, - .sta_mimo_ps_mode_cmdid = WMI_STA_MIMO_PS_MODE_CMDID, - .pdev_dfs_enable_cmdid = WMI_PDEV_DFS_ENABLE_CMDID, - .pdev_dfs_disable_cmdid = WMI_PDEV_DFS_DISABLE_CMDID, - .roam_scan_mode = WMI_ROAM_SCAN_MODE, - .roam_scan_rssi_threshold = WMI_ROAM_SCAN_RSSI_THRESHOLD, - .roam_scan_period = WMI_ROAM_SCAN_PERIOD, - .roam_scan_rssi_change_threshold = WMI_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, - .roam_ap_profile = WMI_ROAM_AP_PROFILE, - .ofl_scan_add_ap_profile = WMI_ROAM_AP_PROFILE, - .ofl_scan_remove_ap_profile = WMI_OFL_SCAN_REMOVE_AP_PROFILE, - .ofl_scan_period = WMI_OFL_SCAN_PERIOD, - .p2p_dev_set_device_info = WMI_P2P_DEV_SET_DEVICE_INFO, - .p2p_dev_set_discoverability = WMI_P2P_DEV_SET_DISCOVERABILITY, - .p2p_go_set_beacon_ie = WMI_P2P_GO_SET_BEACON_IE, - .p2p_go_set_probe_resp_ie = WMI_P2P_GO_SET_PROBE_RESP_IE, - .p2p_set_vendor_ie_data_cmdid = WMI_P2P_SET_VENDOR_IE_DATA_CMDID, - .ap_ps_peer_param_cmdid = WMI_AP_PS_PEER_PARAM_CMDID, - .ap_ps_peer_uapsd_coex_cmdid = WMI_AP_PS_PEER_UAPSD_COEX_CMDID, - .peer_rate_retry_sched_cmdid = WMI_PEER_RATE_RETRY_SCHED_CMDID, - .wlan_profile_trigger_cmdid = WMI_WLAN_PROFILE_TRIGGER_CMDID, - .wlan_profile_set_hist_intvl_cmdid = - WMI_WLAN_PROFILE_SET_HIST_INTVL_CMDID, - .wlan_profile_get_profile_data_cmdid = - WMI_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, - .wlan_profile_enable_profile_id_cmdid = - WMI_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, - .wlan_profile_list_profile_id_cmdid = - WMI_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, - .pdev_suspend_cmdid = WMI_PDEV_SUSPEND_CMDID, - .pdev_resume_cmdid = WMI_PDEV_RESUME_CMDID, - .add_bcn_filter_cmdid = WMI_ADD_BCN_FILTER_CMDID, - .rmv_bcn_filter_cmdid = WMI_RMV_BCN_FILTER_CMDID, - .wow_add_wake_pattern_cmdid = WMI_WOW_ADD_WAKE_PATTERN_CMDID, - .wow_del_wake_pattern_cmdid = WMI_WOW_DEL_WAKE_PATTERN_CMDID, - .wow_enable_disable_wake_event_cmdid = - WMI_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, - .wow_enable_cmdid = WMI_WOW_ENABLE_CMDID, - .wow_hostwakeup_from_sleep_cmdid = WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, - .rtt_measreq_cmdid = WMI_RTT_MEASREQ_CMDID, - .rtt_tsf_cmdid = WMI_RTT_TSF_CMDID, - .vdev_spectral_scan_configure_cmdid = - WMI_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, - .vdev_spectral_scan_enable_cmdid = WMI_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, - .request_stats_cmdid = WMI_REQUEST_STATS_CMDID, - .set_arp_ns_offload_cmdid = WMI_SET_ARP_NS_OFFLOAD_CMDID, - .network_list_offload_config_cmdid = - WMI_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, - .gtk_offload_cmdid = WMI_GTK_OFFLOAD_CMDID, - .csa_offload_enable_cmdid = WMI_CSA_OFFLOAD_ENABLE_CMDID, - .csa_offload_chanswitch_cmdid = WMI_CSA_OFFLOAD_CHANSWITCH_CMDID, - .chatter_set_mode_cmdid = WMI_CHATTER_SET_MODE_CMDID, - .peer_tid_addba_cmdid = WMI_PEER_TID_ADDBA_CMDID, - .peer_tid_delba_cmdid = WMI_PEER_TID_DELBA_CMDID, - .sta_dtim_ps_method_cmdid = WMI_STA_DTIM_PS_METHOD_CMDID, - .sta_uapsd_auto_trig_cmdid = WMI_STA_UAPSD_AUTO_TRIG_CMDID, - .sta_keepalive_cmd = WMI_STA_KEEPALIVE_CMD, - .echo_cmdid = WMI_ECHO_CMDID, - .pdev_utf_cmdid = WMI_PDEV_UTF_CMDID, - .dbglog_cfg_cmdid = WMI_DBGLOG_CFG_CMDID, - .pdev_qvit_cmdid = WMI_PDEV_QVIT_CMDID, - .pdev_ftm_intg_cmdid = WMI_PDEV_FTM_INTG_CMDID, - .vdev_set_keepalive_cmdid = WMI_VDEV_SET_KEEPALIVE_CMDID, - .vdev_get_keepalive_cmdid = WMI_VDEV_GET_KEEPALIVE_CMDID, - .force_fw_hang_cmdid = WMI_FORCE_FW_HANG_CMDID, - .gpio_config_cmdid = WMI_GPIO_CONFIG_CMDID, - .gpio_output_cmdid = WMI_GPIO_OUTPUT_CMDID, -}; - -/* 10.X WMI cmd track */ -static struct wmi_cmd_map wmi_10x_cmd_map = { - .init_cmdid = WMI_10X_INIT_CMDID, - .start_scan_cmdid = WMI_10X_START_SCAN_CMDID, - .stop_scan_cmdid = WMI_10X_STOP_SCAN_CMDID, - .scan_chan_list_cmdid = WMI_10X_SCAN_CHAN_LIST_CMDID, - .scan_sch_prio_tbl_cmdid = WMI_CMD_UNSUPPORTED, - .pdev_set_regdomain_cmdid = WMI_10X_PDEV_SET_REGDOMAIN_CMDID, - .pdev_set_channel_cmdid = WMI_10X_PDEV_SET_CHANNEL_CMDID, - .pdev_set_param_cmdid = WMI_10X_PDEV_SET_PARAM_CMDID, - .pdev_pktlog_enable_cmdid = WMI_10X_PDEV_PKTLOG_ENABLE_CMDID, - .pdev_pktlog_disable_cmdid = WMI_10X_PDEV_PKTLOG_DISABLE_CMDID, - .pdev_set_wmm_params_cmdid = WMI_10X_PDEV_SET_WMM_PARAMS_CMDID, - .pdev_set_ht_cap_ie_cmdid = WMI_10X_PDEV_SET_HT_CAP_IE_CMDID, - .pdev_set_vht_cap_ie_cmdid = WMI_10X_PDEV_SET_VHT_CAP_IE_CMDID, - .pdev_set_dscp_tid_map_cmdid = WMI_10X_PDEV_SET_DSCP_TID_MAP_CMDID, - .pdev_set_quiet_mode_cmdid = WMI_10X_PDEV_SET_QUIET_MODE_CMDID, - .pdev_green_ap_ps_enable_cmdid = WMI_10X_PDEV_GREEN_AP_PS_ENABLE_CMDID, - .pdev_get_tpc_config_cmdid = WMI_10X_PDEV_GET_TPC_CONFIG_CMDID, - .pdev_set_base_macaddr_cmdid = WMI_10X_PDEV_SET_BASE_MACADDR_CMDID, - .vdev_create_cmdid = WMI_10X_VDEV_CREATE_CMDID, - .vdev_delete_cmdid = WMI_10X_VDEV_DELETE_CMDID, - .vdev_start_request_cmdid = WMI_10X_VDEV_START_REQUEST_CMDID, - .vdev_restart_request_cmdid = WMI_10X_VDEV_RESTART_REQUEST_CMDID, - .vdev_up_cmdid = WMI_10X_VDEV_UP_CMDID, - .vdev_stop_cmdid = WMI_10X_VDEV_STOP_CMDID, - .vdev_down_cmdid = WMI_10X_VDEV_DOWN_CMDID, - .vdev_set_param_cmdid = WMI_10X_VDEV_SET_PARAM_CMDID, - .vdev_install_key_cmdid = WMI_10X_VDEV_INSTALL_KEY_CMDID, - .peer_create_cmdid = WMI_10X_PEER_CREATE_CMDID, - .peer_delete_cmdid = WMI_10X_PEER_DELETE_CMDID, - .peer_flush_tids_cmdid = WMI_10X_PEER_FLUSH_TIDS_CMDID, - .peer_set_param_cmdid = WMI_10X_PEER_SET_PARAM_CMDID, - .peer_assoc_cmdid = WMI_10X_PEER_ASSOC_CMDID, - .peer_add_wds_entry_cmdid = WMI_10X_PEER_ADD_WDS_ENTRY_CMDID, - .peer_remove_wds_entry_cmdid = WMI_10X_PEER_REMOVE_WDS_ENTRY_CMDID, - .peer_mcast_group_cmdid = WMI_10X_PEER_MCAST_GROUP_CMDID, - .bcn_tx_cmdid = WMI_10X_BCN_TX_CMDID, - .pdev_send_bcn_cmdid = WMI_10X_PDEV_SEND_BCN_CMDID, - .bcn_tmpl_cmdid = WMI_CMD_UNSUPPORTED, - .bcn_filter_rx_cmdid = WMI_10X_BCN_FILTER_RX_CMDID, - .prb_req_filter_rx_cmdid = WMI_10X_PRB_REQ_FILTER_RX_CMDID, - .mgmt_tx_cmdid = WMI_10X_MGMT_TX_CMDID, - .prb_tmpl_cmdid = WMI_CMD_UNSUPPORTED, - .addba_clear_resp_cmdid = WMI_10X_ADDBA_CLEAR_RESP_CMDID, - .addba_send_cmdid = WMI_10X_ADDBA_SEND_CMDID, - .addba_status_cmdid = WMI_10X_ADDBA_STATUS_CMDID, - .delba_send_cmdid = WMI_10X_DELBA_SEND_CMDID, - .addba_set_resp_cmdid = WMI_10X_ADDBA_SET_RESP_CMDID, - .send_singleamsdu_cmdid = WMI_10X_SEND_SINGLEAMSDU_CMDID, - .sta_powersave_mode_cmdid = WMI_10X_STA_POWERSAVE_MODE_CMDID, - .sta_powersave_param_cmdid = WMI_10X_STA_POWERSAVE_PARAM_CMDID, - .sta_mimo_ps_mode_cmdid = WMI_10X_STA_MIMO_PS_MODE_CMDID, - .pdev_dfs_enable_cmdid = WMI_10X_PDEV_DFS_ENABLE_CMDID, - .pdev_dfs_disable_cmdid = WMI_10X_PDEV_DFS_DISABLE_CMDID, - .roam_scan_mode = WMI_10X_ROAM_SCAN_MODE, - .roam_scan_rssi_threshold = WMI_10X_ROAM_SCAN_RSSI_THRESHOLD, - .roam_scan_period = WMI_10X_ROAM_SCAN_PERIOD, - .roam_scan_rssi_change_threshold = - WMI_10X_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, - .roam_ap_profile = WMI_10X_ROAM_AP_PROFILE, - .ofl_scan_add_ap_profile = WMI_10X_OFL_SCAN_ADD_AP_PROFILE, - .ofl_scan_remove_ap_profile = WMI_10X_OFL_SCAN_REMOVE_AP_PROFILE, - .ofl_scan_period = WMI_10X_OFL_SCAN_PERIOD, - .p2p_dev_set_device_info = WMI_10X_P2P_DEV_SET_DEVICE_INFO, - .p2p_dev_set_discoverability = WMI_10X_P2P_DEV_SET_DISCOVERABILITY, - .p2p_go_set_beacon_ie = WMI_10X_P2P_GO_SET_BEACON_IE, - .p2p_go_set_probe_resp_ie = WMI_10X_P2P_GO_SET_PROBE_RESP_IE, - .p2p_set_vendor_ie_data_cmdid = WMI_CMD_UNSUPPORTED, - .ap_ps_peer_param_cmdid = WMI_CMD_UNSUPPORTED, - .ap_ps_peer_uapsd_coex_cmdid = WMI_CMD_UNSUPPORTED, - .peer_rate_retry_sched_cmdid = WMI_10X_PEER_RATE_RETRY_SCHED_CMDID, - .wlan_profile_trigger_cmdid = WMI_10X_WLAN_PROFILE_TRIGGER_CMDID, - .wlan_profile_set_hist_intvl_cmdid = - WMI_10X_WLAN_PROFILE_SET_HIST_INTVL_CMDID, - .wlan_profile_get_profile_data_cmdid = - WMI_10X_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, - .wlan_profile_enable_profile_id_cmdid = - WMI_10X_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, - .wlan_profile_list_profile_id_cmdid = - WMI_10X_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, - .pdev_suspend_cmdid = WMI_10X_PDEV_SUSPEND_CMDID, - .pdev_resume_cmdid = WMI_10X_PDEV_RESUME_CMDID, - .add_bcn_filter_cmdid = WMI_10X_ADD_BCN_FILTER_CMDID, - .rmv_bcn_filter_cmdid = WMI_10X_RMV_BCN_FILTER_CMDID, - .wow_add_wake_pattern_cmdid = WMI_10X_WOW_ADD_WAKE_PATTERN_CMDID, - .wow_del_wake_pattern_cmdid = WMI_10X_WOW_DEL_WAKE_PATTERN_CMDID, - .wow_enable_disable_wake_event_cmdid = - WMI_10X_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, - .wow_enable_cmdid = WMI_10X_WOW_ENABLE_CMDID, - .wow_hostwakeup_from_sleep_cmdid = - WMI_10X_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, - .rtt_measreq_cmdid = WMI_10X_RTT_MEASREQ_CMDID, - .rtt_tsf_cmdid = WMI_10X_RTT_TSF_CMDID, - .vdev_spectral_scan_configure_cmdid = - WMI_10X_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, - .vdev_spectral_scan_enable_cmdid = - WMI_10X_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, - .request_stats_cmdid = WMI_10X_REQUEST_STATS_CMDID, - .set_arp_ns_offload_cmdid = WMI_CMD_UNSUPPORTED, - .network_list_offload_config_cmdid = WMI_CMD_UNSUPPORTED, - .gtk_offload_cmdid = WMI_CMD_UNSUPPORTED, - .csa_offload_enable_cmdid = WMI_CMD_UNSUPPORTED, - .csa_offload_chanswitch_cmdid = WMI_CMD_UNSUPPORTED, - .chatter_set_mode_cmdid = WMI_CMD_UNSUPPORTED, - .peer_tid_addba_cmdid = WMI_CMD_UNSUPPORTED, - .peer_tid_delba_cmdid = WMI_CMD_UNSUPPORTED, - .sta_dtim_ps_method_cmdid = WMI_CMD_UNSUPPORTED, - .sta_uapsd_auto_trig_cmdid = WMI_CMD_UNSUPPORTED, - .sta_keepalive_cmd = WMI_CMD_UNSUPPORTED, - .echo_cmdid = WMI_10X_ECHO_CMDID, - .pdev_utf_cmdid = WMI_10X_PDEV_UTF_CMDID, - .dbglog_cfg_cmdid = WMI_10X_DBGLOG_CFG_CMDID, - .pdev_qvit_cmdid = WMI_10X_PDEV_QVIT_CMDID, - .pdev_ftm_intg_cmdid = WMI_CMD_UNSUPPORTED, - .vdev_set_keepalive_cmdid = WMI_CMD_UNSUPPORTED, - .vdev_get_keepalive_cmdid = WMI_CMD_UNSUPPORTED, - .force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED, - .gpio_config_cmdid = WMI_10X_GPIO_CONFIG_CMDID, - .gpio_output_cmdid = WMI_10X_GPIO_OUTPUT_CMDID, -}; - -/* MAIN WMI VDEV param map */ -static struct wmi_vdev_param_map wmi_vdev_param_map = { - .rts_threshold = WMI_VDEV_PARAM_RTS_THRESHOLD, - .fragmentation_threshold = WMI_VDEV_PARAM_FRAGMENTATION_THRESHOLD, - .beacon_interval = WMI_VDEV_PARAM_BEACON_INTERVAL, - .listen_interval = WMI_VDEV_PARAM_LISTEN_INTERVAL, - .multicast_rate = WMI_VDEV_PARAM_MULTICAST_RATE, - .mgmt_tx_rate = WMI_VDEV_PARAM_MGMT_TX_RATE, - .slot_time = WMI_VDEV_PARAM_SLOT_TIME, - .preamble = WMI_VDEV_PARAM_PREAMBLE, - .swba_time = WMI_VDEV_PARAM_SWBA_TIME, - .wmi_vdev_stats_update_period = WMI_VDEV_STATS_UPDATE_PERIOD, - .wmi_vdev_pwrsave_ageout_time = WMI_VDEV_PWRSAVE_AGEOUT_TIME, - .wmi_vdev_host_swba_interval = WMI_VDEV_HOST_SWBA_INTERVAL, - .dtim_period = WMI_VDEV_PARAM_DTIM_PERIOD, - .wmi_vdev_oc_scheduler_air_time_limit = - WMI_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, - .wds = WMI_VDEV_PARAM_WDS, - .atim_window = WMI_VDEV_PARAM_ATIM_WINDOW, - .bmiss_count_max = WMI_VDEV_PARAM_BMISS_COUNT_MAX, - .bmiss_first_bcnt = WMI_VDEV_PARAM_BMISS_FIRST_BCNT, - .bmiss_final_bcnt = WMI_VDEV_PARAM_BMISS_FINAL_BCNT, - .feature_wmm = WMI_VDEV_PARAM_FEATURE_WMM, - .chwidth = WMI_VDEV_PARAM_CHWIDTH, - .chextoffset = WMI_VDEV_PARAM_CHEXTOFFSET, - .disable_htprotection = WMI_VDEV_PARAM_DISABLE_HTPROTECTION, - .sta_quickkickout = WMI_VDEV_PARAM_STA_QUICKKICKOUT, - .mgmt_rate = WMI_VDEV_PARAM_MGMT_RATE, - .protection_mode = WMI_VDEV_PARAM_PROTECTION_MODE, - .fixed_rate = WMI_VDEV_PARAM_FIXED_RATE, - .sgi = WMI_VDEV_PARAM_SGI, - .ldpc = WMI_VDEV_PARAM_LDPC, - .tx_stbc = WMI_VDEV_PARAM_TX_STBC, - .rx_stbc = WMI_VDEV_PARAM_RX_STBC, - .intra_bss_fwd = WMI_VDEV_PARAM_INTRA_BSS_FWD, - .def_keyid = WMI_VDEV_PARAM_DEF_KEYID, - .nss = WMI_VDEV_PARAM_NSS, - .bcast_data_rate = WMI_VDEV_PARAM_BCAST_DATA_RATE, - .mcast_data_rate = WMI_VDEV_PARAM_MCAST_DATA_RATE, - .mcast_indicate = WMI_VDEV_PARAM_MCAST_INDICATE, - .dhcp_indicate = WMI_VDEV_PARAM_DHCP_INDICATE, - .unknown_dest_indicate = WMI_VDEV_PARAM_UNKNOWN_DEST_INDICATE, - .ap_keepalive_min_idle_inactive_time_secs = - WMI_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, - .ap_keepalive_max_idle_inactive_time_secs = - WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, - .ap_keepalive_max_unresponsive_time_secs = - WMI_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, - .ap_enable_nawds = WMI_VDEV_PARAM_AP_ENABLE_NAWDS, - .mcast2ucast_set = WMI_VDEV_PARAM_UNSUPPORTED, - .enable_rtscts = WMI_VDEV_PARAM_ENABLE_RTSCTS, - .txbf = WMI_VDEV_PARAM_TXBF, - .packet_powersave = WMI_VDEV_PARAM_PACKET_POWERSAVE, - .drop_unencry = WMI_VDEV_PARAM_DROP_UNENCRY, - .tx_encap_type = WMI_VDEV_PARAM_TX_ENCAP_TYPE, - .ap_detect_out_of_sync_sleeping_sta_time_secs = - WMI_VDEV_PARAM_UNSUPPORTED, -}; - -/* 10.X WMI VDEV param map */ -static struct wmi_vdev_param_map wmi_10x_vdev_param_map = { - .rts_threshold = WMI_10X_VDEV_PARAM_RTS_THRESHOLD, - .fragmentation_threshold = WMI_10X_VDEV_PARAM_FRAGMENTATION_THRESHOLD, - .beacon_interval = WMI_10X_VDEV_PARAM_BEACON_INTERVAL, - .listen_interval = WMI_10X_VDEV_PARAM_LISTEN_INTERVAL, - .multicast_rate = WMI_10X_VDEV_PARAM_MULTICAST_RATE, - .mgmt_tx_rate = WMI_10X_VDEV_PARAM_MGMT_TX_RATE, - .slot_time = WMI_10X_VDEV_PARAM_SLOT_TIME, - .preamble = WMI_10X_VDEV_PARAM_PREAMBLE, - .swba_time = WMI_10X_VDEV_PARAM_SWBA_TIME, - .wmi_vdev_stats_update_period = WMI_10X_VDEV_STATS_UPDATE_PERIOD, - .wmi_vdev_pwrsave_ageout_time = WMI_10X_VDEV_PWRSAVE_AGEOUT_TIME, - .wmi_vdev_host_swba_interval = WMI_10X_VDEV_HOST_SWBA_INTERVAL, - .dtim_period = WMI_10X_VDEV_PARAM_DTIM_PERIOD, - .wmi_vdev_oc_scheduler_air_time_limit = - WMI_10X_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, - .wds = WMI_10X_VDEV_PARAM_WDS, - .atim_window = WMI_10X_VDEV_PARAM_ATIM_WINDOW, - .bmiss_count_max = WMI_10X_VDEV_PARAM_BMISS_COUNT_MAX, - .bmiss_first_bcnt = WMI_VDEV_PARAM_UNSUPPORTED, - .bmiss_final_bcnt = WMI_VDEV_PARAM_UNSUPPORTED, - .feature_wmm = WMI_10X_VDEV_PARAM_FEATURE_WMM, - .chwidth = WMI_10X_VDEV_PARAM_CHWIDTH, - .chextoffset = WMI_10X_VDEV_PARAM_CHEXTOFFSET, - .disable_htprotection = WMI_10X_VDEV_PARAM_DISABLE_HTPROTECTION, - .sta_quickkickout = WMI_10X_VDEV_PARAM_STA_QUICKKICKOUT, - .mgmt_rate = WMI_10X_VDEV_PARAM_MGMT_RATE, - .protection_mode = WMI_10X_VDEV_PARAM_PROTECTION_MODE, - .fixed_rate = WMI_10X_VDEV_PARAM_FIXED_RATE, - .sgi = WMI_10X_VDEV_PARAM_SGI, - .ldpc = WMI_10X_VDEV_PARAM_LDPC, - .tx_stbc = WMI_10X_VDEV_PARAM_TX_STBC, - .rx_stbc = WMI_10X_VDEV_PARAM_RX_STBC, - .intra_bss_fwd = WMI_10X_VDEV_PARAM_INTRA_BSS_FWD, - .def_keyid = WMI_10X_VDEV_PARAM_DEF_KEYID, - .nss = WMI_10X_VDEV_PARAM_NSS, - .bcast_data_rate = WMI_10X_VDEV_PARAM_BCAST_DATA_RATE, - .mcast_data_rate = WMI_10X_VDEV_PARAM_MCAST_DATA_RATE, - .mcast_indicate = WMI_10X_VDEV_PARAM_MCAST_INDICATE, - .dhcp_indicate = WMI_10X_VDEV_PARAM_DHCP_INDICATE, - .unknown_dest_indicate = WMI_10X_VDEV_PARAM_UNKNOWN_DEST_INDICATE, - .ap_keepalive_min_idle_inactive_time_secs = - WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, - .ap_keepalive_max_idle_inactive_time_secs = - WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, - .ap_keepalive_max_unresponsive_time_secs = - WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, - .ap_enable_nawds = WMI_10X_VDEV_PARAM_AP_ENABLE_NAWDS, - .mcast2ucast_set = WMI_10X_VDEV_PARAM_MCAST2UCAST_SET, - .enable_rtscts = WMI_10X_VDEV_PARAM_ENABLE_RTSCTS, - .txbf = WMI_VDEV_PARAM_UNSUPPORTED, - .packet_powersave = WMI_VDEV_PARAM_UNSUPPORTED, - .drop_unencry = WMI_VDEV_PARAM_UNSUPPORTED, - .tx_encap_type = WMI_VDEV_PARAM_UNSUPPORTED, - .ap_detect_out_of_sync_sleeping_sta_time_secs = - WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, -}; - -static struct wmi_pdev_param_map wmi_pdev_param_map = { - .tx_chain_mask = WMI_PDEV_PARAM_TX_CHAIN_MASK, - .rx_chain_mask = WMI_PDEV_PARAM_RX_CHAIN_MASK, - .txpower_limit2g = WMI_PDEV_PARAM_TXPOWER_LIMIT2G, - .txpower_limit5g = WMI_PDEV_PARAM_TXPOWER_LIMIT5G, - .txpower_scale = WMI_PDEV_PARAM_TXPOWER_SCALE, - .beacon_gen_mode = WMI_PDEV_PARAM_BEACON_GEN_MODE, - .beacon_tx_mode = WMI_PDEV_PARAM_BEACON_TX_MODE, - .resmgr_offchan_mode = WMI_PDEV_PARAM_RESMGR_OFFCHAN_MODE, - .protection_mode = WMI_PDEV_PARAM_PROTECTION_MODE, - .dynamic_bw = WMI_PDEV_PARAM_DYNAMIC_BW, - .non_agg_sw_retry_th = WMI_PDEV_PARAM_NON_AGG_SW_RETRY_TH, - .agg_sw_retry_th = WMI_PDEV_PARAM_AGG_SW_RETRY_TH, - .sta_kickout_th = WMI_PDEV_PARAM_STA_KICKOUT_TH, - .ac_aggrsize_scaling = WMI_PDEV_PARAM_AC_AGGRSIZE_SCALING, - .ltr_enable = WMI_PDEV_PARAM_LTR_ENABLE, - .ltr_ac_latency_be = WMI_PDEV_PARAM_LTR_AC_LATENCY_BE, - .ltr_ac_latency_bk = WMI_PDEV_PARAM_LTR_AC_LATENCY_BK, - .ltr_ac_latency_vi = WMI_PDEV_PARAM_LTR_AC_LATENCY_VI, - .ltr_ac_latency_vo = WMI_PDEV_PARAM_LTR_AC_LATENCY_VO, - .ltr_ac_latency_timeout = WMI_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, - .ltr_sleep_override = WMI_PDEV_PARAM_LTR_SLEEP_OVERRIDE, - .ltr_rx_override = WMI_PDEV_PARAM_LTR_RX_OVERRIDE, - .ltr_tx_activity_timeout = WMI_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, - .l1ss_enable = WMI_PDEV_PARAM_L1SS_ENABLE, - .dsleep_enable = WMI_PDEV_PARAM_DSLEEP_ENABLE, - .pcielp_txbuf_flush = WMI_PDEV_PARAM_PCIELP_TXBUF_FLUSH, - .pcielp_txbuf_watermark = WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, - .pcielp_txbuf_tmo_en = WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, - .pcielp_txbuf_tmo_value = WMI_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE, - .pdev_stats_update_period = WMI_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, - .vdev_stats_update_period = WMI_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, - .peer_stats_update_period = WMI_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, - .bcnflt_stats_update_period = WMI_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, - .pmf_qos = WMI_PDEV_PARAM_PMF_QOS, - .arp_ac_override = WMI_PDEV_PARAM_ARP_AC_OVERRIDE, - .arpdhcp_ac_override = WMI_PDEV_PARAM_UNSUPPORTED, - .dcs = WMI_PDEV_PARAM_DCS, - .ani_enable = WMI_PDEV_PARAM_ANI_ENABLE, - .ani_poll_period = WMI_PDEV_PARAM_ANI_POLL_PERIOD, - .ani_listen_period = WMI_PDEV_PARAM_ANI_LISTEN_PERIOD, - .ani_ofdm_level = WMI_PDEV_PARAM_ANI_OFDM_LEVEL, - .ani_cck_level = WMI_PDEV_PARAM_ANI_CCK_LEVEL, - .dyntxchain = WMI_PDEV_PARAM_DYNTXCHAIN, - .proxy_sta = WMI_PDEV_PARAM_PROXY_STA, - .idle_ps_config = WMI_PDEV_PARAM_IDLE_PS_CONFIG, - .power_gating_sleep = WMI_PDEV_PARAM_POWER_GATING_SLEEP, - .fast_channel_reset = WMI_PDEV_PARAM_UNSUPPORTED, - .burst_dur = WMI_PDEV_PARAM_UNSUPPORTED, - .burst_enable = WMI_PDEV_PARAM_UNSUPPORTED, -}; - -static struct wmi_pdev_param_map wmi_10x_pdev_param_map = { - .tx_chain_mask = WMI_10X_PDEV_PARAM_TX_CHAIN_MASK, - .rx_chain_mask = WMI_10X_PDEV_PARAM_RX_CHAIN_MASK, - .txpower_limit2g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT2G, - .txpower_limit5g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT5G, - .txpower_scale = WMI_10X_PDEV_PARAM_TXPOWER_SCALE, - .beacon_gen_mode = WMI_10X_PDEV_PARAM_BEACON_GEN_MODE, - .beacon_tx_mode = WMI_10X_PDEV_PARAM_BEACON_TX_MODE, - .resmgr_offchan_mode = WMI_10X_PDEV_PARAM_RESMGR_OFFCHAN_MODE, - .protection_mode = WMI_10X_PDEV_PARAM_PROTECTION_MODE, - .dynamic_bw = WMI_10X_PDEV_PARAM_DYNAMIC_BW, - .non_agg_sw_retry_th = WMI_10X_PDEV_PARAM_NON_AGG_SW_RETRY_TH, - .agg_sw_retry_th = WMI_10X_PDEV_PARAM_AGG_SW_RETRY_TH, - .sta_kickout_th = WMI_10X_PDEV_PARAM_STA_KICKOUT_TH, - .ac_aggrsize_scaling = WMI_10X_PDEV_PARAM_AC_AGGRSIZE_SCALING, - .ltr_enable = WMI_10X_PDEV_PARAM_LTR_ENABLE, - .ltr_ac_latency_be = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BE, - .ltr_ac_latency_bk = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BK, - .ltr_ac_latency_vi = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VI, - .ltr_ac_latency_vo = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VO, - .ltr_ac_latency_timeout = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, - .ltr_sleep_override = WMI_10X_PDEV_PARAM_LTR_SLEEP_OVERRIDE, - .ltr_rx_override = WMI_10X_PDEV_PARAM_LTR_RX_OVERRIDE, - .ltr_tx_activity_timeout = WMI_10X_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, - .l1ss_enable = WMI_10X_PDEV_PARAM_L1SS_ENABLE, - .dsleep_enable = WMI_10X_PDEV_PARAM_DSLEEP_ENABLE, - .pcielp_txbuf_flush = WMI_PDEV_PARAM_UNSUPPORTED, - .pcielp_txbuf_watermark = WMI_PDEV_PARAM_UNSUPPORTED, - .pcielp_txbuf_tmo_en = WMI_PDEV_PARAM_UNSUPPORTED, - .pcielp_txbuf_tmo_value = WMI_PDEV_PARAM_UNSUPPORTED, - .pdev_stats_update_period = WMI_10X_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, - .vdev_stats_update_period = WMI_10X_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, - .peer_stats_update_period = WMI_10X_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, - .bcnflt_stats_update_period = - WMI_10X_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, - .pmf_qos = WMI_10X_PDEV_PARAM_PMF_QOS, - .arp_ac_override = WMI_PDEV_PARAM_UNSUPPORTED, - .arpdhcp_ac_override = WMI_10X_PDEV_PARAM_ARPDHCP_AC_OVERRIDE, - .dcs = WMI_10X_PDEV_PARAM_DCS, - .ani_enable = WMI_10X_PDEV_PARAM_ANI_ENABLE, - .ani_poll_period = WMI_10X_PDEV_PARAM_ANI_POLL_PERIOD, - .ani_listen_period = WMI_10X_PDEV_PARAM_ANI_LISTEN_PERIOD, - .ani_ofdm_level = WMI_10X_PDEV_PARAM_ANI_OFDM_LEVEL, - .ani_cck_level = WMI_10X_PDEV_PARAM_ANI_CCK_LEVEL, - .dyntxchain = WMI_10X_PDEV_PARAM_DYNTXCHAIN, - .proxy_sta = WMI_PDEV_PARAM_UNSUPPORTED, - .idle_ps_config = WMI_PDEV_PARAM_UNSUPPORTED, - .power_gating_sleep = WMI_PDEV_PARAM_UNSUPPORTED, - .fast_channel_reset = WMI_10X_PDEV_PARAM_FAST_CHANNEL_RESET, - .burst_dur = WMI_10X_PDEV_PARAM_BURST_DUR, - .burst_enable = WMI_10X_PDEV_PARAM_BURST_ENABLE, -}; +void ath10k_wmi_flush_tx(struct ath10k *ar) +{ + int ret; + + lockdep_assert_held(&ar->conf_mutex); + + if (ar->state == ATH10K_STATE_WEDGED) { + ath10k_warn("wmi flush skipped - device is wedged anyway\n"); + return; + } + + ret = wait_event_timeout(ar->wmi.wq, + atomic_read(&ar->wmi.pending_tx_count) == 0, + 5*HZ); + if (atomic_read(&ar->wmi.pending_tx_count) == 0) + return; + + if (ret == 0) + ret = -ETIMEDOUT; + + if (ret < 0) + ath10k_warn("wmi flush failed (%d)\n", ret); +} int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) { @@ -526,14 +85,18 @@ static struct sk_buff *ath10k_wmi_alloc_skb(u32 len) static void ath10k_wmi_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb) { dev_kfree_skb(skb); + + if (atomic_sub_return(1, &ar->wmi.pending_tx_count) == 0) + wake_up(&ar->wmi.wq); } -static int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb, - u32 cmd_id) +/* WMI command API */ +static int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, + enum wmi_cmd_id cmd_id) { struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb); struct wmi_cmd_hdr *cmd_hdr; - int ret; + int status; u32 cmd = 0; if (skb_push(skb, sizeof(struct wmi_cmd_hdr)) == NULL) @@ -544,146 +107,25 @@ static int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb, cmd_hdr = (struct wmi_cmd_hdr *)skb->data; cmd_hdr->cmd_id = __cpu_to_le32(cmd); - memset(skb_cb, 0, sizeof(*skb_cb)); - ret = ath10k_htc_send(&ar->htc, ar->wmi.eid, skb); - trace_ath10k_wmi_cmd(cmd_id, skb->data, skb->len, ret); - - if (ret) - goto err_pull; - - return 0; - -err_pull: - skb_pull(skb, sizeof(struct wmi_cmd_hdr)); - return ret; -} - -static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif) -{ - struct wmi_bcn_tx_arg arg = {0}; - int ret; - - lockdep_assert_held(&arvif->ar->data_lock); - - if (arvif->beacon == NULL) - return; - - arg.vdev_id = arvif->vdev_id; - arg.tx_rate = 0; - arg.tx_power = 0; - arg.bcn = arvif->beacon->data; - arg.bcn_len = arvif->beacon->len; - - ret = ath10k_wmi_beacon_send_nowait(arvif->ar, &arg); - if (ret) - return; - - dev_kfree_skb_any(arvif->beacon); - arvif->beacon = NULL; -} - -static void ath10k_wmi_tx_beacons_iter(void *data, u8 *mac, - struct ieee80211_vif *vif) -{ - struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); - - ath10k_wmi_tx_beacon_nowait(arvif); -} - -static void ath10k_wmi_tx_beacons_nowait(struct ath10k *ar) -{ - spin_lock_bh(&ar->data_lock); - ieee80211_iterate_active_interfaces_atomic(ar->hw, - IEEE80211_IFACE_ITER_NORMAL, - ath10k_wmi_tx_beacons_iter, - NULL); - spin_unlock_bh(&ar->data_lock); -} - -static void ath10k_wmi_op_ep_tx_credits(struct ath10k *ar) -{ - /* try to send pending beacons first. they take priority */ - ath10k_wmi_tx_beacons_nowait(ar); - - wake_up(&ar->wmi.tx_credits_wq); -} - -static int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, - u32 cmd_id) -{ - int ret = -EOPNOTSUPP; - - might_sleep(); - - if (cmd_id == WMI_CMD_UNSUPPORTED) { - ath10k_warn("wmi command %d is not supported by firmware\n", - cmd_id); - return ret; + if (atomic_add_return(1, &ar->wmi.pending_tx_count) > + WMI_MAX_PENDING_TX_COUNT) { + /* avoid using up memory when FW hangs */ + atomic_dec(&ar->wmi.pending_tx_count); + return -EBUSY; } - wait_event_timeout(ar->wmi.tx_credits_wq, ({ - /* try to send pending beacons first. they take priority */ - ath10k_wmi_tx_beacons_nowait(ar); - - ret = ath10k_wmi_cmd_send_nowait(ar, skb, cmd_id); - (ret != -EAGAIN); - }), 3*HZ); - - if (ret) - dev_kfree_skb_any(skb); - - return ret; -} - -int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) -{ - int ret = 0; - struct wmi_mgmt_tx_cmd *cmd; - struct ieee80211_hdr *hdr; - struct sk_buff *wmi_skb; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - int len; - u16 fc; - - hdr = (struct ieee80211_hdr *)skb->data; - fc = le16_to_cpu(hdr->frame_control); - - if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control))) - return -EINVAL; - - len = sizeof(cmd->hdr) + skb->len; - len = round_up(len, 4); - - wmi_skb = ath10k_wmi_alloc_skb(len); - if (!wmi_skb) - return -ENOMEM; - - cmd = (struct wmi_mgmt_tx_cmd *)wmi_skb->data; - - cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(skb)->vdev_id); - cmd->hdr.tx_rate = 0; - cmd->hdr.tx_power = 0; - cmd->hdr.buf_len = __cpu_to_le32((u32)(skb->len)); - - memcpy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr), ETH_ALEN); - memcpy(cmd->buf, skb->data, skb->len); + memset(skb_cb, 0, sizeof(*skb_cb)); - ath10k_dbg(ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n", - wmi_skb, wmi_skb->len, fc & IEEE80211_FCTL_FTYPE, - fc & IEEE80211_FCTL_STYPE); + trace_ath10k_wmi_cmd(cmd_id, skb->data, skb->len); - /* Send the management frame buffer to the target */ - ret = ath10k_wmi_cmd_send(ar, wmi_skb, ar->wmi.cmd->mgmt_tx_cmdid); - if (ret) { + status = ath10k_htc_send(&ar->htc, ar->wmi.eid, skb); + if (status) { dev_kfree_skb_any(skb); - return ret; + atomic_dec(&ar->wmi.pending_tx_count); + return status; } - /* TODO: report tx status to mac80211 - temporary just ACK */ - info->flags |= IEEE80211_TX_STAT_ACK; - ieee80211_tx_status_irqsafe(ar->hw, skb); - - return ret; + return 0; } static int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb) @@ -873,9 +315,7 @@ static inline u8 get_rate_idx(u32 rate, enum ieee80211_band band) static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) { - struct wmi_mgmt_rx_event_v1 *ev_v1; - struct wmi_mgmt_rx_event_v2 *ev_v2; - struct wmi_mgmt_rx_hdr_v1 *ev_hdr; + struct wmi_mgmt_rx_event *event = (struct wmi_mgmt_rx_event *)skb->data; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_hdr *hdr; u32 rx_status; @@ -885,24 +325,13 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) u32 rate; u32 buf_len; u16 fc; - int pull_len; - - if (test_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX, ar->fw_features)) { - ev_v2 = (struct wmi_mgmt_rx_event_v2 *)skb->data; - ev_hdr = &ev_v2->hdr.v1; - pull_len = sizeof(*ev_v2); - } else { - ev_v1 = (struct wmi_mgmt_rx_event_v1 *)skb->data; - ev_hdr = &ev_v1->hdr; - pull_len = sizeof(*ev_v1); - } - channel = __le32_to_cpu(ev_hdr->channel); - buf_len = __le32_to_cpu(ev_hdr->buf_len); - rx_status = __le32_to_cpu(ev_hdr->status); - snr = __le32_to_cpu(ev_hdr->snr); - phy_mode = __le32_to_cpu(ev_hdr->phy_mode); - rate = __le32_to_cpu(ev_hdr->rate); + channel = __le32_to_cpu(event->hdr.channel); + buf_len = __le32_to_cpu(event->hdr.buf_len); + rx_status = __le32_to_cpu(event->hdr.status); + snr = __le32_to_cpu(event->hdr.snr); + phy_mode = __le32_to_cpu(event->hdr.phy_mode); + rate = __le32_to_cpu(event->hdr.rate); memset(status, 0, sizeof(*status)); @@ -929,7 +358,7 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR; status->rate_idx = get_rate_idx(rate, status->band); - skb_pull(skb, pull_len); + skb_pull(skb, sizeof(event->hdr)); hdr = (struct ieee80211_hdr *)skb->data; fc = le16_to_cpu(hdr->frame_control); @@ -1305,8 +734,10 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) int i = -1; struct wmi_bcn_info *bcn_info; struct ath10k_vif *arvif; + struct wmi_bcn_tx_arg arg; struct sk_buff *bcn; int vdev_id = 0; + int ret; ath10k_dbg(ATH10K_DBG_MGMT, "WMI_HOST_SWBA_EVENTID\n"); @@ -1363,17 +794,17 @@ static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) ath10k_wmi_update_tim(ar, arvif, bcn, bcn_info); ath10k_wmi_update_noa(ar, arvif, bcn, bcn_info); - spin_lock_bh(&ar->data_lock); - if (arvif->beacon) { - ath10k_warn("SWBA overrun on vdev %d\n", - arvif->vdev_id); - dev_kfree_skb_any(arvif->beacon); - } + arg.vdev_id = arvif->vdev_id; + arg.tx_rate = 0; + arg.tx_power = 0; + arg.bcn = bcn->data; + arg.bcn_len = bcn->len; - arvif->beacon = bcn; + ret = ath10k_wmi_beacon_send(ar, &arg); + if (ret) + ath10k_warn("could not send beacon (%d)\n", ret); - ath10k_wmi_tx_beacon_nowait(arvif); - spin_unlock_bh(&ar->data_lock); + dev_kfree_skb_any(bcn); } } @@ -1488,55 +919,6 @@ static void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar, ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID\n"); } -static void ath10k_wmi_event_inst_rssi_stats(struct ath10k *ar, - struct sk_buff *skb) -{ - ath10k_dbg(ATH10K_DBG_WMI, "WMI_INST_RSSI_STATS_EVENTID\n"); -} - -static void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, - struct sk_buff *skb) -{ - ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_STANDBY_REQ_EVENTID\n"); -} - -static void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, - struct sk_buff *skb) -{ - ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_RESUME_REQ_EVENTID\n"); -} - -static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id, - u32 num_units, u32 unit_len) -{ - dma_addr_t paddr; - u32 pool_size; - int idx = ar->wmi.num_mem_chunks; - - pool_size = num_units * round_up(unit_len, 4); - - if (!pool_size) - return -EINVAL; - - ar->wmi.mem_chunks[idx].vaddr = dma_alloc_coherent(ar->dev, - pool_size, - &paddr, - GFP_ATOMIC); - if (!ar->wmi.mem_chunks[idx].vaddr) { - ath10k_warn("failed to allocate memory chunk\n"); - return -ENOMEM; - } - - memset(ar->wmi.mem_chunks[idx].vaddr, 0, pool_size); - - ar->wmi.mem_chunks[idx].paddr = paddr; - ar->wmi.mem_chunks[idx].len = pool_size; - ar->wmi.mem_chunks[idx].req_id = req_id; - ar->wmi.num_mem_chunks++; - - return 0; -} - static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, struct sk_buff *skb) { @@ -1561,10 +943,6 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, ar->phy_capability = __le32_to_cpu(ev->phy_capability); ar->num_rf_chains = __le32_to_cpu(ev->num_rf_chains); - /* only manually set fw features when not using FW IE format */ - if (ar->fw_api == 1 && ar->fw_version_build > 636) - set_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX, ar->fw_features); - if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) { ath10k_warn("hardware advertises support for more spatial streams than it should (%d > %d)\n", ar->num_rf_chains, WMI_MAX_SPATIAL_STREAM); @@ -1609,108 +987,6 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, complete(&ar->wmi.service_ready); } -static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar, - struct sk_buff *skb) -{ - u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i; - int ret; - struct wmi_service_ready_event_10x *ev = (void *)skb->data; - - if (skb->len < sizeof(*ev)) { - ath10k_warn("Service ready event was %d B but expected %zu B. Wrong firmware version?\n", - skb->len, sizeof(*ev)); - return; - } - - ar->hw_min_tx_power = __le32_to_cpu(ev->hw_min_tx_power); - ar->hw_max_tx_power = __le32_to_cpu(ev->hw_max_tx_power); - ar->ht_cap_info = __le32_to_cpu(ev->ht_cap_info); - ar->vht_cap_info = __le32_to_cpu(ev->vht_cap_info); - ar->fw_version_major = - (__le32_to_cpu(ev->sw_version) & 0xff000000) >> 24; - ar->fw_version_minor = (__le32_to_cpu(ev->sw_version) & 0x00ffffff); - ar->phy_capability = __le32_to_cpu(ev->phy_capability); - ar->num_rf_chains = __le32_to_cpu(ev->num_rf_chains); - - if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) { - ath10k_warn("hardware advertises support for more spatial streams than it should (%d > %d)\n", - ar->num_rf_chains, WMI_MAX_SPATIAL_STREAM); - ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM; - } - - ar->ath_common.regulatory.current_rd = - __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd); - - ath10k_debug_read_service_map(ar, ev->wmi_service_bitmap, - sizeof(ev->wmi_service_bitmap)); - - if (strlen(ar->hw->wiphy->fw_version) == 0) { - snprintf(ar->hw->wiphy->fw_version, - sizeof(ar->hw->wiphy->fw_version), - "%u.%u", - ar->fw_version_major, - ar->fw_version_minor); - } - - num_mem_reqs = __le32_to_cpu(ev->num_mem_reqs); - - if (num_mem_reqs > ATH10K_MAX_MEM_REQS) { - ath10k_warn("requested memory chunks number (%d) exceeds the limit\n", - num_mem_reqs); - return; - } - - if (!num_mem_reqs) - goto exit; - - ath10k_dbg(ATH10K_DBG_WMI, "firmware has requested %d memory chunks\n", - num_mem_reqs); - - for (i = 0; i < num_mem_reqs; ++i) { - req_id = __le32_to_cpu(ev->mem_reqs[i].req_id); - num_units = __le32_to_cpu(ev->mem_reqs[i].num_units); - unit_size = __le32_to_cpu(ev->mem_reqs[i].unit_size); - num_unit_info = __le32_to_cpu(ev->mem_reqs[i].num_unit_info); - - if (num_unit_info & NUM_UNITS_IS_NUM_PEERS) - /* number of units to allocate is number of - * peers, 1 extra for self peer on target */ - /* this needs to be tied, host and target - * can get out of sync */ - num_units = TARGET_10X_NUM_PEERS + 1; - else if (num_unit_info & NUM_UNITS_IS_NUM_VDEVS) - num_units = TARGET_10X_NUM_VDEVS + 1; - - ath10k_dbg(ATH10K_DBG_WMI, - "wmi mem_req_id %d num_units %d num_unit_info %d unit size %d actual units %d\n", - req_id, - __le32_to_cpu(ev->mem_reqs[i].num_units), - num_unit_info, - unit_size, - num_units); - - ret = ath10k_wmi_alloc_host_mem(ar, req_id, num_units, - unit_size); - if (ret) - return; - } - -exit: - ath10k_dbg(ATH10K_DBG_WMI, - "wmi event service ready sw_ver 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u num_rf_chains %u\n", - __le32_to_cpu(ev->sw_version), - __le32_to_cpu(ev->abi_version), - __le32_to_cpu(ev->phy_capability), - __le32_to_cpu(ev->ht_cap_info), - __le32_to_cpu(ev->vht_cap_info), - __le32_to_cpu(ev->vht_supp_mcs), - __le32_to_cpu(ev->sys_cap_info), - __le32_to_cpu(ev->num_mem_reqs), - __le32_to_cpu(ev->num_rf_chains)); - - complete(&ar->wmi.service_ready); -} - static int ath10k_wmi_ready_event_rx(struct ath10k *ar, struct sk_buff *skb) { struct wmi_ready_event *ev = (struct wmi_ready_event *)skb->data; @@ -1731,7 +1007,7 @@ static int ath10k_wmi_ready_event_rx(struct ath10k *ar, struct sk_buff *skb) return 0; } -static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb) +static void ath10k_wmi_event_process(struct ath10k *ar, struct sk_buff *skb) { struct wmi_cmd_hdr *cmd_hdr; enum wmi_event_id id; @@ -1850,158 +1126,64 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb) dev_kfree_skb(skb); } -static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb) +static void ath10k_wmi_event_work(struct work_struct *work) { - struct wmi_cmd_hdr *cmd_hdr; - enum wmi_10x_event_id id; - u16 len; + struct ath10k *ar = container_of(work, struct ath10k, + wmi.wmi_event_work); + struct sk_buff *skb; - cmd_hdr = (struct wmi_cmd_hdr *)skb->data; - id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); + for (;;) { + skb = skb_dequeue(&ar->wmi.wmi_event_list); + if (!skb) + break; - if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) - return; + ath10k_wmi_event_process(ar, skb); + } +} - len = skb->len; +static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb) +{ + struct wmi_cmd_hdr *cmd_hdr = (struct wmi_cmd_hdr *)skb->data; + enum wmi_event_id event_id; - trace_ath10k_wmi_event(id, skb->data, skb->len); + event_id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); - switch (id) { - case WMI_10X_MGMT_RX_EVENTID: - ath10k_wmi_event_mgmt_rx(ar, skb); - /* mgmt_rx() owns the skb now! */ + /* some events require to be handled ASAP + * thus can't be defered to a worker thread */ + switch (event_id) { + case WMI_HOST_SWBA_EVENTID: + case WMI_MGMT_RX_EVENTID: + ath10k_wmi_event_process(ar, skb); return; - case WMI_10X_SCAN_EVENTID: - ath10k_wmi_event_scan(ar, skb); - break; - case WMI_10X_CHAN_INFO_EVENTID: - ath10k_wmi_event_chan_info(ar, skb); - break; - case WMI_10X_ECHO_EVENTID: - ath10k_wmi_event_echo(ar, skb); - break; - case WMI_10X_DEBUG_MESG_EVENTID: - ath10k_wmi_event_debug_mesg(ar, skb); - break; - case WMI_10X_UPDATE_STATS_EVENTID: - ath10k_wmi_event_update_stats(ar, skb); - break; - case WMI_10X_VDEV_START_RESP_EVENTID: - ath10k_wmi_event_vdev_start_resp(ar, skb); - break; - case WMI_10X_VDEV_STOPPED_EVENTID: - ath10k_wmi_event_vdev_stopped(ar, skb); - break; - case WMI_10X_PEER_STA_KICKOUT_EVENTID: - ath10k_wmi_event_peer_sta_kickout(ar, skb); - break; - case WMI_10X_HOST_SWBA_EVENTID: - ath10k_wmi_event_host_swba(ar, skb); - break; - case WMI_10X_TBTTOFFSET_UPDATE_EVENTID: - ath10k_wmi_event_tbttoffset_update(ar, skb); - break; - case WMI_10X_PHYERR_EVENTID: - ath10k_wmi_event_phyerr(ar, skb); - break; - case WMI_10X_ROAM_EVENTID: - ath10k_wmi_event_roam(ar, skb); - break; - case WMI_10X_PROFILE_MATCH: - ath10k_wmi_event_profile_match(ar, skb); - break; - case WMI_10X_DEBUG_PRINT_EVENTID: - ath10k_wmi_event_debug_print(ar, skb); - break; - case WMI_10X_PDEV_QVIT_EVENTID: - ath10k_wmi_event_pdev_qvit(ar, skb); - break; - case WMI_10X_WLAN_PROFILE_DATA_EVENTID: - ath10k_wmi_event_wlan_profile_data(ar, skb); - break; - case WMI_10X_RTT_MEASUREMENT_REPORT_EVENTID: - ath10k_wmi_event_rtt_measurement_report(ar, skb); - break; - case WMI_10X_TSF_MEASUREMENT_REPORT_EVENTID: - ath10k_wmi_event_tsf_measurement_report(ar, skb); - break; - case WMI_10X_RTT_ERROR_REPORT_EVENTID: - ath10k_wmi_event_rtt_error_report(ar, skb); - break; - case WMI_10X_WOW_WAKEUP_HOST_EVENTID: - ath10k_wmi_event_wow_wakeup_host(ar, skb); - break; - case WMI_10X_DCS_INTERFERENCE_EVENTID: - ath10k_wmi_event_dcs_interference(ar, skb); - break; - case WMI_10X_PDEV_TPC_CONFIG_EVENTID: - ath10k_wmi_event_pdev_tpc_config(ar, skb); - break; - case WMI_10X_INST_RSSI_STATS_EVENTID: - ath10k_wmi_event_inst_rssi_stats(ar, skb); - break; - case WMI_10X_VDEV_STANDBY_REQ_EVENTID: - ath10k_wmi_event_vdev_standby_req(ar, skb); - break; - case WMI_10X_VDEV_RESUME_REQ_EVENTID: - ath10k_wmi_event_vdev_resume_req(ar, skb); - break; - case WMI_10X_SERVICE_READY_EVENTID: - ath10k_wmi_10x_service_ready_event_rx(ar, skb); - break; - case WMI_10X_READY_EVENTID: - ath10k_wmi_ready_event_rx(ar, skb); - break; default: - ath10k_warn("Unknown eventid: %d\n", id); break; } - dev_kfree_skb(skb); -} - - -static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb) -{ - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) - ath10k_wmi_10x_process_rx(ar, skb); - else - ath10k_wmi_main_process_rx(ar, skb); + skb_queue_tail(&ar->wmi.wmi_event_list, skb); + queue_work(ar->workqueue, &ar->wmi.wmi_event_work); } /* WMI Initialization functions */ int ath10k_wmi_attach(struct ath10k *ar) { - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { - ar->wmi.cmd = &wmi_10x_cmd_map; - ar->wmi.vdev_param = &wmi_10x_vdev_param_map; - ar->wmi.pdev_param = &wmi_10x_pdev_param_map; - } else { - ar->wmi.cmd = &wmi_cmd_map; - ar->wmi.vdev_param = &wmi_vdev_param_map; - ar->wmi.pdev_param = &wmi_pdev_param_map; - } - init_completion(&ar->wmi.service_ready); init_completion(&ar->wmi.unified_ready); - init_waitqueue_head(&ar->wmi.tx_credits_wq); + init_waitqueue_head(&ar->wmi.wq); + + skb_queue_head_init(&ar->wmi.wmi_event_list); + INIT_WORK(&ar->wmi.wmi_event_work, ath10k_wmi_event_work); return 0; } void ath10k_wmi_detach(struct ath10k *ar) { - int i; - - /* free the host memory chunks requested by firmware */ - for (i = 0; i < ar->wmi.num_mem_chunks; i++) { - dma_free_coherent(ar->dev, - ar->wmi.mem_chunks[i].len, - ar->wmi.mem_chunks[i].vaddr, - ar->wmi.mem_chunks[i].paddr); - } + /* HTC should've drained the packets already */ + if (WARN_ON(atomic_read(&ar->wmi.pending_tx_count) > 0)) + ath10k_warn("there are still pending packets\n"); - ar->wmi.num_mem_chunks = 0; + cancel_work_sync(&ar->wmi.wmi_event_work); + skb_queue_purge(&ar->wmi.wmi_event_list); } int ath10k_wmi_connect_htc_service(struct ath10k *ar) @@ -2016,7 +1198,6 @@ int ath10k_wmi_connect_htc_service(struct ath10k *ar) /* these fields are the same for all service endpoints */ conn_req.ep_ops.ep_tx_complete = ath10k_wmi_htc_tx_complete; conn_req.ep_ops.ep_rx_complete = ath10k_wmi_process_rx; - conn_req.ep_ops.ep_tx_credits = ath10k_wmi_op_ep_tx_credits; /* connect to control service */ conn_req.service_id = ATH10K_HTC_SVC_ID_WMI_CONTROL; @@ -2053,8 +1234,7 @@ int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g, "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x\n", rd, rd2g, rd5g, ctl2g, ctl5g); - return ath10k_wmi_cmd_send(ar, skb, - ar->wmi.cmd->pdev_set_regdomain_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_SET_REGDOMAIN_CMDID); } int ath10k_wmi_pdev_set_channel(struct ath10k *ar, @@ -2084,8 +1264,7 @@ int ath10k_wmi_pdev_set_channel(struct ath10k *ar, "wmi set channel mode %d freq %d\n", arg->mode, arg->freq); - return ath10k_wmi_cmd_send(ar, skb, - ar->wmi.cmd->pdev_set_channel_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_SET_CHANNEL_CMDID); } int ath10k_wmi_pdev_suspend_target(struct ath10k *ar) @@ -2100,7 +1279,7 @@ int ath10k_wmi_pdev_suspend_target(struct ath10k *ar) cmd = (struct wmi_pdev_suspend_cmd *)skb->data; cmd->suspend_opt = WMI_PDEV_SUSPEND; - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_suspend_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_SUSPEND_CMDID); } int ath10k_wmi_pdev_resume_target(struct ath10k *ar) @@ -2111,19 +1290,15 @@ int ath10k_wmi_pdev_resume_target(struct ath10k *ar) if (skb == NULL) return -ENOMEM; - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_resume_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_RESUME_CMDID); } -int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value) +int ath10k_wmi_pdev_set_param(struct ath10k *ar, enum wmi_pdev_param id, + u32 value) { struct wmi_pdev_set_param_cmd *cmd; struct sk_buff *skb; - if (id == WMI_PDEV_PARAM_UNSUPPORTED) { - ath10k_warn("pdev param %d not supported by firmware\n", id); - return -EOPNOTSUPP; - } - skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); if (!skb) return -ENOMEM; @@ -2134,16 +1309,15 @@ int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value) ath10k_dbg(ATH10K_DBG_WMI, "wmi pdev set param %d value %d\n", id, value); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_set_param_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_SET_PARAM_CMDID); } -static int ath10k_wmi_main_cmd_init(struct ath10k *ar) +int ath10k_wmi_cmd_init(struct ath10k *ar) { struct wmi_init_cmd *cmd; struct sk_buff *buf; struct wmi_resource_config config = {}; - u32 len, val; - int i; + u32 val; config.num_vdevs = __cpu_to_le32(TARGET_NUM_VDEVS); config.num_peers = __cpu_to_le32(TARGET_NUM_PEERS + TARGET_NUM_VDEVS); @@ -2196,158 +1370,23 @@ static int ath10k_wmi_main_cmd_init(struct ath10k *ar) config.num_msdu_desc = __cpu_to_le32(TARGET_NUM_MSDU_DESC); config.max_frag_entries = __cpu_to_le32(TARGET_MAX_FRAG_ENTRIES); - len = sizeof(*cmd) + - (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks); - - buf = ath10k_wmi_alloc_skb(len); + buf = ath10k_wmi_alloc_skb(sizeof(*cmd)); if (!buf) return -ENOMEM; cmd = (struct wmi_init_cmd *)buf->data; - - if (ar->wmi.num_mem_chunks == 0) { - cmd->num_host_mem_chunks = 0; - goto out; - } - - ath10k_dbg(ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", - __cpu_to_le32(ar->wmi.num_mem_chunks)); - - cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); - - for (i = 0; i < ar->wmi.num_mem_chunks; i++) { - cmd->host_mem_chunks[i].ptr = - __cpu_to_le32(ar->wmi.mem_chunks[i].paddr); - cmd->host_mem_chunks[i].size = - __cpu_to_le32(ar->wmi.mem_chunks[i].len); - cmd->host_mem_chunks[i].req_id = - __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); - - ath10k_dbg(ATH10K_DBG_WMI, - "wmi chunk %d len %d requested, addr 0x%x\n", - i, - cmd->host_mem_chunks[i].size, - cmd->host_mem_chunks[i].ptr); - } -out: + cmd->num_host_mem_chunks = 0; memcpy(&cmd->resource_config, &config, sizeof(config)); ath10k_dbg(ATH10K_DBG_WMI, "wmi init\n"); - return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); + return ath10k_wmi_cmd_send(ar, buf, WMI_INIT_CMDID); } -static int ath10k_wmi_10x_cmd_init(struct ath10k *ar) -{ - struct wmi_init_cmd_10x *cmd; - struct sk_buff *buf; - struct wmi_resource_config_10x config = {}; - u32 len, val; - int i; - - config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS); - config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS); - config.num_peer_keys = __cpu_to_le32(TARGET_10X_NUM_PEER_KEYS); - config.num_tids = __cpu_to_le32(TARGET_10X_NUM_TIDS); - config.ast_skid_limit = __cpu_to_le32(TARGET_10X_AST_SKID_LIMIT); - config.tx_chain_mask = __cpu_to_le32(TARGET_10X_TX_CHAIN_MASK); - config.rx_chain_mask = __cpu_to_le32(TARGET_10X_RX_CHAIN_MASK); - config.rx_timeout_pri_vo = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); - config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); - config.rx_timeout_pri_be = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); - config.rx_timeout_pri_bk = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_HI_PRI); - config.rx_decap_mode = __cpu_to_le32(TARGET_10X_RX_DECAP_MODE); - - config.scan_max_pending_reqs = - __cpu_to_le32(TARGET_10X_SCAN_MAX_PENDING_REQS); - - config.bmiss_offload_max_vdev = - __cpu_to_le32(TARGET_10X_BMISS_OFFLOAD_MAX_VDEV); - - config.roam_offload_max_vdev = - __cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_VDEV); - - config.roam_offload_max_ap_profiles = - __cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_AP_PROFILES); - - config.num_mcast_groups = __cpu_to_le32(TARGET_10X_NUM_MCAST_GROUPS); - config.num_mcast_table_elems = - __cpu_to_le32(TARGET_10X_NUM_MCAST_TABLE_ELEMS); - - config.mcast2ucast_mode = __cpu_to_le32(TARGET_10X_MCAST2UCAST_MODE); - config.tx_dbg_log_size = __cpu_to_le32(TARGET_10X_TX_DBG_LOG_SIZE); - config.num_wds_entries = __cpu_to_le32(TARGET_10X_NUM_WDS_ENTRIES); - config.dma_burst_size = __cpu_to_le32(TARGET_10X_DMA_BURST_SIZE); - config.mac_aggr_delim = __cpu_to_le32(TARGET_10X_MAC_AGGR_DELIM); - - val = TARGET_10X_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK; - config.rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(val); - - config.vow_config = __cpu_to_le32(TARGET_10X_VOW_CONFIG); - - config.num_msdu_desc = __cpu_to_le32(TARGET_10X_NUM_MSDU_DESC); - config.max_frag_entries = __cpu_to_le32(TARGET_10X_MAX_FRAG_ENTRIES); - - len = sizeof(*cmd) + - (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks); - - buf = ath10k_wmi_alloc_skb(len); - if (!buf) - return -ENOMEM; - - cmd = (struct wmi_init_cmd_10x *)buf->data; - - if (ar->wmi.num_mem_chunks == 0) { - cmd->num_host_mem_chunks = 0; - goto out; - } - - ath10k_dbg(ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", - __cpu_to_le32(ar->wmi.num_mem_chunks)); - - cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); - - for (i = 0; i < ar->wmi.num_mem_chunks; i++) { - cmd->host_mem_chunks[i].ptr = - __cpu_to_le32(ar->wmi.mem_chunks[i].paddr); - cmd->host_mem_chunks[i].size = - __cpu_to_le32(ar->wmi.mem_chunks[i].len); - cmd->host_mem_chunks[i].req_id = - __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); - - ath10k_dbg(ATH10K_DBG_WMI, - "wmi chunk %d len %d requested, addr 0x%x\n", - i, - cmd->host_mem_chunks[i].size, - cmd->host_mem_chunks[i].ptr); - } -out: - memcpy(&cmd->resource_config, &config, sizeof(config)); - - ath10k_dbg(ATH10K_DBG_WMI, "wmi init 10x\n"); - return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); -} - -int ath10k_wmi_cmd_init(struct ath10k *ar) -{ - int ret; - - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) - ret = ath10k_wmi_10x_cmd_init(ar); - else - ret = ath10k_wmi_main_cmd_init(ar); - - return ret; -} - -static int ath10k_wmi_start_scan_calc_len(struct ath10k *ar, - const struct wmi_start_scan_arg *arg) +static int ath10k_wmi_start_scan_calc_len(const struct wmi_start_scan_arg *arg) { int len; - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) - len = sizeof(struct wmi_start_scan_cmd_10x); - else - len = sizeof(struct wmi_start_scan_cmd); + len = sizeof(struct wmi_start_scan_cmd); if (arg->ie_len) { if (!arg->ie) @@ -2407,7 +1446,7 @@ int ath10k_wmi_start_scan(struct ath10k *ar, int len = 0; int i; - len = ath10k_wmi_start_scan_calc_len(ar, arg); + len = ath10k_wmi_start_scan_calc_len(arg); if (len < 0) return len; /* len contains error code here */ @@ -2439,14 +1478,7 @@ int ath10k_wmi_start_scan(struct ath10k *ar, cmd->scan_ctrl_flags = __cpu_to_le32(arg->scan_ctrl_flags); /* TLV list starts after fields included in the struct */ - /* There's just one filed that differes the two start_scan - * structures - burst_duration, which we are not using btw, - no point to make the split here, just shift the buffer to fit with - given FW */ - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) - off = sizeof(struct wmi_start_scan_cmd_10x); - else - off = sizeof(struct wmi_start_scan_cmd); + off = sizeof(*cmd); if (arg->n_channels) { channels = (void *)skb->data + off; @@ -2508,7 +1540,7 @@ int ath10k_wmi_start_scan(struct ath10k *ar, } ath10k_dbg(ATH10K_DBG_WMI, "wmi start scan\n"); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->start_scan_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_START_SCAN_CMDID); } void ath10k_wmi_start_scan_init(struct ath10k *ar, @@ -2524,7 +1556,7 @@ void ath10k_wmi_start_scan_init(struct ath10k *ar, arg->repeat_probe_time = 0; arg->probe_spacing_time = 0; arg->idle_time = 0; - arg->max_scan_time = 20000; + arg->max_scan_time = 5000; arg->probe_delay = 5; arg->notify_scan_events = WMI_SCAN_EVENT_STARTED | WMI_SCAN_EVENT_COMPLETED @@ -2568,7 +1600,7 @@ int ath10k_wmi_stop_scan(struct ath10k *ar, const struct wmi_stop_scan_arg *arg) ath10k_dbg(ATH10K_DBG_WMI, "wmi stop scan reqid %d req_type %d vdev/scan_id %d\n", arg->req_id, arg->req_type, arg->u.scan_id); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->stop_scan_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_STOP_SCAN_CMDID); } int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id, @@ -2593,7 +1625,7 @@ int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id, "WMI vdev create: id %d type %d subtype %d macaddr %pM\n", vdev_id, type, subtype, macaddr); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_create_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_CREATE_CMDID); } int ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id) @@ -2611,20 +1643,20 @@ int ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id) ath10k_dbg(ATH10K_DBG_WMI, "WMI vdev delete id %d\n", vdev_id); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_delete_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_DELETE_CMDID); } static int ath10k_wmi_vdev_start_restart(struct ath10k *ar, const struct wmi_vdev_start_request_arg *arg, - u32 cmd_id) + enum wmi_cmd_id cmd_id) { struct wmi_vdev_start_request_cmd *cmd; struct sk_buff *skb; const char *cmdname; u32 flags = 0; - if (cmd_id != ar->wmi.cmd->vdev_start_request_cmdid && - cmd_id != ar->wmi.cmd->vdev_restart_request_cmdid) + if (cmd_id != WMI_VDEV_START_REQUEST_CMDID && + cmd_id != WMI_VDEV_RESTART_REQUEST_CMDID) return -EINVAL; if (WARN_ON(arg->ssid && arg->ssid_len == 0)) return -EINVAL; @@ -2633,9 +1665,9 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar, if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid))) return -EINVAL; - if (cmd_id == ar->wmi.cmd->vdev_start_request_cmdid) + if (cmd_id == WMI_VDEV_START_REQUEST_CMDID) cmdname = "start"; - else if (cmd_id == ar->wmi.cmd->vdev_restart_request_cmdid) + else if (cmd_id == WMI_VDEV_RESTART_REQUEST_CMDID) cmdname = "restart"; else return -EINVAL; /* should not happen, we already check cmd_id */ @@ -2686,17 +1718,15 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar, int ath10k_wmi_vdev_start(struct ath10k *ar, const struct wmi_vdev_start_request_arg *arg) { - u32 cmd_id = ar->wmi.cmd->vdev_start_request_cmdid; - - return ath10k_wmi_vdev_start_restart(ar, arg, cmd_id); + return ath10k_wmi_vdev_start_restart(ar, arg, + WMI_VDEV_START_REQUEST_CMDID); } int ath10k_wmi_vdev_restart(struct ath10k *ar, const struct wmi_vdev_start_request_arg *arg) { - u32 cmd_id = ar->wmi.cmd->vdev_restart_request_cmdid; - - return ath10k_wmi_vdev_start_restart(ar, arg, cmd_id); + return ath10k_wmi_vdev_start_restart(ar, arg, + WMI_VDEV_RESTART_REQUEST_CMDID); } int ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id) @@ -2713,7 +1743,7 @@ int ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id) ath10k_dbg(ATH10K_DBG_WMI, "wmi vdev stop id 0x%x\n", vdev_id); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_stop_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_STOP_CMDID); } int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid) @@ -2728,13 +1758,13 @@ int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid) cmd = (struct wmi_vdev_up_cmd *)skb->data; cmd->vdev_id = __cpu_to_le32(vdev_id); cmd->vdev_assoc_id = __cpu_to_le32(aid); - memcpy(&cmd->vdev_bssid.addr, bssid, ETH_ALEN); + memcpy(&cmd->vdev_bssid.addr, bssid, 6); ath10k_dbg(ATH10K_DBG_WMI, "wmi mgmt vdev up id 0x%x assoc id %d bssid %pM\n", vdev_id, aid, bssid); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_up_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_UP_CMDID); } int ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id) @@ -2752,22 +1782,15 @@ int ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id) ath10k_dbg(ATH10K_DBG_WMI, "wmi mgmt vdev down id 0x%x\n", vdev_id); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_down_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_DOWN_CMDID); } int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, - u32 param_id, u32 param_value) + enum wmi_vdev_param param_id, u32 param_value) { struct wmi_vdev_set_param_cmd *cmd; struct sk_buff *skb; - if (param_id == WMI_VDEV_PARAM_UNSUPPORTED) { - ath10k_dbg(ATH10K_DBG_WMI, - "vdev param %d not supported by firmware\n", - param_id); - return -EOPNOTSUPP; - } - skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); if (!skb) return -ENOMEM; @@ -2781,7 +1804,7 @@ int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, "wmi vdev id 0x%x set param %d value %d\n", vdev_id, param_id, param_value); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_set_param_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_SET_PARAM_CMDID); } int ath10k_wmi_vdev_install_key(struct ath10k *ar, @@ -2816,8 +1839,7 @@ int ath10k_wmi_vdev_install_key(struct ath10k *ar, ath10k_dbg(ATH10K_DBG_WMI, "wmi vdev install key idx %d cipher %d len %d\n", arg->key_idx, arg->key_cipher, arg->key_len); - return ath10k_wmi_cmd_send(ar, skb, - ar->wmi.cmd->vdev_install_key_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_VDEV_INSTALL_KEY_CMDID); } int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, @@ -2837,7 +1859,7 @@ int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, ath10k_dbg(ATH10K_DBG_WMI, "wmi peer create vdev_id %d peer_addr %pM\n", vdev_id, peer_addr); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_create_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PEER_CREATE_CMDID); } int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, @@ -2857,7 +1879,7 @@ int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, ath10k_dbg(ATH10K_DBG_WMI, "wmi peer delete vdev_id %d peer_addr %pM\n", vdev_id, peer_addr); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_delete_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PEER_DELETE_CMDID); } int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id, @@ -2878,7 +1900,7 @@ int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id, ath10k_dbg(ATH10K_DBG_WMI, "wmi peer flush vdev_id %d peer_addr %pM tids %08x\n", vdev_id, peer_addr, tid_bitmap); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_flush_tids_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PEER_FLUSH_TIDS_CMDID); } int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, @@ -2896,13 +1918,13 @@ int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, cmd->vdev_id = __cpu_to_le32(vdev_id); cmd->param_id = __cpu_to_le32(param_id); cmd->param_value = __cpu_to_le32(param_value); - memcpy(&cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); + memcpy(&cmd->peer_macaddr.addr, peer_addr, 6); ath10k_dbg(ATH10K_DBG_WMI, "wmi vdev %d peer 0x%pM set param %d value %d\n", vdev_id, peer_addr, param_id, param_value); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_set_param_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PEER_SET_PARAM_CMDID); } int ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id, @@ -2923,8 +1945,7 @@ int ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id, "wmi set powersave id 0x%x mode %d\n", vdev_id, psmode); - return ath10k_wmi_cmd_send(ar, skb, - ar->wmi.cmd->sta_powersave_mode_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_STA_POWERSAVE_MODE_CMDID); } int ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id, @@ -2946,8 +1967,7 @@ int ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id, ath10k_dbg(ATH10K_DBG_WMI, "wmi sta ps param vdev_id 0x%x param %d value %d\n", vdev_id, param_id, value); - return ath10k_wmi_cmd_send(ar, skb, - ar->wmi.cmd->sta_powersave_param_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_STA_POWERSAVE_PARAM_CMDID); } int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac, @@ -2973,8 +1993,7 @@ int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac, "wmi ap ps param vdev_id 0x%X param %d value %d mac_addr %pM\n", vdev_id, param_id, value, mac); - return ath10k_wmi_cmd_send(ar, skb, - ar->wmi.cmd->ap_ps_peer_param_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_AP_PS_PEER_PARAM_CMDID); } int ath10k_wmi_scan_chan_list(struct ath10k *ar, @@ -3027,7 +2046,7 @@ int ath10k_wmi_scan_chan_list(struct ath10k *ar, ci->flags |= __cpu_to_le32(flags); } - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->scan_chan_list_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_SCAN_CHAN_LIST_CMDID); } int ath10k_wmi_peer_assoc(struct ath10k *ar, @@ -3086,11 +2105,10 @@ int ath10k_wmi_peer_assoc(struct ath10k *ar, ath10k_dbg(ATH10K_DBG_WMI, "wmi peer assoc vdev %d addr %pM\n", arg->vdev_id, arg->addr); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_assoc_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PEER_ASSOC_CMDID); } -int ath10k_wmi_beacon_send_nowait(struct ath10k *ar, - const struct wmi_bcn_tx_arg *arg) +int ath10k_wmi_beacon_send(struct ath10k *ar, const struct wmi_bcn_tx_arg *arg) { struct wmi_bcn_tx_cmd *cmd; struct sk_buff *skb; @@ -3106,7 +2124,7 @@ int ath10k_wmi_beacon_send_nowait(struct ath10k *ar, cmd->hdr.bcn_len = __cpu_to_le32(arg->bcn_len); memcpy(cmd->bcn, arg->bcn, arg->bcn_len); - return ath10k_wmi_cmd_send_nowait(ar, skb, ar->wmi.cmd->bcn_tx_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_BCN_TX_CMDID); } static void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params, @@ -3137,8 +2155,7 @@ int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, ath10k_wmi_pdev_set_wmm_param(&cmd->ac_vo, &arg->ac_vo); ath10k_dbg(ATH10K_DBG_WMI, "wmi pdev set wmm params\n"); - return ath10k_wmi_cmd_send(ar, skb, - ar->wmi.cmd->pdev_set_wmm_params_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_PDEV_SET_WMM_PARAMS_CMDID); } int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id) @@ -3154,7 +2171,7 @@ int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id) cmd->stats_id = __cpu_to_le32(stats_id); ath10k_dbg(ATH10K_DBG_WMI, "wmi request stats %d\n", (int)stats_id); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->request_stats_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_REQUEST_STATS_CMDID); } int ath10k_wmi_force_fw_hang(struct ath10k *ar, @@ -3173,5 +2190,5 @@ int ath10k_wmi_force_fw_hang(struct ath10k *ar, ath10k_dbg(ATH10K_DBG_WMI, "wmi force fw hang %d delay %d\n", type, delay_ms); - return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid); + return ath10k_wmi_cmd_send(ar, skb, WMI_FORCE_FW_HANG_CMDID); } diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 78c991a..2c5a4f8 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -208,118 +208,6 @@ struct wmi_mac_addr { (c_macaddr)[5] = (((pwmi_mac_addr)->word1) >> 8) & 0xff; \ } while (0) -struct wmi_cmd_map { - u32 init_cmdid; - u32 start_scan_cmdid; - u32 stop_scan_cmdid; - u32 scan_chan_list_cmdid; - u32 scan_sch_prio_tbl_cmdid; - u32 pdev_set_regdomain_cmdid; - u32 pdev_set_channel_cmdid; - u32 pdev_set_param_cmdid; - u32 pdev_pktlog_enable_cmdid; - u32 pdev_pktlog_disable_cmdid; - u32 pdev_set_wmm_params_cmdid; - u32 pdev_set_ht_cap_ie_cmdid; - u32 pdev_set_vht_cap_ie_cmdid; - u32 pdev_set_dscp_tid_map_cmdid; - u32 pdev_set_quiet_mode_cmdid; - u32 pdev_green_ap_ps_enable_cmdid; - u32 pdev_get_tpc_config_cmdid; - u32 pdev_set_base_macaddr_cmdid; - u32 vdev_create_cmdid; - u32 vdev_delete_cmdid; - u32 vdev_start_request_cmdid; - u32 vdev_restart_request_cmdid; - u32 vdev_up_cmdid; - u32 vdev_stop_cmdid; - u32 vdev_down_cmdid; - u32 vdev_set_param_cmdid; - u32 vdev_install_key_cmdid; - u32 peer_create_cmdid; - u32 peer_delete_cmdid; - u32 peer_flush_tids_cmdid; - u32 peer_set_param_cmdid; - u32 peer_assoc_cmdid; - u32 peer_add_wds_entry_cmdid; - u32 peer_remove_wds_entry_cmdid; - u32 peer_mcast_group_cmdid; - u32 bcn_tx_cmdid; - u32 pdev_send_bcn_cmdid; - u32 bcn_tmpl_cmdid; - u32 bcn_filter_rx_cmdid; - u32 prb_req_filter_rx_cmdid; - u32 mgmt_tx_cmdid; - u32 prb_tmpl_cmdid; - u32 addba_clear_resp_cmdid; - u32 addba_send_cmdid; - u32 addba_status_cmdid; - u32 delba_send_cmdid; - u32 addba_set_resp_cmdid; - u32 send_singleamsdu_cmdid; - u32 sta_powersave_mode_cmdid; - u32 sta_powersave_param_cmdid; - u32 sta_mimo_ps_mode_cmdid; - u32 pdev_dfs_enable_cmdid; - u32 pdev_dfs_disable_cmdid; - u32 roam_scan_mode; - u32 roam_scan_rssi_threshold; - u32 roam_scan_period; - u32 roam_scan_rssi_change_threshold; - u32 roam_ap_profile; - u32 ofl_scan_add_ap_profile; - u32 ofl_scan_remove_ap_profile; - u32 ofl_scan_period; - u32 p2p_dev_set_device_info; - u32 p2p_dev_set_discoverability; - u32 p2p_go_set_beacon_ie; - u32 p2p_go_set_probe_resp_ie; - u32 p2p_set_vendor_ie_data_cmdid; - u32 ap_ps_peer_param_cmdid; - u32 ap_ps_peer_uapsd_coex_cmdid; - u32 peer_rate_retry_sched_cmdid; - u32 wlan_profile_trigger_cmdid; - u32 wlan_profile_set_hist_intvl_cmdid; - u32 wlan_profile_get_profile_data_cmdid; - u32 wlan_profile_enable_profile_id_cmdid; - u32 wlan_profile_list_profile_id_cmdid; - u32 pdev_suspend_cmdid; - u32 pdev_resume_cmdid; - u32 add_bcn_filter_cmdid; - u32 rmv_bcn_filter_cmdid; - u32 wow_add_wake_pattern_cmdid; - u32 wow_del_wake_pattern_cmdid; - u32 wow_enable_disable_wake_event_cmdid; - u32 wow_enable_cmdid; - u32 wow_hostwakeup_from_sleep_cmdid; - u32 rtt_measreq_cmdid; - u32 rtt_tsf_cmdid; - u32 vdev_spectral_scan_configure_cmdid; - u32 vdev_spectral_scan_enable_cmdid; - u32 request_stats_cmdid; - u32 set_arp_ns_offload_cmdid; - u32 network_list_offload_config_cmdid; - u32 gtk_offload_cmdid; - u32 csa_offload_enable_cmdid; - u32 csa_offload_chanswitch_cmdid; - u32 chatter_set_mode_cmdid; - u32 peer_tid_addba_cmdid; - u32 peer_tid_delba_cmdid; - u32 sta_dtim_ps_method_cmdid; - u32 sta_uapsd_auto_trig_cmdid; - u32 sta_keepalive_cmd; - u32 echo_cmdid; - u32 pdev_utf_cmdid; - u32 dbglog_cfg_cmdid; - u32 pdev_qvit_cmdid; - u32 pdev_ftm_intg_cmdid; - u32 vdev_set_keepalive_cmdid; - u32 vdev_get_keepalive_cmdid; - u32 force_fw_hang_cmdid; - u32 gpio_config_cmdid; - u32 gpio_output_cmdid; -}; - /* * wmi command groups. */ @@ -359,9 +247,7 @@ enum wmi_cmd_group { #define WMI_CMD_GRP(grp_id) (((grp_id) << 12) | 0x1) #define WMI_EVT_GRP_START_ID(grp_id) (((grp_id) << 12) | 0x1) -#define WMI_CMD_UNSUPPORTED 0 - -/* Command IDs and command events for MAIN FW. */ +/* Command IDs and commande events. */ enum wmi_cmd_id { WMI_INIT_CMDID = 0x1, @@ -602,217 +488,6 @@ enum wmi_event_id { WMI_GPIO_INPUT_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_GPIO), }; -/* Command IDs and command events for 10.X firmware */ -enum wmi_10x_cmd_id { - WMI_10X_START_CMDID = 0x9000, - WMI_10X_END_CMDID = 0x9FFF, - - /* initialize the wlan sub system */ - WMI_10X_INIT_CMDID, - - /* Scan specific commands */ - - WMI_10X_START_SCAN_CMDID = WMI_10X_START_CMDID, - WMI_10X_STOP_SCAN_CMDID, - WMI_10X_SCAN_CHAN_LIST_CMDID, - WMI_10X_ECHO_CMDID, - - /* PDEV(physical device) specific commands */ - WMI_10X_PDEV_SET_REGDOMAIN_CMDID, - WMI_10X_PDEV_SET_CHANNEL_CMDID, - WMI_10X_PDEV_SET_PARAM_CMDID, - WMI_10X_PDEV_PKTLOG_ENABLE_CMDID, - WMI_10X_PDEV_PKTLOG_DISABLE_CMDID, - WMI_10X_PDEV_SET_WMM_PARAMS_CMDID, - WMI_10X_PDEV_SET_HT_CAP_IE_CMDID, - WMI_10X_PDEV_SET_VHT_CAP_IE_CMDID, - WMI_10X_PDEV_SET_BASE_MACADDR_CMDID, - WMI_10X_PDEV_SET_DSCP_TID_MAP_CMDID, - WMI_10X_PDEV_SET_QUIET_MODE_CMDID, - WMI_10X_PDEV_GREEN_AP_PS_ENABLE_CMDID, - WMI_10X_PDEV_GET_TPC_CONFIG_CMDID, - - /* VDEV(virtual device) specific commands */ - WMI_10X_VDEV_CREATE_CMDID, - WMI_10X_VDEV_DELETE_CMDID, - WMI_10X_VDEV_START_REQUEST_CMDID, - WMI_10X_VDEV_RESTART_REQUEST_CMDID, - WMI_10X_VDEV_UP_CMDID, - WMI_10X_VDEV_STOP_CMDID, - WMI_10X_VDEV_DOWN_CMDID, - WMI_10X_VDEV_STANDBY_RESPONSE_CMDID, - WMI_10X_VDEV_RESUME_RESPONSE_CMDID, - WMI_10X_VDEV_SET_PARAM_CMDID, - WMI_10X_VDEV_INSTALL_KEY_CMDID, - - /* peer specific commands */ - WMI_10X_PEER_CREATE_CMDID, - WMI_10X_PEER_DELETE_CMDID, - WMI_10X_PEER_FLUSH_TIDS_CMDID, - WMI_10X_PEER_SET_PARAM_CMDID, - WMI_10X_PEER_ASSOC_CMDID, - WMI_10X_PEER_ADD_WDS_ENTRY_CMDID, - WMI_10X_PEER_REMOVE_WDS_ENTRY_CMDID, - WMI_10X_PEER_MCAST_GROUP_CMDID, - - /* beacon/management specific commands */ - - WMI_10X_BCN_TX_CMDID, - WMI_10X_BCN_PRB_TMPL_CMDID, - WMI_10X_BCN_FILTER_RX_CMDID, - WMI_10X_PRB_REQ_FILTER_RX_CMDID, - WMI_10X_MGMT_TX_CMDID, - - /* commands to directly control ba negotiation directly from host. */ - WMI_10X_ADDBA_CLEAR_RESP_CMDID, - WMI_10X_ADDBA_SEND_CMDID, - WMI_10X_ADDBA_STATUS_CMDID, - WMI_10X_DELBA_SEND_CMDID, - WMI_10X_ADDBA_SET_RESP_CMDID, - WMI_10X_SEND_SINGLEAMSDU_CMDID, - - /* Station power save specific config */ - WMI_10X_STA_POWERSAVE_MODE_CMDID, - WMI_10X_STA_POWERSAVE_PARAM_CMDID, - WMI_10X_STA_MIMO_PS_MODE_CMDID, - - /* set debug log config */ - WMI_10X_DBGLOG_CFG_CMDID, - - /* DFS-specific commands */ - WMI_10X_PDEV_DFS_ENABLE_CMDID, - WMI_10X_PDEV_DFS_DISABLE_CMDID, - - /* QVIT specific command id */ - WMI_10X_PDEV_QVIT_CMDID, - - /* Offload Scan and Roaming related commands */ - WMI_10X_ROAM_SCAN_MODE, - WMI_10X_ROAM_SCAN_RSSI_THRESHOLD, - WMI_10X_ROAM_SCAN_PERIOD, - WMI_10X_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, - WMI_10X_ROAM_AP_PROFILE, - WMI_10X_OFL_SCAN_ADD_AP_PROFILE, - WMI_10X_OFL_SCAN_REMOVE_AP_PROFILE, - WMI_10X_OFL_SCAN_PERIOD, - - /* P2P specific commands */ - WMI_10X_P2P_DEV_SET_DEVICE_INFO, - WMI_10X_P2P_DEV_SET_DISCOVERABILITY, - WMI_10X_P2P_GO_SET_BEACON_IE, - WMI_10X_P2P_GO_SET_PROBE_RESP_IE, - - /* AP power save specific config */ - WMI_10X_AP_PS_PEER_PARAM_CMDID, - WMI_10X_AP_PS_PEER_UAPSD_COEX_CMDID, - - /* Rate-control specific commands */ - WMI_10X_PEER_RATE_RETRY_SCHED_CMDID, - - /* WLAN Profiling commands. */ - WMI_10X_WLAN_PROFILE_TRIGGER_CMDID, - WMI_10X_WLAN_PROFILE_SET_HIST_INTVL_CMDID, - WMI_10X_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, - WMI_10X_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, - WMI_10X_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, - - /* Suspend resume command Ids */ - WMI_10X_PDEV_SUSPEND_CMDID, - WMI_10X_PDEV_RESUME_CMDID, - - /* Beacon filter commands */ - WMI_10X_ADD_BCN_FILTER_CMDID, - WMI_10X_RMV_BCN_FILTER_CMDID, - - /* WOW Specific WMI commands*/ - WMI_10X_WOW_ADD_WAKE_PATTERN_CMDID, - WMI_10X_WOW_DEL_WAKE_PATTERN_CMDID, - WMI_10X_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, - WMI_10X_WOW_ENABLE_CMDID, - WMI_10X_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, - - /* RTT measurement related cmd */ - WMI_10X_RTT_MEASREQ_CMDID, - WMI_10X_RTT_TSF_CMDID, - - /* transmit beacon by value */ - WMI_10X_PDEV_SEND_BCN_CMDID, - - /* F/W stats */ - WMI_10X_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, - WMI_10X_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, - WMI_10X_REQUEST_STATS_CMDID, - - /* GPIO Configuration */ - WMI_10X_GPIO_CONFIG_CMDID, - WMI_10X_GPIO_OUTPUT_CMDID, - - WMI_10X_PDEV_UTF_CMDID = WMI_10X_END_CMDID - 1, -}; - -enum wmi_10x_event_id { - WMI_10X_SERVICE_READY_EVENTID = 0x8000, - WMI_10X_READY_EVENTID, - WMI_10X_START_EVENTID = 0x9000, - WMI_10X_END_EVENTID = 0x9FFF, - - /* Scan specific events */ - WMI_10X_SCAN_EVENTID = WMI_10X_START_EVENTID, - WMI_10X_ECHO_EVENTID, - WMI_10X_DEBUG_MESG_EVENTID, - WMI_10X_UPDATE_STATS_EVENTID, - - /* Instantaneous RSSI event */ - WMI_10X_INST_RSSI_STATS_EVENTID, - - /* VDEV specific events */ - WMI_10X_VDEV_START_RESP_EVENTID, - WMI_10X_VDEV_STANDBY_REQ_EVENTID, - WMI_10X_VDEV_RESUME_REQ_EVENTID, - WMI_10X_VDEV_STOPPED_EVENTID, - - /* peer specific events */ - WMI_10X_PEER_STA_KICKOUT_EVENTID, - - /* beacon/mgmt specific events */ - WMI_10X_HOST_SWBA_EVENTID, - WMI_10X_TBTTOFFSET_UPDATE_EVENTID, - WMI_10X_MGMT_RX_EVENTID, - - /* Channel stats event */ - WMI_10X_CHAN_INFO_EVENTID, - - /* PHY Error specific WMI event */ - WMI_10X_PHYERR_EVENTID, - - /* Roam event to trigger roaming on host */ - WMI_10X_ROAM_EVENTID, - - /* matching AP found from list of profiles */ - WMI_10X_PROFILE_MATCH, - - /* debug print message used for tracing FW code while debugging */ - WMI_10X_DEBUG_PRINT_EVENTID, - /* VI spoecific event */ - WMI_10X_PDEV_QVIT_EVENTID, - /* FW code profile data in response to profile request */ - WMI_10X_WLAN_PROFILE_DATA_EVENTID, - - /*RTT related event ID*/ - WMI_10X_RTT_MEASUREMENT_REPORT_EVENTID, - WMI_10X_TSF_MEASUREMENT_REPORT_EVENTID, - WMI_10X_RTT_ERROR_REPORT_EVENTID, - - WMI_10X_WOW_WAKEUP_HOST_EVENTID, - WMI_10X_DCS_INTERFERENCE_EVENTID, - - /* TPC config for the current operating channel */ - WMI_10X_PDEV_TPC_CONFIG_EVENTID, - - WMI_10X_GPIO_INPUT_EVENTID, - WMI_10X_PDEV_UTF_EVENTID = WMI_10X_END_EVENTID-1, -}; - enum wmi_phy_mode { MODE_11A = 0, /* 11a Mode */ MODE_11G = 1, /* 11b/g Mode */ @@ -833,48 +508,6 @@ enum wmi_phy_mode { MODE_MAX = 14 }; -static inline const char *ath10k_wmi_phymode_str(enum wmi_phy_mode mode) -{ - switch (mode) { - case MODE_11A: - return "11a"; - case MODE_11G: - return "11g"; - case MODE_11B: - return "11b"; - case MODE_11GONLY: - return "11gonly"; - case MODE_11NA_HT20: - return "11na-ht20"; - case MODE_11NG_HT20: - return "11ng-ht20"; - case MODE_11NA_HT40: - return "11na-ht40"; - case MODE_11NG_HT40: - return "11ng-ht40"; - case MODE_11AC_VHT20: - return "11ac-vht20"; - case MODE_11AC_VHT40: - return "11ac-vht40"; - case MODE_11AC_VHT80: - return "11ac-vht80"; - case MODE_11AC_VHT20_2G: - return "11ac-vht20-2g"; - case MODE_11AC_VHT40_2G: - return "11ac-vht40-2g"; - case MODE_11AC_VHT80_2G: - return "11ac-vht80-2g"; - case MODE_UNKNOWN: - /* skip */ - break; - - /* no default handler to allow compiler to check that the - * enum is fully handled */ - }; - - return "<unknown>"; -} - #define WMI_CHAN_LIST_TAG 0x1 #define WMI_SSID_LIST_TAG 0x2 #define WMI_BSSID_LIST_TAG 0x3 @@ -1130,45 +763,13 @@ struct wmi_service_ready_event { struct wlan_host_mem_req mem_reqs[1]; } __packed; -/* This is the definition from 10.X firmware branch */ -struct wmi_service_ready_event_10x { - __le32 sw_version; - __le32 abi_version; - - /* WMI_PHY_CAPABILITY */ - __le32 phy_capability; - - /* Maximum number of frag table entries that SW will populate less 1 */ - __le32 max_frag_entry; - __le32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE]; - __le32 num_rf_chains; - - /* - * The following field is only valid for service type - * WMI_SERVICE_11AC - */ - __le32 ht_cap_info; /* WMI HT Capability */ - __le32 vht_cap_info; /* VHT capability info field of 802.11ac */ - __le32 vht_supp_mcs; /* VHT Supported MCS Set field Rx/Tx same */ - __le32 hw_min_tx_power; - __le32 hw_max_tx_power; - - struct hal_reg_capabilities hal_reg_capabilities; - - __le32 sys_cap_info; - __le32 min_pkt_size_enable; /* Enterprise mode short pkt enable */ - - /* - * request to host to allocate a chuck of memory and pss it down to FW - * via WM_INIT. FW uses this as FW extesnsion memory for saving its - * data structures. Only valid for low latency interfaces like PCIE - * where FW can access this memory directly (or) by DMA. - */ - __le32 num_mem_reqs; - - struct wlan_host_mem_req mem_reqs[1]; -} __packed; - +/* + * status consists of upper 16 bits fo int status and lower 16 bits of + * module ID that retuned status + */ +#define WLAN_INIT_STATUS_SUCCESS 0x0 +#define WLAN_GET_INIT_STATUS_REASON(status) ((status) & 0xffff) +#define WLAN_GET_INIT_STATUS_MODULE_ID(status) (((status) >> 16) & 0xffff) #define WMI_SERVICE_READY_TIMEOUT_HZ (5*HZ) #define WMI_UNIFIED_READY_TIMEOUT_HZ (5*HZ) @@ -1377,192 +978,6 @@ struct wmi_resource_config { __le32 max_frag_entries; } __packed; -struct wmi_resource_config_10x { - /* number of virtual devices (VAPs) to support */ - __le32 num_vdevs; - - /* number of peer nodes to support */ - __le32 num_peers; - - /* number of keys per peer */ - __le32 num_peer_keys; - - /* total number of TX/RX data TIDs */ - __le32 num_tids; - - /* - * max skid for resolving hash collisions - * - * The address search table is sparse, so that if two MAC addresses - * result in the same hash value, the second of these conflicting - * entries can slide to the next index in the address search table, - * and use it, if it is unoccupied. This ast_skid_limit parameter - * specifies the upper bound on how many subsequent indices to search - * over to find an unoccupied space. - */ - __le32 ast_skid_limit; - - /* - * the nominal chain mask for transmit - * - * The chain mask may be modified dynamically, e.g. to operate AP - * tx with a reduced number of chains if no clients are associated. - * This configuration parameter specifies the nominal chain-mask that - * should be used when not operating with a reduced set of tx chains. - */ - __le32 tx_chain_mask; - - /* - * the nominal chain mask for receive - * - * The chain mask may be modified dynamically, e.g. for a client - * to use a reduced number of chains for receive if the traffic to - * the client is low enough that it doesn't require downlink MIMO - * or antenna diversity. - * This configuration parameter specifies the nominal chain-mask that - * should be used when not operating with a reduced set of rx chains. - */ - __le32 rx_chain_mask; - - /* - * what rx reorder timeout (ms) to use for the AC - * - * Each WMM access class (voice, video, best-effort, background) will - * have its own timeout value to dictate how long to wait for missing - * rx MPDUs to arrive before flushing subsequent MPDUs that have - * already been received. - * This parameter specifies the timeout in milliseconds for each - * class. - */ - __le32 rx_timeout_pri_vi; - __le32 rx_timeout_pri_vo; - __le32 rx_timeout_pri_be; - __le32 rx_timeout_pri_bk; - - /* - * what mode the rx should decap packets to - * - * MAC can decap to RAW (no decap), native wifi or Ethernet types - * THis setting also determines the default TX behavior, however TX - * behavior can be modified on a per VAP basis during VAP init - */ - __le32 rx_decap_mode; - - /* what is the maximum scan requests than can be queued */ - __le32 scan_max_pending_reqs; - - /* maximum VDEV that could use BMISS offload */ - __le32 bmiss_offload_max_vdev; - - /* maximum VDEV that could use offload roaming */ - __le32 roam_offload_max_vdev; - - /* maximum AP profiles that would push to offload roaming */ - __le32 roam_offload_max_ap_profiles; - - /* - * how many groups to use for mcast->ucast conversion - * - * The target's WAL maintains a table to hold information regarding - * which peers belong to a given multicast group, so that if - * multicast->unicast conversion is enabled, the target can convert - * multicast tx frames to a series of unicast tx frames, to each - * peer within the multicast group. - This num_mcast_groups configuration parameter tells the target how - * many multicast groups to provide storage for within its multicast - * group membership table. - */ - __le32 num_mcast_groups; - - /* - * size to alloc for the mcast membership table - * - * This num_mcast_table_elems configuration parameter tells the - * target how many peer elements it needs to provide storage for in - * its multicast group membership table. - * These multicast group membership table elements are shared by the - * multicast groups stored within the table. - */ - __le32 num_mcast_table_elems; - - /* - * whether/how to do multicast->unicast conversion - * - * This configuration parameter specifies whether the target should - * perform multicast --> unicast conversion on transmit, and if so, - * what to do if it finds no entries in its multicast group - * membership table for the multicast IP address in the tx frame. - * Configuration value: - * 0 -> Do not perform multicast to unicast conversion. - * 1 -> Convert multicast frames to unicast, if the IP multicast - * address from the tx frame is found in the multicast group - * membership table. If the IP multicast address is not found, - * drop the frame. - * 2 -> Convert multicast frames to unicast, if the IP multicast - * address from the tx frame is found in the multicast group - * membership table. If the IP multicast address is not found, - * transmit the frame as multicast. - */ - __le32 mcast2ucast_mode; - - /* - * how much memory to allocate for a tx PPDU dbg log - * - * This parameter controls how much memory the target will allocate - * to store a log of tx PPDU meta-information (how large the PPDU - * was, when it was sent, whether it was successful, etc.) - */ - __le32 tx_dbg_log_size; - - /* how many AST entries to be allocated for WDS */ - __le32 num_wds_entries; - - /* - * MAC DMA burst size, e.g., For target PCI limit can be - * 0 -default, 1 256B - */ - __le32 dma_burst_size; - - /* - * Fixed delimiters to be inserted after every MPDU to - * account for interface latency to avoid underrun. - */ - __le32 mac_aggr_delim; - - /* - * determine whether target is responsible for detecting duplicate - * non-aggregate MPDU and timing out stale fragments. - * - * A-MPDU reordering is always performed on the target. - * - * 0: target responsible for frag timeout and dup checking - * 1: host responsible for frag timeout and dup checking - */ - __le32 rx_skip_defrag_timeout_dup_detection_check; - - /* - * Configuration for VoW : - * No of Video Nodes to be supported - * and Max no of descriptors for each Video link (node). - */ - __le32 vow_config; - - /* Number of msdu descriptors target should use */ - __le32 num_msdu_desc; - - /* - * Max. number of Tx fragments per MSDU - * This parameter controls the max number of Tx fragments per MSDU. - * This is sent by the target as part of the WMI_SERVICE_READY event - * and is overriden by the OS shim as required. - */ - __le32 max_frag_entries; -} __packed; - - -#define NUM_UNITS_IS_NUM_VDEVS 0x1 -#define NUM_UNITS_IS_NUM_PEERS 0x2 - /* strucutre describing host memory chunk. */ struct host_memory_chunk { /* id of the request that is passed up in service ready */ @@ -1584,18 +999,6 @@ struct wmi_init_cmd { struct host_memory_chunk host_mem_chunks[1]; } __packed; -/* _10x stucture is from 10.X FW API */ -struct wmi_init_cmd_10x { - struct wmi_resource_config_10x resource_config; - __le32 num_host_mem_chunks; - - /* - * variable number of host memory chunks. - * This should be the last element in the structure - */ - struct host_memory_chunk host_mem_chunks[1]; -} __packed; - /* TLV for channel list */ struct wmi_chan_list { __le32 tag; /* WMI_CHAN_LIST_TAG */ @@ -1715,88 +1118,6 @@ struct wmi_start_scan_cmd { */ } __packed; -/* This is the definition from 10.X firmware branch */ -struct wmi_start_scan_cmd_10x { - /* Scan ID */ - __le32 scan_id; - - /* Scan requestor ID */ - __le32 scan_req_id; - - /* VDEV id(interface) that is requesting scan */ - __le32 vdev_id; - - /* Scan Priority, input to scan scheduler */ - __le32 scan_priority; - - /* Scan events subscription */ - __le32 notify_scan_events; - - /* dwell time in msec on active channels */ - __le32 dwell_time_active; - - /* dwell time in msec on passive channels */ - __le32 dwell_time_passive; - - /* - * min time in msec on the BSS channel,only valid if atleast one - * VDEV is active - */ - __le32 min_rest_time; - - /* - * max rest time in msec on the BSS channel,only valid if at least - * one VDEV is active - */ - /* - * the scanner will rest on the bss channel at least min_rest_time - * after min_rest_time the scanner will start checking for tx/rx - * activity on all VDEVs. if there is no activity the scanner will - * switch to off channel. if there is activity the scanner will let - * the radio on the bss channel until max_rest_time expires.at - * max_rest_time scanner will switch to off channel irrespective of - * activity. activity is determined by the idle_time parameter. - */ - __le32 max_rest_time; - - /* - * time before sending next set of probe requests. - * The scanner keeps repeating probe requests transmission with - * period specified by repeat_probe_time. - * The number of probe requests specified depends on the ssid_list - * and bssid_list - */ - __le32 repeat_probe_time; - - /* time in msec between 2 consequetive probe requests with in a set. */ - __le32 probe_spacing_time; - - /* - * data inactivity time in msec on bss channel that will be used by - * scanner for measuring the inactivity. - */ - __le32 idle_time; - - /* maximum time in msec allowed for scan */ - __le32 max_scan_time; - - /* - * delay in msec before sending first probe request after switching - * to a channel - */ - __le32 probe_delay; - - /* Scan control flags */ - __le32 scan_ctrl_flags; - - /* - * TLV (tag length value ) paramerters follow the scan_cmd structure. - * TLV can contain channel list, bssid list, ssid list and - * ie. the TLV tags are defined above; - */ -} __packed; - - struct wmi_ssid_arg { int len; const u8 *ssid; @@ -1947,7 +1268,7 @@ struct wmi_scan_event { * good idea to pass all the fields in the RX status * descriptor up to the host. */ -struct wmi_mgmt_rx_hdr_v1 { +struct wmi_mgmt_rx_hdr { __le32 channel; __le32 snr; __le32 rate; @@ -1956,18 +1277,8 @@ struct wmi_mgmt_rx_hdr_v1 { __le32 status; /* %WMI_RX_STATUS_ */ } __packed; -struct wmi_mgmt_rx_hdr_v2 { - struct wmi_mgmt_rx_hdr_v1 v1; - __le32 rssi_ctl[4]; -} __packed; - -struct wmi_mgmt_rx_event_v1 { - struct wmi_mgmt_rx_hdr_v1 hdr; - u8 buf[0]; -} __packed; - -struct wmi_mgmt_rx_event_v2 { - struct wmi_mgmt_rx_hdr_v2 hdr; +struct wmi_mgmt_rx_event { + struct wmi_mgmt_rx_hdr hdr; u8 buf[0]; } __packed; @@ -2154,60 +1465,6 @@ struct wmi_csa_event { #define VDEV_DEFAULT_STATS_UPDATE_PERIOD 500 #define PEER_DEFAULT_STATS_UPDATE_PERIOD 500 -struct wmi_pdev_param_map { - u32 tx_chain_mask; - u32 rx_chain_mask; - u32 txpower_limit2g; - u32 txpower_limit5g; - u32 txpower_scale; - u32 beacon_gen_mode; - u32 beacon_tx_mode; - u32 resmgr_offchan_mode; - u32 protection_mode; - u32 dynamic_bw; - u32 non_agg_sw_retry_th; - u32 agg_sw_retry_th; - u32 sta_kickout_th; - u32 ac_aggrsize_scaling; - u32 ltr_enable; - u32 ltr_ac_latency_be; - u32 ltr_ac_latency_bk; - u32 ltr_ac_latency_vi; - u32 ltr_ac_latency_vo; - u32 ltr_ac_latency_timeout; - u32 ltr_sleep_override; - u32 ltr_rx_override; - u32 ltr_tx_activity_timeout; - u32 l1ss_enable; - u32 dsleep_enable; - u32 pcielp_txbuf_flush; - u32 pcielp_txbuf_watermark; - u32 pcielp_txbuf_tmo_en; - u32 pcielp_txbuf_tmo_value; - u32 pdev_stats_update_period; - u32 vdev_stats_update_period; - u32 peer_stats_update_period; - u32 bcnflt_stats_update_period; - u32 pmf_qos; - u32 arp_ac_override; - u32 arpdhcp_ac_override; - u32 dcs; - u32 ani_enable; - u32 ani_poll_period; - u32 ani_listen_period; - u32 ani_ofdm_level; - u32 ani_cck_level; - u32 dyntxchain; - u32 proxy_sta; - u32 idle_ps_config; - u32 power_gating_sleep; - u32 fast_channel_reset; - u32 burst_dur; - u32 burst_enable; -}; - -#define WMI_PDEV_PARAM_UNSUPPORTED 0 - enum wmi_pdev_param { /* TX chian mask */ WMI_PDEV_PARAM_TX_CHAIN_MASK = 0x1, @@ -2307,97 +1564,6 @@ enum wmi_pdev_param { WMI_PDEV_PARAM_POWER_GATING_SLEEP, }; -enum wmi_10x_pdev_param { - /* TX chian mask */ - WMI_10X_PDEV_PARAM_TX_CHAIN_MASK = 0x1, - /* RX chian mask */ - WMI_10X_PDEV_PARAM_RX_CHAIN_MASK, - /* TX power limit for 2G Radio */ - WMI_10X_PDEV_PARAM_TXPOWER_LIMIT2G, - /* TX power limit for 5G Radio */ - WMI_10X_PDEV_PARAM_TXPOWER_LIMIT5G, - /* TX power scale */ - WMI_10X_PDEV_PARAM_TXPOWER_SCALE, - /* Beacon generation mode . 0: host, 1: target */ - WMI_10X_PDEV_PARAM_BEACON_GEN_MODE, - /* Beacon generation mode . 0: staggered 1: bursted */ - WMI_10X_PDEV_PARAM_BEACON_TX_MODE, - /* - * Resource manager off chan mode . - * 0: turn off off chan mode. 1: turn on offchan mode - */ - WMI_10X_PDEV_PARAM_RESMGR_OFFCHAN_MODE, - /* - * Protection mode: - * 0: no protection 1:use CTS-to-self 2: use RTS/CTS - */ - WMI_10X_PDEV_PARAM_PROTECTION_MODE, - /* Dynamic bandwidth 0: disable 1: enable */ - WMI_10X_PDEV_PARAM_DYNAMIC_BW, - /* Non aggregrate/ 11g sw retry threshold.0-disable */ - WMI_10X_PDEV_PARAM_NON_AGG_SW_RETRY_TH, - /* aggregrate sw retry threshold. 0-disable*/ - WMI_10X_PDEV_PARAM_AGG_SW_RETRY_TH, - /* Station kickout threshold (non of consecutive failures).0-disable */ - WMI_10X_PDEV_PARAM_STA_KICKOUT_TH, - /* Aggerate size scaling configuration per AC */ - WMI_10X_PDEV_PARAM_AC_AGGRSIZE_SCALING, - /* LTR enable */ - WMI_10X_PDEV_PARAM_LTR_ENABLE, - /* LTR latency for BE, in us */ - WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BE, - /* LTR latency for BK, in us */ - WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BK, - /* LTR latency for VI, in us */ - WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VI, - /* LTR latency for VO, in us */ - WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VO, - /* LTR AC latency timeout, in ms */ - WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, - /* LTR platform latency override, in us */ - WMI_10X_PDEV_PARAM_LTR_SLEEP_OVERRIDE, - /* LTR-RX override, in us */ - WMI_10X_PDEV_PARAM_LTR_RX_OVERRIDE, - /* Tx activity timeout for LTR, in us */ - WMI_10X_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, - /* L1SS state machine enable */ - WMI_10X_PDEV_PARAM_L1SS_ENABLE, - /* Deep sleep state machine enable */ - WMI_10X_PDEV_PARAM_DSLEEP_ENABLE, - /* pdev level stats update period in ms */ - WMI_10X_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, - /* vdev level stats update period in ms */ - WMI_10X_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, - /* peer level stats update period in ms */ - WMI_10X_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, - /* beacon filter status update period */ - WMI_10X_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, - /* QOS Mgmt frame protection MFP/PMF 0: disable, 1: enable */ - WMI_10X_PDEV_PARAM_PMF_QOS, - /* Access category on which ARP and DHCP frames are sent */ - WMI_10X_PDEV_PARAM_ARPDHCP_AC_OVERRIDE, - /* DCS configuration */ - WMI_10X_PDEV_PARAM_DCS, - /* Enable/Disable ANI on target */ - WMI_10X_PDEV_PARAM_ANI_ENABLE, - /* configure the ANI polling period */ - WMI_10X_PDEV_PARAM_ANI_POLL_PERIOD, - /* configure the ANI listening period */ - WMI_10X_PDEV_PARAM_ANI_LISTEN_PERIOD, - /* configure OFDM immunity level */ - WMI_10X_PDEV_PARAM_ANI_OFDM_LEVEL, - /* configure CCK immunity level */ - WMI_10X_PDEV_PARAM_ANI_CCK_LEVEL, - /* Enable/Disable CDD for 1x1 STAs in rate control module */ - WMI_10X_PDEV_PARAM_DYNTXCHAIN, - /* Enable/Disable Fast channel reset*/ - WMI_10X_PDEV_PARAM_FAST_CHANNEL_RESET, - /* Set Bursting DUR */ - WMI_10X_PDEV_PARAM_BURST_DUR, - /* Set Bursting Enable*/ - WMI_10X_PDEV_PARAM_BURST_ENABLE, -}; - struct wmi_pdev_set_param_cmd { __le32 param_id; __le32 param_value; @@ -2922,61 +2088,6 @@ enum wmi_rate_preamble { /* Value to disable fixed rate setting */ #define WMI_FIXED_RATE_NONE (0xff) -struct wmi_vdev_param_map { - u32 rts_threshold; - u32 fragmentation_threshold; - u32 beacon_interval; - u32 listen_interval; - u32 multicast_rate; - u32 mgmt_tx_rate; - u32 slot_time; - u32 preamble; - u32 swba_time; - u32 wmi_vdev_stats_update_period; - u32 wmi_vdev_pwrsave_ageout_time; - u32 wmi_vdev_host_swba_interval; - u32 dtim_period; - u32 wmi_vdev_oc_scheduler_air_time_limit; - u32 wds; - u32 atim_window; - u32 bmiss_count_max; - u32 bmiss_first_bcnt; - u32 bmiss_final_bcnt; - u32 feature_wmm; - u32 chwidth; - u32 chextoffset; - u32 disable_htprotection; - u32 sta_quickkickout; - u32 mgmt_rate; - u32 protection_mode; - u32 fixed_rate; - u32 sgi; - u32 ldpc; - u32 tx_stbc; - u32 rx_stbc; - u32 intra_bss_fwd; - u32 def_keyid; - u32 nss; - u32 bcast_data_rate; - u32 mcast_data_rate; - u32 mcast_indicate; - u32 dhcp_indicate; - u32 unknown_dest_indicate; - u32 ap_keepalive_min_idle_inactive_time_secs; - u32 ap_keepalive_max_idle_inactive_time_secs; - u32 ap_keepalive_max_unresponsive_time_secs; - u32 ap_enable_nawds; - u32 mcast2ucast_set; - u32 enable_rtscts; - u32 txbf; - u32 packet_powersave; - u32 drop_unencry; - u32 tx_encap_type; - u32 ap_detect_out_of_sync_sleeping_sta_time_secs; -}; - -#define WMI_VDEV_PARAM_UNSUPPORTED 0 - /* the definition of different VDEV parameters */ enum wmi_vdev_param { /* RTS Threshold */ @@ -3108,121 +2219,6 @@ enum wmi_vdev_param { WMI_VDEV_PARAM_TX_ENCAP_TYPE, }; -/* the definition of different VDEV parameters */ -enum wmi_10x_vdev_param { - /* RTS Threshold */ - WMI_10X_VDEV_PARAM_RTS_THRESHOLD = 0x1, - /* Fragmentation threshold */ - WMI_10X_VDEV_PARAM_FRAGMENTATION_THRESHOLD, - /* beacon interval in TUs */ - WMI_10X_VDEV_PARAM_BEACON_INTERVAL, - /* Listen interval in TUs */ - WMI_10X_VDEV_PARAM_LISTEN_INTERVAL, - /* muticast rate in Mbps */ - WMI_10X_VDEV_PARAM_MULTICAST_RATE, - /* management frame rate in Mbps */ - WMI_10X_VDEV_PARAM_MGMT_TX_RATE, - /* slot time (long vs short) */ - WMI_10X_VDEV_PARAM_SLOT_TIME, - /* preamble (long vs short) */ - WMI_10X_VDEV_PARAM_PREAMBLE, - /* SWBA time (time before tbtt in msec) */ - WMI_10X_VDEV_PARAM_SWBA_TIME, - /* time period for updating VDEV stats */ - WMI_10X_VDEV_STATS_UPDATE_PERIOD, - /* age out time in msec for frames queued for station in power save */ - WMI_10X_VDEV_PWRSAVE_AGEOUT_TIME, - /* - * Host SWBA interval (time in msec before tbtt for SWBA event - * generation). - */ - WMI_10X_VDEV_HOST_SWBA_INTERVAL, - /* DTIM period (specified in units of num beacon intervals) */ - WMI_10X_VDEV_PARAM_DTIM_PERIOD, - /* - * scheduler air time limit for this VDEV. used by off chan - * scheduler. - */ - WMI_10X_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, - /* enable/dsiable WDS for this VDEV */ - WMI_10X_VDEV_PARAM_WDS, - /* ATIM Window */ - WMI_10X_VDEV_PARAM_ATIM_WINDOW, - /* BMISS max */ - WMI_10X_VDEV_PARAM_BMISS_COUNT_MAX, - /* WMM enables/disabled */ - WMI_10X_VDEV_PARAM_FEATURE_WMM, - /* Channel width */ - WMI_10X_VDEV_PARAM_CHWIDTH, - /* Channel Offset */ - WMI_10X_VDEV_PARAM_CHEXTOFFSET, - /* Disable HT Protection */ - WMI_10X_VDEV_PARAM_DISABLE_HTPROTECTION, - /* Quick STA Kickout */ - WMI_10X_VDEV_PARAM_STA_QUICKKICKOUT, - /* Rate to be used with Management frames */ - WMI_10X_VDEV_PARAM_MGMT_RATE, - /* Protection Mode */ - WMI_10X_VDEV_PARAM_PROTECTION_MODE, - /* Fixed rate setting */ - WMI_10X_VDEV_PARAM_FIXED_RATE, - /* Short GI Enable/Disable */ - WMI_10X_VDEV_PARAM_SGI, - /* Enable LDPC */ - WMI_10X_VDEV_PARAM_LDPC, - /* Enable Tx STBC */ - WMI_10X_VDEV_PARAM_TX_STBC, - /* Enable Rx STBC */ - WMI_10X_VDEV_PARAM_RX_STBC, - /* Intra BSS forwarding */ - WMI_10X_VDEV_PARAM_INTRA_BSS_FWD, - /* Setting Default xmit key for Vdev */ - WMI_10X_VDEV_PARAM_DEF_KEYID, - /* NSS width */ - WMI_10X_VDEV_PARAM_NSS, - /* Set the custom rate for the broadcast data frames */ - WMI_10X_VDEV_PARAM_BCAST_DATA_RATE, - /* Set the custom rate (rate-code) for multicast data frames */ - WMI_10X_VDEV_PARAM_MCAST_DATA_RATE, - /* Tx multicast packet indicate Enable/Disable */ - WMI_10X_VDEV_PARAM_MCAST_INDICATE, - /* Tx DHCP packet indicate Enable/Disable */ - WMI_10X_VDEV_PARAM_DHCP_INDICATE, - /* Enable host inspection of Tx unicast packet to unknown destination */ - WMI_10X_VDEV_PARAM_UNKNOWN_DEST_INDICATE, - - /* The minimum amount of time AP begins to consider STA inactive */ - WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, - - /* - * An associated STA is considered inactive when there is no recent - * TX/RX activity and no downlink frames are buffered for it. Once a - * STA exceeds the maximum idle inactive time, the AP will send an - * 802.11 data-null as a keep alive to verify the STA is still - * associated. If the STA does ACK the data-null, or if the data-null - * is buffered and the STA does not retrieve it, the STA will be - * considered unresponsive - * (see WMI_10X_VDEV_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS). - */ - WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, - - /* - * An associated STA is considered unresponsive if there is no recent - * TX/RX activity and downlink frames are buffered for it. Once a STA - * exceeds the maximum unresponsive time, the AP will send a - * WMI_10X_STA_KICKOUT event to the host so the STA can be deleted. */ - WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, - - /* Enable NAWDS : MCAST INSPECT Enable, NAWDS Flag set */ - WMI_10X_VDEV_PARAM_AP_ENABLE_NAWDS, - - WMI_10X_VDEV_PARAM_MCAST2UCAST_SET, - /* Enable/Disable RTS-CTS */ - WMI_10X_VDEV_PARAM_ENABLE_RTSCTS, - - WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, -}; - /* slot time long */ #define WMI_VDEV_SLOT_TIME_LONG 0x1 /* slot time short */ @@ -4004,6 +3000,7 @@ struct wmi_force_fw_hang_cmd { #define WMI_MAX_EVENT 0x1000 /* Maximum number of pending TXed WMI packets */ +#define WMI_MAX_PENDING_TX_COUNT 128 #define WMI_SKB_HEADROOM sizeof(struct wmi_cmd_hdr) /* By default disable power save for IBSS */ @@ -4016,6 +3013,7 @@ int ath10k_wmi_attach(struct ath10k *ar); void ath10k_wmi_detach(struct ath10k *ar); int ath10k_wmi_wait_for_service_ready(struct ath10k *ar); int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar); +void ath10k_wmi_flush_tx(struct ath10k *ar); int ath10k_wmi_connect_htc_service(struct ath10k *ar); int ath10k_wmi_pdev_set_channel(struct ath10k *ar, @@ -4024,7 +3022,8 @@ int ath10k_wmi_pdev_suspend_target(struct ath10k *ar); int ath10k_wmi_pdev_resume_target(struct ath10k *ar); int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g, u16 rd5g, u16 ctl2g, u16 ctl5g); -int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value); +int ath10k_wmi_pdev_set_param(struct ath10k *ar, enum wmi_pdev_param id, + u32 value); int ath10k_wmi_cmd_init(struct ath10k *ar); int ath10k_wmi_start_scan(struct ath10k *ar, const struct wmi_start_scan_arg *); void ath10k_wmi_start_scan_init(struct ath10k *ar, struct wmi_start_scan_arg *); @@ -4044,7 +3043,7 @@ int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid); int ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id); int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, - u32 param_id, u32 param_value); + enum wmi_vdev_param param_id, u32 param_value); int ath10k_wmi_vdev_install_key(struct ath10k *ar, const struct wmi_vdev_install_key_arg *arg); int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, @@ -4067,13 +3066,11 @@ int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac, enum wmi_ap_ps_peer_param param_id, u32 value); int ath10k_wmi_scan_chan_list(struct ath10k *ar, const struct wmi_scan_chan_list_arg *arg); -int ath10k_wmi_beacon_send_nowait(struct ath10k *ar, - const struct wmi_bcn_tx_arg *arg); +int ath10k_wmi_beacon_send(struct ath10k *ar, const struct wmi_bcn_tx_arg *arg); int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, const struct wmi_pdev_set_wmm_params_arg *arg); int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id); int ath10k_wmi_force_fw_hang(struct ath10k *ar, enum wmi_force_fw_hang_type type, u32 delay_ms); -int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb); #endif /* _WMI_H_ */ diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index 79bffe1..e9bc9e6 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c @@ -37,9 +37,12 @@ ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) { struct ath5k_hw *ah = common->priv; struct platform_device *pdev = to_platform_device(ah->dev); - struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); + struct ar231x_board_config *bcfg = pdev->dev.platform_data; u16 *eeprom, *eeprom_end; + + + bcfg = pdev->dev.platform_data; eeprom = (u16 *) bcfg->radio; eeprom_end = ((void *) bcfg->config) + BOARD_CONFIG_BUFSZ; @@ -54,7 +57,7 @@ ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) int ath5k_hw_read_srev(struct ath5k_hw *ah) { struct platform_device *pdev = to_platform_device(ah->dev); - struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); + struct ar231x_board_config *bcfg = pdev->dev.platform_data; ah->ah_mac_srev = bcfg->devid; return 0; } @@ -62,7 +65,7 @@ int ath5k_hw_read_srev(struct ath5k_hw *ah) static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) { struct platform_device *pdev = to_platform_device(ah->dev); - struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); + struct ar231x_board_config *bcfg = pdev->dev.platform_data; u8 *cfg_mac; if (to_platform_device(ah->dev)->id == 0) @@ -84,7 +87,7 @@ static const struct ath_bus_ops ath_ahb_bus_ops = { /*Initialization*/ static int ath_ahb_probe(struct platform_device *pdev) { - struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); + struct ar231x_board_config *bcfg = pdev->dev.platform_data; struct ath5k_hw *ah; struct ieee80211_hw *hw; struct resource *res; @@ -93,7 +96,7 @@ static int ath_ahb_probe(struct platform_device *pdev) int ret = 0; u32 reg; - if (!dev_get_platdata(&pdev->dev)) { + if (!pdev->dev.platform_data) { dev_err(&pdev->dev, "no platform data specified\n"); ret = -EINVAL; goto err_out; @@ -190,7 +193,7 @@ static int ath_ahb_probe(struct platform_device *pdev) static int ath_ahb_remove(struct platform_device *pdev) { - struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev); + struct ar231x_board_config *bcfg = pdev->dev.platform_data; struct ieee80211_hw *hw = platform_get_drvdata(pdev); struct ath5k_hw *ah; u32 reg; diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 69f58b0..48161ed 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -1663,15 +1663,15 @@ ath5k_tx_frame_completed(struct ath5k_hw *ah, struct sk_buff *skb, ah->stats.tx_bytes_count += skb->len; info = IEEE80211_SKB_CB(skb); - size = min_t(int, sizeof(info->status.rates), sizeof(bf->rates)); - memcpy(info->status.rates, bf->rates, size); - tries[0] = info->status.rates[0].count; tries[1] = info->status.rates[1].count; tries[2] = info->status.rates[2].count; ieee80211_tx_info_clear_status(info); + size = min_t(int, sizeof(info->status.rates), sizeof(bf->rates)); + memcpy(info->status.rates, bf->rates, size); + for (i = 0; i < ts->ts_final_idx; i++) { struct ieee80211_tx_rate *r = &info->status.rates[i]; diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c index ba200b2..ce86f15 100644 --- a/drivers/net/wireless/ath/ath5k/dma.c +++ b/drivers/net/wireless/ath/ath5k/dma.c @@ -661,7 +661,7 @@ ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask) ah->ah_txq_isr_txok_all |= AR5K_REG_MS(sisr1, AR5K_SISR1_QCU_TXEOL); - /* Currently this is not much useful since we treat + /* Currently this is not much usefull since we treat * all queues the same way if we get a TXURN (update * tx trigger level) but we might need it later on*/ if (pisr & AR5K_ISR_TXURN) diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h index 05debf7..98a8861 100644 --- a/drivers/net/wireless/ath/ath6kl/common.h +++ b/drivers/net/wireless/ath/ath6kl/common.h @@ -22,7 +22,8 @@ #define ATH6KL_MAX_IE 256 -__printf(2, 3) int ath6kl_printk(const char *level, const char *fmt, ...); +extern __printf(2, 3) +int ath6kl_printk(const char *level, const char *fmt, ...); /* * Reflects the version of binary interface exposed by ATH6KL target diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index ca9ba00..74369de 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h @@ -50,10 +50,11 @@ enum ATH6K_DEBUG_MASK { }; extern unsigned int debug_mask; -__printf(2, 3) int ath6kl_printk(const char *level, const char *fmt, ...); -__printf(1, 2) int ath6kl_info(const char *fmt, ...); -__printf(1, 2) int ath6kl_err(const char *fmt, ...); -__printf(1, 2) int ath6kl_warn(const char *fmt, ...); +extern __printf(2, 3) +int ath6kl_printk(const char *level, const char *fmt, ...); +extern __printf(1, 2) int ath6kl_info(const char *fmt, ...); +extern __printf(1, 2) int ath6kl_err(const char *fmt, ...); +extern __printf(1, 2) int ath6kl_warn(const char *fmt, ...); enum ath6kl_war { ATH6KL_WAR_INVALID_RATE, diff --git a/drivers/net/wireless/ath/ath6kl/htc.h b/drivers/net/wireless/ath/ath6kl/htc.h index 14cab14..a2c8ff8 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.h +++ b/drivers/net/wireless/ath/ath6kl/htc.h @@ -60,7 +60,7 @@ /* disable credit flow control on a specific service */ #define HTC_CONN_FLGS_DISABLE_CRED_FLOW_CTRL (1 << 3) #define HTC_CONN_FLGS_SET_RECV_ALLOC_SHIFT 8 -#define HTC_CONN_FLGS_SET_RECV_ALLOC_MASK 0xFF00U +#define HTC_CONN_FLGS_SET_RECV_ALLOC_MASK 0xFF00 /* connect response status codes */ #define HTC_SERVICE_SUCCESS 0 diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 32f139e..7944c25 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig @@ -84,26 +84,6 @@ config ATH9K_DFS_CERTIFIED developed. At this point enabling this option won't do anything except increase code size. -config ATH9K_TX99 - bool "Atheros ath9k TX99 testing support" - depends on CFG80211_CERTIFICATION_ONUS - default n - ---help--- - Say N. This should only be enabled on systems undergoing - certification testing and evaluation in a controlled environment. - Enabling this will only enable TX99 support, all other modes of - operation will be disabled. - - TX99 support enables Specific Absorption Rate (SAR) testing. - SAR is the unit of measurement for the amount of radio frequency(RF) - absorbed by the body when using a wireless device. The RF exposure - limits used are expressed in the terms of SAR, which is a measure - of the electric and magnetic field strength and power density for - transmitters operating at frequencies from 300 kHz to 100 GHz. - Regulatory bodies around the world require that wireless device - be evaluated to meet the RF exposure limits set forth in the - governmental SAR regulations. - config ATH9K_LEGACY_RATE_CONTROL bool "Atheros ath9k rate control" depends on ATH9K diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 6205ef5..75ee9e7 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile @@ -14,7 +14,9 @@ ath9k-$(CONFIG_ATH9K_AHB) += ahb.o ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o ath9k-$(CONFIG_ATH9K_DFS_DEBUGFS) += dfs_debug.o ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += \ - dfs.o + dfs.o \ + dfs_pattern_detector.o \ + dfs_pri_detector.o ath9k-$(CONFIG_PM_SLEEP) += wow.o obj-$(CONFIG_ATH9K) += ath9k.o diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index 2dff276..072e4b5 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c @@ -54,7 +54,7 @@ static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) struct platform_device *pdev = to_platform_device(sc->dev); struct ath9k_platform_data *pdata; - pdata = dev_get_platdata(&pdev->dev); + pdata = (struct ath9k_platform_data *) pdev->dev.platform_data; if (off >= (ARRAY_SIZE(pdata->eeprom_data))) { ath_err(common, "%s: flash read failed, offset %08x is out of range\n", @@ -84,7 +84,7 @@ static int ath_ahb_probe(struct platform_device *pdev) struct ath_hw *ah; char hw_name[64]; - if (!dev_get_platdata(&pdev->dev)) { + if (!pdev->dev.platform_data) { dev_err(&pdev->dev, "no platform data specified\n"); return -EINVAL; } diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index d28923b..be466b0 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -338,9 +338,10 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) aniState->cckNoiseImmunityLevel != ATH9K_ANI_CCK_DEF_LEVEL) { ath_dbg(common, ANI, - "Restore defaults: opmode %u chan %d Mhz is_scanning=%d ofdm:%d cck:%d\n", + "Restore defaults: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n", ah->opmode, chan->channel, + chan->channelFlags, is_scanning, aniState->ofdmNoiseImmunityLevel, aniState->cckNoiseImmunityLevel); @@ -353,9 +354,10 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) * restore historical levels for this channel */ ath_dbg(common, ANI, - "Restore history: opmode %u chan %d Mhz is_scanning=%d ofdm:%d cck:%d\n", + "Restore history: opmode %u chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n", ah->opmode, chan->channel, + chan->channelFlags, is_scanning, aniState->ofdmNoiseImmunityLevel, aniState->cckNoiseImmunityLevel); diff --git a/drivers/net/wireless/ath/ath9k/antenna.c b/drivers/net/wireless/ath/ath9k/antenna.c index bd048cc..dd1cc73 100644 --- a/drivers/net/wireless/ath/ath9k/antenna.c +++ b/drivers/net/wireless/ath/ath9k/antenna.c @@ -332,7 +332,7 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb, } if (antcomb->rssi_lna2 > antcomb->rssi_lna1 + - div_ant_conf->lna1_lna2_switch_delta) + ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA) div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2; else div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1; @@ -554,22 +554,42 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, ant_conf->fast_div_bias = 0x1; break; case 0x10: /* LNA2 A-B */ - ant_conf->fast_div_bias = 0x2; + if ((antcomb->scan == 0) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) { + ant_conf->fast_div_bias = 0x3f; + } else { + ant_conf->fast_div_bias = 0x1; + } break; case 0x12: /* LNA2 LNA1 */ - ant_conf->fast_div_bias = 0x3f; + ant_conf->fast_div_bias = 0x39; break; case 0x13: /* LNA2 A+B */ - ant_conf->fast_div_bias = 0x2; + if ((antcomb->scan == 0) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) { + ant_conf->fast_div_bias = 0x3f; + } else { + ant_conf->fast_div_bias = 0x1; + } break; case 0x20: /* LNA1 A-B */ - ant_conf->fast_div_bias = 0x3; + if ((antcomb->scan == 0) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) { + ant_conf->fast_div_bias = 0x3f; + } else { + ant_conf->fast_div_bias = 0x4; + } break; case 0x21: /* LNA1 LNA2 */ - ant_conf->fast_div_bias = 0x3; + ant_conf->fast_div_bias = 0x6; break; case 0x23: /* LNA1 A+B */ - ant_conf->fast_div_bias = 0x3; + if ((antcomb->scan == 0) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) { + ant_conf->fast_div_bias = 0x3f; + } else { + ant_conf->fast_div_bias = 0x6; + } break; case 0x30: /* A+B A-B */ ant_conf->fast_div_bias = 0x1; @@ -618,7 +638,7 @@ static void ath_ant_try_scan(struct ath_ant_comb *antcomb, antcomb->rssi_sub = alt_rssi_avg; antcomb->scan = false; if (antcomb->rssi_lna2 > - (antcomb->rssi_lna1 + conf->lna1_lna2_switch_delta)) { + (antcomb->rssi_lna1 + ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)) { /* use LNA2 as main LNA */ if ((antcomb->rssi_add > antcomb->rssi_lna1) && (antcomb->rssi_add > antcomb->rssi_sub)) { diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index ff415e8..0865647 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -626,11 +626,12 @@ static void ar5008_hw_override_ini(struct ath_hw *ah, if (AR_SREV_9287_11_OR_LATER(ah)) val = val & (~AR_PCU_MISC_MODE2_HWWAR2); - val |= AR_PCU_MISC_MODE2_CFP_IGNORE; - REG_WRITE(ah, AR_PCU_MISC_MODE2, val); } + REG_SET_BIT(ah, AR_PHY_CCK_DETECT, + AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); + if (AR_SREV_9280_20_OR_LATER(ah)) return; /* @@ -666,13 +667,14 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah, if (IS_CHAN_HT40(chan)) { phymode |= AR_PHY_FC_DYN2040_EN; - if (IS_CHAN_HT40PLUS(chan)) + if ((chan->chanmode == CHANNEL_A_HT40PLUS) || + (chan->chanmode == CHANNEL_G_HT40PLUS)) phymode |= AR_PHY_FC_DYN2040_PRI_CH; } REG_WRITE(ah, AR_PHY_TURBO, phymode); - ath9k_hw_set11nmac2040(ah, chan); + ath9k_hw_set11nmac2040(ah); ENABLE_REGWRITE_BUFFER(ah); @@ -690,12 +692,31 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, int i, regWrites = 0; u32 modesIndex, freqIndex; - if (IS_CHAN_5GHZ(chan)) { + switch (chan->chanmode) { + case CHANNEL_A: + case CHANNEL_A_HT20: + modesIndex = 1; freqIndex = 1; - modesIndex = IS_CHAN_HT40(chan) ? 2 : 1; - } else { + break; + case CHANNEL_A_HT40PLUS: + case CHANNEL_A_HT40MINUS: + modesIndex = 2; + freqIndex = 1; + break; + case CHANNEL_G: + case CHANNEL_G_HT20: + case CHANNEL_B: + modesIndex = 4; freqIndex = 2; - modesIndex = IS_CHAN_HT40(chan) ? 3 : 4; + break; + case CHANNEL_G_HT40PLUS: + case CHANNEL_G_HT40MINUS: + modesIndex = 3; + freqIndex = 2; + break; + + default: + return -EINVAL; } /* @@ -794,10 +815,8 @@ static void ar5008_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan) if (chan == NULL) return; - if (IS_CHAN_2GHZ(chan)) - rfMode |= AR_PHY_MODE_DYNAMIC; - else - rfMode |= AR_PHY_MODE_OFDM; + rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan)) + ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; if (!AR_SREV_9280_20_OR_LATER(ah)) rfMode |= (IS_CHAN_5GHZ(chan)) ? @@ -1200,11 +1219,12 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah) iniDef = &aniState->iniDef; - ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz\n", + ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n", ah->hw_version.macVersion, ah->hw_version.macRev, ah->opmode, - chan->channel); + chan->channel, + chan->channelFlags); val = REG_READ(ah, AR_PHY_SFCORR); iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH); diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c index cdc7400..9f58974 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c @@ -33,12 +33,15 @@ static bool ar9002_hw_is_cal_supported(struct ath_hw *ah, bool supported = false; switch (ah->supp_cals & cal_type) { case IQ_MISMATCH_CAL: - supported = true; + /* Run IQ Mismatch for non-CCK only */ + if (!IS_CHAN_B(chan)) + supported = true; break; case ADC_GAIN_CAL: case ADC_DC_CAL: /* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */ - if (!((IS_CHAN_2GHZ(chan) || IS_CHAN_A_FAST_CLOCK(ah, chan)) && + if (!IS_CHAN_B(chan) && + !((IS_CHAN_2GHZ(chan) || IS_CHAN_A_FAST_CLOCK(ah, chan)) && IS_CHAN_HT20(chan))) supported = true; break; @@ -668,7 +671,7 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah, nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF); if (ah->caldata) - nfcal_pending = test_bit(NFCAL_PENDING, &ah->caldata->cal_flags); + nfcal_pending = ah->caldata->nfcal_pending; if (currCal && !nfcal && (currCal->calState == CAL_RUNNING || @@ -858,7 +861,7 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) ar9002_hw_pa_cal(ah, true); if (ah->caldata) - set_bit(NFCAL_PENDING, &ah->caldata->cal_flags); + ah->caldata->nfcal_pending = true; ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 5c95fd9..fb61b08 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -419,10 +419,28 @@ void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan) u32 modesIndex; int i; - if (IS_CHAN_5GHZ(chan)) - modesIndex = IS_CHAN_HT40(chan) ? 2 : 1; - else - modesIndex = IS_CHAN_HT40(chan) ? 3 : 4; + switch (chan->chanmode) { + case CHANNEL_A: + case CHANNEL_A_HT20: + modesIndex = 1; + break; + case CHANNEL_A_HT40PLUS: + case CHANNEL_A_HT40MINUS: + modesIndex = 2; + break; + case CHANNEL_G: + case CHANNEL_G_HT20: + case CHANNEL_B: + modesIndex = 4; + break; + case CHANNEL_G_HT40PLUS: + case CHANNEL_G_HT40MINUS: + modesIndex = 3; + break; + + default: + return; + } ENABLE_REGWRITE_BUFFER(ah); diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c index f087117..1fc1fa9 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c @@ -485,7 +485,7 @@ static void ar9002_hw_do_getnf(struct ath_hw *ah, if (IS_CHAN_HT40(ah->curchan)) nfarray[3] = sign_extend32(nf, 8); - if (!(ah->rxchainmask & BIT(1))) + if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) return; nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR9280_PHY_CH1_MINCCA_PWR); @@ -532,7 +532,6 @@ static void ar9002_hw_antdiv_comb_conf_get(struct ath_hw *ah, AR_PHY_9285_ANT_DIV_ALT_LNACONF_S; antconf->fast_div_bias = (regval & AR_PHY_9285_FAST_DIV_BIAS) >> AR_PHY_9285_FAST_DIV_BIAS_S; - antconf->lna1_lna2_switch_delta = -1; antconf->lna1_lna2_delta = -3; antconf->div_group = 0; } @@ -680,26 +679,6 @@ static void ar9002_hw_spectral_scan_wait(struct ath_hw *ah) } } -static void ar9002_hw_tx99_start(struct ath_hw *ah, u32 qnum) -{ - REG_SET_BIT(ah, 0x9864, 0x7f000); - REG_SET_BIT(ah, 0x9924, 0x7f00fe); - REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); - REG_WRITE(ah, AR_CR, AR_CR_RXD); - REG_WRITE(ah, AR_DLCL_IFS(qnum), 0); - REG_WRITE(ah, AR_D_GBL_IFS_SIFS, 20); - REG_WRITE(ah, AR_D_GBL_IFS_EIFS, 20); - REG_WRITE(ah, AR_D_FPCTL, 0x10|qnum); - REG_WRITE(ah, AR_TIME_OUT, 0x00000400); - REG_WRITE(ah, AR_DRETRY_LIMIT(qnum), 0xffffffff); - REG_SET_BIT(ah, AR_QMISC(qnum), AR_Q_MISC_DCU_EARLY_TERM_REQ); -} - -static void ar9002_hw_tx99_stop(struct ath_hw *ah) -{ - REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); -} - void ar9002_hw_attach_phy_ops(struct ath_hw *ah) { struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); @@ -721,8 +700,6 @@ void ar9002_hw_attach_phy_ops(struct ath_hw *ah) #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT ops->set_bt_ant_diversity = ar9002_hw_set_bt_ant_diversity; #endif - ops->tx99_start = ar9002_hw_tx99_start; - ops->tx99_stop = ar9002_hw_tx99_stop; ar9002_hw_set_nf_limits(ah); } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 22934d3..6988e1d 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -727,12 +727,8 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); - if (caldata) { - if (is_reusable) - set_bit(TXIQCAL_DONE, &caldata->cal_flags); - else - clear_bit(TXIQCAL_DONE, &caldata->cal_flags); - } + if (caldata) + caldata->done_txiqcal_once = is_reusable; return; } @@ -965,44 +961,18 @@ static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g) } static void ar9003_hw_do_manual_peak_cal(struct ath_hw *ah, - struct ath9k_channel *chan, - bool run_rtt_cal) + struct ath9k_channel *chan) { - struct ath9k_hw_cal_data *caldata = ah->caldata; int i; if (!AR_SREV_9462(ah) && !AR_SREV_9565(ah) && !AR_SREV_9485(ah)) return; - if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && !run_rtt_cal) - return; - for (i = 0; i < AR9300_MAX_CHAINS; i++) { if (!(ah->rxchainmask & (1 << i))) continue; ar9003_hw_manual_peak_cal(ah, i, IS_CHAN_2GHZ(chan)); } - - if (caldata) - set_bit(SW_PKDET_DONE, &caldata->cal_flags); - - if ((ah->caps.hw_caps & ATH9K_HW_CAP_RTT) && caldata) { - if (IS_CHAN_2GHZ(chan)){ - caldata->caldac[0] = REG_READ_FIELD(ah, - AR_PHY_65NM_RXRF_AGC(0), - AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR); - caldata->caldac[1] = REG_READ_FIELD(ah, - AR_PHY_65NM_RXRF_AGC(1), - AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR); - } else { - caldata->caldac[0] = REG_READ_FIELD(ah, - AR_PHY_65NM_RXRF_AGC(0), - AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR); - caldata->caldac[1] = REG_READ_FIELD(ah, - AR_PHY_65NM_RXRF_AGC(1), - AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR); - } - } } static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable) @@ -1020,7 +990,7 @@ static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable) txclcal_done = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_CLC_SUCCESS); - if (test_bit(TXCLCAL_DONE, &caldata->cal_flags)) { + if (caldata->done_txclcal_once) { for (i = 0; i < AR9300_MAX_CHAINS; i++) { if (!(ah->txchainmask & (1 << i))) continue; @@ -1036,7 +1006,7 @@ static void ar9003_hw_cl_cal_post_proc(struct ath_hw *ah, bool is_reusable) caldata->tx_clcal[i][j] = REG_READ(ah, CL_TAB_ENTRY(cl_idx[i])); } - set_bit(TXCLCAL_DONE, &caldata->cal_flags); + caldata->done_txclcal_once = true; } } @@ -1049,7 +1019,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, bool is_reusable = true, status = true; bool run_rtt_cal = false, run_agc_cal, sep_iq_cal = false; bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); - u32 rx_delay = 0; u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | AR_PHY_AGC_CONTROL_FLTR_CAL | AR_PHY_AGC_CONTROL_PKDET_CAL; @@ -1073,22 +1042,17 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, ar9003_hw_rtt_clear_hist(ah); } - if (rtt) { - if (!run_rtt_cal) { - agc_ctrl = REG_READ(ah, AR_PHY_AGC_CONTROL); - agc_supp_cals &= agc_ctrl; - agc_ctrl &= ~(AR_PHY_AGC_CONTROL_OFFSET_CAL | - AR_PHY_AGC_CONTROL_FLTR_CAL | - AR_PHY_AGC_CONTROL_PKDET_CAL); - REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl); - } else { - if (ah->ah_flags & AH_FASTCC) - run_agc_cal = true; - } + if (rtt && !run_rtt_cal) { + agc_ctrl = REG_READ(ah, AR_PHY_AGC_CONTROL); + agc_supp_cals &= agc_ctrl; + agc_ctrl &= ~(AR_PHY_AGC_CONTROL_OFFSET_CAL | + AR_PHY_AGC_CONTROL_FLTR_CAL | + AR_PHY_AGC_CONTROL_PKDET_CAL); + REG_WRITE(ah, AR_PHY_AGC_CONTROL, agc_ctrl); } if (ah->enabled_cals & TX_CL_CAL) { - if (caldata && test_bit(TXCLCAL_DONE, &caldata->cal_flags)) + if (caldata && caldata->done_txclcal_once) REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); else { @@ -1112,14 +1076,14 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, * AGC calibration */ if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) { - if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags)) + if (caldata && !caldata->done_txiqcal_once) REG_SET_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); else REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); txiqcal_done = run_agc_cal = true; - } else if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags)) { + } else if (caldata && !caldata->done_txiqcal_once) { run_agc_cal = true; sep_iq_cal = true; } @@ -1135,15 +1099,6 @@ skip_tx_iqcal: REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); } - if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) { - rx_delay = REG_READ(ah, AR_PHY_RX_DELAY); - /* Disable BB_active */ - REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); - udelay(5); - REG_WRITE(ah, AR_PHY_RX_DELAY, AR_PHY_RX_DELAY_DELAY); - REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); - } - if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { /* Calibrate the AGC */ REG_WRITE(ah, AR_PHY_AGC_CONTROL, @@ -1155,12 +1110,7 @@ skip_tx_iqcal: AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT); - ar9003_hw_do_manual_peak_cal(ah, chan, run_rtt_cal); - } - - if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) { - REG_WRITE(ah, AR_PHY_RX_DELAY, rx_delay); - udelay(5); + ar9003_hw_do_manual_peak_cal(ah, chan); } if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) @@ -1183,23 +1133,19 @@ skip_tx_iqcal: if (txiqcal_done) ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable); - else if (caldata && test_bit(TXIQCAL_DONE, &caldata->cal_flags)) + else if (caldata && caldata->done_txiqcal_once) ar9003_hw_tx_iq_cal_reload(ah); ar9003_hw_cl_cal_post_proc(ah, is_reusable); if (run_rtt_cal && caldata) { if (is_reusable) { - if (!ath9k_hw_rfbus_req(ah)) { + if (!ath9k_hw_rfbus_req(ah)) ath_err(ath9k_hw_common(ah), "Could not stop baseband\n"); - } else { + else ar9003_hw_rtt_fill_hist(ah); - if (test_bit(SW_PKDET_DONE, &caldata->cal_flags)) - ar9003_hw_rtt_load_hist(ah); - } - ath9k_hw_rfbus_done(ah); } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 1ec5235..f486480 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -2991,10 +2991,7 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, case EEP_CHAIN_MASK_REDUCE: return (pBase->miscConfiguration >> 0x3) & 0x1; case EEP_ANT_DIV_CTL1: - if (AR_SREV_9565(ah)) - return AR9300_EEP_ANTDIV_CONTROL_DEFAULT_VALUE; - else - return eep->base_ext1.ant_div_control; + return eep->base_ext1.ant_div_control; case EEP_ANTENNA_GAIN_5G: return eep->modalHeader5G.antennaGain; case EEP_ANTENNA_GAIN_2G: @@ -3427,12 +3424,12 @@ static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, struct ar9300_base_eep_hdr *pBase; if (!dump_base_hdr) { - len += scnprintf(buf + len, size - len, - "%20s :\n", "2GHz modal Header"); + len += snprintf(buf + len, size - len, + "%20s :\n", "2GHz modal Header"); len = ar9003_dump_modal_eeprom(buf, len, size, &eep->modalHeader2G); - len += scnprintf(buf + len, size - len, - "%20s :\n", "5GHz modal Header"); + len += snprintf(buf + len, size - len, + "%20s :\n", "5GHz modal Header"); len = ar9003_dump_modal_eeprom(buf, len, size, &eep->modalHeader5G); goto out; @@ -3482,8 +3479,8 @@ static u32 ath9k_hw_ar9003_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, PR_EEP("Rx Gain", pBase->txrxgain & 0xf); PR_EEP("SW Reg", le32_to_cpu(pBase->swreg)); - len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress", - ah->eeprom.ar9300_eep.macAddr); + len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress", + ah->eeprom.ar9300_eep.macAddr); out: if (len > size) len = size; @@ -3659,23 +3656,9 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) if (AR_SREV_9565(ah)) { if (common->bt_ant_diversity) { regval |= (1 << AR_PHY_ANT_SW_RX_PROT_S); - - REG_SET_BIT(ah, AR_PHY_RESTART, - AR_PHY_RESTART_ENABLE_DIV_M2FLAG); - - /* Force WLAN LNA diversity ON */ - REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, - AR_BTCOEX_WL_LNADIV_FORCE_ON); } else { regval &= ~(1 << AR_PHY_ANT_DIV_LNADIV_S); regval &= ~(1 << AR_PHY_ANT_SW_RX_PROT_S); - - REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL, - (1 << AR_PHY_ANT_SW_RX_PROT_S)); - - /* Force WLAN LNA diversity OFF */ - REG_CLR_BIT(ah, AR_BTCOEX_WL_LNADIV, - AR_BTCOEX_WL_LNADIV_FORCE_ON); } } @@ -3686,8 +3669,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) regval &= (~AR_FAST_DIV_ENABLE); regval |= ((value >> 7) & 0x1) << AR_FAST_DIV_ENABLE_S; - if ((AR_SREV_9485(ah) || AR_SREV_9565(ah)) - && common->bt_ant_diversity) + if (AR_SREV_9485(ah) && common->bt_ant_diversity) regval |= AR_FAST_DIV_ENABLE; REG_WRITE(ah, AR_PHY_CCK_DETECT, regval); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 0e5daa5..75d4fb4 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -52,8 +52,6 @@ #define AR9300_PAPRD_SCALE_2 0x70000000 #define AR9300_PAPRD_SCALE_2_S 28 -#define AR9300_EEP_ANTDIV_CONTROL_DEFAULT_VALUE 0xc9 - /* Delta from which to start power to pdadc table */ /* This offset is used in both open loop and closed loop power control * schemes. In open loop power control, it is not really needed, but for diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 20e4909..608bb48 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -187,17 +187,17 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniCckfirJapan2484, ar9485_1_1_baseband_core_txfir_coeff_japan_2484); - if (ah->config.no_pll_pwrsave) { - INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9485_1_1_pcie_phy_clkreq_disable_L1); - INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, - ar9485_1_1_pcie_phy_clkreq_disable_L1); - } else { - INIT_INI_ARRAY(&ah->iniPcieSerdes, - ar9485_1_1_pll_on_cdr_on_clkreq_disable_L1); - INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, - ar9485_1_1_pll_on_cdr_on_clkreq_disable_L1); - } + /* Load PCIE SERDES settings from INI */ + + /* Awake Setting */ + + INIT_INI_ARRAY(&ah->iniPcieSerdes, + ar9485_1_1_pcie_phy_clkreq_disable_L1); + + /* Sleep Setting */ + + INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, + ar9485_1_1_pcie_phy_clkreq_disable_L1); } else if (AR_SREV_9462_21(ah)) { INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p1_mac_core); @@ -364,8 +364,6 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniModesFastClock, ar9565_1p0_modes_fast_clock); - INIT_INI_ARRAY(&ah->iniCckfirJapan2484, - ar9565_1p0_baseband_core_txfir_coeff_japan_2484); } else { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], @@ -630,9 +628,6 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah) else if (AR_SREV_9462_20(ah)) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9462_common_rx_gain_table_2p0); - else if (AR_SREV_9565(ah)) - INIT_INI_ARRAY(&ah->iniModesRxGain, - ar9565_1p0_Common_rx_gain_table); else INIT_INI_ARRAY(&ah->iniModesRxGain, ar9300Common_rx_gain_table_2p2); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 7b94a6c..8dd0692 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -753,9 +753,9 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, 1 << AR_PHY_TIMING_CONTROL4_DO_GAIN_DC_IQ_CAL_SHIFT); if (caldata) { - clear_bit(TXIQCAL_DONE, &caldata->cal_flags); - clear_bit(TXCLCAL_DONE, &caldata->cal_flags); - clear_bit(RTT_DONE, &caldata->cal_flags); + caldata->done_txiqcal_once = false; + caldata->done_txclcal_once = false; + caldata->rtt_done = false; } if (!ath9k_hw_init_cal(ah, chan)) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index d39b79f..e897648 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -551,7 +551,8 @@ static void ar9003_hw_set_channel_regs(struct ath_hw *ah, if (IS_CHAN_HT40(chan)) { phymode |= AR_PHY_GC_DYN2040_EN; /* Configure control (primary) channel at +-10MHz */ - if (IS_CHAN_HT40PLUS(chan)) + if ((chan->chanmode == CHANNEL_A_HT40PLUS) || + (chan->chanmode == CHANNEL_G_HT40PLUS)) phymode |= AR_PHY_GC_DYN2040_PRI_CH; } @@ -564,7 +565,7 @@ static void ar9003_hw_set_channel_regs(struct ath_hw *ah, REG_WRITE(ah, AR_PHY_GEN_CTRL, phymode); /* Configure MAC for 20/40 operation */ - ath9k_hw_set11nmac2040(ah, chan); + ath9k_hw_set11nmac2040(ah); /* global transmit timeout (25 TUs default)*/ REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S); @@ -626,10 +627,11 @@ static void ar9003_hw_override_ini(struct ath_hw *ah) * MAC addr only will fail. */ val = REG_READ(ah, AR_PCU_MISC_MODE2) & (~AR_ADHOC_MCAST_KEYID_ENABLE); - val |= AR_AGG_WEP_ENABLE_FIX | - AR_AGG_WEP_ENABLE | - AR_PCU_MISC_MODE2_CFP_IGNORE; - REG_WRITE(ah, AR_PCU_MISC_MODE2, val); + REG_WRITE(ah, AR_PCU_MISC_MODE2, + val | AR_AGG_WEP_ENABLE_FIX | AR_AGG_WEP_ENABLE); + + REG_SET_BIT(ah, AR_PHY_CCK_DETECT, + AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV); if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { REG_WRITE(ah, AR_GLB_SWREG_DISCONT_MODE, @@ -681,72 +683,43 @@ static int ar9550_hw_get_modes_txgain_index(struct ath_hw *ah, { int ret; - if (IS_CHAN_2GHZ(chan)) { - if (IS_CHAN_HT40(chan)) - return 7; + switch (chan->chanmode) { + case CHANNEL_A: + case CHANNEL_A_HT20: + if (chan->channel <= 5350) + ret = 1; + else if ((chan->channel > 5350) && (chan->channel <= 5600)) + ret = 3; else - return 8; - } + ret = 5; + break; - if (chan->channel <= 5350) - ret = 1; - else if ((chan->channel > 5350) && (chan->channel <= 5600)) - ret = 3; - else - ret = 5; + case CHANNEL_A_HT40PLUS: + case CHANNEL_A_HT40MINUS: + if (chan->channel <= 5350) + ret = 2; + else if ((chan->channel > 5350) && (chan->channel <= 5600)) + ret = 4; + else + ret = 6; + break; - if (IS_CHAN_HT40(chan)) - ret++; + case CHANNEL_G: + case CHANNEL_G_HT20: + case CHANNEL_B: + ret = 8; + break; - return ret; -} + case CHANNEL_G_HT40PLUS: + case CHANNEL_G_HT40MINUS: + ret = 7; + break; -static void ar9003_doubler_fix(struct ath_hw *ah) -{ - if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) { - REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, - 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | - 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); - REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, - 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | - 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); - REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, - 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | - 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); - - udelay(200); - - REG_CLR_BIT(ah, AR_PHY_65NM_CH0_RXTX2, - AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); - REG_CLR_BIT(ah, AR_PHY_65NM_CH1_RXTX2, - AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); - REG_CLR_BIT(ah, AR_PHY_65NM_CH2_RXTX2, - AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); - - udelay(1); - - REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX2, - AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); - REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX2, - AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); - REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX2, - AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); - - udelay(200); - - REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_SYNTH12, - AR_PHY_65NM_CH0_SYNTH12_VREFMUL3, 0xf); - - REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, 0, - 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | - 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); - REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, 0, - 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | - 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); - REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, 0, - 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | - 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); + default: + ret = -EINVAL; } + + return ret; } static int ar9003_hw_process_ini(struct ath_hw *ah, @@ -755,10 +728,28 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, unsigned int regWrites = 0, i; u32 modesIndex; - if (IS_CHAN_5GHZ(chan)) - modesIndex = IS_CHAN_HT40(chan) ? 2 : 1; - else - modesIndex = IS_CHAN_HT40(chan) ? 3 : 4; + switch (chan->chanmode) { + case CHANNEL_A: + case CHANNEL_A_HT20: + modesIndex = 1; + break; + case CHANNEL_A_HT40PLUS: + case CHANNEL_A_HT40MINUS: + modesIndex = 2; + break; + case CHANNEL_G: + case CHANNEL_G_HT20: + case CHANNEL_B: + modesIndex = 4; + break; + case CHANNEL_G_HT40PLUS: + case CHANNEL_G_HT40MINUS: + modesIndex = 3; + break; + + default: + return -EINVAL; + } /* * SOC, MAC, BB, RADIO initvals. @@ -774,8 +765,6 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, modesIndex); } - ar9003_doubler_fix(ah); - /* * RXGAIN initvals. */ @@ -858,10 +847,8 @@ static void ar9003_hw_set_rfmode(struct ath_hw *ah, if (chan == NULL) return; - if (IS_CHAN_2GHZ(chan)) - rfMode |= AR_PHY_MODE_DYNAMIC; - else - rfMode |= AR_PHY_MODE_OFDM; + rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan)) + ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; if (IS_CHAN_A_FAST_CLOCK(ah, chan)) rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); @@ -1287,11 +1274,12 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah) aniState = &ah->ani; iniDef = &aniState->iniDef; - ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz\n", + ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz/0x%x\n", ah->hw_version.macVersion, ah->hw_version.macRev, ah->opmode, - chan->channel); + chan->channel, + chan->channelFlags); val = REG_READ(ah, AR_PHY_SFCORR); iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH); @@ -1387,19 +1375,15 @@ static void ar9003_hw_antdiv_comb_conf_get(struct ath_hw *ah, AR_PHY_ANT_FAST_DIV_BIAS_S; if (AR_SREV_9330_11(ah)) { - antconf->lna1_lna2_switch_delta = -1; antconf->lna1_lna2_delta = -9; antconf->div_group = 1; } else if (AR_SREV_9485(ah)) { - antconf->lna1_lna2_switch_delta = -1; antconf->lna1_lna2_delta = -9; antconf->div_group = 2; } else if (AR_SREV_9565(ah)) { - antconf->lna1_lna2_switch_delta = 3; - antconf->lna1_lna2_delta = -9; + antconf->lna1_lna2_delta = -3; antconf->div_group = 3; } else { - antconf->lna1_lna2_switch_delta = -1; antconf->lna1_lna2_delta = -3; antconf->div_group = 0; } @@ -1505,24 +1489,17 @@ static void ar9003_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable) } else if (AR_SREV_9565(ah)) { if (enable) { REG_SET_BIT(ah, AR_PHY_MC_GAIN_CTRL, - AR_ANT_DIV_ENABLE); - REG_SET_BIT(ah, AR_PHY_MC_GAIN_CTRL, (1 << AR_PHY_ANT_SW_RX_PROT_S)); - REG_SET_BIT(ah, AR_PHY_CCK_DETECT, - AR_FAST_DIV_ENABLE); - REG_SET_BIT(ah, AR_PHY_RESTART, - AR_PHY_RESTART_ENABLE_DIV_M2FLAG); + if (ah->curchan && IS_CHAN_2GHZ(ah->curchan)) + REG_SET_BIT(ah, AR_PHY_RESTART, + AR_PHY_RESTART_ENABLE_DIV_M2FLAG); REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); } else { - REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL, - AR_ANT_DIV_ENABLE); + REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_ENABLE); REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL, (1 << AR_PHY_ANT_SW_RX_PROT_S)); - REG_CLR_BIT(ah, AR_PHY_CCK_DETECT, - AR_FAST_DIV_ENABLE); - REG_CLR_BIT(ah, AR_PHY_RESTART, - AR_PHY_RESTART_ENABLE_DIV_M2FLAG); + REG_CLR_BIT(ah, AR_PHY_CCK_DETECT, AR_FAST_DIV_ENABLE); REG_CLR_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); @@ -1549,10 +1526,28 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah, unsigned int regWrites = 0; u32 modesIndex; - if (IS_CHAN_5GHZ(chan)) - modesIndex = IS_CHAN_HT40(chan) ? 2 : 1; - else - modesIndex = IS_CHAN_HT40(chan) ? 3 : 4; + switch (chan->chanmode) { + case CHANNEL_A: + case CHANNEL_A_HT20: + modesIndex = 1; + break; + case CHANNEL_A_HT40PLUS: + case CHANNEL_A_HT40MINUS: + modesIndex = 2; + break; + case CHANNEL_G: + case CHANNEL_G_HT20: + case CHANNEL_B: + modesIndex = 4; + break; + case CHANNEL_G_HT40PLUS: + case CHANNEL_G_HT40MINUS: + modesIndex = 3; + break; + + default: + return -EINVAL; + } if (modesIndex == ah->modes_index) { *ini_reloaded = false; @@ -1667,98 +1662,6 @@ static void ar9003_hw_spectral_scan_wait(struct ath_hw *ah) } } -static void ar9003_hw_tx99_start(struct ath_hw *ah, u32 qnum) -{ - REG_SET_BIT(ah, AR_PHY_TEST, PHY_AGC_CLR); - REG_SET_BIT(ah, 0x9864, 0x7f000); - REG_SET_BIT(ah, 0x9924, 0x7f00fe); - REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); - REG_WRITE(ah, AR_CR, AR_CR_RXD); - REG_WRITE(ah, AR_DLCL_IFS(qnum), 0); - REG_WRITE(ah, AR_D_GBL_IFS_SIFS, 20); /* 50 OK */ - REG_WRITE(ah, AR_D_GBL_IFS_EIFS, 20); - REG_WRITE(ah, AR_TIME_OUT, 0x00000400); - REG_WRITE(ah, AR_DRETRY_LIMIT(qnum), 0xffffffff); - REG_SET_BIT(ah, AR_QMISC(qnum), AR_Q_MISC_DCU_EARLY_TERM_REQ); -} - -static void ar9003_hw_tx99_stop(struct ath_hw *ah) -{ - REG_CLR_BIT(ah, AR_PHY_TEST, PHY_AGC_CLR); - REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS); -} - -static void ar9003_hw_tx99_set_txpower(struct ath_hw *ah, u8 txpower) -{ - static s16 p_pwr_array[ar9300RateSize] = { 0 }; - unsigned int i; - - if (txpower <= MAX_RATE_POWER) { - for (i = 0; i < ar9300RateSize; i++) - p_pwr_array[i] = txpower; - } else { - for (i = 0; i < ar9300RateSize; i++) - p_pwr_array[i] = MAX_RATE_POWER; - } - - REG_WRITE(ah, 0xa458, 0); - - REG_WRITE(ah, 0xa3c0, - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 24) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 16) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 8) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 0)); - REG_WRITE(ah, 0xa3c4, - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_54], 24) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_48], 16) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_36], 8) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_6_24], 0)); - REG_WRITE(ah, 0xa3c8, - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], 24) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], 16) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], 0)); - REG_WRITE(ah, 0xa3cc, - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_11S], 24) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_11L], 16) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_5S], 8) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_LEGACY_1L_5L], 0)); - REG_WRITE(ah, 0xa3d0, - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_5], 24) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_4], 16) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_1_3_9_11_17_19], 8)| - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_0_8_16], 0)); - REG_WRITE(ah, 0xa3d4, - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_13], 24) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_12], 16) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_7], 8) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_6], 0)); - REG_WRITE(ah, 0xa3e4, - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_21], 24) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_20], 16) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_15], 8) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_14], 0)); - REG_WRITE(ah, 0xa3e8, - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_23], 24) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_22], 16) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_23], 8) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT20_22], 0)); - REG_WRITE(ah, 0xa3d8, - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_5], 24) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_4], 16) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_1_3_9_11_17_19], 8) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_0_8_16], 0)); - REG_WRITE(ah, 0xa3dc, - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_13], 24) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_12], 16) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_7], 8) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_6], 0)); - REG_WRITE(ah, 0xa3ec, - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_21], 24) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_20], 16) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_15], 8) | - ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_14], 0)); -} - void ar9003_hw_attach_phy_ops(struct ath_hw *ah) { struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); @@ -1798,9 +1701,6 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah) #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT ops->set_bt_ant_diversity = ar9003_hw_set_bt_ant_diversity; #endif - ops->tx99_start = ar9003_hw_tx99_start; - ops->tx99_stop = ar9003_hw_tx99_stop; - ops->tx99_set_txpower = ar9003_hw_tx99_set_txpower; ar9003_hw_set_nf_limits(ah); ar9003_hw_set_radar_conf(ah); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 2af667b..6fd7523 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -343,12 +343,8 @@ #define AR_PHY_CCA_NOM_VAL_9462_2GHZ -127 #define AR_PHY_CCA_MIN_GOOD_VAL_9462_2GHZ -127 -#define AR_PHY_CCA_MAX_GOOD_VAL_9462_2GHZ -60 -#define AR_PHY_CCA_MAX_GOOD_VAL_9462_FCC_2GHZ -95 #define AR_PHY_CCA_NOM_VAL_9462_5GHZ -127 #define AR_PHY_CCA_MIN_GOOD_VAL_9462_5GHZ -127 -#define AR_PHY_CCA_MAX_GOOD_VAL_9462_5GHZ -60 -#define AR_PHY_CCA_MAX_GOOD_VAL_9462_FCC_5GHZ -100 #define AR_PHY_CCA_NOM_VAL_9330_2GHZ -118 @@ -656,24 +652,13 @@ #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x00000001 : 0x00000002) #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0 : 1) #define AR_PHY_65NM_CH0_SYNTH7 0x16098 -#define AR_PHY_65NM_CH0_SYNTH12 0x160ac #define AR_PHY_65NM_CH0_BIAS1 0x160c0 #define AR_PHY_65NM_CH0_BIAS2 0x160c4 #define AR_PHY_65NM_CH0_BIAS4 0x160cc -#define AR_PHY_65NM_CH0_RXTX2 0x16104 -#define AR_PHY_65NM_CH1_RXTX2 0x16504 -#define AR_PHY_65NM_CH2_RXTX2 0x16904 #define AR_PHY_65NM_CH0_RXTX4 0x1610c #define AR_PHY_65NM_CH1_RXTX4 0x1650c #define AR_PHY_65NM_CH2_RXTX4 0x1690c -#define AR_PHY_65NM_CH0_SYNTH12_VREFMUL3 0x00780000 -#define AR_PHY_65NM_CH0_SYNTH12_VREFMUL3_S 19 -#define AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK 0x00000004 -#define AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S 2 -#define AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK 0x00000008 -#define AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S 3 - #define AR_CH0_TOP (AR_SREV_9300(ah) ? 0x16288 : \ (((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x1628c : 0x16280))) #define AR_CH0_TOP_XPABIASLVL (AR_SREV_9550(ah) ? 0x3c0 : 0x300) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_rtt.c b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c index 9344188..74de353 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_rtt.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c @@ -118,27 +118,6 @@ void ar9003_hw_rtt_load_hist(struct ath_hw *ah) } } -static void ar9003_hw_patch_rtt(struct ath_hw *ah, int index, int chain) -{ - int agc, caldac; - - if (!test_bit(SW_PKDET_DONE, &ah->caldata->cal_flags)) - return; - - if ((index != 5) || (chain >= 2)) - return; - - agc = REG_READ_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE); - if (!agc) - return; - - caldac = ah->caldata->caldac[chain]; - ah->caldata->rtt_table[chain][index] &= 0xFFFF05FF; - caldac = (caldac & 0x20) | ((caldac & 0x1F) << 7); - ah->caldata->rtt_table[chain][index] |= (caldac << 4); -} - static int ar9003_hw_rtt_fill_hist_entry(struct ath_hw *ah, u8 chain, u32 index) { u32 val; @@ -176,16 +155,13 @@ void ar9003_hw_rtt_fill_hist(struct ath_hw *ah) for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) { ah->caldata->rtt_table[chain][i] = ar9003_hw_rtt_fill_hist_entry(ah, chain, i); - - ar9003_hw_patch_rtt(ah, i, chain); - ath_dbg(ath9k_hw_common(ah), CALIBRATE, "RTT value at idx %d, chain %d is: 0x%x\n", i, chain, ah->caldata->rtt_table[chain][i]); } } - set_bit(RTT_DONE, &ah->caldata->cal_flags); + ah->caldata->rtt_done = true; } void ar9003_hw_rtt_clear_hist(struct ath_hw *ah) @@ -200,7 +176,7 @@ void ar9003_hw_rtt_clear_hist(struct ath_hw *ah) } if (ah->caldata) - clear_bit(RTT_DONE, &ah->caldata->cal_flags); + ah->caldata->rtt_done = false; } bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan) @@ -210,37 +186,11 @@ bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan) if (!ah->caldata) return false; - if (test_bit(SW_PKDET_DONE, &ah->caldata->cal_flags)) { - if (IS_CHAN_2GHZ(chan)){ - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(0), - AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, - ah->caldata->caldac[0]); - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(1), - AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, - ah->caldata->caldac[1]); - } else { - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(0), - AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, - ah->caldata->caldac[0]); - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(1), - AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, - ah->caldata->caldac[1]); - } - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(1), - AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1); - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(0), - AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1); - } - - if (!test_bit(RTT_DONE, &ah->caldata->cal_flags)) + if (!ah->caldata->rtt_done) return false; ar9003_hw_rtt_enable(ah); - - if (test_bit(SW_PKDET_DONE, &ah->caldata->cal_flags)) - ar9003_hw_rtt_set_mask(ah, 0x30); - else - ar9003_hw_rtt_set_mask(ah, 0x10); + ar9003_hw_rtt_set_mask(ah, 0x10); if (!ath9k_hw_rfbus_req(ah)) { ath_err(ath9k_hw_common(ah), "Could not stop baseband\n"); diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h index 57fc5f4..4dbc294 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h @@ -361,7 +361,7 @@ static const u32 ar9462_2p1_baseband_postamble[][5] = { {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e}, {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, - {0x00009e20, 0x000003a5, 0x000003a5, 0x000003a5, 0x000003a5}, + {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, @@ -400,7 +400,7 @@ static const u32 ar9462_2p1_baseband_postamble[][5] = { {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000}, {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, - {0x0000ae20, 0x000001a6, 0x000001a6, 0x000001aa, 0x000001aa}, + {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, }; @@ -472,7 +472,7 @@ static const u32 ar9462_2p1_radio_postamble[][5] = { static const u32 ar9462_2p1_soc_preamble[][2] = { /* Addr allmodes */ - {0x000040a4, 0x00a0c9c9}, + {0x000040a4, 0x00a0c1c9}, {0x00007020, 0x00000000}, {0x00007034, 0x00000002}, {0x00007038, 0x000004c2}, diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index 7c18452..88ff1d7 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h @@ -20,16 +20,13 @@ /* AR9485 1.1 */ -static const u32 ar9485_1_1_mac_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, - {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, - {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, - {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, - {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, - {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, - {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, - {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, +#define ar9485_1_1_mac_postamble ar9300_2p2_mac_postamble + +static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x18012e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000080c}, }; static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { @@ -37,7 +34,6 @@ static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { {0x00009e00, 0x037216a0}, {0x00009e04, 0x00182020}, {0x00009e18, 0x00000000}, - {0x00009e20, 0x000003a8}, {0x00009e2c, 0x00004121}, {0x00009e44, 0x02282324}, {0x0000a000, 0x00060005}, @@ -178,7 +174,7 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { {0x0000a2e0, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, {0x0000a2e4, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, {0x0000a2e8, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050da, 0x000050da}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, @@ -204,14 +200,14 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a560, 0x900fff0b, 0x900fff0b, 0x62001eee, 0x62001eee}, - {0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001ff6, 0x66001ff6}, - {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001ff6, 0x66001ff6}, - {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001ff6, 0x66001ff6}, - {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001ff6, 0x66001ff6}, - {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001ff6, 0x66001ff6}, - {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001ff6, 0x66001ff6}, - {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001ff6, 0x66001ff6}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, @@ -267,11 +263,6 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { static const u32 ar9485Modes_green_ob_db_tx_gain_1_1[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003}, - {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a}, - {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e0, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e4, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e8, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000}, {0x0000a500, 0x00022200, 0x00022200, 0x00000006, 0x00000006}, @@ -306,22 +297,6 @@ static const u32 ar9485Modes_green_ob_db_tx_gain_1_1[][5] = { {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501}, - {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, - {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, - {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803}, - {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04}, - {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, {0x0000b500, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, {0x0000b504, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, {0x0000b508, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, @@ -366,100 +341,6 @@ static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = { {0x0000a2e0, 0x00000000, 0x00000000, 0xffc63a84, 0xffc63a84}, {0x0000a2e4, 0x00000000, 0x00000000, 0xfe0fc000, 0xfe0fc000}, {0x0000a2e8, 0x00000000, 0x00000000, 0xfff00000, 0xfff00000}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050da, 0x000050da}, - {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, - {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, - {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, - {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, - {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, - {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, - {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, - {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, - {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, - {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, - {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, - {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, - {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, - {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, - {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, - {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, - {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, - {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, - {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, - {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, - {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, - {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, - {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a560, 0x900fff0b, 0x900fff0b, 0x62001eee, 0x62001eee}, - {0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001ff6, 0x66001ff6}, - {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001ff6, 0x66001ff6}, - {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001ff6, 0x66001ff6}, - {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001ff6, 0x66001ff6}, - {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001ff6, 0x66001ff6}, - {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001ff6, 0x66001ff6}, - {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001ff6, 0x66001ff6}, - {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501}, - {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, - {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, - {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803}, - {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04}, - {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, - {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, -}; - -static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, - {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a}, - {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e0, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e4, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e8, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, @@ -546,7 +427,7 @@ static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = { {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, }; -static const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = { +static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a}, @@ -640,15 +521,12 @@ static const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = { {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, }; +#define ar9485_modes_lowest_ob_db_tx_gain_1_1 ar9485Modes_low_ob_db_tx_gain_1_1 + static const u32 ar9485Modes_green_spur_ob_db_tx_gain_1_1[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003}, - {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a}, - {0x0000a2dc, 0x00000000, 0x00000000, 0xffad452a, 0xffad452a}, - {0x0000a2e0, 0x00000000, 0x00000000, 0xffc98634, 0xffc98634}, - {0x0000a2e4, 0x00000000, 0x00000000, 0xfff60780, 0xfff60780}, - {0x0000a2e8, 0x00000000, 0x00000000, 0xfffff800, 0xfffff800}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000}, {0x0000a500, 0x00022200, 0x00022200, 0x00000006, 0x00000006}, {0x0000a504, 0x05062002, 0x05062002, 0x03000201, 0x03000201}, @@ -665,39 +543,23 @@ static const u32 ar9485Modes_green_spur_ob_db_tx_gain_1_1[][5] = { {0x0000a530, 0x48023ec6, 0x48023ec6, 0x310006e0, 0x310006e0}, {0x0000a534, 0x4d023f01, 0x4d023f01, 0x330006e0, 0x330006e0}, {0x0000a538, 0x53023f4b, 0x53023f4b, 0x3e0008e3, 0x3e0008e3}, - {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x430008e6, 0x430008e6}, - {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4a0008ec, 0x4a0008ec}, - {0x0000a544, 0x6502feca, 0x6502feca, 0x4e0008f1, 0x4e0008f1}, - {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x520008f3, 0x520008f3}, - {0x0000a54c, 0x7203feca, 0x7203feca, 0x54000eed, 0x54000eed}, - {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x58000ef1, 0x58000ef1}, - {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5c000ef3, 0x5c000ef3}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x62000ef6, 0x62000ef6}, - {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001ff0, 0x66001ff0}, - {0x0000a560, 0x900fff0b, 0x900fff0b, 0x68001ff6, 0x68001ff6}, - {0x0000a564, 0x960fffcb, 0x960fffcb, 0x68001ff6, 0x68001ff6}, - {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x68001ff6, 0x68001ff6}, - {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x68001ff6, 0x68001ff6}, - {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x68001ff6, 0x68001ff6}, - {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x68001ff6, 0x68001ff6}, - {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x68001ff6, 0x68001ff6}, - {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x68001ff6, 0x68001ff6}, - {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a58c, 0x00000000, 0x00000000, 0x01804000, 0x01804000}, - {0x0000a590, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, - {0x0000a594, 0x00000000, 0x00000000, 0x0340ca02, 0x0340ca02}, - {0x0000a598, 0x00000000, 0x00000000, 0x0340cd03, 0x0340cd03}, - {0x0000a59c, 0x00000000, 0x00000000, 0x0340cd03, 0x0340cd03}, - {0x0000a5a0, 0x00000000, 0x00000000, 0x06415304, 0x06415304}, - {0x0000a5a4, 0x00000000, 0x00000000, 0x04c11905, 0x04c11905}, - {0x0000a5a8, 0x00000000, 0x00000000, 0x06415905, 0x06415905}, - {0x0000a5ac, 0x00000000, 0x00000000, 0x06415905, 0x06415905}, - {0x0000a5b0, 0x00000000, 0x00000000, 0x06415905, 0x06415905}, - {0x0000a5b4, 0x00000000, 0x00000000, 0x06415905, 0x06415905}, - {0x0000a5b8, 0x00000000, 0x00000000, 0x06415905, 0x06415905}, - {0x0000a5bc, 0x00000000, 0x00000000, 0x06415905, 0x06415905}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x410008e5, 0x410008e5}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x430008e6, 0x430008e6}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x4a0008ec, 0x4a0008ec}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4e0008f1, 0x4e0008f1}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x520008f3, 0x520008f3}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x54000eed, 0x54000eed}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x58000ef1, 0x58000ef1}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5c000ef3, 0x5c000ef3}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x60000ef5, 0x60000ef5}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x62000ef6, 0x62000ef6}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x62000ef6, 0x62000ef6}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x62000ef6, 0x62000ef6}, {0x0000b500, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, {0x0000b504, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, {0x0000b508, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, @@ -961,7 +823,6 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = { {0x00009e00, 0x03721b20}, {0x00009e04, 0x00082020}, {0x00009e18, 0x0300501e}, - {0x00009e20, 0x000003ba}, {0x00009e2c, 0x00002e21}, {0x00009e44, 0x02182324}, {0x0000a000, 0x00060005}, @@ -1094,6 +955,20 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = { {0x0000a1fc, 0x00000296}, }; +static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x18052e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000080c}, +}; + +static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x18053e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000080c}, +}; + static const u32 ar9485_1_1_soc_preamble[][2] = { /* Addr allmodes */ {0x00004014, 0xba280400}, @@ -1126,6 +1001,7 @@ static const u32 ar9485_1_1_baseband_postamble[][5] = { {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e}, {0x00009e14, 0x31395d53, 0x31396053, 0x312e6053, 0x312e5d53}, {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, + {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222}, {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010}, {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, @@ -1144,7 +1020,7 @@ static const u32 ar9485_1_1_baseband_postamble[][5] = { {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0}, {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, + {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00058d18, 0x00058d18}, {0x0000a2d0, 0x00071981, 0x00071981, 0x00071982, 0x00071982}, {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, @@ -1152,6 +1028,13 @@ static const u32 ar9485_1_1_baseband_postamble[][5] = { {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, }; +static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x18013e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000080c}, +}; + static const u32 ar9485_1_1_radio_postamble[][2] = { /* Addr allmodes */ {0x0001609c, 0x0b283f31}, @@ -1323,25 +1206,6 @@ static const u32 ar9485_1_1_mac_core[][2] = { {0x000083d0, 0x000301ff}, }; -static const u32 ar9485_1_1_baseband_core_txfir_coeff_japan_2484[][2] = { - /* Addr allmodes */ - {0x0000a398, 0x00000000}, - {0x0000a39c, 0x6f7f0301}, - {0x0000a3a0, 0xca9228ee}, -}; - -static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = { - /* Addr allmodes */ - {0x00018c00, 0x18013e5e}, - {0x00018c04, 0x000801d8}, - {0x00018c08, 0x0000080c}, -}; - -static const u32 ar9485_1_1_pll_on_cdr_on_clkreq_disable_L1[][2] = { - /* Addr allmodes */ - {0x00018c00, 0x1801265e}, - {0x00018c04, 0x000801d8}, - {0x00018c08, 0x0000080c}, -}; +#define ar9485_1_1_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484 #endif /* INITVALS_9485_H */ diff --git a/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h index a8c757b..e85a8b0 100644 --- a/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h @@ -272,9 +272,9 @@ static const u32 ar9565_1p0_baseband_core[][2] = { {0x0000a398, 0x001f0e0f}, {0x0000a39c, 0x0075393f}, {0x0000a3a0, 0xb79f6427}, - {0x0000a3a4, 0x00000011}, - {0x0000a3a8, 0xaaaaaa6e}, - {0x0000a3ac, 0x3c466455}, + {0x0000a3a4, 0x00000000}, + {0x0000a3a8, 0xaaaaaaaa}, + {0x0000a3ac, 0x3c466478}, {0x0000a3c0, 0x20202020}, {0x0000a3c4, 0x22222220}, {0x0000a3c8, 0x20200020}, @@ -295,11 +295,11 @@ static const u32 ar9565_1p0_baseband_core[][2] = { {0x0000a404, 0x00000000}, {0x0000a408, 0x0e79e5c6}, {0x0000a40c, 0x00820820}, - {0x0000a414, 0x1ce739c5}, + {0x0000a414, 0x1ce739ce}, {0x0000a418, 0x2d001dce}, - {0x0000a41c, 0x1ce739c5}, + {0x0000a41c, 0x1ce739ce}, {0x0000a420, 0x000001ce}, - {0x0000a424, 0x1ce739c5}, + {0x0000a424, 0x1ce739ce}, {0x0000a428, 0x000001ce}, {0x0000a42c, 0x1ce739ce}, {0x0000a430, 0x1ce739ce}, @@ -351,9 +351,9 @@ static const u32 ar9565_1p0_baseband_postamble[][5] = { {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e}, {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, - {0x00009e20, 0x000003b5, 0x000003b5, 0x000003a4, 0x000003a4}, + {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, - {0x00009e3c, 0xcf946222, 0xcf946222, 0xcf946220, 0xcf946220}, + {0x00009e3c, 0xcf946222, 0xcf946222, 0xcf946222, 0xcf946222}, {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27}, {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, @@ -452,7 +452,6 @@ static const u32 ar9565_1p0_Common_rx_gain_table[][2] = { /* Addr allmodes */ {0x00004050, 0x00300300}, {0x0000406c, 0x00100000}, - {0x00009e20, 0x000003b6}, {0x0000a000, 0x00010000}, {0x0000a004, 0x00030002}, {0x0000a008, 0x00050004}, @@ -1231,11 +1230,4 @@ static const u32 ar9565_1p0_modes_high_power_tx_gain_table[][5] = { {0x00016054, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, }; -static const u32 ar9565_1p0_baseband_core_txfir_coeff_japan_2484[][2] = { - /* Addr allmodes */ - {0x0000a398, 0x00000000}, - {0x0000a39c, 0x6f7f0301}, - {0x0000a3a0, 0xca9228ee}, -}; - #endif /* INITVALS_9565_1P0_H */ diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 60a5da5..2ee35f6 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -64,6 +64,7 @@ struct ath_node; struct ath_config { u16 txpowlimit; + u8 cabqReadytime; }; /*************************/ @@ -206,14 +207,6 @@ struct ath_frame_info { u8 baw_tracked : 1; }; -struct ath_rxbuf { - struct list_head list; - struct sk_buff *bf_mpdu; - void *bf_desc; - dma_addr_t bf_daddr; - dma_addr_t bf_buf_addr; -}; - struct ath_buf_state { u8 bf_type; u8 bfs_paprd; @@ -314,7 +307,7 @@ struct ath_rx { struct ath_descdma rxdma; struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; - struct ath_rxbuf *buf_hold; + struct ath_buf *buf_hold; struct sk_buff *frag; u32 ampdu_ref; @@ -466,8 +459,8 @@ void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); #define ATH_DUMP_BTCOEX(_s, _val) \ do { \ - len += scnprintf(buf + len, size - len, \ - "%20s : %10d\n", _s, (_val)); \ + len += snprintf(buf + len, size - len, \ + "%20s : %10d\n", _s, (_val)); \ } while (0) enum bt_op_flags { @@ -588,6 +581,7 @@ static inline void ath_fill_led_pin(struct ath_softc *sc) #define ATH_ANT_DIV_COMB_ALT_ANT_RATIO_LOW_RSSI 50 #define ATH_ANT_DIV_COMB_ALT_ANT_RATIO2_LOW_RSSI 50 +#define ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA -1 #define ATH_ANT_DIV_COMB_LNA1_DELTA_HI -4 #define ATH_ANT_DIV_COMB_LNA1_DELTA_MID -2 #define ATH_ANT_DIV_COMB_LNA1_DELTA_LOW 2 @@ -632,16 +626,12 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs); /* Main driver core */ /********************/ -#define ATH9K_PCI_CUS198 0x0001 -#define ATH9K_PCI_CUS230 0x0002 -#define ATH9K_PCI_CUS217 0x0004 -#define ATH9K_PCI_CUS252 0x0008 -#define ATH9K_PCI_WOW 0x0010 -#define ATH9K_PCI_BT_ANT_DIV 0x0020 -#define ATH9K_PCI_D3_L1_WAR 0x0040 -#define ATH9K_PCI_AR9565_1ANT 0x0080 -#define ATH9K_PCI_AR9565_2ANT 0x0100 -#define ATH9K_PCI_NO_PLL_PWRSAVE 0x0200 +#define ATH9K_PCI_CUS198 0x0001 +#define ATH9K_PCI_CUS230 0x0002 +#define ATH9K_PCI_CUS217 0x0004 +#define ATH9K_PCI_WOW 0x0008 +#define ATH9K_PCI_BT_ANT_DIV 0x0010 +#define ATH9K_PCI_D3_L1_WAR 0x0020 /* * Default cache line size, in bytes. @@ -779,11 +769,6 @@ struct ath_softc { enum spectral_mode spectral_mode; struct ath_spec_scan spec_config; - struct ieee80211_vif *tx99_vif; - struct sk_buff *tx99_skb; - bool tx99_state; - s16 tx99_power; - #ifdef CONFIG_PM_SLEEP atomic_t wow_got_bmiss_intr; atomic_t wow_sleep_proc_intr; /* in the middle of WoW sleep ? */ @@ -892,7 +877,6 @@ static inline u8 spectral_bitmap_weight(u8 *bins) */ enum ath_fft_sample_type { ATH_FFT_SAMPLE_HT20 = 1, - ATH_FFT_SAMPLE_HT20_40, }; struct fft_sample_tlv { @@ -919,39 +903,6 @@ struct fft_sample_ht20 { u8 data[SPECTRAL_HT20_NUM_BINS]; } __packed; -struct fft_sample_ht20_40 { - struct fft_sample_tlv tlv; - - u8 channel_type; - __be16 freq; - - s8 lower_rssi; - s8 upper_rssi; - - __be64 tsf; - - s8 lower_noise; - s8 upper_noise; - - __be16 lower_max_magnitude; - __be16 upper_max_magnitude; - - u8 lower_max_index; - u8 upper_max_index; - - u8 lower_bitmap_weight; - u8 upper_bitmap_weight; - - u8 max_exp; - - u8 data[SPECTRAL_HT20_40_NUM_BINS]; -} __packed; - -int ath9k_tx99_init(struct ath_softc *sc); -void ath9k_tx99_deinit(struct ath_softc *sc); -int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb, - struct ath_tx_control *txctl); - void ath9k_tasklet(unsigned long data); int ath_cabq_update(struct ath_softc *); @@ -973,6 +924,7 @@ void ath9k_deinit_device(struct ath_softc *sc); void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); void ath9k_reload_chainmask_settings(struct ath_softc *sc); +bool ath9k_uses_beacons(int type); void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw); int ath9k_spectral_scan_config(struct ieee80211_hw *hw, enum spectral_mode spectral_mode); @@ -1000,7 +952,7 @@ void ath9k_ps_restore(struct ath_softc *sc); u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate); void ath_start_rfkill_poll(struct ath_softc *sc); -void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); +extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); void ath9k_calculate_iter_data(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ath9k_vif_iter_data *iter_data); diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 17be353..b5c16b3a 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c @@ -334,8 +334,6 @@ void ath9k_beacon_tasklet(unsigned long data) if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) { sc->beacon.bmisscnt++; - ath9k_hw_check_nav(ah); - if (!ath9k_hw_check_alive(ah)) ieee80211_queue_work(sc->hw, &sc->hw_check_work); diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 278365b..5e8219a 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c @@ -63,13 +63,13 @@ static s16 ath9k_hw_get_default_nf(struct ath_hw *ah, return ath9k_hw_get_nf_limits(ah, chan)->nominal; } -s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan, - s16 nf) +s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan) { s8 noise = ATH_DEFAULT_NOISE_FLOOR; - if (nf) { - s8 delta = nf - ATH9K_NF_CAL_NOISE_THRESH - + if (chan && chan->noisefloor) { + s8 delta = chan->noisefloor - + ATH9K_NF_CAL_NOISE_THRESH - ath9k_hw_get_default_nf(ah, chan); if (delta > 0) noise += delta; @@ -119,7 +119,7 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah, ath_dbg(common, CALIBRATE, "NFmid[%d] (%d) > MAX (%d), %s\n", i, h[i].privNF, limit->max, - (test_bit(NFCAL_INTF, &cal->cal_flags) ? + (cal->nfcal_interference ? "not corrected (due to interference)" : "correcting to MAX")); @@ -130,7 +130,7 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah, * we bypass this limit here in order to better deal * with our environment. */ - if (!test_bit(NFCAL_INTF, &cal->cal_flags)) + if (!cal->nfcal_interference) h[i].privNF = limit->max; } } @@ -141,7 +141,7 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah, * Re-enable the enforcement of the NF maximum again. */ if (!high_nf_mid) - clear_bit(NFCAL_INTF, &cal->cal_flags); + cal->nfcal_interference = false; } static bool ath9k_hw_get_nf_thresh(struct ath_hw *ah, @@ -186,6 +186,7 @@ void ath9k_hw_reset_calibration(struct ath_hw *ah, bool ath9k_hw_reset_calvalid(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); + struct ieee80211_conf *conf = &common->hw->conf; struct ath9k_cal_list *currCal = ah->cal_list_curr; if (!ah->caldata) @@ -207,7 +208,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah) return true; ath_dbg(common, CALIBRATE, "Resetting Cal %d state for channel %u\n", - currCal->calData->calType, ah->curchan->chan->center_freq); + currCal->calData->calType, conf->chandef.chan->center_freq); ah->caldata->CalValid &= ~currCal->calData->calType; currCal->calState = CAL_WAITING; @@ -219,7 +220,7 @@ EXPORT_SYMBOL(ath9k_hw_reset_calvalid); void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update) { if (ah->caldata) - set_bit(NFCAL_PENDING, &ah->caldata->cal_flags); + ah->caldata->nfcal_pending = true; REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_ENABLE_NF); @@ -241,6 +242,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) int32_t val; u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; struct ath_common *common = ath9k_hw_common(ah); + struct ieee80211_conf *conf = &common->hw->conf; s16 default_nf = ath9k_hw_get_default_nf(ah, chan); if (ah->caldata) @@ -250,7 +252,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) if (chainmask & (1 << i)) { s16 nfval; - if ((i >= AR5416_MAX_CHAINS) && !IS_CHAN_HT40(chan)) + if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)) continue; if (h) @@ -312,7 +314,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) ENABLE_REGWRITE_BUFFER(ah); for (i = 0; i < NUM_NF_READINGS; i++) { if (chainmask & (1 << i)) { - if ((i >= AR5416_MAX_CHAINS) && !IS_CHAN_HT40(chan)) + if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)) continue; val = REG_READ(ah, ah->nf_regs[i]); @@ -389,10 +391,10 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan) } h = caldata->nfCalHist; - clear_bit(NFCAL_PENDING, &caldata->cal_flags); + caldata->nfcal_pending = false; ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray); chan->noisefloor = h[0].privNF; - ah->noise = ath9k_hw_getchan_noise(ah, chan, chan->noisefloor); + ah->noise = ath9k_hw_getchan_noise(ah, chan); return true; } EXPORT_SYMBOL(ath9k_hw_getnf); @@ -406,6 +408,7 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, ah->caldata->channel = chan->channel; ah->caldata->channelFlags = chan->channelFlags; + ah->caldata->chanmode = chan->chanmode; h = ah->caldata->nfCalHist; default_nf = ath9k_hw_get_default_nf(ah, chan); for (i = 0; i < NUM_NF_READINGS; i++) { @@ -434,12 +437,12 @@ void ath9k_hw_bstuck_nfcal(struct ath_hw *ah) * the baseband update the internal NF value itself, similar to * what is being done after a full reset. */ - if (!test_bit(NFCAL_PENDING, &caldata->cal_flags)) + if (!caldata->nfcal_pending) ath9k_hw_start_nfcal(ah, true); else if (!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF)) ath9k_hw_getnf(ah, ah->curchan); - set_bit(NFCAL_INTF, &caldata->cal_flags); + caldata->nfcal_interference = true; } EXPORT_SYMBOL(ath9k_hw_bstuck_nfcal); diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h index b8ed95e..3d70b8c 100644 --- a/drivers/net/wireless/ath/ath9k/calib.h +++ b/drivers/net/wireless/ath/ath9k/calib.h @@ -116,8 +116,7 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, void ath9k_hw_bstuck_nfcal(struct ath_hw *ah); void ath9k_hw_reset_calibration(struct ath_hw *ah, struct ath9k_cal_list *currCal); -s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan, - s16 nf); +s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan); #endif /* CALIB_H */ diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index a7e5a05..d3063c2 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c @@ -49,64 +49,103 @@ int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb) } EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_keytype); +static u32 ath9k_get_extchanmode(struct cfg80211_chan_def *chandef) +{ + u32 chanmode = 0; + + switch (chandef->chan->band) { + case IEEE80211_BAND_2GHZ: + switch (chandef->width) { + case NL80211_CHAN_WIDTH_20_NOHT: + case NL80211_CHAN_WIDTH_20: + chanmode = CHANNEL_G_HT20; + break; + case NL80211_CHAN_WIDTH_40: + if (chandef->center_freq1 > chandef->chan->center_freq) + chanmode = CHANNEL_G_HT40PLUS; + else + chanmode = CHANNEL_G_HT40MINUS; + break; + default: + break; + } + break; + case IEEE80211_BAND_5GHZ: + switch (chandef->width) { + case NL80211_CHAN_WIDTH_20_NOHT: + case NL80211_CHAN_WIDTH_20: + chanmode = CHANNEL_A_HT20; + break; + case NL80211_CHAN_WIDTH_40: + if (chandef->center_freq1 > chandef->chan->center_freq) + chanmode = CHANNEL_A_HT40PLUS; + else + chanmode = CHANNEL_A_HT40MINUS; + break; + default: + break; + } + break; + default: + break; + } + + return chanmode; +} + /* * Update internal channel flags. */ -static void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, - struct cfg80211_chan_def *chandef) +void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, + struct cfg80211_chan_def *chandef) { - struct ieee80211_channel *chan = chandef->chan; - u16 flags = 0; - - ichan->channel = chan->center_freq; - ichan->chan = chan; - - if (chan->band == IEEE80211_BAND_5GHZ) - flags |= CHANNEL_5GHZ; + ichan->channel = chandef->chan->center_freq; + ichan->chan = chandef->chan; + + if (chandef->chan->band == IEEE80211_BAND_2GHZ) { + ichan->chanmode = CHANNEL_G; + ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM; + } else { + ichan->chanmode = CHANNEL_A; + ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; + } switch (chandef->width) { case NL80211_CHAN_WIDTH_5: - flags |= CHANNEL_QUARTER; + ichan->channelFlags |= CHANNEL_QUARTER; break; case NL80211_CHAN_WIDTH_10: - flags |= CHANNEL_HALF; + ichan->channelFlags |= CHANNEL_HALF; break; case NL80211_CHAN_WIDTH_20_NOHT: break; case NL80211_CHAN_WIDTH_20: - flags |= CHANNEL_HT; - break; case NL80211_CHAN_WIDTH_40: - if (chandef->center_freq1 > chandef->chan->center_freq) - flags |= CHANNEL_HT40PLUS | CHANNEL_HT; - else - flags |= CHANNEL_HT40MINUS | CHANNEL_HT; + ichan->chanmode = ath9k_get_extchanmode(chandef); break; default: WARN_ON(1); } - - ichan->channelFlags = flags; } +EXPORT_SYMBOL(ath9k_cmn_update_ichannel); /* * Get the internal channel reference. */ -struct ath9k_channel *ath9k_cmn_get_channel(struct ieee80211_hw *hw, - struct ath_hw *ah, - struct cfg80211_chan_def *chandef) +struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, + struct ath_hw *ah) { - struct ieee80211_channel *curchan = chandef->chan; + struct ieee80211_channel *curchan = hw->conf.chandef.chan; struct ath9k_channel *channel; u8 chan_idx; chan_idx = curchan->hw_value; channel = &ah->channels[chan_idx]; - ath9k_cmn_update_ichannel(channel, chandef); + ath9k_cmn_update_ichannel(channel, &hw->conf.chandef); return channel; } -EXPORT_SYMBOL(ath9k_cmn_get_channel); +EXPORT_SYMBOL(ath9k_cmn_get_curchannel); int ath9k_cmn_count_streams(unsigned int chainmask, int max) { diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index eb85e1b..e039bcb 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h @@ -43,9 +43,10 @@ (((x) + ((mul)/2)) / (mul)) int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); -struct ath9k_channel *ath9k_cmn_get_channel(struct ieee80211_hw *hw, - struct ath_hw *ah, - struct cfg80211_chan_def *chandef); +void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, + struct cfg80211_chan_def *chandef); +struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, + struct ath_hw *ah); int ath9k_cmn_count_streams(unsigned int chainmask, int max); void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common, enum ath_stomp_type stomp_type); diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 83a2c59..c088744 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -104,37 +104,37 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf, return -ENOMEM; if (common->disable_ani) { - len += scnprintf(buf + len, size - len, "%s: %s\n", - "ANI", "DISABLED"); + len += snprintf(buf + len, size - len, "%s: %s\n", + "ANI", "DISABLED"); goto exit; } - len += scnprintf(buf + len, size - len, "%15s: %s\n", - "ANI", "ENABLED"); - len += scnprintf(buf + len, size - len, "%15s: %u\n", - "ANI RESET", ah->stats.ast_ani_reset); - len += scnprintf(buf + len, size - len, "%15s: %u\n", - "SPUR UP", ah->stats.ast_ani_spurup); - len += scnprintf(buf + len, size - len, "%15s: %u\n", - "SPUR DOWN", ah->stats.ast_ani_spurup); - len += scnprintf(buf + len, size - len, "%15s: %u\n", - "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon); - len += scnprintf(buf + len, size - len, "%15s: %u\n", - "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff); - len += scnprintf(buf + len, size - len, "%15s: %u\n", - "MRC-CCK ON", ah->stats.ast_ani_ccklow); - len += scnprintf(buf + len, size - len, "%15s: %u\n", - "MRC-CCK OFF", ah->stats.ast_ani_cckhigh); - len += scnprintf(buf + len, size - len, "%15s: %u\n", - "FIR-STEP UP", ah->stats.ast_ani_stepup); - len += scnprintf(buf + len, size - len, "%15s: %u\n", - "FIR-STEP DOWN", ah->stats.ast_ani_stepdown); - len += scnprintf(buf + len, size - len, "%15s: %u\n", - "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero); - len += scnprintf(buf + len, size - len, "%15s: %u\n", - "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs); - len += scnprintf(buf + len, size - len, "%15s: %u\n", - "CCK ERRORS", ah->stats.ast_ani_cckerrs); + len += snprintf(buf + len, size - len, "%15s: %s\n", + "ANI", "ENABLED"); + len += snprintf(buf + len, size - len, "%15s: %u\n", + "ANI RESET", ah->stats.ast_ani_reset); + len += snprintf(buf + len, size - len, "%15s: %u\n", + "SPUR UP", ah->stats.ast_ani_spurup); + len += snprintf(buf + len, size - len, "%15s: %u\n", + "SPUR DOWN", ah->stats.ast_ani_spurup); + len += snprintf(buf + len, size - len, "%15s: %u\n", + "OFDM WS-DET ON", ah->stats.ast_ani_ofdmon); + len += snprintf(buf + len, size - len, "%15s: %u\n", + "OFDM WS-DET OFF", ah->stats.ast_ani_ofdmoff); + len += snprintf(buf + len, size - len, "%15s: %u\n", + "MRC-CCK ON", ah->stats.ast_ani_ccklow); + len += snprintf(buf + len, size - len, "%15s: %u\n", + "MRC-CCK OFF", ah->stats.ast_ani_cckhigh); + len += snprintf(buf + len, size - len, "%15s: %u\n", + "FIR-STEP UP", ah->stats.ast_ani_stepup); + len += snprintf(buf + len, size - len, "%15s: %u\n", + "FIR-STEP DOWN", ah->stats.ast_ani_stepdown); + len += snprintf(buf + len, size - len, "%15s: %u\n", + "INV LISTENTIME", ah->stats.ast_ani_lneg_or_lzero); + len += snprintf(buf + len, size - len, "%15s: %u\n", + "OFDM ERRORS", ah->stats.ast_ani_ofdmerrs); + len += snprintf(buf + len, size - len, "%15s: %u\n", + "CCK ERRORS", ah->stats.ast_ani_cckerrs); exit: if (len > size) len = size; @@ -280,70 +280,70 @@ static ssize_t read_file_antenna_diversity(struct file *file, return -ENOMEM; if (!(pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)) { - len += scnprintf(buf + len, size - len, "%s\n", - "Antenna Diversity Combining is disabled"); + len += snprintf(buf + len, size - len, "%s\n", + "Antenna Diversity Combining is disabled"); goto exit; } ath9k_ps_wakeup(sc); ath9k_hw_antdiv_comb_conf_get(ah, &div_ant_conf); - len += scnprintf(buf + len, size - len, "Current MAIN config : %s\n", - lna_conf_str[div_ant_conf.main_lna_conf]); - len += scnprintf(buf + len, size - len, "Current ALT config : %s\n", - lna_conf_str[div_ant_conf.alt_lna_conf]); - len += scnprintf(buf + len, size - len, "Average MAIN RSSI : %d\n", - as_main->rssi_avg); - len += scnprintf(buf + len, size - len, "Average ALT RSSI : %d\n\n", - as_alt->rssi_avg); + len += snprintf(buf + len, size - len, "Current MAIN config : %s\n", + lna_conf_str[div_ant_conf.main_lna_conf]); + len += snprintf(buf + len, size - len, "Current ALT config : %s\n", + lna_conf_str[div_ant_conf.alt_lna_conf]); + len += snprintf(buf + len, size - len, "Average MAIN RSSI : %d\n", + as_main->rssi_avg); + len += snprintf(buf + len, size - len, "Average ALT RSSI : %d\n\n", + as_alt->rssi_avg); ath9k_ps_restore(sc); - len += scnprintf(buf + len, size - len, "Packet Receive Cnt:\n"); - len += scnprintf(buf + len, size - len, "-------------------\n"); - - len += scnprintf(buf + len, size - len, "%30s%15s\n", - "MAIN", "ALT"); - len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", - "TOTAL COUNT", - as_main->recv_cnt, - as_alt->recv_cnt); - len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", - "LNA1", - as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1], - as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1]); - len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", - "LNA2", - as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2], - as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2]); - len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", - "LNA1 + LNA2", - as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2], - as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]); - len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", - "LNA1 - LNA2", - as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2], - as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]); - - len += scnprintf(buf + len, size - len, "\nLNA Config Attempts:\n"); - len += scnprintf(buf + len, size - len, "--------------------\n"); - - len += scnprintf(buf + len, size - len, "%30s%15s\n", - "MAIN", "ALT"); - len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", - "LNA1", - as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1], - as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1]); - len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", - "LNA2", - as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2], - as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2]); - len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", - "LNA1 + LNA2", - as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2], - as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]); - len += scnprintf(buf + len, size - len, "%-14s:%15d%15d\n", - "LNA1 - LNA2", - as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2], - as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]); + len += snprintf(buf + len, size - len, "Packet Receive Cnt:\n"); + len += snprintf(buf + len, size - len, "-------------------\n"); + + len += snprintf(buf + len, size - len, "%30s%15s\n", + "MAIN", "ALT"); + len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", + "TOTAL COUNT", + as_main->recv_cnt, + as_alt->recv_cnt); + len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", + "LNA1", + as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1], + as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1]); + len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", + "LNA2", + as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2], + as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA2]); + len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", + "LNA1 + LNA2", + as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2], + as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]); + len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", + "LNA1 - LNA2", + as_main->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2], + as_alt->lna_recv_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]); + + len += snprintf(buf + len, size - len, "\nLNA Config Attempts:\n"); + len += snprintf(buf + len, size - len, "--------------------\n"); + + len += snprintf(buf + len, size - len, "%30s%15s\n", + "MAIN", "ALT"); + len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", + "LNA1", + as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1], + as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1]); + len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", + "LNA2", + as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2], + as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA2]); + len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", + "LNA1 + LNA2", + as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2], + as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2]); + len += snprintf(buf + len, size - len, "%-14s:%15d%15d\n", + "LNA1 - LNA2", + as_main->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2], + as_alt->lna_attempt_cnt[ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2]); exit: if (len > size) @@ -385,21 +385,21 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf, (AR_MACMISC_MISC_OBS_BUS_1 << AR_MACMISC_MISC_OBS_BUS_MSB_S))); - len += scnprintf(buf + len, DMA_BUF_LEN - len, - "Raw DMA Debug values:\n"); + len += snprintf(buf + len, DMA_BUF_LEN - len, + "Raw DMA Debug values:\n"); for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) { if (i % 4 == 0) - len += scnprintf(buf + len, DMA_BUF_LEN - len, "\n"); + len += snprintf(buf + len, DMA_BUF_LEN - len, "\n"); val[i] = REG_READ_D(ah, AR_DMADBG_0 + (i * sizeof(u32))); - len += scnprintf(buf + len, DMA_BUF_LEN - len, "%d: %08x ", - i, val[i]); + len += snprintf(buf + len, DMA_BUF_LEN - len, "%d: %08x ", + i, val[i]); } - len += scnprintf(buf + len, DMA_BUF_LEN - len, "\n\n"); - len += scnprintf(buf + len, DMA_BUF_LEN - len, - "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n"); + len += snprintf(buf + len, DMA_BUF_LEN - len, "\n\n"); + len += snprintf(buf + len, DMA_BUF_LEN - len, + "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n"); for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) { if (i == 8) { @@ -412,39 +412,39 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf, dcuBase++; } - len += scnprintf(buf + len, DMA_BUF_LEN - len, - "%2d %2x %1x %2x %2x\n", - i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset, - (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3), - val[2] & (0x7 << (i * 3)) >> (i * 3), - (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset); + len += snprintf(buf + len, DMA_BUF_LEN - len, + "%2d %2x %1x %2x %2x\n", + i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset, + (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3), + val[2] & (0x7 << (i * 3)) >> (i * 3), + (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset); } - len += scnprintf(buf + len, DMA_BUF_LEN - len, "\n"); + len += snprintf(buf + len, DMA_BUF_LEN - len, "\n"); - len += scnprintf(buf + len, DMA_BUF_LEN - len, + len += snprintf(buf + len, DMA_BUF_LEN - len, "qcu_stitch state: %2x qcu_fetch state: %2x\n", (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22); - len += scnprintf(buf + len, DMA_BUF_LEN - len, + len += snprintf(buf + len, DMA_BUF_LEN - len, "qcu_complete state: %2x dcu_complete state: %2x\n", (val[3] & 0x1c000000) >> 26, (val[6] & 0x3)); - len += scnprintf(buf + len, DMA_BUF_LEN - len, + len += snprintf(buf + len, DMA_BUF_LEN - len, "dcu_arb state: %2x dcu_fp state: %2x\n", (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27); - len += scnprintf(buf + len, DMA_BUF_LEN - len, + len += snprintf(buf + len, DMA_BUF_LEN - len, "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n", (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10); - len += scnprintf(buf + len, DMA_BUF_LEN - len, + len += snprintf(buf + len, DMA_BUF_LEN - len, "txfifo_valid_0: %1d txfifo_valid_1: %1d\n", (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12); - len += scnprintf(buf + len, DMA_BUF_LEN - len, + len += snprintf(buf + len, DMA_BUF_LEN - len, "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n", (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17); - len += scnprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x\n", - REG_READ_D(ah, AR_OBS_BUS_1)); - len += scnprintf(buf + len, DMA_BUF_LEN - len, - "AR_CR: 0x%x\n", REG_READ_D(ah, AR_CR)); + len += snprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x\n", + REG_READ_D(ah, AR_OBS_BUS_1)); + len += snprintf(buf + len, DMA_BUF_LEN - len, + "AR_CR: 0x%x\n", REG_READ_D(ah, AR_CR)); ath9k_ps_restore(sc); @@ -530,9 +530,9 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, #define PR_IS(a, s) \ do { \ - len += scnprintf(buf + len, mxlen - len, \ - "%21s: %10u\n", a, \ - sc->debug.stats.istats.s); \ + len += snprintf(buf + len, mxlen - len, \ + "%21s: %10u\n", a, \ + sc->debug.stats.istats.s); \ } while (0) if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { @@ -563,8 +563,8 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, PR_IS("GENTIMER", gen_timer); PR_IS("TOTAL", total); - len += scnprintf(buf + len, mxlen - len, - "SYNC_CAUSE stats:\n"); + len += snprintf(buf + len, mxlen - len, + "SYNC_CAUSE stats:\n"); PR_IS("Sync-All", sync_cause_all); PR_IS("RTC-IRQ", sync_rtc_irq); @@ -655,16 +655,16 @@ static ssize_t print_queue(struct ath_softc *sc, struct ath_txq *txq, ath_txq_lock(sc, txq); - len += scnprintf(buf + len, size - len, "%s: %d ", - "qnum", txq->axq_qnum); - len += scnprintf(buf + len, size - len, "%s: %2d ", - "qdepth", txq->axq_depth); - len += scnprintf(buf + len, size - len, "%s: %2d ", - "ampdu-depth", txq->axq_ampdu_depth); - len += scnprintf(buf + len, size - len, "%s: %3d ", - "pending", txq->pending_frames); - len += scnprintf(buf + len, size - len, "%s: %d\n", - "stopped", txq->stopped); + len += snprintf(buf + len, size - len, "%s: %d ", + "qnum", txq->axq_qnum); + len += snprintf(buf + len, size - len, "%s: %2d ", + "qdepth", txq->axq_depth); + len += snprintf(buf + len, size - len, "%s: %2d ", + "ampdu-depth", txq->axq_ampdu_depth); + len += snprintf(buf + len, size - len, "%s: %3d ", + "pending", txq->pending_frames); + len += snprintf(buf + len, size - len, "%s: %d\n", + "stopped", txq->stopped); ath_txq_unlock(sc, txq); return len; @@ -687,11 +687,11 @@ static ssize_t read_file_queues(struct file *file, char __user *user_buf, for (i = 0; i < IEEE80211_NUM_ACS; i++) { txq = sc->tx.txq_map[i]; - len += scnprintf(buf + len, size - len, "(%s): ", qname[i]); + len += snprintf(buf + len, size - len, "(%s): ", qname[i]); len += print_queue(sc, txq, buf + len, size - len); } - len += scnprintf(buf + len, size - len, "(CAB): "); + len += snprintf(buf + len, size - len, "(CAB): "); len += print_queue(sc, sc->beacon.cabq, buf + len, size - len); if (len > size) @@ -716,82 +716,80 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, unsigned int reg; u32 rxfilter; - len += scnprintf(buf + len, sizeof(buf) - len, - "BSSID: %pM\n", common->curbssid); - len += scnprintf(buf + len, sizeof(buf) - len, - "BSSID-MASK: %pM\n", common->bssidmask); - len += scnprintf(buf + len, sizeof(buf) - len, - "OPMODE: %s\n", - ath_opmode_to_string(sc->sc_ah->opmode)); + len += snprintf(buf + len, sizeof(buf) - len, + "BSSID: %pM\n", common->curbssid); + len += snprintf(buf + len, sizeof(buf) - len, + "BSSID-MASK: %pM\n", common->bssidmask); + len += snprintf(buf + len, sizeof(buf) - len, + "OPMODE: %s\n", ath_opmode_to_string(sc->sc_ah->opmode)); ath9k_ps_wakeup(sc); rxfilter = ath9k_hw_getrxfilter(sc->sc_ah); ath9k_ps_restore(sc); - len += scnprintf(buf + len, sizeof(buf) - len, - "RXFILTER: 0x%x", rxfilter); + len += snprintf(buf + len, sizeof(buf) - len, + "RXFILTER: 0x%x", rxfilter); if (rxfilter & ATH9K_RX_FILTER_UCAST) - len += scnprintf(buf + len, sizeof(buf) - len, " UCAST"); + len += snprintf(buf + len, sizeof(buf) - len, " UCAST"); if (rxfilter & ATH9K_RX_FILTER_MCAST) - len += scnprintf(buf + len, sizeof(buf) - len, " MCAST"); + len += snprintf(buf + len, sizeof(buf) - len, " MCAST"); if (rxfilter & ATH9K_RX_FILTER_BCAST) - len += scnprintf(buf + len, sizeof(buf) - len, " BCAST"); + len += snprintf(buf + len, sizeof(buf) - len, " BCAST"); if (rxfilter & ATH9K_RX_FILTER_CONTROL) - len += scnprintf(buf + len, sizeof(buf) - len, " CONTROL"); + len += snprintf(buf + len, sizeof(buf) - len, " CONTROL"); if (rxfilter & ATH9K_RX_FILTER_BEACON) - len += scnprintf(buf + len, sizeof(buf) - len, " BEACON"); + len += snprintf(buf + len, sizeof(buf) - len, " BEACON"); if (rxfilter & ATH9K_RX_FILTER_PROM) - len += scnprintf(buf + len, sizeof(buf) - len, " PROM"); + len += snprintf(buf + len, sizeof(buf) - len, " PROM"); if (rxfilter & ATH9K_RX_FILTER_PROBEREQ) - len += scnprintf(buf + len, sizeof(buf) - len, " PROBEREQ"); + len += snprintf(buf + len, sizeof(buf) - len, " PROBEREQ"); if (rxfilter & ATH9K_RX_FILTER_PHYERR) - len += scnprintf(buf + len, sizeof(buf) - len, " PHYERR"); + len += snprintf(buf + len, sizeof(buf) - len, " PHYERR"); if (rxfilter & ATH9K_RX_FILTER_MYBEACON) - len += scnprintf(buf + len, sizeof(buf) - len, " MYBEACON"); + len += snprintf(buf + len, sizeof(buf) - len, " MYBEACON"); if (rxfilter & ATH9K_RX_FILTER_COMP_BAR) - len += scnprintf(buf + len, sizeof(buf) - len, " COMP_BAR"); + len += snprintf(buf + len, sizeof(buf) - len, " COMP_BAR"); if (rxfilter & ATH9K_RX_FILTER_PSPOLL) - len += scnprintf(buf + len, sizeof(buf) - len, " PSPOLL"); + len += snprintf(buf + len, sizeof(buf) - len, " PSPOLL"); if (rxfilter & ATH9K_RX_FILTER_PHYRADAR) - len += scnprintf(buf + len, sizeof(buf) - len, " PHYRADAR"); + len += snprintf(buf + len, sizeof(buf) - len, " PHYRADAR"); if (rxfilter & ATH9K_RX_FILTER_MCAST_BCAST_ALL) - len += scnprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL"); + len += snprintf(buf + len, sizeof(buf) - len, " MCAST_BCAST_ALL"); if (rxfilter & ATH9K_RX_FILTER_CONTROL_WRAPPER) - len += scnprintf(buf + len, sizeof(buf) - len, " CONTROL_WRAPPER"); + len += snprintf(buf + len, sizeof(buf) - len, " CONTROL_WRAPPER"); - len += scnprintf(buf + len, sizeof(buf) - len, "\n"); + len += snprintf(buf + len, sizeof(buf) - len, "\n"); reg = sc->sc_ah->imask; - len += scnprintf(buf + len, sizeof(buf) - len, - "INTERRUPT-MASK: 0x%x", reg); + len += snprintf(buf + len, sizeof(buf) - len, "INTERRUPT-MASK: 0x%x", reg); if (reg & ATH9K_INT_SWBA) - len += scnprintf(buf + len, sizeof(buf) - len, " SWBA"); + len += snprintf(buf + len, sizeof(buf) - len, " SWBA"); if (reg & ATH9K_INT_BMISS) - len += scnprintf(buf + len, sizeof(buf) - len, " BMISS"); + len += snprintf(buf + len, sizeof(buf) - len, " BMISS"); if (reg & ATH9K_INT_CST) - len += scnprintf(buf + len, sizeof(buf) - len, " CST"); + len += snprintf(buf + len, sizeof(buf) - len, " CST"); if (reg & ATH9K_INT_RX) - len += scnprintf(buf + len, sizeof(buf) - len, " RX"); + len += snprintf(buf + len, sizeof(buf) - len, " RX"); if (reg & ATH9K_INT_RXHP) - len += scnprintf(buf + len, sizeof(buf) - len, " RXHP"); + len += snprintf(buf + len, sizeof(buf) - len, " RXHP"); if (reg & ATH9K_INT_RXLP) - len += scnprintf(buf + len, sizeof(buf) - len, " RXLP"); + len += snprintf(buf + len, sizeof(buf) - len, " RXLP"); if (reg & ATH9K_INT_BB_WATCHDOG) - len += scnprintf(buf + len, sizeof(buf) - len, " BB_WATCHDOG"); + len += snprintf(buf + len, sizeof(buf) - len, " BB_WATCHDOG"); - len += scnprintf(buf + len, sizeof(buf) - len, "\n"); + len += snprintf(buf + len, sizeof(buf) - len, "\n"); ath9k_calculate_iter_data(hw, NULL, &iter_data); - len += scnprintf(buf + len, sizeof(buf) - len, - "VIF-COUNTS: AP: %i STA: %i MESH: %i WDS: %i" - " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n", - iter_data.naps, iter_data.nstations, iter_data.nmeshes, - iter_data.nwds, iter_data.nadhocs, - sc->nvifs, sc->nbcnvifs); + len += snprintf(buf + len, sizeof(buf) - len, + "VIF-COUNTS: AP: %i STA: %i MESH: %i WDS: %i" + " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n", + iter_data.naps, iter_data.nstations, iter_data.nmeshes, + iter_data.nwds, iter_data.nadhocs, + sc->nvifs, sc->nbcnvifs); if (len > sizeof(buf)) len = sizeof(buf); @@ -807,27 +805,27 @@ static ssize_t read_file_reset(struct file *file, char __user *user_buf, char buf[512]; unsigned int len = 0; - len += scnprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "Baseband Hang", - sc->debug.stats.reset[RESET_TYPE_BB_HANG]); - len += scnprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "Baseband Watchdog", - sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG]); - len += scnprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "Fatal HW Error", - sc->debug.stats.reset[RESET_TYPE_FATAL_INT]); - len += scnprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "TX HW error", - sc->debug.stats.reset[RESET_TYPE_TX_ERROR]); - len += scnprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "TX Path Hang", - sc->debug.stats.reset[RESET_TYPE_TX_HANG]); - len += scnprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "PLL RX Hang", - sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); - len += scnprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "MCI Reset", - sc->debug.stats.reset[RESET_TYPE_MCI]); + len += snprintf(buf + len, sizeof(buf) - len, + "%17s: %2d\n", "Baseband Hang", + sc->debug.stats.reset[RESET_TYPE_BB_HANG]); + len += snprintf(buf + len, sizeof(buf) - len, + "%17s: %2d\n", "Baseband Watchdog", + sc->debug.stats.reset[RESET_TYPE_BB_WATCHDOG]); + len += snprintf(buf + len, sizeof(buf) - len, + "%17s: %2d\n", "Fatal HW Error", + sc->debug.stats.reset[RESET_TYPE_FATAL_INT]); + len += snprintf(buf + len, sizeof(buf) - len, + "%17s: %2d\n", "TX HW error", + sc->debug.stats.reset[RESET_TYPE_TX_ERROR]); + len += snprintf(buf + len, sizeof(buf) - len, + "%17s: %2d\n", "TX Path Hang", + sc->debug.stats.reset[RESET_TYPE_TX_HANG]); + len += snprintf(buf + len, sizeof(buf) - len, + "%17s: %2d\n", "PLL RX Hang", + sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); + len += snprintf(buf + len, sizeof(buf) - len, + "%17s: %2d\n", "MCI Reset", + sc->debug.stats.reset[RESET_TYPE_MCI]); if (len > sizeof(buf)) len = sizeof(buf); @@ -904,14 +902,14 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { #define PHY_ERR(s, p) \ - len += scnprintf(buf + len, size - len, "%22s : %10u\n", s, \ - sc->debug.stats.rxstats.phy_err_stats[p]); + len += snprintf(buf + len, size - len, "%22s : %10u\n", s, \ + sc->debug.stats.rxstats.phy_err_stats[p]); #define RXS_ERR(s, e) \ do { \ - len += scnprintf(buf + len, size - len, \ - "%22s : %10u\n", s, \ - sc->debug.stats.rxstats.e);\ + len += snprintf(buf + len, size - len, \ + "%22s : %10u\n", s, \ + sc->debug.stats.rxstats.e); \ } while (0) struct ath_softc *sc = file->private_data; @@ -1050,9 +1048,6 @@ static ssize_t write_file_spec_scan_ctl(struct file *file, char buf[32]; ssize_t len; - if (config_enabled(CONFIG_ATH9K_TX99)) - return -EOPNOTSUPP; - len = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, len)) return -EFAULT; @@ -1444,22 +1439,22 @@ static ssize_t read_file_dump_nfcal(struct file *file, char __user *user_buf, if (!buf) return -ENOMEM; - len += scnprintf(buf + len, size - len, - "Channel Noise Floor : %d\n", ah->noise); - len += scnprintf(buf + len, size - len, - "Chain | privNF | # Readings | NF Readings\n"); + len += snprintf(buf + len, size - len, + "Channel Noise Floor : %d\n", ah->noise); + len += snprintf(buf + len, size - len, + "Chain | privNF | # Readings | NF Readings\n"); for (i = 0; i < NUM_NF_READINGS; i++) { if (!(chainmask & (1 << i)) || ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))) continue; nread = AR_PHY_CCA_FILTERWINDOW_LENGTH - h[i].invalidNFcount; - len += scnprintf(buf + len, size - len, " %d\t %d\t %d\t\t", - i, h[i].privNF, nread); + len += snprintf(buf + len, size - len, " %d\t %d\t %d\t\t", + i, h[i].privNF, nread); for (j = 0; j < nread; j++) - len += scnprintf(buf + len, size - len, - " %d", h[i].nfCalBuffer[j]); - len += scnprintf(buf + len, size - len, "\n"); + len += snprintf(buf + len, size - len, + " %d", h[i].nfCalBuffer[j]); + len += snprintf(buf + len, size - len, "\n"); } if (len > size) @@ -1548,8 +1543,8 @@ static ssize_t read_file_btcoex(struct file *file, char __user *user_buf, return -ENOMEM; if (!sc->sc_ah->common.btcoex_enabled) { - len = scnprintf(buf, size, "%s\n", - "BTCOEX is disabled"); + len = snprintf(buf, size, "%s\n", + "BTCOEX is disabled"); goto exit; } @@ -1587,43 +1582,43 @@ static ssize_t read_file_node_stat(struct file *file, char __user *user_buf, return -ENOMEM; if (!an->sta->ht_cap.ht_supported) { - len = scnprintf(buf, size, "%s\n", - "HT not supported"); + len = snprintf(buf, size, "%s\n", + "HT not supported"); goto exit; } - len = scnprintf(buf, size, "Max-AMPDU: %d\n", - an->maxampdu); - len += scnprintf(buf + len, size - len, "MPDU Density: %d\n\n", - an->mpdudensity); + len = snprintf(buf, size, "Max-AMPDU: %d\n", + an->maxampdu); + len += snprintf(buf + len, size - len, "MPDU Density: %d\n\n", + an->mpdudensity); - len += scnprintf(buf + len, size - len, - "%2s%7s\n", "AC", "SCHED"); + len += snprintf(buf + len, size - len, + "%2s%7s\n", "AC", "SCHED"); for (acno = 0, ac = &an->ac[acno]; acno < IEEE80211_NUM_ACS; acno++, ac++) { txq = ac->txq; ath_txq_lock(sc, txq); - len += scnprintf(buf + len, size - len, - "%2d%7d\n", - acno, ac->sched); + len += snprintf(buf + len, size - len, + "%2d%7d\n", + acno, ac->sched); ath_txq_unlock(sc, txq); } - len += scnprintf(buf + len, size - len, - "\n%3s%11s%10s%10s%10s%10s%9s%6s%8s\n", - "TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE", - "BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED"); + len += snprintf(buf + len, size - len, + "\n%3s%11s%10s%10s%10s%10s%9s%6s%8s\n", + "TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE", + "BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED"); for (tidno = 0, tid = &an->tid[tidno]; tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { txq = tid->ac->txq; ath_txq_lock(sc, txq); - len += scnprintf(buf + len, size - len, - "%3d%11d%10d%10d%10d%10d%9d%6d%8d\n", - tid->tidno, tid->seq_start, tid->seq_next, - tid->baw_size, tid->baw_head, tid->baw_tail, - tid->bar_index, tid->sched, tid->paused); + len += snprintf(buf + len, size - len, + "%3d%11d%10d%10d%10d%10d%9d%6d%8d\n", + tid->tidno, tid->seq_start, tid->seq_next, + tid->baw_size, tid->baw_head, tid->baw_tail, + tid->bar_index, tid->sched, tid->paused); ath_txq_unlock(sc, txq); } exit: @@ -1778,111 +1773,6 @@ void ath9k_deinit_debug(struct ath_softc *sc) } } -static ssize_t read_file_tx99(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath_softc *sc = file->private_data; - char buf[3]; - unsigned int len; - - len = sprintf(buf, "%d\n", sc->tx99_state); - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static ssize_t write_file_tx99(struct file *file, const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath_softc *sc = file->private_data; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - char buf[32]; - bool start; - ssize_t len; - int r; - - if (sc->nvifs > 1) - return -EOPNOTSUPP; - - len = min(count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, len)) - return -EFAULT; - - if (strtobool(buf, &start)) - return -EINVAL; - - if (start == sc->tx99_state) { - if (!start) - return count; - ath_dbg(common, XMIT, "Resetting TX99\n"); - ath9k_tx99_deinit(sc); - } - - if (!start) { - ath9k_tx99_deinit(sc); - return count; - } - - r = ath9k_tx99_init(sc); - if (r) - return r; - - return count; -} - -static const struct file_operations fops_tx99 = { - .read = read_file_tx99, - .write = write_file_tx99, - .open = simple_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -static ssize_t read_file_tx99_power(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath_softc *sc = file->private_data; - char buf[32]; - unsigned int len; - - len = sprintf(buf, "%d (%d dBm)\n", - sc->tx99_power, - sc->tx99_power / 2); - - return simple_read_from_buffer(user_buf, count, ppos, buf, len); -} - -static ssize_t write_file_tx99_power(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath_softc *sc = file->private_data; - int r; - u8 tx_power; - - r = kstrtou8_from_user(user_buf, count, 0, &tx_power); - if (r) - return r; - - if (tx_power > MAX_RATE_POWER) - return -EINVAL; - - sc->tx99_power = tx_power; - - ath9k_ps_wakeup(sc); - ath9k_hw_tx99_set_txpower(sc->sc_ah, sc->tx99_power); - ath9k_ps_restore(sc); - - return count; -} - -static const struct file_operations fops_tx99_power = { - .read = read_file_tx99_power, - .write = write_file_tx99_power, - .open = simple_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - int ath9k_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); @@ -1974,15 +1864,5 @@ int ath9k_init_debug(struct ath_hw *ah) debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_btcoex); #endif - if (config_enabled(CONFIG_ATH9K_TX99) && - AR_SREV_9300_20_OR_LATER(ah)) { - debugfs_create_file("tx99", S_IRUSR | S_IWUSR, - sc->debug.debugfs_phy, sc, - &fops_tx99); - debugfs_create_file("tx99_power", S_IRUSR | S_IWUSR, - sc->debug.debugfs_phy, sc, - &fops_tx99_power); - } - return 0; } diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index d6e3fa4..6e1556f 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -193,12 +193,12 @@ struct ath_tx_stats { #define TXSTATS sc->debug.stats.txstats #define PR(str, elem) \ do { \ - len += scnprintf(buf + len, size - len, \ - "%s%13u%11u%10u%10u\n", str, \ - TXSTATS[PR_QNUM(IEEE80211_AC_BE)].elem,\ - TXSTATS[PR_QNUM(IEEE80211_AC_BK)].elem,\ - TXSTATS[PR_QNUM(IEEE80211_AC_VI)].elem,\ - TXSTATS[PR_QNUM(IEEE80211_AC_VO)].elem); \ + len += snprintf(buf + len, size - len, \ + "%s%13u%11u%10u%10u\n", str, \ + TXSTATS[PR_QNUM(IEEE80211_AC_BE)].elem, \ + TXSTATS[PR_QNUM(IEEE80211_AC_BK)].elem, \ + TXSTATS[PR_QNUM(IEEE80211_AC_VI)].elem, \ + TXSTATS[PR_QNUM(IEEE80211_AC_VO)].elem); \ } while(0) #define RX_STAT_INC(c) (sc->debug.stats.rxstats.c++) diff --git a/drivers/net/wireless/ath/ath9k/dfs.h b/drivers/net/wireless/ath/ath9k/dfs.h index c6fa3d5..3c839f0 100644 --- a/drivers/net/wireless/ath/ath9k/dfs.h +++ b/drivers/net/wireless/ath/ath9k/dfs.h @@ -17,7 +17,7 @@ #ifndef ATH9K_DFS_H #define ATH9K_DFS_H -#include "../dfs_pattern_detector.h" +#include "dfs_pattern_detector.h" #if defined(CONFIG_ATH9K_DFS_CERTIFIED) /** diff --git a/drivers/net/wireless/ath/ath9k/dfs_debug.c b/drivers/net/wireless/ath/ath9k/dfs_debug.c index 8824610..3c6e413 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_debug.c +++ b/drivers/net/wireless/ath/ath9k/dfs_debug.c @@ -20,16 +20,16 @@ #include "ath9k.h" #include "dfs_debug.h" -#include "../dfs_pattern_detector.h" -static struct ath_dfs_pool_stats dfs_pool_stats = { 0 }; + +struct ath_dfs_pool_stats global_dfs_pool_stats = { 0 }; #define ATH9K_DFS_STAT(s, p) \ - len += scnprintf(buf + len, size - len, "%28s : %10u\n", s, \ - sc->debug.stats.dfs_stats.p); + len += snprintf(buf + len, size - len, "%28s : %10u\n", s, \ + sc->debug.stats.dfs_stats.p); #define ATH9K_DFS_POOL_STAT(s, p) \ - len += scnprintf(buf + len, size - len, "%28s : %10u\n", s, \ - dfs_pool_stats.p); + len += snprintf(buf + len, size - len, "%28s : %10u\n", s, \ + global_dfs_pool_stats.p); static ssize_t read_file_dfs(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -44,21 +44,12 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf, if (buf == NULL) return -ENOMEM; - len += scnprintf(buf + len, size - len, "DFS support for " - "macVersion = 0x%x, macRev = 0x%x: %s\n", - hw_ver->macVersion, hw_ver->macRev, - (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_DFS) ? + len += snprintf(buf + len, size - len, "DFS support for " + "macVersion = 0x%x, macRev = 0x%x: %s\n", + hw_ver->macVersion, hw_ver->macRev, + (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_DFS) ? "enabled" : "disabled"); - - if (!sc->dfs_detector) { - len += scnprintf(buf + len, size - len, - "DFS detector not enabled\n"); - goto exit; - } - - dfs_pool_stats = sc->dfs_detector->get_stats(sc->dfs_detector); - - len += scnprintf(buf + len, size - len, "Pulse detector statistics:\n"); + len += snprintf(buf + len, size - len, "Pulse detector statistics:\n"); ATH9K_DFS_STAT("pulse events reported ", pulses_total); ATH9K_DFS_STAT("invalid pulse events ", pulses_no_dfs); ATH9K_DFS_STAT("DFS pulses detected ", pulses_detected); @@ -68,12 +59,11 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf, ATH9K_DFS_STAT("Primary channel pulses ", pri_phy_errors); ATH9K_DFS_STAT("Secondary channel pulses", ext_phy_errors); ATH9K_DFS_STAT("Dual channel pulses ", dc_phy_errors); - len += scnprintf(buf + len, size - len, "Radar detector statistics " - "(current DFS region: %d)\n", - sc->dfs_detector->region); + len += snprintf(buf + len, size - len, "Radar detector statistics " + "(current DFS region: %d)\n", sc->dfs_detector->region); ATH9K_DFS_STAT("Pulse events processed ", pulses_processed); ATH9K_DFS_STAT("Radars detected ", radar_detected); - len += scnprintf(buf + len, size - len, "Global Pool statistics:\n"); + len += snprintf(buf + len, size - len, "Global Pool statistics:\n"); ATH9K_DFS_POOL_STAT("Pool references ", pool_reference); ATH9K_DFS_POOL_STAT("Pulses allocated ", pulse_allocated); ATH9K_DFS_POOL_STAT("Pulses alloc error ", pulse_alloc_error); @@ -82,7 +72,6 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf, ATH9K_DFS_POOL_STAT("Seqs. alloc error ", pseq_alloc_error); ATH9K_DFS_POOL_STAT("Seqs. in use ", pseq_used); -exit: if (len > size) len = size; diff --git a/drivers/net/wireless/ath/ath9k/dfs_debug.h b/drivers/net/wireless/ath/ath9k/dfs_debug.h index 0a7ddf4..e36810a 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_debug.h +++ b/drivers/net/wireless/ath/ath9k/dfs_debug.h @@ -51,11 +51,25 @@ struct ath_dfs_stats { u32 radar_detected; }; +/** + * struct ath_dfs_pool_stats - DFS Statistics for global pools + */ +struct ath_dfs_pool_stats { + u32 pool_reference; + u32 pulse_allocated; + u32 pulse_alloc_error; + u32 pulse_used; + u32 pseq_allocated; + u32 pseq_alloc_error; + u32 pseq_used; +}; #if defined(CONFIG_ATH9K_DFS_DEBUGFS) #define DFS_STAT_INC(sc, c) (sc->debug.stats.dfs_stats.c++) void ath9k_dfs_init_debug(struct ath_softc *sc); +#define DFS_POOL_STAT_INC(c) (global_dfs_pool_stats.c++) +#define DFS_POOL_STAT_DEC(c) (global_dfs_pool_stats.c--) extern struct ath_dfs_pool_stats global_dfs_pool_stats; #else @@ -63,6 +77,8 @@ extern struct ath_dfs_pool_stats global_dfs_pool_stats; #define DFS_STAT_INC(sc, c) do { } while (0) static inline void ath9k_dfs_init_debug(struct ath_softc *sc) { } +#define DFS_POOL_STAT_INC(c) do { } while (0) +#define DFS_POOL_STAT_DEC(c) do { } while (0) #endif /* CONFIG_ATH9K_DFS_DEBUGFS */ #endif /* ATH9K_DFS_DEBUG_H */ diff --git a/drivers/net/wireless/ath/dfs_pattern_detector.c b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c index a1a69c5..491305c 100644 --- a/drivers/net/wireless/ath/dfs_pattern_detector.c +++ b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c @@ -19,7 +19,7 @@ #include "dfs_pattern_detector.h" #include "dfs_pri_detector.h" -#include "ath.h" +#include "ath9k.h" /* * tolerated deviation of radar time stamp in usecs on both sides @@ -143,6 +143,7 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq) { u32 sz, i; struct channel_detector *cd; + struct ath_common *common = ath9k_hw_common(dpd->ah); cd = kmalloc(sizeof(*cd), GFP_ATOMIC); if (cd == NULL) @@ -166,7 +167,7 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq) return cd; fail: - ath_dbg(dpd->common, DFS, + ath_dbg(common, DFS, "failed to allocate channel_detector for freq=%d\n", freq); channel_detector_exit(dpd, cd); return NULL; @@ -241,7 +242,7 @@ dpd_add_pulse(struct dfs_pattern_detector *dpd, struct pulse_event *event) struct pri_detector *pd = cd->detectors[i]; struct pri_sequence *ps = pd->add_pulse(pd, event); if (ps != NULL) { - ath_dbg(dpd->common, DFS, + ath_dbg(ath9k_hw_common(dpd->ah), DFS, "DFS: radar found on freq=%d: id=%d, pri=%d, " "count=%d, count_false=%d\n", event->freq, pd->rs->type_id, @@ -253,12 +254,6 @@ dpd_add_pulse(struct dfs_pattern_detector *dpd, struct pulse_event *event) return false; } -static struct ath_dfs_pool_stats -dpd_get_stats(struct dfs_pattern_detector *dpd) -{ - return global_dfs_pool_stats; -} - static bool dpd_set_domain(struct dfs_pattern_detector *dpd, enum nl80211_dfs_regions region) { @@ -289,18 +284,14 @@ static struct dfs_pattern_detector default_dpd = { .exit = dpd_exit, .set_dfs_domain = dpd_set_domain, .add_pulse = dpd_add_pulse, - .get_stats = dpd_get_stats, .region = NL80211_DFS_UNSET, }; struct dfs_pattern_detector * -dfs_pattern_detector_init(struct ath_common *common, - enum nl80211_dfs_regions region) +dfs_pattern_detector_init(struct ath_hw *ah, enum nl80211_dfs_regions region) { struct dfs_pattern_detector *dpd; - - if (!config_enabled(CONFIG_CFG80211_CERTIFICATION_ONUS)) - return NULL; + struct ath_common *common = ath9k_hw_common(ah); dpd = kmalloc(sizeof(*dpd), GFP_KERNEL); if (dpd == NULL) @@ -309,7 +300,7 @@ dfs_pattern_detector_init(struct ath_common *common, *dpd = default_dpd; INIT_LIST_HEAD(&dpd->channel_detectors); - dpd->common = common; + dpd->ah = ah; if (dpd->set_dfs_domain(dpd, region)) return dpd; diff --git a/drivers/net/wireless/ath/dfs_pattern_detector.h b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h index dde2652..90a5abc 100644 --- a/drivers/net/wireless/ath/dfs_pattern_detector.h +++ b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h @@ -22,19 +22,6 @@ #include <linux/nl80211.h> /** - * struct ath_dfs_pool_stats - DFS Statistics for global pools - */ -struct ath_dfs_pool_stats { - u32 pool_reference; - u32 pulse_allocated; - u32 pulse_alloc_error; - u32 pulse_used; - u32 pseq_allocated; - u32 pseq_alloc_error; - u32 pseq_used; -}; - -/** * struct pulse_event - describing pulses reported by PHY * @ts: pulse time stamp in us * @freq: channel frequency in MHz @@ -90,12 +77,11 @@ struct dfs_pattern_detector { bool (*add_pulse)(struct dfs_pattern_detector *dpd, struct pulse_event *pe); - struct ath_dfs_pool_stats (*get_stats)(struct dfs_pattern_detector *dpd); enum nl80211_dfs_regions region; u8 num_radar_types; u64 last_pulse_ts; /* needed for ath_dbg() */ - struct ath_common *common; + struct ath_hw *ah; const struct radar_detector_specs *radar_spec; struct list_head channel_detectors; @@ -106,7 +92,15 @@ struct dfs_pattern_detector { * @param region: DFS domain to be used, can be NL80211_DFS_UNSET at creation * @return instance pointer on success, NULL otherwise */ +#if defined(CONFIG_ATH9K_DFS_CERTIFIED) extern struct dfs_pattern_detector * -dfs_pattern_detector_init(struct ath_common *common, - enum nl80211_dfs_regions region); +dfs_pattern_detector_init(struct ath_hw *ah, enum nl80211_dfs_regions region); +#else +static inline struct dfs_pattern_detector * +dfs_pattern_detector_init(struct ath_hw *ah, enum nl80211_dfs_regions region) +{ + return NULL; +} +#endif /* CONFIG_ATH9K_DFS_CERTIFIED */ + #endif /* DFS_PATTERN_DETECTOR_H */ diff --git a/drivers/net/wireless/ath/dfs_pri_detector.c b/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c index 43b6081..5ba4b6f 100644 --- a/drivers/net/wireless/ath/dfs_pri_detector.c +++ b/drivers/net/wireless/ath/ath9k/dfs_pri_detector.c @@ -17,14 +17,10 @@ #include <linux/slab.h> #include <linux/spinlock.h> -#include "ath.h" +#include "ath9k.h" #include "dfs_pattern_detector.h" #include "dfs_pri_detector.h" - -struct ath_dfs_pool_stats global_dfs_pool_stats = {}; - -#define DFS_POOL_STAT_INC(c) (global_dfs_pool_stats.c++) -#define DFS_POOL_STAT_DEC(c) (global_dfs_pool_stats.c--) +#include "dfs_debug.h" /** * struct pulse_elem - elements in pulse queue @@ -396,7 +392,7 @@ static struct pri_sequence *pri_detector_add_pulse(struct pri_detector *de, if (!pseq_handler_create_sequences(de, ts, max_updated_seq)) { pri_detector_reset(de, ts); - return NULL; + return false; } ps = pseq_handler_check_detection(de); diff --git a/drivers/net/wireless/ath/dfs_pri_detector.h b/drivers/net/wireless/ath/ath9k/dfs_pri_detector.h index 79f0fff..723962d 100644 --- a/drivers/net/wireless/ath/dfs_pri_detector.h +++ b/drivers/net/wireless/ath/ath9k/dfs_pri_detector.h @@ -19,8 +19,6 @@ #include <linux/list.h> -extern struct ath_dfs_pool_stats global_dfs_pool_stats; - /** * struct pri_sequence - sequence of pulses matching one PRI * @head: list_head diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index b409171..9ea8e4b 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c @@ -129,10 +129,10 @@ static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, struct base_eep_header_4k *pBase = &eep->baseEepHeader; if (!dump_base_hdr) { - len += scnprintf(buf + len, size - len, - "%20s :\n", "2GHz modal Header"); + len += snprintf(buf + len, size - len, + "%20s :\n", "2GHz modal Header"); len = ath9k_dump_4k_modal_eeprom(buf, len, size, - &eep->modalHeader); + &eep->modalHeader); goto out; } @@ -160,8 +160,8 @@ static u32 ath9k_hw_4k_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF); PR_EEP("TX Gain type", pBase->txGainType); - len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress", - pBase->macAddr); + len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress", + pBase->macAddr); out: if (len > size) diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index e1d0c21..3ae1f3d 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c @@ -125,8 +125,8 @@ static u32 ath9k_hw_ar9287_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, struct base_eep_ar9287_header *pBase = &eep->baseEepHeader; if (!dump_base_hdr) { - len += scnprintf(buf + len, size - len, - "%20s :\n", "2GHz modal Header"); + len += snprintf(buf + len, size - len, + "%20s :\n", "2GHz modal Header"); len = ar9287_dump_modal_eeprom(buf, len, size, &eep->modalHeader); goto out; @@ -157,8 +157,8 @@ static u32 ath9k_hw_ar9287_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, PR_EEP("Power Table Offset", pBase->pwrTableOffset); PR_EEP("OpenLoop Power Ctrl", pBase->openLoopPwrCntl); - len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress", - pBase->macAddr); + len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress", + pBase->macAddr); out: if (len > size) diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 39107e3..1c25368 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c @@ -205,12 +205,12 @@ static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, struct base_eep_header *pBase = &eep->baseEepHeader; if (!dump_base_hdr) { - len += scnprintf(buf + len, size - len, - "%20s :\n", "2GHz modal Header"); + len += snprintf(buf + len, size - len, + "%20s :\n", "2GHz modal Header"); len = ath9k_def_dump_modal_eeprom(buf, len, size, &eep->modalHeader[0]); - len += scnprintf(buf + len, size - len, - "%20s :\n", "5GHz modal Header"); + len += snprintf(buf + len, size - len, + "%20s :\n", "5GHz modal Header"); len = ath9k_def_dump_modal_eeprom(buf, len, size, &eep->modalHeader[1]); goto out; @@ -240,8 +240,8 @@ static u32 ath9k_hw_def_dump_eeprom(struct ath_hw *ah, bool dump_base_hdr, PR_EEP("Cal Bin Build", (pBase->binBuildNumber >> 8) & 0xFF); PR_EEP("OpenLoop Power Ctrl", pBase->openLoopPwrCntl); - len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress", - pBase->macAddr); + len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress", + pBase->macAddr); out: if (len > size) diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index c34f212..4b412aa 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -522,22 +522,22 @@ static int ath9k_dump_mci_btcoex(struct ath_softc *sc, u8 *buf, u32 size) ATH_DUMP_BTCOEX("Concurrent Tx", btcoex_hw->mci.concur_tx); ATH_DUMP_BTCOEX("Concurrent RSSI cnt", btcoex->rssi_count); - len += scnprintf(buf + len, size - len, "BT Weights: "); + len += snprintf(buf + len, size - len, "BT Weights: "); for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) - len += scnprintf(buf + len, size - len, "%08x ", - btcoex_hw->bt_weight[i]); - len += scnprintf(buf + len, size - len, "\n"); - len += scnprintf(buf + len, size - len, "WLAN Weights: "); + len += snprintf(buf + len, size - len, "%08x ", + btcoex_hw->bt_weight[i]); + len += snprintf(buf + len, size - len, "\n"); + len += snprintf(buf + len, size - len, "WLAN Weights: "); for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) - len += scnprintf(buf + len, size - len, "%08x ", - btcoex_hw->wlan_weight[i]); - len += scnprintf(buf + len, size - len, "\n"); - len += scnprintf(buf + len, size - len, "Tx Priorities: "); + len += snprintf(buf + len, size - len, "%08x ", + btcoex_hw->wlan_weight[i]); + len += snprintf(buf + len, size - len, "\n"); + len += snprintf(buf + len, size - len, "Tx Priorities: "); for (i = 0; i < ATH_BTCOEX_STOMP_MAX; i++) - len += scnprintf(buf + len, size - len, "%08x ", + len += snprintf(buf + len, size - len, "%08x ", btcoex_hw->tx_prio[i]); - len += scnprintf(buf + len, size - len, "\n"); + len += snprintf(buf + len, size - len, "\n"); return len; } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index fb071ee..c1b45e2 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -37,29 +37,29 @@ static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf, ath9k_htc_ps_restore(priv); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "RX", - be32_to_cpu(cmd_rsp.rx)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "RX", + be32_to_cpu(cmd_rsp.rx)); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "RXORN", - be32_to_cpu(cmd_rsp.rxorn)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "RXORN", + be32_to_cpu(cmd_rsp.rxorn)); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "RXEOL", - be32_to_cpu(cmd_rsp.rxeol)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "RXEOL", + be32_to_cpu(cmd_rsp.rxeol)); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "TXURN", - be32_to_cpu(cmd_rsp.txurn)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "TXURN", + be32_to_cpu(cmd_rsp.txurn)); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "TXTO", - be32_to_cpu(cmd_rsp.txto)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "TXTO", + be32_to_cpu(cmd_rsp.txto)); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "CST", - be32_to_cpu(cmd_rsp.cst)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "CST", + be32_to_cpu(cmd_rsp.cst)); if (len > sizeof(buf)) len = sizeof(buf); @@ -95,41 +95,41 @@ static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf, ath9k_htc_ps_restore(priv); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "Xretries", - be32_to_cpu(cmd_rsp.xretries)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "Xretries", + be32_to_cpu(cmd_rsp.xretries)); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "FifoErr", - be32_to_cpu(cmd_rsp.fifoerr)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "FifoErr", + be32_to_cpu(cmd_rsp.fifoerr)); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "Filtered", - be32_to_cpu(cmd_rsp.filtered)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "Filtered", + be32_to_cpu(cmd_rsp.filtered)); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "TimerExp", - be32_to_cpu(cmd_rsp.timer_exp)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "TimerExp", + be32_to_cpu(cmd_rsp.timer_exp)); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "ShortRetries", - be32_to_cpu(cmd_rsp.shortretries)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "ShortRetries", + be32_to_cpu(cmd_rsp.shortretries)); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "LongRetries", - be32_to_cpu(cmd_rsp.longretries)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "LongRetries", + be32_to_cpu(cmd_rsp.longretries)); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "QueueNull", - be32_to_cpu(cmd_rsp.qnull)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "QueueNull", + be32_to_cpu(cmd_rsp.qnull)); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "EncapFail", - be32_to_cpu(cmd_rsp.encap_fail)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "EncapFail", + be32_to_cpu(cmd_rsp.encap_fail)); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "NoBuf", - be32_to_cpu(cmd_rsp.nobuf)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "NoBuf", + be32_to_cpu(cmd_rsp.nobuf)); if (len > sizeof(buf)) len = sizeof(buf); @@ -165,17 +165,17 @@ static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf, ath9k_htc_ps_restore(priv); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "NoBuf", - be32_to_cpu(cmd_rsp.nobuf)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "NoBuf", + be32_to_cpu(cmd_rsp.nobuf)); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "HostSend", - be32_to_cpu(cmd_rsp.host_send)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "HostSend", + be32_to_cpu(cmd_rsp.host_send)); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "HostDone", - be32_to_cpu(cmd_rsp.host_done)); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "HostDone", + be32_to_cpu(cmd_rsp.host_done)); if (len > sizeof(buf)) len = sizeof(buf); @@ -197,37 +197,37 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, char buf[512]; unsigned int len = 0; - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "Buffers queued", - priv->debug.tx_stats.buf_queued); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "Buffers completed", - priv->debug.tx_stats.buf_completed); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs queued", - priv->debug.tx_stats.skb_queued); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs success", - priv->debug.tx_stats.skb_success); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "SKBs failed", - priv->debug.tx_stats.skb_failed); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "CAB queued", - priv->debug.tx_stats.cab_queued); - - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "BE queued", - priv->debug.tx_stats.queue_stats[IEEE80211_AC_BE]); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "BK queued", - priv->debug.tx_stats.queue_stats[IEEE80211_AC_BK]); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "VI queued", - priv->debug.tx_stats.queue_stats[IEEE80211_AC_VI]); - len += scnprintf(buf + len, sizeof(buf) - len, - "%20s : %10u\n", "VO queued", - priv->debug.tx_stats.queue_stats[IEEE80211_AC_VO]); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "Buffers queued", + priv->debug.tx_stats.buf_queued); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "Buffers completed", + priv->debug.tx_stats.buf_completed); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "SKBs queued", + priv->debug.tx_stats.skb_queued); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "SKBs success", + priv->debug.tx_stats.skb_success); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "SKBs failed", + priv->debug.tx_stats.skb_failed); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "CAB queued", + priv->debug.tx_stats.cab_queued); + + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "BE queued", + priv->debug.tx_stats.queue_stats[IEEE80211_AC_BE]); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "BK queued", + priv->debug.tx_stats.queue_stats[IEEE80211_AC_BK]); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "VI queued", + priv->debug.tx_stats.queue_stats[IEEE80211_AC_VI]); + len += snprintf(buf + len, sizeof(buf) - len, + "%20s : %10u\n", "VO queued", + priv->debug.tx_stats.queue_stats[IEEE80211_AC_VO]); if (len > sizeof(buf)) len = sizeof(buf); @@ -273,8 +273,8 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { #define PHY_ERR(s, p) \ - len += scnprintf(buf + len, size - len, "%20s : %10u\n", s, \ - priv->debug.rx_stats.err_phy_stats[p]); + len += snprintf(buf + len, size - len, "%20s : %10u\n", s, \ + priv->debug.rx_stats.err_phy_stats[p]); struct ath9k_htc_priv *priv = file->private_data; char *buf; @@ -285,37 +285,37 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, if (buf == NULL) return -ENOMEM; - len += scnprintf(buf + len, size - len, - "%20s : %10u\n", "SKBs allocated", - priv->debug.rx_stats.skb_allocated); - len += scnprintf(buf + len, size - len, - "%20s : %10u\n", "SKBs completed", - priv->debug.rx_stats.skb_completed); - len += scnprintf(buf + len, size - len, - "%20s : %10u\n", "SKBs Dropped", - priv->debug.rx_stats.skb_dropped); - - len += scnprintf(buf + len, size - len, - "%20s : %10u\n", "CRC ERR", - priv->debug.rx_stats.err_crc); - len += scnprintf(buf + len, size - len, - "%20s : %10u\n", "DECRYPT CRC ERR", - priv->debug.rx_stats.err_decrypt_crc); - len += scnprintf(buf + len, size - len, - "%20s : %10u\n", "MIC ERR", - priv->debug.rx_stats.err_mic); - len += scnprintf(buf + len, size - len, - "%20s : %10u\n", "PRE-DELIM CRC ERR", - priv->debug.rx_stats.err_pre_delim); - len += scnprintf(buf + len, size - len, - "%20s : %10u\n", "POST-DELIM CRC ERR", - priv->debug.rx_stats.err_post_delim); - len += scnprintf(buf + len, size - len, - "%20s : %10u\n", "DECRYPT BUSY ERR", - priv->debug.rx_stats.err_decrypt_busy); - len += scnprintf(buf + len, size - len, - "%20s : %10u\n", "TOTAL PHY ERR", - priv->debug.rx_stats.err_phy); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "SKBs allocated", + priv->debug.rx_stats.skb_allocated); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "SKBs completed", + priv->debug.rx_stats.skb_completed); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "SKBs Dropped", + priv->debug.rx_stats.skb_dropped); + + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "CRC ERR", + priv->debug.rx_stats.err_crc); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "DECRYPT CRC ERR", + priv->debug.rx_stats.err_decrypt_crc); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "MIC ERR", + priv->debug.rx_stats.err_mic); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "PRE-DELIM CRC ERR", + priv->debug.rx_stats.err_pre_delim); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "POST-DELIM CRC ERR", + priv->debug.rx_stats.err_post_delim); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "DECRYPT BUSY ERR", + priv->debug.rx_stats.err_decrypt_busy); + len += snprintf(buf + len, size - len, + "%20s : %10u\n", "TOTAL PHY ERR", + priv->debug.rx_stats.err_phy); PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN); @@ -372,16 +372,16 @@ static ssize_t read_file_slot(struct file *file, char __user *user_buf, spin_lock_bh(&priv->tx.tx_lock); - len += scnprintf(buf + len, sizeof(buf) - len, "TX slot bitmap : "); + len += snprintf(buf + len, sizeof(buf) - len, "TX slot bitmap : "); len += bitmap_scnprintf(buf + len, sizeof(buf) - len, priv->tx.tx_slot, MAX_TX_BUF_NUM); - len += scnprintf(buf + len, sizeof(buf) - len, "\n"); + len += snprintf(buf + len, sizeof(buf) - len, "\n"); - len += scnprintf(buf + len, sizeof(buf) - len, - "Used slots : %d\n", - bitmap_weight(priv->tx.tx_slot, MAX_TX_BUF_NUM)); + len += snprintf(buf + len, sizeof(buf) - len, + "Used slots : %d\n", + bitmap_weight(priv->tx.tx_slot, MAX_TX_BUF_NUM)); spin_unlock_bh(&priv->tx.tx_lock); @@ -405,30 +405,30 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf, char buf[512]; unsigned int len = 0; - len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", - "Mgmt endpoint", skb_queue_len(&priv->tx.mgmt_ep_queue)); + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", + "Mgmt endpoint", skb_queue_len(&priv->tx.mgmt_ep_queue)); - len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", - "Cab endpoint", skb_queue_len(&priv->tx.cab_ep_queue)); + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", + "Cab endpoint", skb_queue_len(&priv->tx.cab_ep_queue)); - len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", - "Data BE endpoint", skb_queue_len(&priv->tx.data_be_queue)); + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", + "Data BE endpoint", skb_queue_len(&priv->tx.data_be_queue)); - len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", - "Data BK endpoint", skb_queue_len(&priv->tx.data_bk_queue)); + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", + "Data BK endpoint", skb_queue_len(&priv->tx.data_bk_queue)); - len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", - "Data VI endpoint", skb_queue_len(&priv->tx.data_vi_queue)); + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", + "Data VI endpoint", skb_queue_len(&priv->tx.data_vi_queue)); - len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", - "Data VO endpoint", skb_queue_len(&priv->tx.data_vo_queue)); + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", + "Data VO endpoint", skb_queue_len(&priv->tx.data_vo_queue)); - len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", - "Failed queue", skb_queue_len(&priv->tx.tx_failed)); + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", + "Failed queue", skb_queue_len(&priv->tx.tx_failed)); spin_lock_bh(&priv->tx.tx_lock); - len += scnprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", - "Queued count", priv->tx.queued_cnt); + len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", + "Queued count", priv->tx.queued_cnt); spin_unlock_bh(&priv->tx.tx_lock); if (len > sizeof(buf)) @@ -507,70 +507,70 @@ static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, if (buf == NULL) return -ENOMEM; - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", "Major Version", - pBase->version >> 12); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", "Minor Version", - pBase->version & 0xFFF); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", "Checksum", - pBase->checksum); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", "Length", - pBase->length); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", "RegDomain1", - pBase->regDmn[0]); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", "RegDomain2", - pBase->regDmn[1]); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", - "TX Mask", pBase->txMask); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", - "RX Mask", pBase->rxMask); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", - "Allow 5GHz", - !!(pBase->opCapFlags & AR5416_OPFLAGS_11A)); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", - "Allow 2GHz", - !!(pBase->opCapFlags & AR5416_OPFLAGS_11G)); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", - "Disable 2GHz HT20", - !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT20)); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", - "Disable 2GHz HT40", - !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT40)); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", - "Disable 5Ghz HT20", - !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT20)); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", - "Disable 5Ghz HT40", - !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT40)); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", - "Big Endian", - !!(pBase->eepMisc & 0x01)); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", - "Cal Bin Major Ver", - (pBase->binBuildNumber >> 24) & 0xFF); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", - "Cal Bin Minor Ver", - (pBase->binBuildNumber >> 16) & 0xFF); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", - "Cal Bin Build", - (pBase->binBuildNumber >> 8) & 0xFF); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", "Major Version", + pBase->version >> 12); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", "Minor Version", + pBase->version & 0xFFF); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", "Checksum", + pBase->checksum); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", "Length", + pBase->length); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", "RegDomain1", + pBase->regDmn[0]); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", "RegDomain2", + pBase->regDmn[1]); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", + "TX Mask", pBase->txMask); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", + "RX Mask", pBase->rxMask); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", + "Allow 5GHz", + !!(pBase->opCapFlags & AR5416_OPFLAGS_11A)); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", + "Allow 2GHz", + !!(pBase->opCapFlags & AR5416_OPFLAGS_11G)); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", + "Disable 2GHz HT20", + !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT20)); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", + "Disable 2GHz HT40", + !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT40)); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", + "Disable 5Ghz HT20", + !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT20)); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", + "Disable 5Ghz HT40", + !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT40)); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", + "Big Endian", + !!(pBase->eepMisc & 0x01)); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", + "Cal Bin Major Ver", + (pBase->binBuildNumber >> 24) & 0xFF); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", + "Cal Bin Minor Ver", + (pBase->binBuildNumber >> 16) & 0xFF); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", + "Cal Bin Build", + (pBase->binBuildNumber >> 8) & 0xFF); /* * UB91 specific data. @@ -579,10 +579,10 @@ static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, struct base_eep_header_4k *pBase4k = &priv->ah->eeprom.map4k.baseEepHeader; - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", - "TX Gain type", - pBase4k->txGainType); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", + "TX Gain type", + pBase4k->txGainType); } /* @@ -592,19 +592,19 @@ static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, struct base_eep_ar9287_header *pBase9287 = &priv->ah->eeprom.map9287.baseEepHeader; - len += scnprintf(buf + len, size - len, - "%20s : %10ddB\n", - "Power Table Offset", - pBase9287->pwrTableOffset); + len += snprintf(buf + len, size - len, + "%20s : %10ddB\n", + "Power Table Offset", + pBase9287->pwrTableOffset); - len += scnprintf(buf + len, size - len, - "%20s : %10d\n", - "OpenLoop Power Ctrl", - pBase9287->openLoopPwrCntl); + len += snprintf(buf + len, size - len, + "%20s : %10d\n", + "OpenLoop Power Ctrl", + pBase9287->openLoopPwrCntl); } - len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress", - pBase->macAddr); + len += snprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress", + pBase->macAddr); if (len > size) len = size; @@ -627,8 +627,8 @@ static ssize_t read_4k_modal_eeprom(struct file *file, { #define PR_EEP(_s, _val) \ do { \ - len += scnprintf(buf + len, size - len, "%20s : %10d\n",\ - _s, (_val)); \ + len += snprintf(buf + len, size - len, "%20s : %10d\n", \ + _s, (_val)); \ } while (0) struct ath9k_htc_priv *priv = file->private_data; @@ -708,12 +708,12 @@ static ssize_t read_def_modal_eeprom(struct file *file, do { \ if (pBase->opCapFlags & AR5416_OPFLAGS_11G) { \ pModal = &priv->ah->eeprom.def.modalHeader[1]; \ - len += scnprintf(buf + len, size - len, "%20s : %8d%7s", \ - _s, (_val), "|"); \ + len += snprintf(buf + len, size - len, "%20s : %8d%7s", \ + _s, (_val), "|"); \ } \ if (pBase->opCapFlags & AR5416_OPFLAGS_11A) { \ pModal = &priv->ah->eeprom.def.modalHeader[0]; \ - len += scnprintf(buf + len, size - len, "%9d\n",\ + len += snprintf(buf + len, size - len, "%9d\n", \ (_val)); \ } \ } while (0) @@ -729,10 +729,10 @@ static ssize_t read_def_modal_eeprom(struct file *file, if (buf == NULL) return -ENOMEM; - len += scnprintf(buf + len, size - len, - "%31s %15s\n", "2G", "5G"); - len += scnprintf(buf + len, size - len, - "%32s %16s\n", "====", "====\n"); + len += snprintf(buf + len, size - len, + "%31s %15s\n", "2G", "5G"); + len += snprintf(buf + len, size - len, + "%32s %16s\n", "====", "====\n"); PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]); PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]); @@ -814,8 +814,8 @@ static ssize_t read_9287_modal_eeprom(struct file *file, { #define PR_EEP(_s, _val) \ do { \ - len += scnprintf(buf + len, size - len, "%20s : %10d\n",\ - _s, (_val)); \ + len += snprintf(buf + len, size - len, "%20s : %10d\n", \ + _s, (_val)); \ } while (0) struct ath9k_htc_priv *priv = file->private_data; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 9a2657f..d442581 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -24,10 +24,30 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv, struct ath9k_channel *ichan) { - if (IS_CHAN_5GHZ(ichan)) - return HTC_MODE_11NA; + enum htc_phymode mode; + + mode = -EINVAL; + + switch (ichan->chanmode) { + case CHANNEL_G: + case CHANNEL_G_HT20: + case CHANNEL_G_HT40PLUS: + case CHANNEL_G_HT40MINUS: + mode = HTC_MODE_11NG; + break; + case CHANNEL_A: + case CHANNEL_A_HT20: + case CHANNEL_A_HT40PLUS: + case CHANNEL_A_HT40MINUS: + mode = HTC_MODE_11NA; + break; + default: + break; + } - return HTC_MODE_11NG; + WARN_ON(mode < 0); + + return mode; } bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, @@ -906,7 +926,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) WMI_CMD(WMI_FLUSH_RECV_CMDID); /* setup initial channel */ - init_channel = ath9k_cmn_get_channel(hw, ah, &hw->conf.chandef); + init_channel = ath9k_cmn_get_curchannel(hw, ah); ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false); if (ret) { @@ -1188,7 +1208,9 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) ath_dbg(common, CONFIG, "Set channel: %d MHz\n", curchan->center_freq); - ath9k_cmn_get_channel(hw, priv->ah, &hw->conf.chandef); + ath9k_cmn_update_ichannel(&priv->ah->channels[pos], + &hw->conf.chandef); + if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) { ath_err(common, "Unable to set channel\n"); ret = -EINVAL; diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index 4f9378d..83f4927 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -78,22 +78,6 @@ static inline void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah, ath9k_hw_ops(ah)->antdiv_comb_conf_set(ah, antconf); } -static inline void ath9k_hw_tx99_start(struct ath_hw *ah, u32 qnum) -{ - ath9k_hw_ops(ah)->tx99_start(ah, qnum); -} - -static inline void ath9k_hw_tx99_stop(struct ath_hw *ah) -{ - ath9k_hw_ops(ah)->tx99_stop(ah); -} - -static inline void ath9k_hw_tx99_set_txpower(struct ath_hw *ah, u8 power) -{ - if (ath9k_hw_ops(ah)->tx99_set_txpower) - ath9k_hw_ops(ah)->tx99_set_txpower(ah, power); -} - #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable) diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 54b0415..ecc6ec4 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -130,29 +130,29 @@ void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause) static void ath9k_hw_set_clockrate(struct ath_hw *ah) { + struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_channel *chan = ah->curchan; unsigned int clockrate; /* AR9287 v1.3+ uses async FIFO and runs the MAC at 117 MHz */ if (AR_SREV_9287(ah) && AR_SREV_9287_13_OR_LATER(ah)) clockrate = 117; - else if (!chan) /* should really check for CCK instead */ + else if (!ah->curchan) /* should really check for CCK instead */ clockrate = ATH9K_CLOCK_RATE_CCK; - else if (IS_CHAN_2GHZ(chan)) + else if (conf->chandef.chan->band == IEEE80211_BAND_2GHZ) clockrate = ATH9K_CLOCK_RATE_2GHZ_OFDM; else if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK) clockrate = ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM; else clockrate = ATH9K_CLOCK_RATE_5GHZ_OFDM; - if (IS_CHAN_HT40(chan)) + if (conf_is_ht40(conf)) clockrate *= 2; if (ah->curchan) { - if (IS_CHAN_HALF_RATE(chan)) + if (IS_CHAN_HALF_RATE(ah->curchan)) clockrate /= 2; - if (IS_CHAN_QUARTER_RATE(chan)) + if (IS_CHAN_QUARTER_RATE(ah->curchan)) clockrate /= 4; } @@ -190,7 +190,10 @@ EXPORT_SYMBOL(ath9k_hw_wait); void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan, int hw_delay) { - hw_delay /= 10; + if (IS_CHAN_B(chan)) + hw_delay = (4 * hw_delay) / 22; + else + hw_delay /= 10; if (IS_CHAN_HALF_RATE(chan)) hw_delay *= 2; @@ -291,7 +294,8 @@ void ath9k_hw_get_channel_centers(struct ath_hw *ah, return; } - if (IS_CHAN_HT40PLUS(chan)) { + if ((chan->chanmode == CHANNEL_A_HT40PLUS) || + (chan->chanmode == CHANNEL_G_HT40PLUS)) { centers->synth_center = chan->channel + HT40_CHANNEL_CENTER_SHIFT; extoff = 1; @@ -545,18 +549,6 @@ static int ath9k_hw_post_init(struct ath_hw *ah) ath9k_hw_ani_init(ah); - /* - * EEPROM needs to be initialized before we do this. - * This is required for regulatory compliance. - */ - if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { - u16 regdmn = ah->eep_ops->get_eeprom(ah, EEP_REG_0); - if ((regdmn & 0xF0) == CTL_FCC) { - ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9462_FCC_2GHZ; - ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9462_FCC_5GHZ; - } - } - return 0; } @@ -1038,6 +1030,7 @@ static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) void ath9k_hw_init_global_settings(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); + struct ieee80211_conf *conf = &common->hw->conf; const struct ath9k_channel *chan = ah->curchan; int acktimeout, ctstimeout, ack_offset = 0; int slottime; @@ -1112,7 +1105,8 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) * BA frames in some implementations, but it has been found to fix ACK * timeout issues in other cases as well. */ - if (IS_CHAN_2GHZ(chan) && + if (conf->chandef.chan && + conf->chandef.chan->band == IEEE80211_BAND_2GHZ && !IS_CHAN_HALF_RATE(chan) && !IS_CHAN_QUARTER_RATE(chan)) { acktimeout += 64 - sifstime - ah->slottime; ctstimeout += 48 - sifstime - ah->slottime; @@ -1154,7 +1148,9 @@ u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan) { u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band); - if (IS_CHAN_2GHZ(chan)) + if (IS_CHAN_B(chan)) + ctl |= CTL_11B; + else if (IS_CHAN_G(chan)) ctl |= CTL_11G; else ctl |= CTL_11A; @@ -1502,8 +1498,10 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, int r; if (pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) { - band_switch = IS_CHAN_5GHZ(ah->curchan) != IS_CHAN_5GHZ(chan); - mode_diff = (chan->channelFlags != ah->curchan->channelFlags); + u32 cur = ah->curchan->channelFlags & (CHANNEL_2GHZ | CHANNEL_5GHZ); + u32 new = chan->channelFlags & (CHANNEL_2GHZ | CHANNEL_5GHZ); + band_switch = (cur != new); + mode_diff = (chan->chanmode != ah->curchan->chanmode); } for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { @@ -1542,7 +1540,9 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, ath9k_hw_set_clockrate(ah); ath9k_hw_apply_txpower(ah, chan, false); - ath9k_hw_set_delta_slope(ah, chan); + if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) + ath9k_hw_set_delta_slope(ah, chan); + ath9k_hw_spur_mitigate_freq(ah, chan); if (band_switch || ini_reloaded) @@ -1644,19 +1644,6 @@ hang_check_iter: return true; } -void ath9k_hw_check_nav(struct ath_hw *ah) -{ - struct ath_common *common = ath9k_hw_common(ah); - u32 val; - - val = REG_READ(ah, AR_NAV); - if (val != 0xdeadbeef && val > 0x7fff) { - ath_dbg(common, BSTUCK, "Abnormal NAV: 0x%x\n", val); - REG_WRITE(ah, AR_NAV, 0); - } -} -EXPORT_SYMBOL(ath9k_hw_check_nav); - bool ath9k_hw_check_alive(struct ath_hw *ah) { int count = 50; @@ -1812,11 +1799,20 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) goto fail; /* - * If cross-band fcc is not supoprted, bail out if channelFlags differ. + * If cross-band fcc is not supoprted, bail out if + * either channelFlags or chanmode differ. + * + * chanmode will be different if the HT operating mode + * changes because of CSA. */ - if (!(pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) && - chan->channelFlags != ah->curchan->channelFlags) - goto fail; + if (!(pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH)) { + if ((chan->channelFlags & CHANNEL_ALL) != + (ah->curchan->channelFlags & CHANNEL_ALL)) + goto fail; + + if (chan->chanmode != ah->curchan->chanmode) + goto fail; + } if (!ath9k_hw_check_alive(ah)) goto fail; @@ -1826,9 +1822,9 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) * re-using are present. */ if (AR_SREV_9462(ah) && (ah->caldata && - (!test_bit(TXIQCAL_DONE, &ah->caldata->cal_flags) || - !test_bit(TXCLCAL_DONE, &ah->caldata->cal_flags) || - !test_bit(RTT_DONE, &ah->caldata->cal_flags)))) + (!ah->caldata->done_txiqcal_once || + !ah->caldata->done_txclcal_once || + !ah->caldata->rtt_done))) goto fail; ath_dbg(common, RESET, "FastChannelChange for %d -> %d\n", @@ -1878,14 +1874,15 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ah->caldata = caldata; if (caldata && (chan->channel != caldata->channel || - chan->channelFlags != caldata->channelFlags)) { + chan->channelFlags != caldata->channelFlags || + chan->chanmode != caldata->chanmode)) { /* Operating channel changed, reset channel calibration data */ memset(caldata, 0, sizeof(*caldata)); ath9k_init_nfcal_hist_buffer(ah, chan); } else if (caldata) { - clear_bit(PAPRD_PACKET_SENT, &caldata->cal_flags); + caldata->paprd_packet_sent = false; } - ah->noise = ath9k_hw_getchan_noise(ah, chan, chan->noisefloor); + ah->noise = ath9k_hw_getchan_noise(ah, chan); if (fastcc) { r = ath9k_hw_do_fastcc(ah, chan); @@ -1967,7 +1964,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_init_mfp(ah); - ath9k_hw_set_delta_slope(ah, chan); + if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) + ath9k_hw_set_delta_slope(ah, chan); + ath9k_hw_spur_mitigate_freq(ah, chan); ah->eep_ops->set_board_values(ah, chan); @@ -2018,8 +2017,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_init_bb(ah, chan); if (caldata) { - clear_bit(TXIQCAL_DONE, &caldata->cal_flags); - clear_bit(TXCLCAL_DONE, &caldata->cal_flags); + caldata->done_txiqcal_once = false; + caldata->done_txclcal_once = false; } if (!ath9k_hw_init_cal(ah, chan)) return -EIO; @@ -2944,11 +2943,12 @@ void ath9k_hw_set_tsfadjust(struct ath_hw *ah, bool set) } EXPORT_SYMBOL(ath9k_hw_set_tsfadjust); -void ath9k_hw_set11nmac2040(struct ath_hw *ah, struct ath9k_channel *chan) +void ath9k_hw_set11nmac2040(struct ath_hw *ah) { + struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; u32 macmode; - if (IS_CHAN_HT40(chan) && !ah->config.cwm_ignore_extcca) + if (conf_is_ht40(conf) && !ah->config.cwm_ignore_extcca) macmode = AR_2040_JOINED_RX_CLEAR; else macmode = 0; @@ -3240,19 +3240,19 @@ void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len) /* chipsets >= AR9280 are single-chip */ if (AR_SREV_9280_20_OR_LATER(ah)) { - used = scnprintf(hw_name, len, - "Atheros AR%s Rev:%x", - ath9k_hw_mac_bb_name(ah->hw_version.macVersion), - ah->hw_version.macRev); + used = snprintf(hw_name, len, + "Atheros AR%s Rev:%x", + ath9k_hw_mac_bb_name(ah->hw_version.macVersion), + ah->hw_version.macRev); } else { - used = scnprintf(hw_name, len, - "Atheros AR%s MAC/BB Rev:%x AR%s RF Rev:%x", - ath9k_hw_mac_bb_name(ah->hw_version.macVersion), - ah->hw_version.macRev, - ath9k_hw_rf_name((ah->hw_version.analog5GhzRev - & AR_RADIO_SREV_MAJOR)), - ah->hw_version.phyRev); + used = snprintf(hw_name, len, + "Atheros AR%s MAC/BB Rev:%x AR%s RF Rev:%x", + ath9k_hw_mac_bb_name(ah->hw_version.macVersion), + ah->hw_version.macRev, + ath9k_hw_rf_name((ah->hw_version.analog5GhzRev & + AR_RADIO_SREV_MAJOR)), + ah->hw_version.phyRev); } hw_name[used] = '\0'; diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index a2c9a5d..69a907b 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -98,8 +98,8 @@ #define PR_EEP(_s, _val) \ do { \ - len += scnprintf(buf + len, size - len, "%20s : %10d\n",\ - _s, (_val)); \ + len += snprintf(buf + len, size - len, "%20s : %10d\n", \ + _s, (_val)); \ } while (0) #define SM(_v, _f) (((_v) << _f##_S) & _f) @@ -316,7 +316,6 @@ struct ath9k_ops_config { u32 ant_ctrl_comm2g_switch_enable; bool xatten_margin_cfg; bool alt_mingainidx; - bool no_pll_pwrsave; }; enum ath9k_int { @@ -370,30 +369,55 @@ enum ath9k_int { ATH9K_INT_NOCARD = 0xffffffff }; +#define CHANNEL_CCK 0x00020 +#define CHANNEL_OFDM 0x00040 +#define CHANNEL_2GHZ 0x00080 +#define CHANNEL_5GHZ 0x00100 +#define CHANNEL_PASSIVE 0x00200 +#define CHANNEL_DYN 0x00400 +#define CHANNEL_HALF 0x04000 +#define CHANNEL_QUARTER 0x08000 +#define CHANNEL_HT20 0x10000 +#define CHANNEL_HT40PLUS 0x20000 +#define CHANNEL_HT40MINUS 0x40000 + +#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM) +#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK) +#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM) +#define CHANNEL_G_HT20 (CHANNEL_2GHZ|CHANNEL_HT20) +#define CHANNEL_A_HT20 (CHANNEL_5GHZ|CHANNEL_HT20) +#define CHANNEL_G_HT40PLUS (CHANNEL_2GHZ|CHANNEL_HT40PLUS) +#define CHANNEL_G_HT40MINUS (CHANNEL_2GHZ|CHANNEL_HT40MINUS) +#define CHANNEL_A_HT40PLUS (CHANNEL_5GHZ|CHANNEL_HT40PLUS) +#define CHANNEL_A_HT40MINUS (CHANNEL_5GHZ|CHANNEL_HT40MINUS) +#define CHANNEL_ALL \ + (CHANNEL_OFDM| \ + CHANNEL_CCK| \ + CHANNEL_2GHZ | \ + CHANNEL_5GHZ | \ + CHANNEL_HT20 | \ + CHANNEL_HT40PLUS | \ + CHANNEL_HT40MINUS) + #define MAX_RTT_TABLE_ENTRY 6 #define MAX_IQCAL_MEASUREMENT 8 #define MAX_CL_TAB_ENTRY 16 #define CL_TAB_ENTRY(reg_base) (reg_base + (4 * j)) -enum ath9k_cal_flags { - RTT_DONE, - PAPRD_PACKET_SENT, - PAPRD_DONE, - NFCAL_PENDING, - NFCAL_INTF, - TXIQCAL_DONE, - TXCLCAL_DONE, - SW_PKDET_DONE, -}; - struct ath9k_hw_cal_data { u16 channel; - u16 channelFlags; - unsigned long cal_flags; + u32 channelFlags; + u32 chanmode; int32_t CalValid; int8_t iCoff; int8_t qCoff; - u8 caldac[2]; + bool rtt_done; + bool paprd_packet_sent; + bool paprd_done; + bool nfcal_pending; + bool nfcal_interference; + bool done_txiqcal_once; + bool done_txclcal_once; u16 small_signal_gain[AR9300_MAX_CHAINS]; u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ]; u32 num_measures[AR9300_MAX_CHAINS]; @@ -406,34 +430,33 @@ struct ath9k_hw_cal_data { struct ath9k_channel { struct ieee80211_channel *chan; u16 channel; - u16 channelFlags; + u32 channelFlags; + u32 chanmode; s16 noisefloor; }; -#define CHANNEL_5GHZ BIT(0) -#define CHANNEL_HALF BIT(1) -#define CHANNEL_QUARTER BIT(2) -#define CHANNEL_HT BIT(3) -#define CHANNEL_HT40PLUS BIT(4) -#define CHANNEL_HT40MINUS BIT(5) - -#define IS_CHAN_5GHZ(_c) (!!((_c)->channelFlags & CHANNEL_5GHZ)) -#define IS_CHAN_2GHZ(_c) (!IS_CHAN_5GHZ(_c)) - -#define IS_CHAN_HALF_RATE(_c) (!!((_c)->channelFlags & CHANNEL_HALF)) -#define IS_CHAN_QUARTER_RATE(_c) (!!((_c)->channelFlags & CHANNEL_QUARTER)) +#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \ + (((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \ + (((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \ + (((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS)) +#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0) +#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0) +#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0) +#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0) +#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0) #define IS_CHAN_A_FAST_CLOCK(_ah, _c) \ - (IS_CHAN_5GHZ(_c) && ((_ah)->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)) - -#define IS_CHAN_HT(_c) ((_c)->channelFlags & CHANNEL_HT) - -#define IS_CHAN_HT20(_c) (IS_CHAN_HT(_c) && !IS_CHAN_HT40(_c)) - -#define IS_CHAN_HT40(_c) \ - (!!((_c)->channelFlags & (CHANNEL_HT40PLUS | CHANNEL_HT40MINUS))) - -#define IS_CHAN_HT40PLUS(_c) ((_c)->channelFlags & CHANNEL_HT40PLUS) -#define IS_CHAN_HT40MINUS(_c) ((_c)->channelFlags & CHANNEL_HT40MINUS) + ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \ + ((_ah)->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)) + +/* These macros check chanmode and not channelFlags */ +#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B) +#define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) || \ + ((_c)->chanmode == CHANNEL_G_HT20)) +#define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) || \ + ((_c)->chanmode == CHANNEL_A_HT40MINUS) || \ + ((_c)->chanmode == CHANNEL_G_HT40PLUS) || \ + ((_c)->chanmode == CHANNEL_G_HT40MINUS)) +#define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c))) enum ath9k_power_mode { ATH9K_PM_AWAKE = 0, @@ -535,7 +558,6 @@ struct ath_hw_antcomb_conf { u8 main_gaintb; u8 alt_gaintb; int lna1_lna2_delta; - int lna1_lna2_switch_delta; u8 div_group; }; @@ -704,10 +726,6 @@ struct ath_hw_ops { void (*spectral_scan_trigger)(struct ath_hw *ah); void (*spectral_scan_wait)(struct ath_hw *ah); - void (*tx99_start)(struct ath_hw *ah, u32 qnum); - void (*tx99_stop)(struct ath_hw *ah); - void (*tx99_set_txpower)(struct ath_hw *ah, u8 power); - #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT void (*set_bt_ant_diversity)(struct ath_hw *hw, bool enable); #endif @@ -1008,11 +1026,10 @@ void ath9k_hw_reset_tsf(struct ath_hw *ah); void ath9k_hw_set_tsfadjust(struct ath_hw *ah, bool set); void ath9k_hw_init_global_settings(struct ath_hw *ah); u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah); -void ath9k_hw_set11nmac2040(struct ath_hw *ah, struct ath9k_channel *chan); +void ath9k_hw_set11nmac2040(struct ath_hw *ah); void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, const struct ath9k_beacon_state *bs); -void ath9k_hw_check_nav(struct ath_hw *ah); bool ath9k_hw_check_alive(struct ath_hw *ah); bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 710192e..9a1f349 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -347,6 +347,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, { struct ath_common *common = ath9k_hw_common(sc->sc_ah); u8 *ds; + struct ath_buf *bf; int i, bsize, desc_len; ath_dbg(common, CONFIG, "%s DMA: %u buffers %u desc/buf\n", @@ -398,68 +399,33 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); /* allocate buffers */ - if (is_tx) { - struct ath_buf *bf; - - bsize = sizeof(struct ath_buf) * nbuf; - bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL); - if (!bf) - return -ENOMEM; - - for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) { - bf->bf_desc = ds; - bf->bf_daddr = DS2PHYS(dd, ds); - - if (!(sc->sc_ah->caps.hw_caps & - ATH9K_HW_CAP_4KB_SPLITTRANS)) { - /* - * Skip descriptor addresses which can cause 4KB - * boundary crossing (addr + length) with a 32 dword - * descriptor fetch. - */ - while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) { - BUG_ON((caddr_t) bf->bf_desc >= - ((caddr_t) dd->dd_desc + - dd->dd_desc_len)); - - ds += (desc_len * ndesc); - bf->bf_desc = ds; - bf->bf_daddr = DS2PHYS(dd, ds); - } - } - list_add_tail(&bf->list, head); - } - } else { - struct ath_rxbuf *bf; - - bsize = sizeof(struct ath_rxbuf) * nbuf; - bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL); - if (!bf) - return -ENOMEM; + bsize = sizeof(struct ath_buf) * nbuf; + bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL); + if (!bf) + return -ENOMEM; - for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) { - bf->bf_desc = ds; - bf->bf_daddr = DS2PHYS(dd, ds); - - if (!(sc->sc_ah->caps.hw_caps & - ATH9K_HW_CAP_4KB_SPLITTRANS)) { - /* - * Skip descriptor addresses which can cause 4KB - * boundary crossing (addr + length) with a 32 dword - * descriptor fetch. - */ - while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) { - BUG_ON((caddr_t) bf->bf_desc >= - ((caddr_t) dd->dd_desc + - dd->dd_desc_len)); - - ds += (desc_len * ndesc); - bf->bf_desc = ds; - bf->bf_daddr = DS2PHYS(dd, ds); - } + for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) { + bf->bf_desc = ds; + bf->bf_daddr = DS2PHYS(dd, ds); + + if (!(sc->sc_ah->caps.hw_caps & + ATH9K_HW_CAP_4KB_SPLITTRANS)) { + /* + * Skip descriptor addresses which can cause 4KB + * boundary crossing (addr + length) with a 32 dword + * descriptor fetch. + */ + while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) { + BUG_ON((caddr_t) bf->bf_desc >= + ((caddr_t) dd->dd_desc + + dd->dd_desc_len)); + + ds += (desc_len * ndesc); + bf->bf_desc = ds; + bf->bf_daddr = DS2PHYS(dd, ds); } - list_add_tail(&bf->list, head); } + list_add_tail(&bf->list, head); } return 0; } @@ -471,6 +437,7 @@ static int ath9k_init_queues(struct ath_softc *sc) sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah); sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); + sc->config.cabqReadytime = ATH_CABQ_READY_TIME; ath_cabq_update(sc); sc->tx.uapsdq = ath_txq_setup(sc, ATH9K_TX_QUEUE_UAPSD, 0); @@ -580,26 +547,6 @@ static void ath9k_init_platform(struct ath_softc *sc) if (sc->driver_data & ATH9K_PCI_CUS217) ath_info(common, "CUS217 card detected\n"); - if (sc->driver_data & ATH9K_PCI_CUS252) - ath_info(common, "CUS252 card detected\n"); - - if (sc->driver_data & ATH9K_PCI_AR9565_1ANT) - ath_info(common, "WB335 1-ANT card detected\n"); - - if (sc->driver_data & ATH9K_PCI_AR9565_2ANT) - ath_info(common, "WB335 2-ANT card detected\n"); - - /* - * Some WB335 cards do not support antenna diversity. Since - * we use a hardcoded value for AR9565 instead of using the - * EEPROM/OTP data, remove the combining feature from - * the HW capabilities bitmap. - */ - if (sc->driver_data & (ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_AR9565_2ANT)) { - if (!(sc->driver_data & ATH9K_PCI_BT_ANT_DIV)) - pCap->hw_caps &= ~ATH9K_HW_CAP_ANT_DIV_COMB; - } - if (sc->driver_data & ATH9K_PCI_BT_ANT_DIV) { pCap->hw_caps |= ATH9K_HW_CAP_BT_ANT_DIV; ath_info(common, "Set BT/WLAN RX diversity capability\n"); @@ -609,11 +556,6 @@ static void ath9k_init_platform(struct ath_softc *sc) ah->config.pcie_waen = 0x0040473b; ath_info(common, "Enable WAR for ASPM D3/L1\n"); } - - if (sc->driver_data & ATH9K_PCI_NO_PLL_PWRSAVE) { - ah->config.no_pll_pwrsave = true; - ath_info(common, "Disable PLL PowerSave\n"); - } } static void ath9k_eeprom_request_cb(const struct firmware *eeprom_blob, @@ -685,9 +627,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, sc->sc_ah = ah; pCap = &ah->caps; - common = ath9k_hw_common(ah); - sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET); - sc->tx99_power = MAX_RATE_POWER + 1; + sc->dfs_detector = dfs_pattern_detector_init(ah, NL80211_DFS_UNSET); if (!pdata) { ah->ah_flags |= AH_USE_EEPROM; @@ -701,6 +641,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, ah->external_reset = pdata->external_reset; } + common = ath9k_hw_common(ah); common->ops = &ah->reg_ops; common->bus_ops = bus_ops; common->ah = ah; @@ -791,7 +732,6 @@ err_queues: ath9k_hw_deinit(ah); err_hw: ath9k_eeprom_release(sc); - dev_kfree_skb_any(sc->tx99_skb); return ret; } @@ -808,7 +748,7 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band) chan = &sband->channels[i]; ah->curchan = &ah->channels[chan->hw_value]; cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20); - ath9k_cmn_get_channel(sc->hw, ah, &chandef); + ath9k_cmn_update_ichannel(ah->curchan, &chandef); ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, true); } } @@ -849,9 +789,9 @@ static const struct ieee80211_iface_limit if_limits[] = { BIT(NL80211_IFTYPE_P2P_GO) }, }; + static const struct ieee80211_iface_limit if_dfs_limits[] = { - { .max = 1, .types = BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_ADHOC) }, + { .max = 1, .types = BIT(NL80211_IFTYPE_AP) }, }; static const struct ieee80211_iface_combination if_comb[] = { @@ -868,8 +808,8 @@ static const struct ieee80211_iface_combination if_comb[] = { .max_interfaces = 1, .num_different_channels = 1, .beacon_int_infra_match = true, - .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | - BIT(NL80211_CHAN_WIDTH_20), + .radar_detect_widths = BIT(NL80211_CHAN_NO_HT) | + BIT(NL80211_CHAN_HT20), } }; @@ -910,18 +850,17 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR; - if (!config_enabled(CONFIG_ATH9K_TX99)) { - hw->wiphy->interface_modes = - BIT(NL80211_IFTYPE_P2P_GO) | - BIT(NL80211_IFTYPE_P2P_CLIENT) | - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_WDS) | - BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_MESH_POINT); - hw->wiphy->iface_combinations = if_comb; - hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); - } + hw->wiphy->interface_modes = + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_AP) | + BIT(NL80211_IFTYPE_WDS) | + BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_MESH_POINT); + + hw->wiphy->iface_combinations = if_comb; + hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index aed7e29..2f831db 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c @@ -28,13 +28,6 @@ void ath_tx_complete_poll_work(struct work_struct *work) int i; bool needreset = false; - - if (sc->tx99_state) { - ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, - "skip tx hung detection on tx99\n"); - return; - } - for (i = 0; i < IEEE80211_NUM_ACS; i++) { txq = sc->tx.txq_map[i]; @@ -77,7 +70,7 @@ void ath_hw_check(struct work_struct *work) ath9k_ps_wakeup(sc); is_alive = ath9k_hw_check_alive(sc->sc_ah); - if ((is_alive && !AR_SREV_9300(sc->sc_ah)) || sc->tx99_state) + if (is_alive && !AR_SREV_9300(sc->sc_ah)) goto out; else if (!is_alive && AR_SREV_9300(sc->sc_ah)) { ath_dbg(common, RESET, @@ -148,9 +141,6 @@ void ath_hw_pll_work(struct work_struct *work) if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) return; - if (sc->tx99_state) - return; - ath9k_ps_wakeup(sc); pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); ath9k_ps_restore(sc); @@ -194,7 +184,7 @@ static void ath_paprd_activate(struct ath_softc *sc) struct ath9k_hw_cal_data *caldata = ah->caldata; int chain; - if (!caldata || !test_bit(PAPRD_DONE, &caldata->cal_flags)) { + if (!caldata || !caldata->paprd_done) { ath_dbg(common, CALIBRATE, "Failed to activate PAPRD\n"); return; } @@ -266,9 +256,7 @@ void ath_paprd_calibrate(struct work_struct *work) int len = 1800; int ret; - if (!caldata || - !test_bit(PAPRD_PACKET_SENT, &caldata->cal_flags) || - test_bit(PAPRD_DONE, &caldata->cal_flags)) { + if (!caldata || !caldata->paprd_packet_sent || caldata->paprd_done) { ath_dbg(common, CALIBRATE, "Skipping PAPRD calibration\n"); return; } @@ -328,7 +316,7 @@ void ath_paprd_calibrate(struct work_struct *work) kfree_skb(skb); if (chain_ok) { - set_bit(PAPRD_DONE, &caldata->cal_flags); + caldata->paprd_done = true; ath_paprd_activate(sc); } @@ -355,7 +343,7 @@ void ath_ani_calibrate(unsigned long data) u32 cal_interval, short_cal_interval, long_cal_interval; unsigned long flags; - if (ah->caldata && test_bit(NFCAL_INTF, &ah->caldata->cal_flags)) + if (ah->caldata && ah->caldata->nfcal_interference) long_cal_interval = ATH_LONG_CALINTERVAL_INT; else long_cal_interval = ATH_LONG_CALINTERVAL; @@ -444,7 +432,7 @@ set_timer: mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); if (ar9003_is_paprd_enabled(ah) && ah->caldata) { - if (!test_bit(PAPRD_DONE, &ah->caldata->cal_flags)) { + if (!ah->caldata->paprd_done) { ieee80211_queue_work(sc->hw, &sc->paprd_work); } else if (!ah->paprd_table_write_done) { ath9k_ps_wakeup(sc); @@ -528,8 +516,7 @@ void ath_update_survey_nf(struct ath_softc *sc, int channel) if (chan->noisefloor) { survey->filled |= SURVEY_INFO_NOISE_DBM; - survey->noise = ath9k_hw_getchan_noise(ah, chan, - chan->noisefloor); + survey->noise = ath9k_hw_getchan_noise(ah, chan); } } diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 6a18f9d..a3eff09 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -374,6 +374,7 @@ EXPORT_SYMBOL(ath9k_hw_releasetxqueue); bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) { struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_channel *chan = ah->curchan; struct ath9k_tx_queue_info *qi; u32 cwMin, chanCwMin, value; @@ -386,7 +387,10 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) ath_dbg(common, QUEUE, "Reset TX queue: %u\n", q); if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) { - chanCwMin = INIT_CWMIN; + if (chan && IS_CHAN_B(chan)) + chanCwMin = INIT_CWMIN_11B; + else + chanCwMin = INIT_CWMIN; for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1); } else diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index e3eed81..bfccace 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -603,6 +603,8 @@ enum ath9k_tx_queue_flags { #define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001 #define ATH9K_DECOMP_MASK_SIZE 128 +#define ATH9K_READY_TIME_LO_BOUND 50 +#define ATH9K_READY_TIME_HI_BOUND 96 enum ath9k_pkt_type { ATH9K_PKT_TYPE_NORMAL = 0, diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 74f452c..709301f 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -312,91 +312,17 @@ out: * by reseting the chip. To accomplish this we must first cleanup any pending * DMA, then restart stuff. */ -static int ath_set_channel(struct ath_softc *sc, struct cfg80211_chan_def *chandef) +static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, + struct ath9k_channel *hchan) { - struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); - struct ieee80211_hw *hw = sc->hw; - struct ath9k_channel *hchan; - struct ieee80211_channel *chan = chandef->chan; - unsigned long flags; - bool offchannel; - int pos = chan->hw_value; - int old_pos = -1; int r; if (test_bit(SC_OP_INVALID, &sc->sc_flags)) return -EIO; - offchannel = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL); - - if (ah->curchan) - old_pos = ah->curchan - &ah->channels[0]; - - ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n", - chan->center_freq, chandef->width); - - /* update survey stats for the old channel before switching */ - spin_lock_irqsave(&common->cc_lock, flags); - ath_update_survey_stats(sc); - spin_unlock_irqrestore(&common->cc_lock, flags); - - ath9k_cmn_get_channel(hw, ah, chandef); - - /* - * If the operating channel changes, change the survey in-use flags - * along with it. - * Reset the survey data for the new channel, unless we're switching - * back to the operating channel from an off-channel operation. - */ - if (!offchannel && sc->cur_survey != &sc->survey[pos]) { - if (sc->cur_survey) - sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE; - - sc->cur_survey = &sc->survey[pos]; - - memset(sc->cur_survey, 0, sizeof(struct survey_info)); - sc->cur_survey->filled |= SURVEY_INFO_IN_USE; - } else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) { - memset(&sc->survey[pos], 0, sizeof(struct survey_info)); - } - - hchan = &sc->sc_ah->channels[pos]; r = ath_reset_internal(sc, hchan); - if (r) - return r; - /* - * The most recent snapshot of channel->noisefloor for the old - * channel is only available after the hardware reset. Copy it to - * the survey stats now. - */ - if (old_pos >= 0) - ath_update_survey_nf(sc, old_pos); - - /* - * Enable radar pulse detection if on a DFS channel. Spectral - * scanning and radar detection can not be used concurrently. - */ - if (hw->conf.radar_enabled) { - u32 rxfilter; - - /* set HW specific DFS configuration */ - ath9k_hw_set_radar_params(ah); - rxfilter = ath9k_hw_getrxfilter(ah); - rxfilter |= ATH9K_RX_FILTER_PHYRADAR | - ATH9K_RX_FILTER_PHYERR; - ath9k_hw_setrxfilter(ah, rxfilter); - ath_dbg(common, DFS, "DFS enabled at freq %d\n", - chan->center_freq); - } else { - /* perform spectral scan if requested. */ - if (test_bit(SC_OP_SCANNING, &sc->sc_flags) && - sc->spectral_mode == SPECTRAL_CHANSCAN) - ath9k_spectral_scan_trigger(hw); - } - - return 0; + return r; } static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, @@ -446,13 +372,6 @@ void ath9k_tasklet(unsigned long data) type = RESET_TYPE_BB_WATCHDOG; ath9k_queue_reset(sc, type); - - /* - * Increment the ref. counter here so that - * interrupts are enabled in the reset routine. - */ - atomic_inc(&ah->intr_ref_cnt); - ath_dbg(common, ANY, "FATAL: Skipping interrupts\n"); goto out; } @@ -491,9 +410,10 @@ void ath9k_tasklet(unsigned long data) ath9k_btcoex_handle_interrupt(sc, status); +out: /* re-enable hardware interrupt */ ath9k_hw_enable_interrupts(ah); -out: + spin_unlock(&sc->sc_pcu_lock); ath9k_ps_restore(sc); } @@ -674,7 +594,7 @@ static int ath9k_start(struct ieee80211_hw *hw) ath9k_ps_wakeup(sc); mutex_lock(&sc->mutex); - init_channel = ath9k_cmn_get_channel(hw, ah, &hw->conf.chandef); + init_channel = ath9k_cmn_get_curchannel(hw, ah); /* Reset SERDES registers */ ath9k_hw_configpcipowersave(ah, false); @@ -877,7 +797,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) } if (!ah->curchan) - ah->curchan = ath9k_cmn_get_channel(hw, ah, &hw->conf.chandef); + ah->curchan = ath9k_cmn_get_curchannel(hw, ah); ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); ath9k_hw_phy_disable(ah); @@ -896,7 +816,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) ath_dbg(common, CONFIG, "Driver halt\n"); } -static bool ath9k_uses_beacons(int type) +bool ath9k_uses_beacons(int type) { switch (type) { case NL80211_IFTYPE_AP: @@ -1046,14 +966,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, mutex_lock(&sc->mutex); - if (config_enabled(CONFIG_ATH9K_TX99)) { - if (sc->nvifs >= 1) { - mutex_unlock(&sc->mutex); - return -EOPNOTSUPP; - } - sc->tx99_vif = vif; - } - ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); sc->nvifs++; @@ -1082,14 +994,8 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); - mutex_lock(&sc->mutex); - - if (config_enabled(CONFIG_ATH9K_TX99)) { - mutex_unlock(&sc->mutex); - return -EOPNOTSUPP; - } - ath_dbg(common, CONFIG, "Change Interface\n"); + mutex_lock(&sc->mutex); if (ath9k_uses_beacons(vif->type)) ath9k_beacon_remove_slot(sc, vif); @@ -1120,7 +1026,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, mutex_lock(&sc->mutex); sc->nvifs--; - sc->tx99_vif = NULL; if (ath9k_uses_beacons(vif->type)) ath9k_beacon_remove_slot(sc, vif); @@ -1142,9 +1047,6 @@ static void ath9k_enable_ps(struct ath_softc *sc) struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - if (config_enabled(CONFIG_ATH9K_TX99)) - return; - sc->ps_enabled = true; if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { if ((ah->imask & ATH9K_INT_TIM_TIMER) == 0) { @@ -1161,9 +1063,6 @@ static void ath9k_disable_ps(struct ath_softc *sc) struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - if (config_enabled(CONFIG_ATH9K_TX99)) - return; - sc->ps_enabled = false; ath9k_hw_setpower(ah, ATH9K_PM_AWAKE); if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { @@ -1187,9 +1086,6 @@ void ath9k_spectral_scan_trigger(struct ieee80211_hw *hw) struct ath_common *common = ath9k_hw_common(ah); u32 rxfilter; - if (config_enabled(CONFIG_ATH9K_TX99)) - return; - if (!ath9k_hw_ops(ah)->spectral_scan_trigger) { ath_err(common, "spectrum analyzer not implemented on this hardware\n"); return; @@ -1305,12 +1201,81 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) } if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || reset_channel) { - if (ath_set_channel(sc, &hw->conf.chandef) < 0) { + struct ieee80211_channel *curchan = hw->conf.chandef.chan; + int pos = curchan->hw_value; + int old_pos = -1; + unsigned long flags; + + if (ah->curchan) + old_pos = ah->curchan - &ah->channels[0]; + + ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n", + curchan->center_freq, hw->conf.chandef.width); + + /* update survey stats for the old channel before switching */ + spin_lock_irqsave(&common->cc_lock, flags); + ath_update_survey_stats(sc); + spin_unlock_irqrestore(&common->cc_lock, flags); + + ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos], + &conf->chandef); + + /* + * If the operating channel changes, change the survey in-use flags + * along with it. + * Reset the survey data for the new channel, unless we're switching + * back to the operating channel from an off-channel operation. + */ + if (!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) && + sc->cur_survey != &sc->survey[pos]) { + + if (sc->cur_survey) + sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE; + + sc->cur_survey = &sc->survey[pos]; + + memset(sc->cur_survey, 0, sizeof(struct survey_info)); + sc->cur_survey->filled |= SURVEY_INFO_IN_USE; + } else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) { + memset(&sc->survey[pos], 0, sizeof(struct survey_info)); + } + + if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { ath_err(common, "Unable to set channel\n"); mutex_unlock(&sc->mutex); ath9k_ps_restore(sc); return -EINVAL; } + + /* + * The most recent snapshot of channel->noisefloor for the old + * channel is only available after the hardware reset. Copy it to + * the survey stats now. + */ + if (old_pos >= 0) + ath_update_survey_nf(sc, old_pos); + + /* + * Enable radar pulse detection if on a DFS channel. Spectral + * scanning and radar detection can not be used concurrently. + */ + if (hw->conf.radar_enabled) { + u32 rxfilter; + + /* set HW specific DFS configuration */ + ath9k_hw_set_radar_params(ah); + rxfilter = ath9k_hw_getrxfilter(ah); + rxfilter |= ATH9K_RX_FILTER_PHYRADAR | + ATH9K_RX_FILTER_PHYERR; + ath9k_hw_setrxfilter(ah, rxfilter); + ath_dbg(common, DFS, "DFS enabled at freq %d\n", + curchan->center_freq); + } else { + /* perform spectral scan if requested. */ + if (test_bit(SC_OP_SCANNING, &sc->sc_flags) && + sc->spectral_mode == SPECTRAL_CHANSCAN) + ath9k_spectral_scan_trigger(hw); + } } if (changed & IEEE80211_CONF_CHANGE_POWER) { @@ -1769,9 +1734,6 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, unsigned long flags; int pos; - if (config_enabled(CONFIG_ATH9K_TX99)) - return -EOPNOTSUPP; - spin_lock_irqsave(&common->cc_lock, flags); if (idx == 0) ath_update_survey_stats(sc); @@ -1804,9 +1766,6 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) struct ath_softc *sc = hw->priv; struct ath_hw *ah = sc->sc_ah; - if (config_enabled(CONFIG_ATH9K_TX99)) - return; - mutex_lock(&sc->mutex); ah->coverage_class = coverage_class; @@ -2373,134 +2332,6 @@ static void ath9k_channel_switch_beacon(struct ieee80211_hw *hw, sc->csa_vif = vif; } -static void ath9k_tx99_stop(struct ath_softc *sc) -{ - struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); - - ath_drain_all_txq(sc); - ath_startrecv(sc); - - ath9k_hw_set_interrupts(ah); - ath9k_hw_enable_interrupts(ah); - - ieee80211_wake_queues(sc->hw); - - kfree_skb(sc->tx99_skb); - sc->tx99_skb = NULL; - sc->tx99_state = false; - - ath9k_hw_tx99_stop(sc->sc_ah); - ath_dbg(common, XMIT, "TX99 stopped\n"); -} - -static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc) -{ - static u8 PN9Data[] = {0xff, 0x87, 0xb8, 0x59, 0xb7, 0xa1, 0xcc, 0x24, - 0x57, 0x5e, 0x4b, 0x9c, 0x0e, 0xe9, 0xea, 0x50, - 0x2a, 0xbe, 0xb4, 0x1b, 0xb6, 0xb0, 0x5d, 0xf1, - 0xe6, 0x9a, 0xe3, 0x45, 0xfd, 0x2c, 0x53, 0x18, - 0x0c, 0xca, 0xc9, 0xfb, 0x49, 0x37, 0xe5, 0xa8, - 0x51, 0x3b, 0x2f, 0x61, 0xaa, 0x72, 0x18, 0x84, - 0x02, 0x23, 0x23, 0xab, 0x63, 0x89, 0x51, 0xb3, - 0xe7, 0x8b, 0x72, 0x90, 0x4c, 0xe8, 0xfb, 0xc0}; - u32 len = 1200; - struct ieee80211_hw *hw = sc->hw; - struct ieee80211_hdr *hdr; - struct ieee80211_tx_info *tx_info; - struct sk_buff *skb; - - skb = alloc_skb(len, GFP_KERNEL); - if (!skb) - return NULL; - - skb_put(skb, len); - - memset(skb->data, 0, len); - - hdr = (struct ieee80211_hdr *)skb->data; - hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA); - hdr->duration_id = 0; - - memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN); - memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); - memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); - - hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no); - - tx_info = IEEE80211_SKB_CB(skb); - memset(tx_info, 0, sizeof(*tx_info)); - tx_info->band = hw->conf.chandef.chan->band; - tx_info->flags = IEEE80211_TX_CTL_NO_ACK; - tx_info->control.vif = sc->tx99_vif; - - memcpy(skb->data + sizeof(*hdr), PN9Data, sizeof(PN9Data)); - - return skb; -} - -void ath9k_tx99_deinit(struct ath_softc *sc) -{ - ath_reset(sc); - - ath9k_ps_wakeup(sc); - ath9k_tx99_stop(sc); - ath9k_ps_restore(sc); -} - -int ath9k_tx99_init(struct ath_softc *sc) -{ - struct ieee80211_hw *hw = sc->hw; - struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(ah); - struct ath_tx_control txctl; - int r; - - if (sc->sc_flags & SC_OP_INVALID) { - ath_err(common, - "driver is in invalid state unable to use TX99"); - return -EINVAL; - } - - sc->tx99_skb = ath9k_build_tx99_skb(sc); - if (!sc->tx99_skb) - return -ENOMEM; - - memset(&txctl, 0, sizeof(txctl)); - txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO]; - - ath_reset(sc); - - ath9k_ps_wakeup(sc); - - ath9k_hw_disable_interrupts(ah); - atomic_set(&ah->intr_ref_cnt, -1); - ath_drain_all_txq(sc); - ath_stoprecv(sc); - - sc->tx99_state = true; - - ieee80211_stop_queues(hw); - - if (sc->tx99_power == MAX_RATE_POWER + 1) - sc->tx99_power = MAX_RATE_POWER; - - ath9k_hw_tx99_set_txpower(ah, sc->tx99_power); - r = ath9k_tx99_send(sc, sc->tx99_skb, &txctl); - if (r) { - ath_dbg(common, XMIT, "Failed to xmit TX99 skb\n"); - return r; - } - - ath_dbg(common, XMIT, "TX99 xmit started using %d ( %ddBm)\n", - sc->tx99_power, - sc->tx99_power / 2); - - /* We leave the harware awake as it will be chugging on */ - - return 0; -} - struct ieee80211_ops ath9k_ops = { .tx = ath9k_tx, .start = ath9k_start, diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 0ac1b5f..815bee2 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -661,9 +661,9 @@ void ath9k_mci_update_wlan_channels(struct ath_softc *sc, bool allow_all) chan_start = wlan_chan - 10; chan_end = wlan_chan + 10; - if (IS_CHAN_HT40PLUS(chan)) + if (chan->chanmode == CHANNEL_G_HT40PLUS) chan_end += 20; - else if (IS_CHAN_HT40MINUS(chan)) + else if (chan->chanmode == CHANNEL_G_HT40MINUS) chan_start -= 20; /* adjust side band */ @@ -707,11 +707,11 @@ void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel, if (setchannel) { struct ath9k_hw_cal_data *caldata = &sc->caldata; - if (IS_CHAN_HT40PLUS(ah->curchan) && + if ((caldata->chanmode == CHANNEL_G_HT40PLUS) && (ah->curchan->channel > caldata->channel) && (ah->curchan->channel <= caldata->channel + 20)) return; - if (IS_CHAN_HT40MINUS(ah->curchan) && + if ((caldata->chanmode == CHANNEL_G_HT40MINUS) && (ah->curchan->channel < caldata->channel) && (ah->curchan->channel >= caldata->channel - 20)) return; diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index b5656fc..d089a7c 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -195,93 +195,6 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { 0x3219), .driver_data = ATH9K_PCI_BT_ANT_DIV }, - /* AR9485 cards with PLL power-save disabled by default. */ - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0032, - PCI_VENDOR_ID_AZWAVE, - 0x2C97), - .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0032, - PCI_VENDOR_ID_AZWAVE, - 0x2100), - .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0032, - 0x1C56, /* ASKEY */ - 0x4001), - .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0032, - 0x11AD, /* LITEON */ - 0x6627), - .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0032, - 0x11AD, /* LITEON */ - 0x6628), - .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0032, - PCI_VENDOR_ID_FOXCONN, - 0xE04E), - .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0032, - PCI_VENDOR_ID_FOXCONN, - 0xE04F), - .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0032, - 0x144F, /* ASKEY */ - 0x7197), - .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0032, - 0x1B9A, /* XAVI */ - 0x2000), - .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0032, - 0x1B9A, /* XAVI */ - 0x2001), - .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0032, - PCI_VENDOR_ID_AZWAVE, - 0x1186), - .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0032, - PCI_VENDOR_ID_AZWAVE, - 0x1F86), - .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0032, - PCI_VENDOR_ID_AZWAVE, - 0x1195), - .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0032, - PCI_VENDOR_ID_AZWAVE, - 0x1F95), - .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0032, - 0x1B9A, /* XAVI */ - 0x1C00), - .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0032, - 0x1B9A, /* XAVI */ - 0x1C01), - .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0032, - PCI_VENDOR_ID_ASUSTEK, - 0x850D), - .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, - { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */ { PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */ @@ -356,200 +269,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */ { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */ - - /* CUS252 */ - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_ATHEROS, - 0x3028), - .driver_data = ATH9K_PCI_CUS252 | - ATH9K_PCI_AR9565_2ANT | - ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_AZWAVE, - 0x2176), - .driver_data = ATH9K_PCI_CUS252 | - ATH9K_PCI_AR9565_2ANT | - ATH9K_PCI_BT_ANT_DIV }, - - /* WB335 1-ANT */ - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_FOXCONN, - 0xE068), - .driver_data = ATH9K_PCI_AR9565_1ANT }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - 0x185F, /* WNC */ - 0xA119), - .driver_data = ATH9K_PCI_AR9565_1ANT }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - 0x11AD, /* LITEON */ - 0x0632), - .driver_data = ATH9K_PCI_AR9565_1ANT }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - 0x11AD, /* LITEON */ - 0x6671), - .driver_data = ATH9K_PCI_AR9565_1ANT }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - 0x1B9A, /* XAVI */ - 0x2811), - .driver_data = ATH9K_PCI_AR9565_1ANT }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - 0x1B9A, /* XAVI */ - 0x2812), - .driver_data = ATH9K_PCI_AR9565_1ANT }, - - /* WB335 1-ANT / Antenna Diversity */ - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_ATHEROS, - 0x3025), - .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_ATHEROS, - 0x3026), - .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_ATHEROS, - 0x302B), - .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_FOXCONN, - 0xE069), - .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - 0x185F, /* WNC */ - 0x3028), - .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - 0x11AD, /* LITEON */ - 0x0622), - .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - 0x11AD, /* LITEON */ - 0x0672), - .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - 0x11AD, /* LITEON */ - 0x0662), - .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_AZWAVE, - 0x213A), - .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_LENOVO, - 0x3026), - .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_HP, - 0x18E3), - .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_HP, - 0x217F), - .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_DELL, - 0x020E), - .driver_data = ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_BT_ANT_DIV }, - - /* WB335 2-ANT */ - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_SAMSUNG, - 0x411A), - .driver_data = ATH9K_PCI_AR9565_2ANT }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_SAMSUNG, - 0x411B), - .driver_data = ATH9K_PCI_AR9565_2ANT }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_SAMSUNG, - 0x411C), - .driver_data = ATH9K_PCI_AR9565_2ANT }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_SAMSUNG, - 0x411D), - .driver_data = ATH9K_PCI_AR9565_2ANT }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_SAMSUNG, - 0x411E), - .driver_data = ATH9K_PCI_AR9565_2ANT }, - - /* WB335 2-ANT / Antenna-Diversity */ - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_ATHEROS, - 0x3027), - .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_ATHEROS, - 0x302C), - .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - 0x11AD, /* LITEON */ - 0x0642), - .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - 0x11AD, /* LITEON */ - 0x0652), - .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - 0x11AD, /* LITEON */ - 0x0612), - .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - PCI_VENDOR_ID_AZWAVE, - 0x2130), - .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - 0x144F, /* ASKEY */ - 0x7202), - .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - 0x1B9A, /* XAVI */ - 0x2810), - .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, - { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, - 0x0036, - 0x185F, /* WNC */ - 0x3027), - .driver_data = ATH9K_PCI_AR9565_2ANT | ATH9K_PCI_BT_ANT_DIV }, - - /* PCI-E AR9565 (WB335) */ - { PCI_VDEVICE(ATHEROS, 0x0036), - .driver_data = ATH9K_PCI_BT_ANT_DIV }, - + { PCI_VDEVICE(ATHEROS, 0x0036) }, /* PCI-E AR9565 */ { 0 } }; diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index d829bb6..d3d7c51 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1387,31 +1387,31 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, int used_mcs = 0, used_htmode = 0; if (WLAN_RC_PHY_HT(rc->rate_table->info[i].phy)) { - used_mcs = scnprintf(mcs, 5, "%d", - rc->rate_table->info[i].ratecode); + used_mcs = snprintf(mcs, 5, "%d", + rc->rate_table->info[i].ratecode); if (WLAN_RC_PHY_40(rc->rate_table->info[i].phy)) - used_htmode = scnprintf(htmode, 5, "HT40"); + used_htmode = snprintf(htmode, 5, "HT40"); else if (WLAN_RC_PHY_20(rc->rate_table->info[i].phy)) - used_htmode = scnprintf(htmode, 5, "HT20"); + used_htmode = snprintf(htmode, 5, "HT20"); else - used_htmode = scnprintf(htmode, 5, "????"); + used_htmode = snprintf(htmode, 5, "????"); } mcs[used_mcs] = '\0'; htmode[used_htmode] = '\0'; - len += scnprintf(buf + len, max - len, - "%6s %6s %3u.%d: " - "%10u %10u %10u %10u\n", - htmode, - mcs, - ratekbps / 1000, - (ratekbps % 1000) / 100, - stats->success, - stats->retries, - stats->xretries, - stats->per); + len += snprintf(buf + len, max - len, + "%6s %6s %3u.%d: " + "%10u %10u %10u %10u\n", + htmode, + mcs, + ratekbps / 1000, + (ratekbps % 1000) / 100, + stats->success, + stats->retries, + stats->xretries, + stats->per); } if (len > max) diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 95ddca5..ab9e3a8 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -19,7 +19,7 @@ #include "ath9k.h" #include "ar9003_mac.h" -#define SKB_CB_ATHBUF(__skb) (*((struct ath_rxbuf **)__skb->cb)) +#define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb)) static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) { @@ -35,7 +35,7 @@ static inline bool ath9k_check_auto_sleep(struct ath_softc *sc) * buffer (or rx fifo). This can incorrectly acknowledge packets * to a sender if last desc is self-linked. */ -static void ath_rx_buf_link(struct ath_softc *sc, struct ath_rxbuf *bf) +static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); @@ -68,7 +68,7 @@ static void ath_rx_buf_link(struct ath_softc *sc, struct ath_rxbuf *bf) sc->rx.rxlink = &ds->ds_link; } -static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_rxbuf *bf) +static void ath_rx_buf_relink(struct ath_softc *sc, struct ath_buf *bf) { if (sc->rx.buf_hold) ath_rx_buf_link(sc, sc->rx.buf_hold); @@ -112,13 +112,13 @@ static bool ath_rx_edma_buf_link(struct ath_softc *sc, struct ath_hw *ah = sc->sc_ah; struct ath_rx_edma *rx_edma; struct sk_buff *skb; - struct ath_rxbuf *bf; + struct ath_buf *bf; rx_edma = &sc->rx.rx_edma[qtype]; if (skb_queue_len(&rx_edma->rx_fifo) >= rx_edma->rx_fifo_hwsize) return false; - bf = list_first_entry(&sc->rx.rxbuf, struct ath_rxbuf, list); + bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list); list_del_init(&bf->list); skb = bf->bf_mpdu; @@ -138,7 +138,7 @@ static void ath_rx_addbuffer_edma(struct ath_softc *sc, enum ath9k_rx_qtype qtype) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ath_rxbuf *bf, *tbf; + struct ath_buf *bf, *tbf; if (list_empty(&sc->rx.rxbuf)) { ath_dbg(common, QUEUE, "No free rx buf available\n"); @@ -154,7 +154,7 @@ static void ath_rx_addbuffer_edma(struct ath_softc *sc, static void ath_rx_remove_buffer(struct ath_softc *sc, enum ath9k_rx_qtype qtype) { - struct ath_rxbuf *bf; + struct ath_buf *bf; struct ath_rx_edma *rx_edma; struct sk_buff *skb; @@ -171,7 +171,7 @@ static void ath_rx_edma_cleanup(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - struct ath_rxbuf *bf; + struct ath_buf *bf; ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP); ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP); @@ -199,7 +199,7 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs) struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_hw *ah = sc->sc_ah; struct sk_buff *skb; - struct ath_rxbuf *bf; + struct ath_buf *bf; int error = 0, i; u32 size; @@ -211,7 +211,7 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs) ath_rx_edma_init_queue(&sc->rx.rx_edma[ATH9K_RX_QUEUE_HP], ah->caps.rx_hp_qdepth); - size = sizeof(struct ath_rxbuf) * nbufs; + size = sizeof(struct ath_buf) * nbufs; bf = devm_kzalloc(sc->dev, size, GFP_KERNEL); if (!bf) return -ENOMEM; @@ -271,7 +271,7 @@ int ath_rx_init(struct ath_softc *sc, int nbufs) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct sk_buff *skb; - struct ath_rxbuf *bf; + struct ath_buf *bf; int error = 0; spin_lock_init(&sc->sc_pcu_lock); @@ -332,7 +332,7 @@ void ath_rx_cleanup(struct ath_softc *sc) struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct sk_buff *skb; - struct ath_rxbuf *bf; + struct ath_buf *bf; if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { ath_rx_edma_cleanup(sc); @@ -375,9 +375,6 @@ u32 ath_calcrxfilter(struct ath_softc *sc) { u32 rfilt; - if (config_enabled(CONFIG_ATH9K_TX99)) - return 0; - rfilt = ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST | ATH9K_RX_FILTER_MCAST; @@ -430,7 +427,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc) int ath_startrecv(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; - struct ath_rxbuf *bf, *tbf; + struct ath_buf *bf, *tbf; if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { ath_edma_start_recv(sc); @@ -450,7 +447,7 @@ int ath_startrecv(struct ath_softc *sc) if (list_empty(&sc->rx.rxbuf)) goto start_recv; - bf = list_first_entry(&sc->rx.rxbuf, struct ath_rxbuf, list); + bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list); ath9k_hw_putrxbuf(ah, bf->bf_daddr); ath9k_hw_rxena(ah); @@ -606,13 +603,13 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb, bool mybeacon) static bool ath_edma_get_buffers(struct ath_softc *sc, enum ath9k_rx_qtype qtype, struct ath_rx_status *rs, - struct ath_rxbuf **dest) + struct ath_buf **dest) { struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype]; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct sk_buff *skb; - struct ath_rxbuf *bf; + struct ath_buf *bf; int ret; skb = skb_peek(&rx_edma->rx_fifo); @@ -656,11 +653,11 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, return true; } -static struct ath_rxbuf *ath_edma_get_next_rx_buf(struct ath_softc *sc, +static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc, struct ath_rx_status *rs, enum ath9k_rx_qtype qtype) { - struct ath_rxbuf *bf = NULL; + struct ath_buf *bf = NULL; while (ath_edma_get_buffers(sc, qtype, rs, &bf)) { if (!bf) @@ -671,13 +668,13 @@ static struct ath_rxbuf *ath_edma_get_next_rx_buf(struct ath_softc *sc, return NULL; } -static struct ath_rxbuf *ath_get_next_rx_buf(struct ath_softc *sc, +static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, struct ath_rx_status *rs) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); struct ath_desc *ds; - struct ath_rxbuf *bf; + struct ath_buf *bf; int ret; if (list_empty(&sc->rx.rxbuf)) { @@ -685,7 +682,7 @@ static struct ath_rxbuf *ath_get_next_rx_buf(struct ath_softc *sc, return NULL; } - bf = list_first_entry(&sc->rx.rxbuf, struct ath_rxbuf, list); + bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list); if (bf == sc->rx.buf_hold) return NULL; @@ -705,7 +702,7 @@ static struct ath_rxbuf *ath_get_next_rx_buf(struct ath_softc *sc, ret = ath9k_hw_rxprocdesc(ah, ds, rs); if (ret == -EINPROGRESS) { struct ath_rx_status trs; - struct ath_rxbuf *tbf; + struct ath_buf *tbf; struct ath_desc *tds; memset(&trs, 0, sizeof(trs)); @@ -714,7 +711,7 @@ static struct ath_rxbuf *ath_get_next_rx_buf(struct ath_softc *sc, return NULL; } - tbf = list_entry(bf->list.next, struct ath_rxbuf, list); + tbf = list_entry(bf->list.next, struct ath_buf, list); /* * On some hardware the descriptor status words could @@ -975,15 +972,14 @@ static int ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr, { #ifdef CONFIG_ATH9K_DEBUGFS struct ath_hw *ah = sc->sc_ah; - u8 num_bins, *bins, *vdata = (u8 *)hdr; - struct fft_sample_ht20 fft_sample_20; - struct fft_sample_ht20_40 fft_sample_40; - struct fft_sample_tlv *tlv; + u8 bins[SPECTRAL_HT20_NUM_BINS]; + u8 *vdata = (u8 *)hdr; + struct fft_sample_ht20 fft_sample; struct ath_radar_info *radar_info; + struct ath_ht20_mag_info *mag_info; int len = rs->rs_datalen; int dc_pos; - u16 fft_len, length, freq = ah->curchan->chan->center_freq; - enum nl80211_channel_type chan_type; + u16 length, max_magnitude; /* AR9280 and before report via ATH9K_PHYERR_RADAR, AR93xx and newer * via ATH9K_PHYERR_SPECTRAL. Haven't seen ATH9K_PHYERR_FALSE_RADAR_EXT @@ -1001,44 +997,45 @@ static int ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr, if (!(radar_info->pulse_bw_info & SPECTRAL_SCAN_BITMASK)) return 0; - chan_type = cfg80211_get_chandef_type(&sc->hw->conf.chandef); - if ((chan_type == NL80211_CHAN_HT40MINUS) || - (chan_type == NL80211_CHAN_HT40PLUS)) { - fft_len = SPECTRAL_HT20_40_TOTAL_DATA_LEN; - num_bins = SPECTRAL_HT20_40_NUM_BINS; - bins = (u8 *)fft_sample_40.data; - } else { - fft_len = SPECTRAL_HT20_TOTAL_DATA_LEN; - num_bins = SPECTRAL_HT20_NUM_BINS; - bins = (u8 *)fft_sample_20.data; - } - - /* Variation in the data length is possible and will be fixed later */ - if ((len > fft_len + 2) || (len < fft_len - 1)) + /* Variation in the data length is possible and will be fixed later. + * Note that we only support HT20 for now. + * + * TODO: add HT20_40 support as well. + */ + if ((len > SPECTRAL_HT20_TOTAL_DATA_LEN + 2) || + (len < SPECTRAL_HT20_TOTAL_DATA_LEN - 1)) return 1; - switch (len - fft_len) { + fft_sample.tlv.type = ATH_FFT_SAMPLE_HT20; + length = sizeof(fft_sample) - sizeof(fft_sample.tlv); + fft_sample.tlv.length = __cpu_to_be16(length); + + fft_sample.freq = __cpu_to_be16(ah->curchan->chan->center_freq); + fft_sample.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0); + fft_sample.noise = ah->noise; + + switch (len - SPECTRAL_HT20_TOTAL_DATA_LEN) { case 0: /* length correct, nothing to do. */ - memcpy(bins, vdata, num_bins); + memcpy(bins, vdata, SPECTRAL_HT20_NUM_BINS); break; case -1: /* first byte missing, duplicate it. */ - memcpy(&bins[1], vdata, num_bins - 1); + memcpy(&bins[1], vdata, SPECTRAL_HT20_NUM_BINS - 1); bins[0] = vdata[0]; break; case 2: /* MAC added 2 extra bytes at bin 30 and 32, remove them. */ memcpy(bins, vdata, 30); bins[30] = vdata[31]; - memcpy(&bins[31], &vdata[33], num_bins - 31); + memcpy(&bins[31], &vdata[33], SPECTRAL_HT20_NUM_BINS - 31); break; case 1: /* MAC added 2 extra bytes AND first byte is missing. */ bins[0] = vdata[0]; - memcpy(&bins[1], vdata, 30); + memcpy(&bins[0], vdata, 30); bins[31] = vdata[31]; - memcpy(&bins[32], &vdata[33], num_bins - 32); + memcpy(&bins[32], &vdata[33], SPECTRAL_HT20_NUM_BINS - 32); break; default: return 1; @@ -1047,93 +1044,23 @@ static int ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr, /* DC value (value in the middle) is the blind spot of the spectral * sample and invalid, interpolate it. */ - dc_pos = num_bins / 2; + dc_pos = SPECTRAL_HT20_NUM_BINS / 2; bins[dc_pos] = (bins[dc_pos + 1] + bins[dc_pos - 1]) / 2; - if ((chan_type == NL80211_CHAN_HT40MINUS) || - (chan_type == NL80211_CHAN_HT40PLUS)) { - s8 lower_rssi, upper_rssi; - s16 ext_nf; - u8 lower_max_index, upper_max_index; - u8 lower_bitmap_w, upper_bitmap_w; - u16 lower_mag, upper_mag; - struct ath9k_hw_cal_data *caldata = ah->caldata; - struct ath_ht20_40_mag_info *mag_info; - - if (caldata) - ext_nf = ath9k_hw_getchan_noise(ah, ah->curchan, - caldata->nfCalHist[3].privNF); - else - ext_nf = ATH_DEFAULT_NOISE_FLOOR; - - length = sizeof(fft_sample_40) - sizeof(struct fft_sample_tlv); - fft_sample_40.tlv.type = ATH_FFT_SAMPLE_HT20_40; - fft_sample_40.tlv.length = __cpu_to_be16(length); - fft_sample_40.freq = __cpu_to_be16(freq); - fft_sample_40.channel_type = chan_type; - - if (chan_type == NL80211_CHAN_HT40PLUS) { - lower_rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0); - upper_rssi = fix_rssi_inv_only(rs->rs_rssi_ext0); + /* mag data is at the end of the frame, in front of radar_info */ + mag_info = ((struct ath_ht20_mag_info *)radar_info) - 1; - fft_sample_40.lower_noise = ah->noise; - fft_sample_40.upper_noise = ext_nf; - } else { - lower_rssi = fix_rssi_inv_only(rs->rs_rssi_ext0); - upper_rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0); + /* copy raw bins without scaling them */ + memcpy(fft_sample.data, bins, SPECTRAL_HT20_NUM_BINS); + fft_sample.max_exp = mag_info->max_exp & 0xf; - fft_sample_40.lower_noise = ext_nf; - fft_sample_40.upper_noise = ah->noise; - } - fft_sample_40.lower_rssi = lower_rssi; - fft_sample_40.upper_rssi = upper_rssi; - - mag_info = ((struct ath_ht20_40_mag_info *)radar_info) - 1; - lower_mag = spectral_max_magnitude(mag_info->lower_bins); - upper_mag = spectral_max_magnitude(mag_info->upper_bins); - fft_sample_40.lower_max_magnitude = __cpu_to_be16(lower_mag); - fft_sample_40.upper_max_magnitude = __cpu_to_be16(upper_mag); - lower_max_index = spectral_max_index(mag_info->lower_bins); - upper_max_index = spectral_max_index(mag_info->upper_bins); - fft_sample_40.lower_max_index = lower_max_index; - fft_sample_40.upper_max_index = upper_max_index; - lower_bitmap_w = spectral_bitmap_weight(mag_info->lower_bins); - upper_bitmap_w = spectral_bitmap_weight(mag_info->upper_bins); - fft_sample_40.lower_bitmap_weight = lower_bitmap_w; - fft_sample_40.upper_bitmap_weight = upper_bitmap_w; - fft_sample_40.max_exp = mag_info->max_exp & 0xf; - - fft_sample_40.tsf = __cpu_to_be64(tsf); - - tlv = (struct fft_sample_tlv *)&fft_sample_40; - } else { - u8 max_index, bitmap_w; - u16 magnitude; - struct ath_ht20_mag_info *mag_info; - - length = sizeof(fft_sample_20) - sizeof(struct fft_sample_tlv); - fft_sample_20.tlv.type = ATH_FFT_SAMPLE_HT20; - fft_sample_20.tlv.length = __cpu_to_be16(length); - fft_sample_20.freq = __cpu_to_be16(freq); - - fft_sample_20.rssi = fix_rssi_inv_only(rs->rs_rssi_ctl0); - fft_sample_20.noise = ah->noise; - - mag_info = ((struct ath_ht20_mag_info *)radar_info) - 1; - magnitude = spectral_max_magnitude(mag_info->all_bins); - fft_sample_20.max_magnitude = __cpu_to_be16(magnitude); - max_index = spectral_max_index(mag_info->all_bins); - fft_sample_20.max_index = max_index; - bitmap_w = spectral_bitmap_weight(mag_info->all_bins); - fft_sample_20.bitmap_weight = bitmap_w; - fft_sample_20.max_exp = mag_info->max_exp & 0xf; - - fft_sample_20.tsf = __cpu_to_be64(tsf); - - tlv = (struct fft_sample_tlv *)&fft_sample_20; - } + max_magnitude = spectral_max_magnitude(mag_info->all_bins); + fft_sample.max_magnitude = __cpu_to_be16(max_magnitude); + fft_sample.max_index = spectral_max_index(mag_info->all_bins); + fft_sample.bitmap_weight = spectral_bitmap_weight(mag_info->all_bins); + fft_sample.tsf = __cpu_to_be64(tsf); - ath_debug_send_fft_sample(sc, tlv); + ath_debug_send_fft_sample(sc, &fft_sample.tlv); return 1; #else return 0; @@ -1381,7 +1308,7 @@ static void ath9k_apply_ampdu_details(struct ath_softc *sc, int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) { - struct ath_rxbuf *bf; + struct ath_buf *bf; struct sk_buff *skb = NULL, *requeue_skb, *hdr_skb; struct ieee80211_rx_status *rxs; struct ath_hw *ah = sc->sc_ah; diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h index 0db37f2..fde6da6 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.h +++ b/drivers/net/wireless/ath/ath9k/wmi.h @@ -39,7 +39,7 @@ struct wmi_fw_version { struct wmi_event_swba { __be64 tsf; u8 beacon_pending; -} __packed; +}; /* * 64 - HTC header - WMI header - 1 / txstatus diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 09cdbcd..dd30452 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -1241,13 +1241,12 @@ static void ath_tx_fill_desc(struct ath_softc *sc, struct ath_buf *bf, if (bf->bf_next) info.link = bf->bf_next->bf_daddr; else - info.link = (sc->tx99_state) ? bf->bf_daddr : 0; + info.link = 0; if (!bf_first) { bf_first = bf; - if (!sc->tx99_state) - info.flags = ATH9K_TXDESC_INTREQ; + info.flags = ATH9K_TXDESC_INTREQ; if ((tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) || txq == sc->tx.uapsdq) info.flags |= ATH9K_TXDESC_CLRDMASK; @@ -1705,9 +1704,16 @@ int ath_cabq_update(struct ath_softc *sc) int qnum = sc->beacon.cabq->axq_qnum; ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi); + /* + * Ensure the readytime % is within the bounds. + */ + if (sc->config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND) + sc->config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND; + else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND) + sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND; qi.tqi_readyTime = (cur_conf->beacon_interval * - ATH_CABQ_READY_TIME) / 100; + sc->config.cabqReadytime) / 100; ath_txq_update(sc, qnum, &qi); return 0; @@ -1942,7 +1948,7 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); } - if (!edma || sc->tx99_state) { + if (!edma) { TX_STAT_INC(txq->axq_qnum, txstart); ath9k_hw_txstart(ah, txq->axq_qnum); } @@ -2021,9 +2027,6 @@ static void setup_frame_info(struct ieee80211_hw *hw, fi->keyix = ATH9K_TXKEYIX_INVALID; fi->keytype = keytype; fi->framelen = framelen; - - if (!rate) - return; fi->rtscts_rate = rate->hw_value; if (short_preamble) fi->rtscts_rate |= rate->hw_value_short; @@ -2034,7 +2037,8 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) struct ath_hw *ah = sc->sc_ah; struct ath9k_channel *curchan = ah->curchan; - if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && IS_CHAN_5GHZ(curchan) && + if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && + (curchan->channelFlags & CHANNEL_5GHZ) && (chainmask == 0x7) && (rate < 0x90)) return 0x3; else if (AR_SREV_9462(ah) && ath9k_hw_btcoex_is_enabled(ah) && @@ -2325,7 +2329,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); if (sc->sc_ah->caldata) - set_bit(PAPRD_PACKET_SENT, &sc->sc_ah->caldata->cal_flags); + sc->sc_ah->caldata->paprd_packet_sent = true; if (!(tx_flags & ATH_TX_ERROR)) /* Frame was ACKed */ @@ -2375,8 +2379,6 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, dma_unmap_single(sc->dev, bf->bf_buf_addr, skb->len, DMA_TO_DEVICE); bf->bf_buf_addr = 0; - if (sc->tx99_state) - goto skip_tx_complete; if (bf->bf_state.bfs_paprd) { if (time_after(jiffies, @@ -2389,7 +2391,6 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, ath_debug_stat_tx(sc, bf, ts, txq, tx_flags); ath_tx_complete(sc, skb, tx_flags, txq); } -skip_tx_complete: /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't * accidentally reference it later. */ @@ -2748,46 +2749,3 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) ath_txq_unlock(sc, txq); } } - -int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb, - struct ath_tx_control *txctl) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - struct ath_frame_info *fi = get_frame_info(skb); - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ath_buf *bf; - int padpos, padsize; - - padpos = ieee80211_hdrlen(hdr->frame_control); - padsize = padpos & 3; - - if (padsize && skb->len > padpos) { - if (skb_headroom(skb) < padsize) { - ath_dbg(common, XMIT, - "tx99 padding failed\n"); - return -EINVAL; - } - - skb_push(skb, padsize); - memmove(skb->data, skb->data + padsize, padpos); - } - - fi->keyix = ATH9K_TXKEYIX_INVALID; - fi->framelen = skb->len + FCS_LEN; - fi->keytype = ATH9K_KEY_TYPE_CLEAR; - - bf = ath_tx_setup_buffer(sc, txctl->txq, NULL, skb); - if (!bf) { - ath_dbg(common, XMIT, "tx99 buffer setup failed\n"); - return -EINVAL; - } - - ath_set_rates(sc->tx99_vif, NULL, bf); - - ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, bf->bf_daddr); - ath9k_hw_tx99_start(sc->sc_ah, txctl->txq->axq_qnum); - - ath_tx_send_normal(sc, txctl->txq, NULL, skb); - - return 0; -} diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index ca115f3..307bc0d 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c @@ -773,7 +773,7 @@ void carl9170_usb_stop(struct ar9170 *ar) complete_all(&ar->cmd_wait); /* This is required to prevent an early completion on _start */ - reinit_completion(&ar->cmd_wait); + INIT_COMPLETION(ar->cmd_wait); /* * Note: diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 1217c52..7d077c7 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -356,132 +356,14 @@ static u16 ath_regd_find_country_by_name(char *alpha2) return -1; } -static int __ath_reg_dyn_country(struct wiphy *wiphy, - struct ath_regulatory *reg, - struct regulatory_request *request) -{ - u16 country_code; - - if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && - !ath_is_world_regd(reg)) - return -EINVAL; - - country_code = ath_regd_find_country_by_name(request->alpha2); - if (country_code == (u16) -1) - return -EINVAL; - - reg->current_rd = COUNTRY_ERD_FLAG; - reg->current_rd |= country_code; - - __ath_regd_init(reg); - - ath_reg_apply_world_flags(wiphy, request->initiator, reg); - - return 0; -} - -static void ath_reg_dyn_country(struct wiphy *wiphy, - struct ath_regulatory *reg, - struct regulatory_request *request) -{ - if (__ath_reg_dyn_country(wiphy, reg, request)) - return; - - printk(KERN_DEBUG "ath: regdomain 0x%0x " - "dynamically updated by %s\n", - reg->current_rd, - reg_initiator_name(request->initiator)); -} - -static bool dynamic_country_user_possible(struct ath_regulatory *reg) -{ - if (config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING)) - return true; - - switch (reg->country_code) { - case CTRY_UNITED_STATES: - case CTRY_JAPAN1: - case CTRY_JAPAN2: - case CTRY_JAPAN3: - case CTRY_JAPAN4: - case CTRY_JAPAN5: - case CTRY_JAPAN6: - case CTRY_JAPAN7: - case CTRY_JAPAN8: - case CTRY_JAPAN9: - case CTRY_JAPAN10: - case CTRY_JAPAN11: - case CTRY_JAPAN12: - case CTRY_JAPAN13: - case CTRY_JAPAN14: - case CTRY_JAPAN15: - case CTRY_JAPAN16: - case CTRY_JAPAN17: - case CTRY_JAPAN18: - case CTRY_JAPAN19: - case CTRY_JAPAN20: - case CTRY_JAPAN21: - case CTRY_JAPAN22: - case CTRY_JAPAN23: - case CTRY_JAPAN24: - case CTRY_JAPAN25: - case CTRY_JAPAN26: - case CTRY_JAPAN27: - case CTRY_JAPAN28: - case CTRY_JAPAN29: - case CTRY_JAPAN30: - case CTRY_JAPAN31: - case CTRY_JAPAN32: - case CTRY_JAPAN33: - case CTRY_JAPAN34: - case CTRY_JAPAN35: - case CTRY_JAPAN36: - case CTRY_JAPAN37: - case CTRY_JAPAN38: - case CTRY_JAPAN39: - case CTRY_JAPAN40: - case CTRY_JAPAN41: - case CTRY_JAPAN42: - case CTRY_JAPAN43: - case CTRY_JAPAN44: - case CTRY_JAPAN45: - case CTRY_JAPAN46: - case CTRY_JAPAN47: - case CTRY_JAPAN48: - case CTRY_JAPAN49: - case CTRY_JAPAN50: - case CTRY_JAPAN51: - case CTRY_JAPAN52: - case CTRY_JAPAN53: - case CTRY_JAPAN54: - case CTRY_JAPAN55: - case CTRY_JAPAN56: - case CTRY_JAPAN57: - case CTRY_JAPAN58: - case CTRY_JAPAN59: - return false; - } - - return true; -} - -static void ath_reg_dyn_country_user(struct wiphy *wiphy, - struct ath_regulatory *reg, - struct regulatory_request *request) -{ - if (!config_enabled(CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS)) - return; - if (!dynamic_country_user_possible(reg)) - return; - ath_reg_dyn_country(wiphy, reg, request); -} - void ath_reg_notifier_apply(struct wiphy *wiphy, struct regulatory_request *request, struct ath_regulatory *reg) { struct ath_common *common = container_of(reg, struct ath_common, regulatory); + u16 country_code; + /* We always apply this */ ath_reg_apply_radar_flags(wiphy); @@ -506,12 +388,25 @@ void ath_reg_notifier_apply(struct wiphy *wiphy, sizeof(struct ath_regulatory)); break; case NL80211_REGDOM_SET_BY_DRIVER: - break; case NL80211_REGDOM_SET_BY_USER: - ath_reg_dyn_country_user(wiphy, reg, request); break; case NL80211_REGDOM_SET_BY_COUNTRY_IE: - ath_reg_dyn_country(wiphy, reg, request); + if (!ath_is_world_regd(reg)) + break; + + country_code = ath_regd_find_country_by_name(request->alpha2); + if (country_code == (u16) -1) + break; + + reg->current_rd = COUNTRY_ERD_FLAG; + reg->current_rd |= country_code; + + printk(KERN_DEBUG "ath: regdomain 0x%0x updated by CountryIE\n", + reg->current_rd); + __ath_regd_init(reg); + + ath_reg_apply_world_flags(wiphy, request->initiator, reg); + break; } } diff --git a/drivers/net/wireless/ath/wcn36xx/Kconfig b/drivers/net/wireless/ath/wcn36xx/Kconfig deleted file mode 100644 index 591ebae..0000000 --- a/drivers/net/wireless/ath/wcn36xx/Kconfig +++ /dev/null @@ -1,16 +0,0 @@ -config WCN36XX - tristate "Qualcomm Atheros WCN3660/3680 support" - depends on MAC80211 && HAS_DMA - ---help--- - This module adds support for wireless adapters based on - Qualcomm Atheros WCN3660 and WCN3680 mobile chipsets. - - If you choose to build a module, it'll be called wcn36xx. - -config WCN36XX_DEBUGFS - bool "WCN36XX debugfs support" - depends on WCN36XX - ---help--- - Enabled debugfs support - - If unsure, say Y to make it easier to debug problems. diff --git a/drivers/net/wireless/ath/wcn36xx/Makefile b/drivers/net/wireless/ath/wcn36xx/Makefile deleted file mode 100644 index 50c43b4..0000000 --- a/drivers/net/wireless/ath/wcn36xx/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -obj-$(CONFIG_WCN36XX) := wcn36xx.o -wcn36xx-y += main.o \ - dxe.o \ - txrx.o \ - smd.o \ - pmc.o \ - debug.o diff --git a/drivers/net/wireless/ath/wcn36xx/debug.c b/drivers/net/wireless/ath/wcn36xx/debug.c deleted file mode 100644 index ef44a2da..0000000 --- a/drivers/net/wireless/ath/wcn36xx/debug.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/debugfs.h> -#include <linux/uaccess.h> -#include "wcn36xx.h" -#include "debug.h" -#include "pmc.h" - -#ifdef CONFIG_WCN36XX_DEBUGFS - -static ssize_t read_file_bool_bmps(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct wcn36xx *wcn = file->private_data; - struct wcn36xx_vif *vif_priv = NULL; - struct ieee80211_vif *vif = NULL; - char buf[3]; - - list_for_each_entry(vif_priv, &wcn->vif_list, list) { - vif = container_of((void *)vif_priv, - struct ieee80211_vif, - drv_priv); - if (NL80211_IFTYPE_STATION == vif->type) { - if (vif_priv->pw_state == WCN36XX_BMPS) - buf[0] = '1'; - else - buf[0] = '0'; - break; - } - } - buf[1] = '\n'; - buf[2] = 0x00; - - return simple_read_from_buffer(user_buf, count, ppos, buf, 2); -} - -static ssize_t write_file_bool_bmps(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct wcn36xx *wcn = file->private_data; - struct wcn36xx_vif *vif_priv = NULL; - struct ieee80211_vif *vif = NULL; - - char buf[32]; - int buf_size; - - buf_size = min(count, (sizeof(buf)-1)); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - - switch (buf[0]) { - case 'y': - case 'Y': - case '1': - list_for_each_entry(vif_priv, &wcn->vif_list, list) { - vif = container_of((void *)vif_priv, - struct ieee80211_vif, - drv_priv); - if (NL80211_IFTYPE_STATION == vif->type) { - wcn36xx_enable_keep_alive_null_packet(wcn, vif); - wcn36xx_pmc_enter_bmps_state(wcn, vif); - } - } - break; - case 'n': - case 'N': - case '0': - list_for_each_entry(vif_priv, &wcn->vif_list, list) { - vif = container_of((void *)vif_priv, - struct ieee80211_vif, - drv_priv); - if (NL80211_IFTYPE_STATION == vif->type) - wcn36xx_pmc_exit_bmps_state(wcn, vif); - } - break; - } - - return count; -} - -static const struct file_operations fops_wcn36xx_bmps = { - .open = simple_open, - .read = read_file_bool_bmps, - .write = write_file_bool_bmps, -}; - -static ssize_t write_file_dump(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct wcn36xx *wcn = file->private_data; - char buf[255], *tmp; - int buf_size; - u32 arg[WCN36xx_MAX_DUMP_ARGS]; - int i; - - memset(buf, 0, sizeof(buf)); - memset(arg, 0, sizeof(arg)); - - buf_size = min(count, (sizeof(buf) - 1)); - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - - tmp = buf; - - for (i = 0; i < WCN36xx_MAX_DUMP_ARGS; i++) { - char *begin; - begin = strsep(&tmp, " "); - if (begin == NULL) - break; - - if (kstrtou32(begin, 0, &arg[i]) != 0) - break; - } - - wcn36xx_info("DUMP args is %d %d %d %d %d\n", arg[0], arg[1], arg[2], - arg[3], arg[4]); - wcn36xx_smd_dump_cmd_req(wcn, arg[0], arg[1], arg[2], arg[3], arg[4]); - - return count; -} - -static const struct file_operations fops_wcn36xx_dump = { - .open = simple_open, - .write = write_file_dump, -}; - -#define ADD_FILE(name, mode, fop, priv_data) \ - do { \ - struct dentry *d; \ - d = debugfs_create_file(__stringify(name), \ - mode, dfs->rootdir, \ - priv_data, fop); \ - dfs->file_##name.dentry = d; \ - if (IS_ERR(d)) { \ - wcn36xx_warn("Create the debugfs entry failed");\ - dfs->file_##name.dentry = NULL; \ - } \ - } while (0) - - -void wcn36xx_debugfs_init(struct wcn36xx *wcn) -{ - struct wcn36xx_dfs_entry *dfs = &wcn->dfs; - - dfs->rootdir = debugfs_create_dir(KBUILD_MODNAME, - wcn->hw->wiphy->debugfsdir); - if (IS_ERR(dfs->rootdir)) { - wcn36xx_warn("Create the debugfs failed\n"); - dfs->rootdir = NULL; - } - - ADD_FILE(bmps_switcher, S_IRUSR | S_IWUSR, - &fops_wcn36xx_bmps, wcn); - ADD_FILE(dump, S_IWUSR, &fops_wcn36xx_dump, wcn); -} - -void wcn36xx_debugfs_exit(struct wcn36xx *wcn) -{ - struct wcn36xx_dfs_entry *dfs = &wcn->dfs; - debugfs_remove_recursive(dfs->rootdir); -} - -#endif /* CONFIG_WCN36XX_DEBUGFS */ diff --git a/drivers/net/wireless/ath/wcn36xx/debug.h b/drivers/net/wireless/ath/wcn36xx/debug.h deleted file mode 100644 index 46307aa..0000000 --- a/drivers/net/wireless/ath/wcn36xx/debug.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _WCN36XX_DEBUG_H_ -#define _WCN36XX_DEBUG_H_ - -#include <linux/kernel.h> - -#define WCN36xx_MAX_DUMP_ARGS 5 - -#ifdef CONFIG_WCN36XX_DEBUGFS -struct wcn36xx_dfs_file { - struct dentry *dentry; - u32 value; -}; - -struct wcn36xx_dfs_entry { - struct dentry *rootdir; - struct wcn36xx_dfs_file file_bmps_switcher; - struct wcn36xx_dfs_file file_dump; -}; - -void wcn36xx_debugfs_init(struct wcn36xx *wcn); -void wcn36xx_debugfs_exit(struct wcn36xx *wcn); - -#else -static inline void wcn36xx_debugfs_init(struct wcn36xx *wcn) -{ -} -static inline void wcn36xx_debugfs_exit(struct wcn36xx *wcn) -{ -} - -#endif /* CONFIG_WCN36XX_DEBUGFS */ - -#endif /* _WCN36XX_DEBUG_H_ */ diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c deleted file mode 100644 index ee25786..0000000 --- a/drivers/net/wireless/ath/wcn36xx/dxe.c +++ /dev/null @@ -1,805 +0,0 @@ -/* - * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* DXE - DMA transfer engine - * we have 2 channels(High prio and Low prio) for TX and 2 channels for RX. - * through low channels data packets are transfered - * through high channels managment packets are transfered - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/interrupt.h> -#include "wcn36xx.h" -#include "txrx.h" - -void *wcn36xx_dxe_get_next_bd(struct wcn36xx *wcn, bool is_low) -{ - struct wcn36xx_dxe_ch *ch = is_low ? - &wcn->dxe_tx_l_ch : - &wcn->dxe_tx_h_ch; - - return ch->head_blk_ctl->bd_cpu_addr; -} - -static void wcn36xx_dxe_write_register(struct wcn36xx *wcn, int addr, int data) -{ - wcn36xx_dbg(WCN36XX_DBG_DXE, - "wcn36xx_dxe_write_register: addr=%x, data=%x\n", - addr, data); - - writel(data, wcn->mmio + addr); -} - -static void wcn36xx_dxe_read_register(struct wcn36xx *wcn, int addr, int *data) -{ - *data = readl(wcn->mmio + addr); - - wcn36xx_dbg(WCN36XX_DBG_DXE, - "wcn36xx_dxe_read_register: addr=%x, data=%x\n", - addr, *data); -} - -static void wcn36xx_dxe_free_ctl_block(struct wcn36xx_dxe_ch *ch) -{ - struct wcn36xx_dxe_ctl *ctl = ch->head_blk_ctl, *next; - int i; - - for (i = 0; i < ch->desc_num && ctl; i++) { - next = ctl->next; - kfree(ctl); - ctl = next; - } -} - -static int wcn36xx_dxe_allocate_ctl_block(struct wcn36xx_dxe_ch *ch) -{ - struct wcn36xx_dxe_ctl *prev_ctl = NULL; - struct wcn36xx_dxe_ctl *cur_ctl = NULL; - int i; - - for (i = 0; i < ch->desc_num; i++) { - cur_ctl = kzalloc(sizeof(*cur_ctl), GFP_KERNEL); - if (!cur_ctl) - goto out_fail; - - cur_ctl->ctl_blk_order = i; - if (i == 0) { - ch->head_blk_ctl = cur_ctl; - ch->tail_blk_ctl = cur_ctl; - } else if (ch->desc_num - 1 == i) { - prev_ctl->next = cur_ctl; - cur_ctl->next = ch->head_blk_ctl; - } else { - prev_ctl->next = cur_ctl; - } - prev_ctl = cur_ctl; - } - - return 0; - -out_fail: - wcn36xx_dxe_free_ctl_block(ch); - return -ENOMEM; -} - -int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn) -{ - int ret; - - wcn->dxe_tx_l_ch.ch_type = WCN36XX_DXE_CH_TX_L; - wcn->dxe_tx_h_ch.ch_type = WCN36XX_DXE_CH_TX_H; - wcn->dxe_rx_l_ch.ch_type = WCN36XX_DXE_CH_RX_L; - wcn->dxe_rx_h_ch.ch_type = WCN36XX_DXE_CH_RX_H; - - wcn->dxe_tx_l_ch.desc_num = WCN36XX_DXE_CH_DESC_NUMB_TX_L; - wcn->dxe_tx_h_ch.desc_num = WCN36XX_DXE_CH_DESC_NUMB_TX_H; - wcn->dxe_rx_l_ch.desc_num = WCN36XX_DXE_CH_DESC_NUMB_RX_L; - wcn->dxe_rx_h_ch.desc_num = WCN36XX_DXE_CH_DESC_NUMB_RX_H; - - wcn->dxe_tx_l_ch.dxe_wq = WCN36XX_DXE_WQ_TX_L; - wcn->dxe_tx_h_ch.dxe_wq = WCN36XX_DXE_WQ_TX_H; - - wcn->dxe_tx_l_ch.ctrl_bd = WCN36XX_DXE_CTRL_TX_L_BD; - wcn->dxe_tx_h_ch.ctrl_bd = WCN36XX_DXE_CTRL_TX_H_BD; - - wcn->dxe_tx_l_ch.ctrl_skb = WCN36XX_DXE_CTRL_TX_L_SKB; - wcn->dxe_tx_h_ch.ctrl_skb = WCN36XX_DXE_CTRL_TX_H_SKB; - - wcn->dxe_tx_l_ch.reg_ctrl = WCN36XX_DXE_REG_CTL_TX_L; - wcn->dxe_tx_h_ch.reg_ctrl = WCN36XX_DXE_REG_CTL_TX_H; - - wcn->dxe_tx_l_ch.def_ctrl = WCN36XX_DXE_CH_DEFAULT_CTL_TX_L; - wcn->dxe_tx_h_ch.def_ctrl = WCN36XX_DXE_CH_DEFAULT_CTL_TX_H; - - /* DXE control block allocation */ - ret = wcn36xx_dxe_allocate_ctl_block(&wcn->dxe_tx_l_ch); - if (ret) - goto out_err; - ret = wcn36xx_dxe_allocate_ctl_block(&wcn->dxe_tx_h_ch); - if (ret) - goto out_err; - ret = wcn36xx_dxe_allocate_ctl_block(&wcn->dxe_rx_l_ch); - if (ret) - goto out_err; - ret = wcn36xx_dxe_allocate_ctl_block(&wcn->dxe_rx_h_ch); - if (ret) - goto out_err; - - /* Initialize SMSM state Clear TX Enable RING EMPTY STATE */ - ret = wcn->ctrl_ops->smsm_change_state( - WCN36XX_SMSM_WLAN_TX_ENABLE, - WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY); - - return 0; - -out_err: - wcn36xx_err("Failed to allocate DXE control blocks\n"); - wcn36xx_dxe_free_ctl_blks(wcn); - return -ENOMEM; -} - -void wcn36xx_dxe_free_ctl_blks(struct wcn36xx *wcn) -{ - wcn36xx_dxe_free_ctl_block(&wcn->dxe_tx_l_ch); - wcn36xx_dxe_free_ctl_block(&wcn->dxe_tx_h_ch); - wcn36xx_dxe_free_ctl_block(&wcn->dxe_rx_l_ch); - wcn36xx_dxe_free_ctl_block(&wcn->dxe_rx_h_ch); -} - -static int wcn36xx_dxe_init_descs(struct wcn36xx_dxe_ch *wcn_ch) -{ - struct wcn36xx_dxe_desc *cur_dxe = NULL; - struct wcn36xx_dxe_desc *prev_dxe = NULL; - struct wcn36xx_dxe_ctl *cur_ctl = NULL; - size_t size; - int i; - - size = wcn_ch->desc_num * sizeof(struct wcn36xx_dxe_desc); - wcn_ch->cpu_addr = dma_alloc_coherent(NULL, size, &wcn_ch->dma_addr, - GFP_KERNEL); - if (!wcn_ch->cpu_addr) - return -ENOMEM; - - memset(wcn_ch->cpu_addr, 0, size); - - cur_dxe = (struct wcn36xx_dxe_desc *)wcn_ch->cpu_addr; - cur_ctl = wcn_ch->head_blk_ctl; - - for (i = 0; i < wcn_ch->desc_num; i++) { - cur_ctl->desc = cur_dxe; - cur_ctl->desc_phy_addr = wcn_ch->dma_addr + - i * sizeof(struct wcn36xx_dxe_desc); - - switch (wcn_ch->ch_type) { - case WCN36XX_DXE_CH_TX_L: - cur_dxe->ctrl = WCN36XX_DXE_CTRL_TX_L; - cur_dxe->dst_addr_l = WCN36XX_DXE_WQ_TX_L; - break; - case WCN36XX_DXE_CH_TX_H: - cur_dxe->ctrl = WCN36XX_DXE_CTRL_TX_H; - cur_dxe->dst_addr_l = WCN36XX_DXE_WQ_TX_H; - break; - case WCN36XX_DXE_CH_RX_L: - cur_dxe->ctrl = WCN36XX_DXE_CTRL_RX_L; - cur_dxe->src_addr_l = WCN36XX_DXE_WQ_RX_L; - break; - case WCN36XX_DXE_CH_RX_H: - cur_dxe->ctrl = WCN36XX_DXE_CTRL_RX_H; - cur_dxe->src_addr_l = WCN36XX_DXE_WQ_RX_H; - break; - } - if (0 == i) { - cur_dxe->phy_next_l = 0; - } else if ((0 < i) && (i < wcn_ch->desc_num - 1)) { - prev_dxe->phy_next_l = - cur_ctl->desc_phy_addr; - } else if (i == (wcn_ch->desc_num - 1)) { - prev_dxe->phy_next_l = - cur_ctl->desc_phy_addr; - cur_dxe->phy_next_l = - wcn_ch->head_blk_ctl->desc_phy_addr; - } - cur_ctl = cur_ctl->next; - prev_dxe = cur_dxe; - cur_dxe++; - } - - return 0; -} - -static void wcn36xx_dxe_init_tx_bd(struct wcn36xx_dxe_ch *ch, - struct wcn36xx_dxe_mem_pool *pool) -{ - int i, chunk_size = pool->chunk_size; - dma_addr_t bd_phy_addr = pool->phy_addr; - void *bd_cpu_addr = pool->virt_addr; - struct wcn36xx_dxe_ctl *cur = ch->head_blk_ctl; - - for (i = 0; i < ch->desc_num; i++) { - /* Only every second dxe needs a bd pointer, - the other will point to the skb data */ - if (!(i & 1)) { - cur->bd_phy_addr = bd_phy_addr; - cur->bd_cpu_addr = bd_cpu_addr; - bd_phy_addr += chunk_size; - bd_cpu_addr += chunk_size; - } else { - cur->bd_phy_addr = 0; - cur->bd_cpu_addr = NULL; - } - cur = cur->next; - } -} - -static int wcn36xx_dxe_enable_ch_int(struct wcn36xx *wcn, u16 wcn_ch) -{ - int reg_data = 0; - - wcn36xx_dxe_read_register(wcn, - WCN36XX_DXE_INT_MASK_REG, - ®_data); - - reg_data |= wcn_ch; - - wcn36xx_dxe_write_register(wcn, - WCN36XX_DXE_INT_MASK_REG, - (int)reg_data); - return 0; -} - -static int wcn36xx_dxe_fill_skb(struct wcn36xx_dxe_ctl *ctl) -{ - struct wcn36xx_dxe_desc *dxe = ctl->desc; - struct sk_buff *skb; - - skb = alloc_skb(WCN36XX_PKT_SIZE, GFP_ATOMIC); - if (skb == NULL) - return -ENOMEM; - - dxe->dst_addr_l = dma_map_single(NULL, - skb_tail_pointer(skb), - WCN36XX_PKT_SIZE, - DMA_FROM_DEVICE); - ctl->skb = skb; - - return 0; -} - -static int wcn36xx_dxe_ch_alloc_skb(struct wcn36xx *wcn, - struct wcn36xx_dxe_ch *wcn_ch) -{ - int i; - struct wcn36xx_dxe_ctl *cur_ctl = NULL; - - cur_ctl = wcn_ch->head_blk_ctl; - - for (i = 0; i < wcn_ch->desc_num; i++) { - wcn36xx_dxe_fill_skb(cur_ctl); - cur_ctl = cur_ctl->next; - } - - return 0; -} - -static void wcn36xx_dxe_ch_free_skbs(struct wcn36xx *wcn, - struct wcn36xx_dxe_ch *wcn_ch) -{ - struct wcn36xx_dxe_ctl *cur = wcn_ch->head_blk_ctl; - int i; - - for (i = 0; i < wcn_ch->desc_num; i++) { - kfree_skb(cur->skb); - cur = cur->next; - } -} - -void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status) -{ - struct ieee80211_tx_info *info; - struct sk_buff *skb; - unsigned long flags; - - spin_lock_irqsave(&wcn->dxe_lock, flags); - skb = wcn->tx_ack_skb; - wcn->tx_ack_skb = NULL; - spin_unlock_irqrestore(&wcn->dxe_lock, flags); - - if (!skb) { - wcn36xx_warn("Spurious TX complete indication\n"); - return; - } - - info = IEEE80211_SKB_CB(skb); - - if (status == 1) - info->flags |= IEEE80211_TX_STAT_ACK; - - wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ack status: %d\n", status); - - ieee80211_tx_status_irqsafe(wcn->hw, skb); - ieee80211_wake_queues(wcn->hw); -} - -static void reap_tx_dxes(struct wcn36xx *wcn, struct wcn36xx_dxe_ch *ch) -{ - struct wcn36xx_dxe_ctl *ctl = ch->tail_blk_ctl; - struct ieee80211_tx_info *info; - unsigned long flags; - - /* - * Make at least one loop of do-while because in case ring is - * completely full head and tail are pointing to the same element - * and while-do will not make any cycles. - */ - do { - if (ctl->skb) { - dma_unmap_single(NULL, ctl->desc->src_addr_l, - ctl->skb->len, DMA_TO_DEVICE); - info = IEEE80211_SKB_CB(ctl->skb); - if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) { - /* Keep frame until TX status comes */ - ieee80211_free_txskb(wcn->hw, ctl->skb); - } - spin_lock_irqsave(&ctl->skb_lock, flags); - if (wcn->queues_stopped) { - wcn->queues_stopped = false; - ieee80211_wake_queues(wcn->hw); - } - spin_unlock_irqrestore(&ctl->skb_lock, flags); - - ctl->skb = NULL; - } - ctl = ctl->next; - } while (ctl != ch->head_blk_ctl && - !(ctl->desc->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)); - - ch->tail_blk_ctl = ctl; -} - -static irqreturn_t wcn36xx_irq_tx_complete(int irq, void *dev) -{ - struct wcn36xx *wcn = (struct wcn36xx *)dev; - int int_src, int_reason; - - wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_INT_SRC_RAW_REG, &int_src); - - if (int_src & WCN36XX_INT_MASK_CHAN_TX_H) { - wcn36xx_dxe_read_register(wcn, - WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_H, - &int_reason); - - /* TODO: Check int_reason */ - - wcn36xx_dxe_write_register(wcn, - WCN36XX_DXE_0_INT_CLR, - WCN36XX_INT_MASK_CHAN_TX_H); - - wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_ED_CLR, - WCN36XX_INT_MASK_CHAN_TX_H); - wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready high\n"); - reap_tx_dxes(wcn, &wcn->dxe_tx_h_ch); - } - - if (int_src & WCN36XX_INT_MASK_CHAN_TX_L) { - wcn36xx_dxe_read_register(wcn, - WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_L, - &int_reason); - /* TODO: Check int_reason */ - - wcn36xx_dxe_write_register(wcn, - WCN36XX_DXE_0_INT_CLR, - WCN36XX_INT_MASK_CHAN_TX_L); - - wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_ED_CLR, - WCN36XX_INT_MASK_CHAN_TX_L); - wcn36xx_dbg(WCN36XX_DBG_DXE, "dxe tx ready low\n"); - reap_tx_dxes(wcn, &wcn->dxe_tx_l_ch); - } - - return IRQ_HANDLED; -} - -static irqreturn_t wcn36xx_irq_rx_ready(int irq, void *dev) -{ - struct wcn36xx *wcn = (struct wcn36xx *)dev; - - disable_irq_nosync(wcn->rx_irq); - wcn36xx_dxe_rx_frame(wcn); - enable_irq(wcn->rx_irq); - return IRQ_HANDLED; -} - -static int wcn36xx_dxe_request_irqs(struct wcn36xx *wcn) -{ - int ret; - - ret = request_irq(wcn->tx_irq, wcn36xx_irq_tx_complete, - IRQF_TRIGGER_HIGH, "wcn36xx_tx", wcn); - if (ret) { - wcn36xx_err("failed to alloc tx irq\n"); - goto out_err; - } - - ret = request_irq(wcn->rx_irq, wcn36xx_irq_rx_ready, IRQF_TRIGGER_HIGH, - "wcn36xx_rx", wcn); - if (ret) { - wcn36xx_err("failed to alloc rx irq\n"); - goto out_txirq; - } - - enable_irq_wake(wcn->rx_irq); - - return 0; - -out_txirq: - free_irq(wcn->tx_irq, wcn); -out_err: - return ret; - -} - -static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn, - struct wcn36xx_dxe_ch *ch) -{ - struct wcn36xx_dxe_ctl *ctl = ch->head_blk_ctl; - struct wcn36xx_dxe_desc *dxe = ctl->desc; - dma_addr_t dma_addr; - struct sk_buff *skb; - - while (!(dxe->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)) { - skb = ctl->skb; - dma_addr = dxe->dst_addr_l; - wcn36xx_dxe_fill_skb(ctl); - - switch (ch->ch_type) { - case WCN36XX_DXE_CH_RX_L: - dxe->ctrl = WCN36XX_DXE_CTRL_RX_L; - wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_ENCH_ADDR, - WCN36XX_DXE_INT_CH1_MASK); - break; - case WCN36XX_DXE_CH_RX_H: - dxe->ctrl = WCN36XX_DXE_CTRL_RX_H; - wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_ENCH_ADDR, - WCN36XX_DXE_INT_CH3_MASK); - break; - default: - wcn36xx_warn("Unknown channel\n"); - } - - dma_unmap_single(NULL, dma_addr, WCN36XX_PKT_SIZE, - DMA_FROM_DEVICE); - wcn36xx_rx_skb(wcn, skb); - ctl = ctl->next; - dxe = ctl->desc; - } - - ch->head_blk_ctl = ctl; - - return 0; -} - -void wcn36xx_dxe_rx_frame(struct wcn36xx *wcn) -{ - int int_src; - - wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_INT_SRC_RAW_REG, &int_src); - - /* RX_LOW_PRI */ - if (int_src & WCN36XX_DXE_INT_CH1_MASK) { - wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_CLR, - WCN36XX_DXE_INT_CH1_MASK); - wcn36xx_rx_handle_packets(wcn, &(wcn->dxe_rx_l_ch)); - } - - /* RX_HIGH_PRI */ - if (int_src & WCN36XX_DXE_INT_CH3_MASK) { - /* Clean up all the INT within this channel */ - wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_0_INT_CLR, - WCN36XX_DXE_INT_CH3_MASK); - wcn36xx_rx_handle_packets(wcn, &(wcn->dxe_rx_h_ch)); - } - - if (!int_src) - wcn36xx_warn("No DXE interrupt pending\n"); -} - -int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn) -{ - size_t s; - void *cpu_addr; - - /* Allocate BD headers for MGMT frames */ - - /* Where this come from ask QC */ - wcn->mgmt_mem_pool.chunk_size = WCN36XX_BD_CHUNK_SIZE + - 16 - (WCN36XX_BD_CHUNK_SIZE % 8); - - s = wcn->mgmt_mem_pool.chunk_size * WCN36XX_DXE_CH_DESC_NUMB_TX_H; - cpu_addr = dma_alloc_coherent(NULL, s, &wcn->mgmt_mem_pool.phy_addr, - GFP_KERNEL); - if (!cpu_addr) - goto out_err; - - wcn->mgmt_mem_pool.virt_addr = cpu_addr; - memset(cpu_addr, 0, s); - - /* Allocate BD headers for DATA frames */ - - /* Where this come from ask QC */ - wcn->data_mem_pool.chunk_size = WCN36XX_BD_CHUNK_SIZE + - 16 - (WCN36XX_BD_CHUNK_SIZE % 8); - - s = wcn->data_mem_pool.chunk_size * WCN36XX_DXE_CH_DESC_NUMB_TX_L; - cpu_addr = dma_alloc_coherent(NULL, s, &wcn->data_mem_pool.phy_addr, - GFP_KERNEL); - if (!cpu_addr) - goto out_err; - - wcn->data_mem_pool.virt_addr = cpu_addr; - memset(cpu_addr, 0, s); - - return 0; - -out_err: - wcn36xx_dxe_free_mem_pools(wcn); - wcn36xx_err("Failed to allocate BD mempool\n"); - return -ENOMEM; -} - -void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn) -{ - if (wcn->mgmt_mem_pool.virt_addr) - dma_free_coherent(NULL, wcn->mgmt_mem_pool.chunk_size * - WCN36XX_DXE_CH_DESC_NUMB_TX_H, - wcn->mgmt_mem_pool.virt_addr, - wcn->mgmt_mem_pool.phy_addr); - - if (wcn->data_mem_pool.virt_addr) { - dma_free_coherent(NULL, wcn->data_mem_pool.chunk_size * - WCN36XX_DXE_CH_DESC_NUMB_TX_L, - wcn->data_mem_pool.virt_addr, - wcn->data_mem_pool.phy_addr); - } -} - -int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn, - struct wcn36xx_vif *vif_priv, - struct sk_buff *skb, - bool is_low) -{ - struct wcn36xx_dxe_ctl *ctl = NULL; - struct wcn36xx_dxe_desc *desc = NULL; - struct wcn36xx_dxe_ch *ch = NULL; - unsigned long flags; - - ch = is_low ? &wcn->dxe_tx_l_ch : &wcn->dxe_tx_h_ch; - - ctl = ch->head_blk_ctl; - - spin_lock_irqsave(&ctl->next->skb_lock, flags); - - /* - * If skb is not null that means that we reached the tail of the ring - * hence ring is full. Stop queues to let mac80211 back off until ring - * has an empty slot again. - */ - if (NULL != ctl->next->skb) { - ieee80211_stop_queues(wcn->hw); - wcn->queues_stopped = true; - spin_unlock_irqrestore(&ctl->next->skb_lock, flags); - return -EBUSY; - } - spin_unlock_irqrestore(&ctl->next->skb_lock, flags); - - ctl->skb = NULL; - desc = ctl->desc; - - /* Set source address of the BD we send */ - desc->src_addr_l = ctl->bd_phy_addr; - - desc->dst_addr_l = ch->dxe_wq; - desc->fr_len = sizeof(struct wcn36xx_tx_bd); - desc->ctrl = ch->ctrl_bd; - - wcn36xx_dbg(WCN36XX_DBG_DXE, "DXE TX\n"); - - wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP, "DESC1 >>> ", - (char *)desc, sizeof(*desc)); - wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP, - "BD >>> ", (char *)ctl->bd_cpu_addr, - sizeof(struct wcn36xx_tx_bd)); - - /* Set source address of the SKB we send */ - ctl = ctl->next; - ctl->skb = skb; - desc = ctl->desc; - if (ctl->bd_cpu_addr) { - wcn36xx_err("bd_cpu_addr cannot be NULL for skb DXE\n"); - return -EINVAL; - } - - desc->src_addr_l = dma_map_single(NULL, - ctl->skb->data, - ctl->skb->len, - DMA_TO_DEVICE); - - desc->dst_addr_l = ch->dxe_wq; - desc->fr_len = ctl->skb->len; - - /* set dxe descriptor to VALID */ - desc->ctrl = ch->ctrl_skb; - - wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP, "DESC2 >>> ", - (char *)desc, sizeof(*desc)); - wcn36xx_dbg_dump(WCN36XX_DBG_DXE_DUMP, "SKB >>> ", - (char *)ctl->skb->data, ctl->skb->len); - - /* Move the head of the ring to the next empty descriptor */ - ch->head_blk_ctl = ctl->next; - - /* - * When connected and trying to send data frame chip can be in sleep - * mode and writing to the register will not wake up the chip. Instead - * notify chip about new frame through SMSM bus. - */ - if (is_low && vif_priv->pw_state == WCN36XX_BMPS) { - wcn->ctrl_ops->smsm_change_state( - 0, - WCN36XX_SMSM_WLAN_TX_ENABLE); - } else { - /* indicate End Of Packet and generate interrupt on descriptor - * done. - */ - wcn36xx_dxe_write_register(wcn, - ch->reg_ctrl, ch->def_ctrl); - } - - return 0; -} - -int wcn36xx_dxe_init(struct wcn36xx *wcn) -{ - int reg_data = 0, ret; - - reg_data = WCN36XX_DXE_REG_RESET; - wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_REG_CSR_RESET, reg_data); - - /* Setting interrupt path */ - reg_data = WCN36XX_DXE_CCU_INT; - wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_REG_CCU_INT, reg_data); - - /***************************************/ - /* Init descriptors for TX LOW channel */ - /***************************************/ - wcn36xx_dxe_init_descs(&wcn->dxe_tx_l_ch); - wcn36xx_dxe_init_tx_bd(&wcn->dxe_tx_l_ch, &wcn->data_mem_pool); - - /* Write channel head to a NEXT register */ - wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_L, - wcn->dxe_tx_l_ch.head_blk_ctl->desc_phy_addr); - - /* Program DMA destination addr for TX LOW */ - wcn36xx_dxe_write_register(wcn, - WCN36XX_DXE_CH_DEST_ADDR_TX_L, - WCN36XX_DXE_WQ_TX_L); - - wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_REG_CH_EN, ®_data); - wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_TX_L); - - /***************************************/ - /* Init descriptors for TX HIGH channel */ - /***************************************/ - wcn36xx_dxe_init_descs(&wcn->dxe_tx_h_ch); - wcn36xx_dxe_init_tx_bd(&wcn->dxe_tx_h_ch, &wcn->mgmt_mem_pool); - - /* Write channel head to a NEXT register */ - wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_H, - wcn->dxe_tx_h_ch.head_blk_ctl->desc_phy_addr); - - /* Program DMA destination addr for TX HIGH */ - wcn36xx_dxe_write_register(wcn, - WCN36XX_DXE_CH_DEST_ADDR_TX_H, - WCN36XX_DXE_WQ_TX_H); - - wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_REG_CH_EN, ®_data); - - /* Enable channel interrupts */ - wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_TX_H); - - /***************************************/ - /* Init descriptors for RX LOW channel */ - /***************************************/ - wcn36xx_dxe_init_descs(&wcn->dxe_rx_l_ch); - - /* For RX we need to preallocated buffers */ - wcn36xx_dxe_ch_alloc_skb(wcn, &wcn->dxe_rx_l_ch); - - /* Write channel head to a NEXT register */ - wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_L, - wcn->dxe_rx_l_ch.head_blk_ctl->desc_phy_addr); - - /* Write DMA source address */ - wcn36xx_dxe_write_register(wcn, - WCN36XX_DXE_CH_SRC_ADDR_RX_L, - WCN36XX_DXE_WQ_RX_L); - - /* Program preallocated destination address */ - wcn36xx_dxe_write_register(wcn, - WCN36XX_DXE_CH_DEST_ADDR_RX_L, - wcn->dxe_rx_l_ch.head_blk_ctl->desc->phy_next_l); - - /* Enable default control registers */ - wcn36xx_dxe_write_register(wcn, - WCN36XX_DXE_REG_CTL_RX_L, - WCN36XX_DXE_CH_DEFAULT_CTL_RX_L); - - /* Enable channel interrupts */ - wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_RX_L); - - /***************************************/ - /* Init descriptors for RX HIGH channel */ - /***************************************/ - wcn36xx_dxe_init_descs(&wcn->dxe_rx_h_ch); - - /* For RX we need to prealocat buffers */ - wcn36xx_dxe_ch_alloc_skb(wcn, &wcn->dxe_rx_h_ch); - - /* Write chanel head to a NEXT register */ - wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_H, - wcn->dxe_rx_h_ch.head_blk_ctl->desc_phy_addr); - - /* Write DMA source address */ - wcn36xx_dxe_write_register(wcn, - WCN36XX_DXE_CH_SRC_ADDR_RX_H, - WCN36XX_DXE_WQ_RX_H); - - /* Program preallocated destination address */ - wcn36xx_dxe_write_register(wcn, - WCN36XX_DXE_CH_DEST_ADDR_RX_H, - wcn->dxe_rx_h_ch.head_blk_ctl->desc->phy_next_l); - - /* Enable default control registers */ - wcn36xx_dxe_write_register(wcn, - WCN36XX_DXE_REG_CTL_RX_H, - WCN36XX_DXE_CH_DEFAULT_CTL_RX_H); - - /* Enable channel interrupts */ - wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_RX_H); - - ret = wcn36xx_dxe_request_irqs(wcn); - if (ret < 0) - goto out_err; - - return 0; - -out_err: - return ret; -} - -void wcn36xx_dxe_deinit(struct wcn36xx *wcn) -{ - free_irq(wcn->tx_irq, wcn); - free_irq(wcn->rx_irq, wcn); - - if (wcn->tx_ack_skb) { - ieee80211_tx_status_irqsafe(wcn->hw, wcn->tx_ack_skb); - wcn->tx_ack_skb = NULL; - } - - wcn36xx_dxe_ch_free_skbs(wcn, &wcn->dxe_rx_l_ch); - wcn36xx_dxe_ch_free_skbs(wcn, &wcn->dxe_rx_h_ch); -} diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.h b/drivers/net/wireless/ath/wcn36xx/dxe.h deleted file mode 100644 index c88562f..0000000 --- a/drivers/net/wireless/ath/wcn36xx/dxe.h +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _DXE_H_ -#define _DXE_H_ - -#include "wcn36xx.h" - -/* -TX_LOW = DMA0 -TX_HIGH = DMA4 -RX_LOW = DMA1 -RX_HIGH = DMA3 -H2H_TEST_RX_TX = DMA2 -*/ - -/* DXE registers */ -#define WCN36XX_DXE_MEM_BASE 0x03000000 -#define WCN36XX_DXE_MEM_REG 0x202000 - -#define WCN36XX_DXE_CCU_INT 0xA0011 -#define WCN36XX_DXE_REG_CCU_INT 0x200b10 - -/* TODO This must calculated properly but not hardcoded */ -#define WCN36XX_DXE_CTRL_TX_L 0x328a44 -#define WCN36XX_DXE_CTRL_TX_H 0x32ce44 -#define WCN36XX_DXE_CTRL_RX_L 0x12ad2f -#define WCN36XX_DXE_CTRL_RX_H 0x12d12f -#define WCN36XX_DXE_CTRL_TX_H_BD 0x30ce45 -#define WCN36XX_DXE_CTRL_TX_H_SKB 0x32ce4d -#define WCN36XX_DXE_CTRL_TX_L_BD 0x308a45 -#define WCN36XX_DXE_CTRL_TX_L_SKB 0x328a4d - -/* TODO This must calculated properly but not hardcoded */ -#define WCN36XX_DXE_WQ_TX_L 0x17 -#define WCN36XX_DXE_WQ_TX_H 0x17 -#define WCN36XX_DXE_WQ_RX_L 0xB -#define WCN36XX_DXE_WQ_RX_H 0x4 - -/* DXE descriptor control filed */ -#define WCN36XX_DXE_CTRL_VALID_MASK (0x00000001) - -/* TODO This must calculated properly but not hardcoded */ -/* DXE default control register values */ -#define WCN36XX_DXE_CH_DEFAULT_CTL_RX_L 0x847EAD2F -#define WCN36XX_DXE_CH_DEFAULT_CTL_RX_H 0x84FED12F -#define WCN36XX_DXE_CH_DEFAULT_CTL_TX_H 0x853ECF4D -#define WCN36XX_DXE_CH_DEFAULT_CTL_TX_L 0x843e8b4d - -/* Common DXE registers */ -#define WCN36XX_DXE_MEM_CSR (WCN36XX_DXE_MEM_REG + 0x00) -#define WCN36XX_DXE_REG_CSR_RESET (WCN36XX_DXE_MEM_REG + 0x00) -#define WCN36XX_DXE_ENCH_ADDR (WCN36XX_DXE_MEM_REG + 0x04) -#define WCN36XX_DXE_REG_CH_EN (WCN36XX_DXE_MEM_REG + 0x08) -#define WCN36XX_DXE_REG_CH_DONE (WCN36XX_DXE_MEM_REG + 0x0C) -#define WCN36XX_DXE_REG_CH_ERR (WCN36XX_DXE_MEM_REG + 0x10) -#define WCN36XX_DXE_INT_MASK_REG (WCN36XX_DXE_MEM_REG + 0x18) -#define WCN36XX_DXE_INT_SRC_RAW_REG (WCN36XX_DXE_MEM_REG + 0x20) - /* #define WCN36XX_DXE_INT_CH6_MASK 0x00000040 */ - /* #define WCN36XX_DXE_INT_CH5_MASK 0x00000020 */ - #define WCN36XX_DXE_INT_CH4_MASK 0x00000010 - #define WCN36XX_DXE_INT_CH3_MASK 0x00000008 - /* #define WCN36XX_DXE_INT_CH2_MASK 0x00000004 */ - #define WCN36XX_DXE_INT_CH1_MASK 0x00000002 - #define WCN36XX_DXE_INT_CH0_MASK 0x00000001 -#define WCN36XX_DXE_0_INT_CLR (WCN36XX_DXE_MEM_REG + 0x30) -#define WCN36XX_DXE_0_INT_ED_CLR (WCN36XX_DXE_MEM_REG + 0x34) -#define WCN36XX_DXE_0_INT_DONE_CLR (WCN36XX_DXE_MEM_REG + 0x38) -#define WCN36XX_DXE_0_INT_ERR_CLR (WCN36XX_DXE_MEM_REG + 0x3C) - -#define WCN36XX_DXE_0_CH0_STATUS (WCN36XX_DXE_MEM_REG + 0x404) -#define WCN36XX_DXE_0_CH1_STATUS (WCN36XX_DXE_MEM_REG + 0x444) -#define WCN36XX_DXE_0_CH2_STATUS (WCN36XX_DXE_MEM_REG + 0x484) -#define WCN36XX_DXE_0_CH3_STATUS (WCN36XX_DXE_MEM_REG + 0x4C4) -#define WCN36XX_DXE_0_CH4_STATUS (WCN36XX_DXE_MEM_REG + 0x504) - -#define WCN36XX_DXE_REG_RESET 0x5c89 - -/* Temporary BMU Workqueue 4 */ -#define WCN36XX_DXE_BMU_WQ_RX_LOW 0xB -#define WCN36XX_DXE_BMU_WQ_RX_HIGH 0x4 -/* DMA channel offset */ -#define WCN36XX_DXE_TX_LOW_OFFSET 0x400 -#define WCN36XX_DXE_TX_HIGH_OFFSET 0x500 -#define WCN36XX_DXE_RX_LOW_OFFSET 0x440 -#define WCN36XX_DXE_RX_HIGH_OFFSET 0x4C0 - -/* Address of the next DXE descriptor */ -#define WCN36XX_DXE_CH_NEXT_DESC_ADDR 0x001C -#define WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_L (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_TX_LOW_OFFSET + \ - WCN36XX_DXE_CH_NEXT_DESC_ADDR) -#define WCN36XX_DXE_CH_NEXT_DESC_ADDR_TX_H (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_TX_HIGH_OFFSET + \ - WCN36XX_DXE_CH_NEXT_DESC_ADDR) -#define WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_L (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_RX_LOW_OFFSET + \ - WCN36XX_DXE_CH_NEXT_DESC_ADDR) -#define WCN36XX_DXE_CH_NEXT_DESC_ADDR_RX_H (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_RX_HIGH_OFFSET + \ - WCN36XX_DXE_CH_NEXT_DESC_ADDR) - -/* DXE Descriptor source address */ -#define WCN36XX_DXE_CH_SRC_ADDR 0x000C -#define WCN36XX_DXE_CH_SRC_ADDR_RX_L (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_RX_LOW_OFFSET + \ - WCN36XX_DXE_CH_SRC_ADDR) -#define WCN36XX_DXE_CH_SRC_ADDR_RX_H (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_RX_HIGH_OFFSET + \ - WCN36XX_DXE_CH_SRC_ADDR) - -/* DXE Descriptor address destination address */ -#define WCN36XX_DXE_CH_DEST_ADDR 0x0014 -#define WCN36XX_DXE_CH_DEST_ADDR_TX_L (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_TX_LOW_OFFSET + \ - WCN36XX_DXE_CH_DEST_ADDR) -#define WCN36XX_DXE_CH_DEST_ADDR_TX_H (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_TX_HIGH_OFFSET + \ - WCN36XX_DXE_CH_DEST_ADDR) -#define WCN36XX_DXE_CH_DEST_ADDR_RX_L (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_RX_LOW_OFFSET + \ - WCN36XX_DXE_CH_DEST_ADDR) -#define WCN36XX_DXE_CH_DEST_ADDR_RX_H (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_RX_HIGH_OFFSET + \ - WCN36XX_DXE_CH_DEST_ADDR) - -/* Interrupt status */ -#define WCN36XX_DXE_CH_STATUS_REG_ADDR 0x0004 -#define WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_L (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_TX_LOW_OFFSET + \ - WCN36XX_DXE_CH_STATUS_REG_ADDR) -#define WCN36XX_DXE_CH_STATUS_REG_ADDR_TX_H (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_TX_HIGH_OFFSET + \ - WCN36XX_DXE_CH_STATUS_REG_ADDR) -#define WCN36XX_DXE_CH_STATUS_REG_ADDR_RX_L (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_RX_LOW_OFFSET + \ - WCN36XX_DXE_CH_STATUS_REG_ADDR) -#define WCN36XX_DXE_CH_STATUS_REG_ADDR_RX_H (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_RX_HIGH_OFFSET + \ - WCN36XX_DXE_CH_STATUS_REG_ADDR) - - -/* DXE default control register */ -#define WCN36XX_DXE_REG_CTL_RX_L (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_RX_LOW_OFFSET) -#define WCN36XX_DXE_REG_CTL_RX_H (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_RX_HIGH_OFFSET) -#define WCN36XX_DXE_REG_CTL_TX_H (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_TX_HIGH_OFFSET) -#define WCN36XX_DXE_REG_CTL_TX_L (WCN36XX_DXE_MEM_REG + \ - WCN36XX_DXE_TX_LOW_OFFSET) - -#define WCN36XX_SMSM_WLAN_TX_ENABLE 0x00000400 -#define WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY 0x00000200 - - -/* Interrupt control channel mask */ -#define WCN36XX_INT_MASK_CHAN_TX_L 0x00000001 -#define WCN36XX_INT_MASK_CHAN_RX_L 0x00000002 -#define WCN36XX_INT_MASK_CHAN_RX_H 0x00000008 -#define WCN36XX_INT_MASK_CHAN_TX_H 0x00000010 - -#define WCN36XX_BD_CHUNK_SIZE 128 - -#define WCN36XX_PKT_SIZE 0xF20 -enum wcn36xx_dxe_ch_type { - WCN36XX_DXE_CH_TX_L, - WCN36XX_DXE_CH_TX_H, - WCN36XX_DXE_CH_RX_L, - WCN36XX_DXE_CH_RX_H -}; - -/* amount of descriptors per channel */ -enum wcn36xx_dxe_ch_desc_num { - WCN36XX_DXE_CH_DESC_NUMB_TX_L = 128, - WCN36XX_DXE_CH_DESC_NUMB_TX_H = 10, - WCN36XX_DXE_CH_DESC_NUMB_RX_L = 512, - WCN36XX_DXE_CH_DESC_NUMB_RX_H = 40 -}; - -/** - * struct wcn36xx_dxe_desc - describes descriptor of one DXE buffer - * - * @ctrl: is a union that consists of following bits: - * union { - * u32 valid :1; //0 = DMA stop, 1 = DMA continue with this - * //descriptor - * u32 transfer_type :2; //0 = Host to Host space - * u32 eop :1; //End of Packet - * u32 bd_handling :1; //if transferType = Host to BMU, then 0 - * // means first 128 bytes contain BD, and 1 - * // means create new empty BD - * u32 siq :1; // SIQ - * u32 diq :1; // DIQ - * u32 pdu_rel :1; //0 = don't release BD and PDUs when done, - * // 1 = release them - * u32 bthld_sel :4; //BMU Threshold Select - * u32 prio :3; //Specifies the priority level to use for - * // the transfer - * u32 stop_channel :1; //1 = DMA stops processing further, channel - * //requires re-enabling after this - * u32 intr :1; //Interrupt on Descriptor Done - * u32 rsvd :1; //reserved - * u32 size :14;//14 bits used - ignored for BMU transfers, - * //only used for host to host transfers? - * } ctrl; - */ -struct wcn36xx_dxe_desc { - u32 ctrl; - u32 fr_len; - - u32 src_addr_l; - u32 dst_addr_l; - u32 phy_next_l; - u32 src_addr_h; - u32 dst_addr_h; - u32 phy_next_h; -} __packed; - -/* DXE Control block */ -struct wcn36xx_dxe_ctl { - struct wcn36xx_dxe_ctl *next; - struct wcn36xx_dxe_desc *desc; - unsigned int desc_phy_addr; - int ctl_blk_order; - struct sk_buff *skb; - spinlock_t skb_lock; - void *bd_cpu_addr; - dma_addr_t bd_phy_addr; -}; - -struct wcn36xx_dxe_ch { - enum wcn36xx_dxe_ch_type ch_type; - void *cpu_addr; - dma_addr_t dma_addr; - enum wcn36xx_dxe_ch_desc_num desc_num; - /* DXE control block ring */ - struct wcn36xx_dxe_ctl *head_blk_ctl; - struct wcn36xx_dxe_ctl *tail_blk_ctl; - - /* DXE channel specific configs */ - u32 dxe_wq; - u32 ctrl_bd; - u32 ctrl_skb; - u32 reg_ctrl; - u32 def_ctrl; -}; - -/* Memory Pool for BD headers */ -struct wcn36xx_dxe_mem_pool { - int chunk_size; - void *virt_addr; - dma_addr_t phy_addr; -}; - -struct wcn36xx_vif; -int wcn36xx_dxe_allocate_mem_pools(struct wcn36xx *wcn); -void wcn36xx_dxe_free_mem_pools(struct wcn36xx *wcn); -void wcn36xx_dxe_rx_frame(struct wcn36xx *wcn); -int wcn36xx_dxe_alloc_ctl_blks(struct wcn36xx *wcn); -void wcn36xx_dxe_free_ctl_blks(struct wcn36xx *wcn); -int wcn36xx_dxe_init(struct wcn36xx *wcn); -void wcn36xx_dxe_deinit(struct wcn36xx *wcn); -int wcn36xx_dxe_init_channels(struct wcn36xx *wcn); -int wcn36xx_dxe_tx_frame(struct wcn36xx *wcn, - struct wcn36xx_vif *vif_priv, - struct sk_buff *skb, - bool is_low); -void wcn36xx_dxe_tx_ack_ind(struct wcn36xx *wcn, u32 status); -void *wcn36xx_dxe_get_next_bd(struct wcn36xx *wcn, bool is_low); -#endif /* _DXE_H_ */ diff --git a/drivers/net/wireless/ath/wcn36xx/hal.h b/drivers/net/wireless/ath/wcn36xx/hal.h deleted file mode 100644 index c02dbc6..0000000 --- a/drivers/net/wireless/ath/wcn36xx/hal.h +++ /dev/null @@ -1,4657 +0,0 @@ -/* - * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _HAL_H_ -#define _HAL_H_ - -/*--------------------------------------------------------------------------- - API VERSIONING INFORMATION - - The RIVA API is versioned as MAJOR.MINOR.VERSION.REVISION - The MAJOR is incremented for major product/architecture changes - (and then MINOR/VERSION/REVISION are zeroed) - The MINOR is incremented for minor product/architecture changes - (and then VERSION/REVISION are zeroed) - The VERSION is incremented if a significant API change occurs - (and then REVISION is zeroed) - The REVISION is incremented if an insignificant API change occurs - or if a new API is added - All values are in the range 0..255 (ie they are 8-bit values) - ---------------------------------------------------------------------------*/ -#define WCN36XX_HAL_VER_MAJOR 1 -#define WCN36XX_HAL_VER_MINOR 4 -#define WCN36XX_HAL_VER_VERSION 1 -#define WCN36XX_HAL_VER_REVISION 2 - -/* This is to force compiler to use the maximum of an int ( 4 bytes ) */ -#define WCN36XX_HAL_MAX_ENUM_SIZE 0x7FFFFFFF -#define WCN36XX_HAL_MSG_TYPE_MAX_ENUM_SIZE 0x7FFF - -/* Max no. of transmit categories */ -#define STACFG_MAX_TC 8 - -/* The maximum value of access category */ -#define WCN36XX_HAL_MAX_AC 4 - -#define WCN36XX_HAL_IPV4_ADDR_LEN 4 - -#define WALN_HAL_STA_INVALID_IDX 0xFF -#define WCN36XX_HAL_BSS_INVALID_IDX 0xFF - -/* Default Beacon template size */ -#define BEACON_TEMPLATE_SIZE 0x180 - -/* Param Change Bitmap sent to HAL */ -#define PARAM_BCN_INTERVAL_CHANGED (1 << 0) -#define PARAM_SHORT_PREAMBLE_CHANGED (1 << 1) -#define PARAM_SHORT_SLOT_TIME_CHANGED (1 << 2) -#define PARAM_llACOEXIST_CHANGED (1 << 3) -#define PARAM_llBCOEXIST_CHANGED (1 << 4) -#define PARAM_llGCOEXIST_CHANGED (1 << 5) -#define PARAM_HT20MHZCOEXIST_CHANGED (1<<6) -#define PARAM_NON_GF_DEVICES_PRESENT_CHANGED (1<<7) -#define PARAM_RIFS_MODE_CHANGED (1<<8) -#define PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED (1<<9) -#define PARAM_OBSS_MODE_CHANGED (1<<10) -#define PARAM_BEACON_UPDATE_MASK \ - (PARAM_BCN_INTERVAL_CHANGED | \ - PARAM_SHORT_PREAMBLE_CHANGED | \ - PARAM_SHORT_SLOT_TIME_CHANGED | \ - PARAM_llACOEXIST_CHANGED | \ - PARAM_llBCOEXIST_CHANGED | \ - PARAM_llGCOEXIST_CHANGED | \ - PARAM_HT20MHZCOEXIST_CHANGED | \ - PARAM_NON_GF_DEVICES_PRESENT_CHANGED | \ - PARAM_RIFS_MODE_CHANGED | \ - PARAM_LSIG_TXOP_FULL_SUPPORT_CHANGED | \ - PARAM_OBSS_MODE_CHANGED) - -/* dump command response Buffer size */ -#define DUMPCMD_RSP_BUFFER 100 - -/* version string max length (including NULL) */ -#define WCN36XX_HAL_VERSION_LENGTH 64 - -/* message types for messages exchanged between WDI and HAL */ -enum wcn36xx_hal_host_msg_type { - /* Init/De-Init */ - WCN36XX_HAL_START_REQ = 0, - WCN36XX_HAL_START_RSP = 1, - WCN36XX_HAL_STOP_REQ = 2, - WCN36XX_HAL_STOP_RSP = 3, - - /* Scan */ - WCN36XX_HAL_INIT_SCAN_REQ = 4, - WCN36XX_HAL_INIT_SCAN_RSP = 5, - WCN36XX_HAL_START_SCAN_REQ = 6, - WCN36XX_HAL_START_SCAN_RSP = 7, - WCN36XX_HAL_END_SCAN_REQ = 8, - WCN36XX_HAL_END_SCAN_RSP = 9, - WCN36XX_HAL_FINISH_SCAN_REQ = 10, - WCN36XX_HAL_FINISH_SCAN_RSP = 11, - - /* HW STA configuration/deconfiguration */ - WCN36XX_HAL_CONFIG_STA_REQ = 12, - WCN36XX_HAL_CONFIG_STA_RSP = 13, - WCN36XX_HAL_DELETE_STA_REQ = 14, - WCN36XX_HAL_DELETE_STA_RSP = 15, - WCN36XX_HAL_CONFIG_BSS_REQ = 16, - WCN36XX_HAL_CONFIG_BSS_RSP = 17, - WCN36XX_HAL_DELETE_BSS_REQ = 18, - WCN36XX_HAL_DELETE_BSS_RSP = 19, - - /* Infra STA asscoiation */ - WCN36XX_HAL_JOIN_REQ = 20, - WCN36XX_HAL_JOIN_RSP = 21, - WCN36XX_HAL_POST_ASSOC_REQ = 22, - WCN36XX_HAL_POST_ASSOC_RSP = 23, - - /* Security */ - WCN36XX_HAL_SET_BSSKEY_REQ = 24, - WCN36XX_HAL_SET_BSSKEY_RSP = 25, - WCN36XX_HAL_SET_STAKEY_REQ = 26, - WCN36XX_HAL_SET_STAKEY_RSP = 27, - WCN36XX_HAL_RMV_BSSKEY_REQ = 28, - WCN36XX_HAL_RMV_BSSKEY_RSP = 29, - WCN36XX_HAL_RMV_STAKEY_REQ = 30, - WCN36XX_HAL_RMV_STAKEY_RSP = 31, - - /* Qos Related */ - WCN36XX_HAL_ADD_TS_REQ = 32, - WCN36XX_HAL_ADD_TS_RSP = 33, - WCN36XX_HAL_DEL_TS_REQ = 34, - WCN36XX_HAL_DEL_TS_RSP = 35, - WCN36XX_HAL_UPD_EDCA_PARAMS_REQ = 36, - WCN36XX_HAL_UPD_EDCA_PARAMS_RSP = 37, - WCN36XX_HAL_ADD_BA_REQ = 38, - WCN36XX_HAL_ADD_BA_RSP = 39, - WCN36XX_HAL_DEL_BA_REQ = 40, - WCN36XX_HAL_DEL_BA_RSP = 41, - - WCN36XX_HAL_CH_SWITCH_REQ = 42, - WCN36XX_HAL_CH_SWITCH_RSP = 43, - WCN36XX_HAL_SET_LINK_ST_REQ = 44, - WCN36XX_HAL_SET_LINK_ST_RSP = 45, - WCN36XX_HAL_GET_STATS_REQ = 46, - WCN36XX_HAL_GET_STATS_RSP = 47, - WCN36XX_HAL_UPDATE_CFG_REQ = 48, - WCN36XX_HAL_UPDATE_CFG_RSP = 49, - - WCN36XX_HAL_MISSED_BEACON_IND = 50, - WCN36XX_HAL_UNKNOWN_ADDR2_FRAME_RX_IND = 51, - WCN36XX_HAL_MIC_FAILURE_IND = 52, - WCN36XX_HAL_FATAL_ERROR_IND = 53, - WCN36XX_HAL_SET_KEYDONE_MSG = 54, - - /* NV Interface */ - WCN36XX_HAL_DOWNLOAD_NV_REQ = 55, - WCN36XX_HAL_DOWNLOAD_NV_RSP = 56, - - WCN36XX_HAL_ADD_BA_SESSION_REQ = 57, - WCN36XX_HAL_ADD_BA_SESSION_RSP = 58, - WCN36XX_HAL_TRIGGER_BA_REQ = 59, - WCN36XX_HAL_TRIGGER_BA_RSP = 60, - WCN36XX_HAL_UPDATE_BEACON_REQ = 61, - WCN36XX_HAL_UPDATE_BEACON_RSP = 62, - WCN36XX_HAL_SEND_BEACON_REQ = 63, - WCN36XX_HAL_SEND_BEACON_RSP = 64, - - WCN36XX_HAL_SET_BCASTKEY_REQ = 65, - WCN36XX_HAL_SET_BCASTKEY_RSP = 66, - WCN36XX_HAL_DELETE_STA_CONTEXT_IND = 67, - WCN36XX_HAL_UPDATE_PROBE_RSP_TEMPLATE_REQ = 68, - WCN36XX_HAL_UPDATE_PROBE_RSP_TEMPLATE_RSP = 69, - - /* PTT interface support */ - WCN36XX_HAL_PROCESS_PTT_REQ = 70, - WCN36XX_HAL_PROCESS_PTT_RSP = 71, - - /* BTAMP related events */ - WCN36XX_HAL_SIGNAL_BTAMP_EVENT_REQ = 72, - WCN36XX_HAL_SIGNAL_BTAMP_EVENT_RSP = 73, - WCN36XX_HAL_TL_HAL_FLUSH_AC_REQ = 74, - WCN36XX_HAL_TL_HAL_FLUSH_AC_RSP = 75, - - WCN36XX_HAL_ENTER_IMPS_REQ = 76, - WCN36XX_HAL_EXIT_IMPS_REQ = 77, - WCN36XX_HAL_ENTER_BMPS_REQ = 78, - WCN36XX_HAL_EXIT_BMPS_REQ = 79, - WCN36XX_HAL_ENTER_UAPSD_REQ = 80, - WCN36XX_HAL_EXIT_UAPSD_REQ = 81, - WCN36XX_HAL_UPDATE_UAPSD_PARAM_REQ = 82, - WCN36XX_HAL_CONFIGURE_RXP_FILTER_REQ = 83, - WCN36XX_HAL_ADD_BCN_FILTER_REQ = 84, - WCN36XX_HAL_REM_BCN_FILTER_REQ = 85, - WCN36XX_HAL_ADD_WOWL_BCAST_PTRN = 86, - WCN36XX_HAL_DEL_WOWL_BCAST_PTRN = 87, - WCN36XX_HAL_ENTER_WOWL_REQ = 88, - WCN36XX_HAL_EXIT_WOWL_REQ = 89, - WCN36XX_HAL_HOST_OFFLOAD_REQ = 90, - WCN36XX_HAL_SET_RSSI_THRESH_REQ = 91, - WCN36XX_HAL_GET_RSSI_REQ = 92, - WCN36XX_HAL_SET_UAPSD_AC_PARAMS_REQ = 93, - WCN36XX_HAL_CONFIGURE_APPS_CPU_WAKEUP_STATE_REQ = 94, - - WCN36XX_HAL_ENTER_IMPS_RSP = 95, - WCN36XX_HAL_EXIT_IMPS_RSP = 96, - WCN36XX_HAL_ENTER_BMPS_RSP = 97, - WCN36XX_HAL_EXIT_BMPS_RSP = 98, - WCN36XX_HAL_ENTER_UAPSD_RSP = 99, - WCN36XX_HAL_EXIT_UAPSD_RSP = 100, - WCN36XX_HAL_SET_UAPSD_AC_PARAMS_RSP = 101, - WCN36XX_HAL_UPDATE_UAPSD_PARAM_RSP = 102, - WCN36XX_HAL_CONFIGURE_RXP_FILTER_RSP = 103, - WCN36XX_HAL_ADD_BCN_FILTER_RSP = 104, - WCN36XX_HAL_REM_BCN_FILTER_RSP = 105, - WCN36XX_HAL_SET_RSSI_THRESH_RSP = 106, - WCN36XX_HAL_HOST_OFFLOAD_RSP = 107, - WCN36XX_HAL_ADD_WOWL_BCAST_PTRN_RSP = 108, - WCN36XX_HAL_DEL_WOWL_BCAST_PTRN_RSP = 109, - WCN36XX_HAL_ENTER_WOWL_RSP = 110, - WCN36XX_HAL_EXIT_WOWL_RSP = 111, - WCN36XX_HAL_RSSI_NOTIFICATION_IND = 112, - WCN36XX_HAL_GET_RSSI_RSP = 113, - WCN36XX_HAL_CONFIGURE_APPS_CPU_WAKEUP_STATE_RSP = 114, - - /* 11k related events */ - WCN36XX_HAL_SET_MAX_TX_POWER_REQ = 115, - WCN36XX_HAL_SET_MAX_TX_POWER_RSP = 116, - - /* 11R related msgs */ - WCN36XX_HAL_AGGR_ADD_TS_REQ = 117, - WCN36XX_HAL_AGGR_ADD_TS_RSP = 118, - - /* P2P WLAN_FEATURE_P2P */ - WCN36XX_HAL_SET_P2P_GONOA_REQ = 119, - WCN36XX_HAL_SET_P2P_GONOA_RSP = 120, - - /* WLAN Dump commands */ - WCN36XX_HAL_DUMP_COMMAND_REQ = 121, - WCN36XX_HAL_DUMP_COMMAND_RSP = 122, - - /* OEM_DATA FEATURE SUPPORT */ - WCN36XX_HAL_START_OEM_DATA_REQ = 123, - WCN36XX_HAL_START_OEM_DATA_RSP = 124, - - /* ADD SELF STA REQ and RSP */ - WCN36XX_HAL_ADD_STA_SELF_REQ = 125, - WCN36XX_HAL_ADD_STA_SELF_RSP = 126, - - /* DEL SELF STA SUPPORT */ - WCN36XX_HAL_DEL_STA_SELF_REQ = 127, - WCN36XX_HAL_DEL_STA_SELF_RSP = 128, - - /* Coex Indication */ - WCN36XX_HAL_COEX_IND = 129, - - /* Tx Complete Indication */ - WCN36XX_HAL_OTA_TX_COMPL_IND = 130, - - /* Host Suspend/resume messages */ - WCN36XX_HAL_HOST_SUSPEND_IND = 131, - WCN36XX_HAL_HOST_RESUME_REQ = 132, - WCN36XX_HAL_HOST_RESUME_RSP = 133, - - WCN36XX_HAL_SET_TX_POWER_REQ = 134, - WCN36XX_HAL_SET_TX_POWER_RSP = 135, - WCN36XX_HAL_GET_TX_POWER_REQ = 136, - WCN36XX_HAL_GET_TX_POWER_RSP = 137, - - WCN36XX_HAL_P2P_NOA_ATTR_IND = 138, - - WCN36XX_HAL_ENABLE_RADAR_DETECT_REQ = 139, - WCN36XX_HAL_ENABLE_RADAR_DETECT_RSP = 140, - WCN36XX_HAL_GET_TPC_REPORT_REQ = 141, - WCN36XX_HAL_GET_TPC_REPORT_RSP = 142, - WCN36XX_HAL_RADAR_DETECT_IND = 143, - WCN36XX_HAL_RADAR_DETECT_INTR_IND = 144, - WCN36XX_HAL_KEEP_ALIVE_REQ = 145, - WCN36XX_HAL_KEEP_ALIVE_RSP = 146, - - /* PNO messages */ - WCN36XX_HAL_SET_PREF_NETWORK_REQ = 147, - WCN36XX_HAL_SET_PREF_NETWORK_RSP = 148, - WCN36XX_HAL_SET_RSSI_FILTER_REQ = 149, - WCN36XX_HAL_SET_RSSI_FILTER_RSP = 150, - WCN36XX_HAL_UPDATE_SCAN_PARAM_REQ = 151, - WCN36XX_HAL_UPDATE_SCAN_PARAM_RSP = 152, - WCN36XX_HAL_PREF_NETW_FOUND_IND = 153, - - WCN36XX_HAL_SET_TX_PER_TRACKING_REQ = 154, - WCN36XX_HAL_SET_TX_PER_TRACKING_RSP = 155, - WCN36XX_HAL_TX_PER_HIT_IND = 156, - - WCN36XX_HAL_8023_MULTICAST_LIST_REQ = 157, - WCN36XX_HAL_8023_MULTICAST_LIST_RSP = 158, - - WCN36XX_HAL_SET_PACKET_FILTER_REQ = 159, - WCN36XX_HAL_SET_PACKET_FILTER_RSP = 160, - WCN36XX_HAL_PACKET_FILTER_MATCH_COUNT_REQ = 161, - WCN36XX_HAL_PACKET_FILTER_MATCH_COUNT_RSP = 162, - WCN36XX_HAL_CLEAR_PACKET_FILTER_REQ = 163, - WCN36XX_HAL_CLEAR_PACKET_FILTER_RSP = 164, - - /* - * This is temp fix. Should be removed once Host and Riva code is - * in sync. - */ - WCN36XX_HAL_INIT_SCAN_CON_REQ = 165, - - WCN36XX_HAL_SET_POWER_PARAMS_REQ = 166, - WCN36XX_HAL_SET_POWER_PARAMS_RSP = 167, - - WCN36XX_HAL_TSM_STATS_REQ = 168, - WCN36XX_HAL_TSM_STATS_RSP = 169, - - /* wake reason indication (WOW) */ - WCN36XX_HAL_WAKE_REASON_IND = 170, - - /* GTK offload support */ - WCN36XX_HAL_GTK_OFFLOAD_REQ = 171, - WCN36XX_HAL_GTK_OFFLOAD_RSP = 172, - WCN36XX_HAL_GTK_OFFLOAD_GETINFO_REQ = 173, - WCN36XX_HAL_GTK_OFFLOAD_GETINFO_RSP = 174, - - WCN36XX_HAL_FEATURE_CAPS_EXCHANGE_REQ = 175, - WCN36XX_HAL_FEATURE_CAPS_EXCHANGE_RSP = 176, - WCN36XX_HAL_EXCLUDE_UNENCRYPTED_IND = 177, - - WCN36XX_HAL_SET_THERMAL_MITIGATION_REQ = 178, - WCN36XX_HAL_SET_THERMAL_MITIGATION_RSP = 179, - - WCN36XX_HAL_UPDATE_VHT_OP_MODE_REQ = 182, - WCN36XX_HAL_UPDATE_VHT_OP_MODE_RSP = 183, - - WCN36XX_HAL_P2P_NOA_START_IND = 184, - - WCN36XX_HAL_GET_ROAM_RSSI_REQ = 185, - WCN36XX_HAL_GET_ROAM_RSSI_RSP = 186, - - WCN36XX_HAL_CLASS_B_STATS_IND = 187, - WCN36XX_HAL_DEL_BA_IND = 188, - WCN36XX_HAL_DHCP_START_IND = 189, - WCN36XX_HAL_DHCP_STOP_IND = 190, - - WCN36XX_HAL_MSG_MAX = WCN36XX_HAL_MSG_TYPE_MAX_ENUM_SIZE -}; - -/* Enumeration for Version */ -enum wcn36xx_hal_host_msg_version { - WCN36XX_HAL_MSG_VERSION0 = 0, - WCN36XX_HAL_MSG_VERSION1 = 1, - /* define as 2 bytes data */ - WCN36XX_HAL_MSG_WCNSS_CTRL_VERSION = 0x7FFF, - WCN36XX_HAL_MSG_VERSION_MAX_FIELD = WCN36XX_HAL_MSG_WCNSS_CTRL_VERSION -}; - -enum driver_type { - DRIVER_TYPE_PRODUCTION = 0, - DRIVER_TYPE_MFG = 1, - DRIVER_TYPE_DVT = 2, - DRIVER_TYPE_MAX = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -enum wcn36xx_hal_stop_type { - HAL_STOP_TYPE_SYS_RESET, - HAL_STOP_TYPE_SYS_DEEP_SLEEP, - HAL_STOP_TYPE_RF_KILL, - HAL_STOP_TYPE_MAX = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -enum wcn36xx_hal_sys_mode { - HAL_SYS_MODE_NORMAL, - HAL_SYS_MODE_LEARN, - HAL_SYS_MODE_SCAN, - HAL_SYS_MODE_PROMISC, - HAL_SYS_MODE_SUSPEND_LINK, - HAL_SYS_MODE_ROAM_SCAN, - HAL_SYS_MODE_ROAM_SUSPEND_LINK, - HAL_SYS_MODE_MAX = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -enum phy_chan_bond_state { - /* 20MHz IF bandwidth centered on IF carrier */ - PHY_SINGLE_CHANNEL_CENTERED = 0, - - /* 40MHz IF bandwidth with lower 20MHz supporting the primary channel */ - PHY_DOUBLE_CHANNEL_LOW_PRIMARY = 1, - - /* 40MHz IF bandwidth centered on IF carrier */ - PHY_DOUBLE_CHANNEL_CENTERED = 2, - - /* 40MHz IF bandwidth with higher 20MHz supporting the primary ch */ - PHY_DOUBLE_CHANNEL_HIGH_PRIMARY = 3, - - /* 20/40MHZ offset LOW 40/80MHZ offset CENTERED */ - PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_CENTERED = 4, - - /* 20/40MHZ offset CENTERED 40/80MHZ offset CENTERED */ - PHY_QUADRUPLE_CHANNEL_20MHZ_CENTERED_40MHZ_CENTERED = 5, - - /* 20/40MHZ offset HIGH 40/80MHZ offset CENTERED */ - PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_CENTERED = 6, - - /* 20/40MHZ offset LOW 40/80MHZ offset LOW */ - PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW = 7, - - /* 20/40MHZ offset HIGH 40/80MHZ offset LOW */ - PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW = 8, - - /* 20/40MHZ offset LOW 40/80MHZ offset HIGH */ - PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH = 9, - - /* 20/40MHZ offset-HIGH 40/80MHZ offset HIGH */ - PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH = 10, - - PHY_CHANNEL_BONDING_STATE_MAX = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -/* Spatial Multiplexing(SM) Power Save mode */ -enum wcn36xx_hal_ht_mimo_state { - /* Static SM Power Save mode */ - WCN36XX_HAL_HT_MIMO_PS_STATIC = 0, - - /* Dynamic SM Power Save mode */ - WCN36XX_HAL_HT_MIMO_PS_DYNAMIC = 1, - - /* reserved */ - WCN36XX_HAL_HT_MIMO_PS_NA = 2, - - /* SM Power Save disabled */ - WCN36XX_HAL_HT_MIMO_PS_NO_LIMIT = 3, - - WCN36XX_HAL_HT_MIMO_PS_MAX = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -/* each station added has a rate mode which specifies the sta attributes */ -enum sta_rate_mode { - STA_TAURUS = 0, - STA_TITAN, - STA_POLARIS, - STA_11b, - STA_11bg, - STA_11a, - STA_11n, - STA_11ac, - STA_INVALID_RATE_MODE = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -/* 1,2,5.5,11 */ -#define WCN36XX_HAL_NUM_DSSS_RATES 4 - -/* 6,9,12,18,24,36,48,54 */ -#define WCN36XX_HAL_NUM_OFDM_RATES 8 - -/* 72,96,108 */ -#define WCN36XX_HAL_NUM_POLARIS_RATES 3 - -#define WCN36XX_HAL_MAC_MAX_SUPPORTED_MCS_SET 16 - -enum wcn36xx_hal_bss_type { - WCN36XX_HAL_INFRASTRUCTURE_MODE, - - /* Added for softAP support */ - WCN36XX_HAL_INFRA_AP_MODE, - - WCN36XX_HAL_IBSS_MODE, - - /* Added for BT-AMP support */ - WCN36XX_HAL_BTAMP_STA_MODE, - - /* Added for BT-AMP support */ - WCN36XX_HAL_BTAMP_AP_MODE, - - WCN36XX_HAL_AUTO_MODE, - - WCN36XX_HAL_DONOT_USE_BSS_TYPE = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -enum wcn36xx_hal_nw_type { - WCN36XX_HAL_11A_NW_TYPE, - WCN36XX_HAL_11B_NW_TYPE, - WCN36XX_HAL_11G_NW_TYPE, - WCN36XX_HAL_11N_NW_TYPE, - WCN36XX_HAL_DONOT_USE_NW_TYPE = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -#define WCN36XX_HAL_MAC_RATESET_EID_MAX 12 - -enum wcn36xx_hal_ht_operating_mode { - /* No Protection */ - WCN36XX_HAL_HT_OP_MODE_PURE, - - /* Overlap Legacy device present, protection is optional */ - WCN36XX_HAL_HT_OP_MODE_OVERLAP_LEGACY, - - /* No legacy device, but 20 MHz HT present */ - WCN36XX_HAL_HT_OP_MODE_NO_LEGACY_20MHZ_HT, - - /* Protection is required */ - WCN36XX_HAL_HT_OP_MODE_MIXED, - - WCN36XX_HAL_HT_OP_MODE_MAX = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -/* Encryption type enum used with peer */ -enum ani_ed_type { - WCN36XX_HAL_ED_NONE, - WCN36XX_HAL_ED_WEP40, - WCN36XX_HAL_ED_WEP104, - WCN36XX_HAL_ED_TKIP, - WCN36XX_HAL_ED_CCMP, - WCN36XX_HAL_ED_WPI, - WCN36XX_HAL_ED_AES_128_CMAC, - WCN36XX_HAL_ED_NOT_IMPLEMENTED = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -#define WLAN_MAX_KEY_RSC_LEN 16 -#define WLAN_WAPI_KEY_RSC_LEN 16 - -/* MAX key length when ULA is used */ -#define WCN36XX_HAL_MAC_MAX_KEY_LENGTH 32 -#define WCN36XX_HAL_MAC_MAX_NUM_OF_DEFAULT_KEYS 4 - -/* - * Enum to specify whether key is used for TX only, RX only or both. - */ -enum ani_key_direction { - WCN36XX_HAL_TX_ONLY, - WCN36XX_HAL_RX_ONLY, - WCN36XX_HAL_TX_RX, - WCN36XX_HAL_TX_DEFAULT, - WCN36XX_HAL_DONOT_USE_KEY_DIRECTION = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -enum ani_wep_type { - WCN36XX_HAL_WEP_STATIC, - WCN36XX_HAL_WEP_DYNAMIC, - WCN36XX_HAL_WEP_MAX = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -enum wcn36xx_hal_link_state { - - WCN36XX_HAL_LINK_IDLE_STATE = 0, - WCN36XX_HAL_LINK_PREASSOC_STATE = 1, - WCN36XX_HAL_LINK_POSTASSOC_STATE = 2, - WCN36XX_HAL_LINK_AP_STATE = 3, - WCN36XX_HAL_LINK_IBSS_STATE = 4, - - /* BT-AMP Case */ - WCN36XX_HAL_LINK_BTAMP_PREASSOC_STATE = 5, - WCN36XX_HAL_LINK_BTAMP_POSTASSOC_STATE = 6, - WCN36XX_HAL_LINK_BTAMP_AP_STATE = 7, - WCN36XX_HAL_LINK_BTAMP_STA_STATE = 8, - - /* Reserved for HAL Internal Use */ - WCN36XX_HAL_LINK_LEARN_STATE = 9, - WCN36XX_HAL_LINK_SCAN_STATE = 10, - WCN36XX_HAL_LINK_FINISH_SCAN_STATE = 11, - WCN36XX_HAL_LINK_INIT_CAL_STATE = 12, - WCN36XX_HAL_LINK_FINISH_CAL_STATE = 13, - WCN36XX_HAL_LINK_LISTEN_STATE = 14, - - WCN36XX_HAL_LINK_MAX = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -enum wcn36xx_hal_stats_mask { - HAL_SUMMARY_STATS_INFO = 0x00000001, - HAL_GLOBAL_CLASS_A_STATS_INFO = 0x00000002, - HAL_GLOBAL_CLASS_B_STATS_INFO = 0x00000004, - HAL_GLOBAL_CLASS_C_STATS_INFO = 0x00000008, - HAL_GLOBAL_CLASS_D_STATS_INFO = 0x00000010, - HAL_PER_STA_STATS_INFO = 0x00000020 -}; - -/* BT-AMP events type */ -enum bt_amp_event_type { - BTAMP_EVENT_CONNECTION_START, - BTAMP_EVENT_CONNECTION_STOP, - BTAMP_EVENT_CONNECTION_TERMINATED, - - /* This and beyond are invalid values */ - BTAMP_EVENT_TYPE_MAX = WCN36XX_HAL_MAX_ENUM_SIZE, -}; - -/* PE Statistics */ -enum pe_stats_mask { - PE_SUMMARY_STATS_INFO = 0x00000001, - PE_GLOBAL_CLASS_A_STATS_INFO = 0x00000002, - PE_GLOBAL_CLASS_B_STATS_INFO = 0x00000004, - PE_GLOBAL_CLASS_C_STATS_INFO = 0x00000008, - PE_GLOBAL_CLASS_D_STATS_INFO = 0x00000010, - PE_PER_STA_STATS_INFO = 0x00000020, - - /* This and beyond are invalid values */ - PE_STATS_TYPE_MAX = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -/* - * Configuration Parameter IDs - */ -#define WCN36XX_HAL_CFG_STA_ID 0 -#define WCN36XX_HAL_CFG_CURRENT_TX_ANTENNA 1 -#define WCN36XX_HAL_CFG_CURRENT_RX_ANTENNA 2 -#define WCN36XX_HAL_CFG_LOW_GAIN_OVERRIDE 3 -#define WCN36XX_HAL_CFG_POWER_STATE_PER_CHAIN 4 -#define WCN36XX_HAL_CFG_CAL_PERIOD 5 -#define WCN36XX_HAL_CFG_CAL_CONTROL 6 -#define WCN36XX_HAL_CFG_PROXIMITY 7 -#define WCN36XX_HAL_CFG_NETWORK_DENSITY 8 -#define WCN36XX_HAL_CFG_MAX_MEDIUM_TIME 9 -#define WCN36XX_HAL_CFG_MAX_MPDUS_IN_AMPDU 10 -#define WCN36XX_HAL_CFG_RTS_THRESHOLD 11 -#define WCN36XX_HAL_CFG_SHORT_RETRY_LIMIT 12 -#define WCN36XX_HAL_CFG_LONG_RETRY_LIMIT 13 -#define WCN36XX_HAL_CFG_FRAGMENTATION_THRESHOLD 14 -#define WCN36XX_HAL_CFG_DYNAMIC_THRESHOLD_ZERO 15 -#define WCN36XX_HAL_CFG_DYNAMIC_THRESHOLD_ONE 16 -#define WCN36XX_HAL_CFG_DYNAMIC_THRESHOLD_TWO 17 -#define WCN36XX_HAL_CFG_FIXED_RATE 18 -#define WCN36XX_HAL_CFG_RETRYRATE_POLICY 19 -#define WCN36XX_HAL_CFG_RETRYRATE_SECONDARY 20 -#define WCN36XX_HAL_CFG_RETRYRATE_TERTIARY 21 -#define WCN36XX_HAL_CFG_FORCE_POLICY_PROTECTION 22 -#define WCN36XX_HAL_CFG_FIXED_RATE_MULTICAST_24GHZ 23 -#define WCN36XX_HAL_CFG_FIXED_RATE_MULTICAST_5GHZ 24 -#define WCN36XX_HAL_CFG_DEFAULT_RATE_INDEX_24GHZ 25 -#define WCN36XX_HAL_CFG_DEFAULT_RATE_INDEX_5GHZ 26 -#define WCN36XX_HAL_CFG_MAX_BA_SESSIONS 27 -#define WCN36XX_HAL_CFG_PS_DATA_INACTIVITY_TIMEOUT 28 -#define WCN36XX_HAL_CFG_PS_ENABLE_BCN_FILTER 29 -#define WCN36XX_HAL_CFG_PS_ENABLE_RSSI_MONITOR 30 -#define WCN36XX_HAL_CFG_NUM_BEACON_PER_RSSI_AVERAGE 31 -#define WCN36XX_HAL_CFG_STATS_PERIOD 32 -#define WCN36XX_HAL_CFG_CFP_MAX_DURATION 33 -#define WCN36XX_HAL_CFG_FRAME_TRANS_ENABLED 34 -#define WCN36XX_HAL_CFG_DTIM_PERIOD 35 -#define WCN36XX_HAL_CFG_EDCA_WMM_ACBK 36 -#define WCN36XX_HAL_CFG_EDCA_WMM_ACBE 37 -#define WCN36XX_HAL_CFG_EDCA_WMM_ACVO 38 -#define WCN36XX_HAL_CFG_EDCA_WMM_ACVI 39 -#define WCN36XX_HAL_CFG_BA_THRESHOLD_HIGH 40 -#define WCN36XX_HAL_CFG_MAX_BA_BUFFERS 41 -#define WCN36XX_HAL_CFG_RPE_POLLING_THRESHOLD 42 -#define WCN36XX_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC0_REG 43 -#define WCN36XX_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC1_REG 44 -#define WCN36XX_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC2_REG 45 -#define WCN36XX_HAL_CFG_RPE_AGING_THRESHOLD_FOR_AC3_REG 46 -#define WCN36XX_HAL_CFG_NO_OF_ONCHIP_REORDER_SESSIONS 47 -#define WCN36XX_HAL_CFG_PS_LISTEN_INTERVAL 48 -#define WCN36XX_HAL_CFG_PS_HEART_BEAT_THRESHOLD 49 -#define WCN36XX_HAL_CFG_PS_NTH_BEACON_FILTER 50 -#define WCN36XX_HAL_CFG_PS_MAX_PS_POLL 51 -#define WCN36XX_HAL_CFG_PS_MIN_RSSI_THRESHOLD 52 -#define WCN36XX_HAL_CFG_PS_RSSI_FILTER_PERIOD 53 -#define WCN36XX_HAL_CFG_PS_BROADCAST_FRAME_FILTER_ENABLE 54 -#define WCN36XX_HAL_CFG_PS_IGNORE_DTIM 55 -#define WCN36XX_HAL_CFG_PS_ENABLE_BCN_EARLY_TERM 56 -#define WCN36XX_HAL_CFG_DYNAMIC_PS_POLL_VALUE 57 -#define WCN36XX_HAL_CFG_PS_NULLDATA_AP_RESP_TIMEOUT 58 -#define WCN36XX_HAL_CFG_TELE_BCN_WAKEUP_EN 59 -#define WCN36XX_HAL_CFG_TELE_BCN_TRANS_LI 60 -#define WCN36XX_HAL_CFG_TELE_BCN_TRANS_LI_IDLE_BCNS 61 -#define WCN36XX_HAL_CFG_TELE_BCN_MAX_LI 62 -#define WCN36XX_HAL_CFG_TELE_BCN_MAX_LI_IDLE_BCNS 63 -#define WCN36XX_HAL_CFG_TX_PWR_CTRL_ENABLE 64 -#define WCN36XX_HAL_CFG_VALID_RADAR_CHANNEL_LIST 65 -#define WCN36XX_HAL_CFG_TX_POWER_24_20 66 -#define WCN36XX_HAL_CFG_TX_POWER_24_40 67 -#define WCN36XX_HAL_CFG_TX_POWER_50_20 68 -#define WCN36XX_HAL_CFG_TX_POWER_50_40 69 -#define WCN36XX_HAL_CFG_MCAST_BCAST_FILTER_SETTING 70 -#define WCN36XX_HAL_CFG_BCN_EARLY_TERM_WAKEUP_INTERVAL 71 -#define WCN36XX_HAL_CFG_MAX_TX_POWER_2_4 72 -#define WCN36XX_HAL_CFG_MAX_TX_POWER_5 73 -#define WCN36XX_HAL_CFG_INFRA_STA_KEEP_ALIVE_PERIOD 74 -#define WCN36XX_HAL_CFG_ENABLE_CLOSE_LOOP 75 -#define WCN36XX_HAL_CFG_BTC_EXECUTION_MODE 76 -#define WCN36XX_HAL_CFG_BTC_DHCP_BT_SLOTS_TO_BLOCK 77 -#define WCN36XX_HAL_CFG_BTC_A2DP_DHCP_BT_SUB_INTERVALS 78 -#define WCN36XX_HAL_CFG_PS_TX_INACTIVITY_TIMEOUT 79 -#define WCN36XX_HAL_CFG_WCNSS_API_VERSION 80 -#define WCN36XX_HAL_CFG_AP_KEEPALIVE_TIMEOUT 81 -#define WCN36XX_HAL_CFG_GO_KEEPALIVE_TIMEOUT 82 -#define WCN36XX_HAL_CFG_ENABLE_MC_ADDR_LIST 83 -#define WCN36XX_HAL_CFG_BTC_STATIC_LEN_INQ_BT 84 -#define WCN36XX_HAL_CFG_BTC_STATIC_LEN_PAGE_BT 85 -#define WCN36XX_HAL_CFG_BTC_STATIC_LEN_CONN_BT 86 -#define WCN36XX_HAL_CFG_BTC_STATIC_LEN_LE_BT 87 -#define WCN36XX_HAL_CFG_BTC_STATIC_LEN_INQ_WLAN 88 -#define WCN36XX_HAL_CFG_BTC_STATIC_LEN_PAGE_WLAN 89 -#define WCN36XX_HAL_CFG_BTC_STATIC_LEN_CONN_WLAN 90 -#define WCN36XX_HAL_CFG_BTC_STATIC_LEN_LE_WLAN 91 -#define WCN36XX_HAL_CFG_BTC_DYN_MAX_LEN_BT 92 -#define WCN36XX_HAL_CFG_BTC_DYN_MAX_LEN_WLAN 93 -#define WCN36XX_HAL_CFG_BTC_MAX_SCO_BLOCK_PERC 94 -#define WCN36XX_HAL_CFG_BTC_DHCP_PROT_ON_A2DP 95 -#define WCN36XX_HAL_CFG_BTC_DHCP_PROT_ON_SCO 96 -#define WCN36XX_HAL_CFG_ENABLE_UNICAST_FILTER 97 -#define WCN36XX_HAL_CFG_MAX_ASSOC_LIMIT 98 -#define WCN36XX_HAL_CFG_ENABLE_LPWR_IMG_TRANSITION 99 -#define WCN36XX_HAL_CFG_ENABLE_MCC_ADAPTIVE_SCHEDULER 100 -#define WCN36XX_HAL_CFG_ENABLE_DETECT_PS_SUPPORT 101 -#define WCN36XX_HAL_CFG_AP_LINK_MONITOR_TIMEOUT 102 -#define WCN36XX_HAL_CFG_BTC_DWELL_TIME_MULTIPLIER 103 -#define WCN36XX_HAL_CFG_ENABLE_TDLS_OXYGEN_MODE 104 -#define WCN36XX_HAL_CFG_MAX_PARAMS 105 - -/* Message definitons - All the messages below need to be packed */ - -/* Definition for HAL API Version. */ -struct wcnss_wlan_version { - u8 revision; - u8 version; - u8 minor; - u8 major; -} __packed; - -/* Definition for Encryption Keys */ -struct wcn36xx_hal_keys { - u8 id; - - /* 0 for multicast */ - u8 unicast; - - enum ani_key_direction direction; - - /* Usage is unknown */ - u8 rsc[WLAN_MAX_KEY_RSC_LEN]; - - /* =1 for authenticator,=0 for supplicant */ - u8 pae_role; - - u16 length; - u8 key[WCN36XX_HAL_MAC_MAX_KEY_LENGTH]; -} __packed; - -/* - * set_sta_key_params Moving here since it is shared by - * configbss/setstakey msgs - */ -struct wcn36xx_hal_set_sta_key_params { - /* STA Index */ - u16 sta_index; - - /* Encryption Type used with peer */ - enum ani_ed_type enc_type; - - /* STATIC/DYNAMIC - valid only for WEP */ - enum ani_wep_type wep_type; - - /* Default WEP key, valid only for static WEP, must between 0 and 3. */ - u8 def_wep_idx; - - /* valid only for non-static WEP encyrptions */ - struct wcn36xx_hal_keys key[WCN36XX_HAL_MAC_MAX_NUM_OF_DEFAULT_KEYS]; - - /* - * Control for Replay Count, 1= Single TID based replay count on Tx - * 0 = Per TID based replay count on TX - */ - u8 single_tid_rc; - -} __packed; - -/* 4-byte control message header used by HAL*/ -struct wcn36xx_hal_msg_header { - enum wcn36xx_hal_host_msg_type msg_type:16; - enum wcn36xx_hal_host_msg_version msg_version:16; - u32 len; -} __packed; - -/* Config format required by HAL for each CFG item*/ -struct wcn36xx_hal_cfg { - /* Cfg Id. The Id required by HAL is exported by HAL - * in shared header file between UMAC and HAL.*/ - u16 id; - - /* Length of the Cfg. This parameter is used to go to next cfg - * in the TLV format.*/ - u16 len; - - /* Padding bytes for unaligned address's */ - u16 pad_bytes; - - /* Reserve bytes for making cfgVal to align address */ - u16 reserve; - - /* Following the uCfgLen field there should be a 'uCfgLen' bytes - * containing the uCfgValue ; u8 uCfgValue[uCfgLen] */ -} __packed; - -struct wcn36xx_hal_mac_start_parameters { - /* Drive Type - Production or FTM etc */ - enum driver_type type; - - /* Length of the config buffer */ - u32 len; - - /* Following this there is a TLV formatted buffer of length - * "len" bytes containing all config values. - * The TLV is expected to be formatted like this: - * 0 15 31 31+CFG_LEN-1 length-1 - * | CFG_ID | CFG_LEN | CFG_BODY | CFG_ID |......| - */ -} __packed; - -struct wcn36xx_hal_mac_start_req_msg { - /* config buffer must start in TLV format just here */ - struct wcn36xx_hal_msg_header header; - struct wcn36xx_hal_mac_start_parameters params; -} __packed; - -struct wcn36xx_hal_mac_start_rsp_params { - /* success or failure */ - u16 status; - - /* Max number of STA supported by the device */ - u8 stations; - - /* Max number of BSS supported by the device */ - u8 bssids; - - /* API Version */ - struct wcnss_wlan_version version; - - /* CRM build information */ - u8 crm_version[WCN36XX_HAL_VERSION_LENGTH]; - - /* hardware/chipset/misc version information */ - u8 wlan_version[WCN36XX_HAL_VERSION_LENGTH]; - -} __packed; - -struct wcn36xx_hal_mac_start_rsp_msg { - struct wcn36xx_hal_msg_header header; - struct wcn36xx_hal_mac_start_rsp_params start_rsp_params; -} __packed; - -struct wcn36xx_hal_mac_stop_req_params { - /* The reason for which the device is being stopped */ - enum wcn36xx_hal_stop_type reason; - -} __packed; - -struct wcn36xx_hal_mac_stop_req_msg { - struct wcn36xx_hal_msg_header header; - struct wcn36xx_hal_mac_stop_req_params stop_req_params; -} __packed; - -struct wcn36xx_hal_mac_stop_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -} __packed; - -struct wcn36xx_hal_update_cfg_req_msg { - /* - * Note: The length specified in tHalUpdateCfgReqMsg messages should be - * header.msgLen = sizeof(tHalUpdateCfgReqMsg) + uConfigBufferLen - */ - struct wcn36xx_hal_msg_header header; - - /* Length of the config buffer. Allows UMAC to update multiple CFGs */ - u32 len; - - /* - * Following this there is a TLV formatted buffer of length - * "uConfigBufferLen" bytes containing all config values. - * The TLV is expected to be formatted like this: - * 0 15 31 31+CFG_LEN-1 length-1 - * | CFG_ID | CFG_LEN | CFG_BODY | CFG_ID |......| - */ - -} __packed; - -struct wcn36xx_hal_update_cfg_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - -} __packed; - -/* Frame control field format (2 bytes) */ -struct wcn36xx_hal_mac_frame_ctl { - -#ifndef ANI_LITTLE_BIT_ENDIAN - - u8 subType:4; - u8 type:2; - u8 protVer:2; - - u8 order:1; - u8 wep:1; - u8 moreData:1; - u8 powerMgmt:1; - u8 retry:1; - u8 moreFrag:1; - u8 fromDS:1; - u8 toDS:1; - -#else - - u8 protVer:2; - u8 type:2; - u8 subType:4; - - u8 toDS:1; - u8 fromDS:1; - u8 moreFrag:1; - u8 retry:1; - u8 powerMgmt:1; - u8 moreData:1; - u8 wep:1; - u8 order:1; - -#endif - -}; - -/* Sequence control field */ -struct wcn36xx_hal_mac_seq_ctl { - u8 fragNum:4; - u8 seqNumLo:4; - u8 seqNumHi:8; -}; - -/* Management header format */ -struct wcn36xx_hal_mac_mgmt_hdr { - struct wcn36xx_hal_mac_frame_ctl fc; - u8 durationLo; - u8 durationHi; - u8 da[6]; - u8 sa[6]; - u8 bssId[6]; - struct wcn36xx_hal_mac_seq_ctl seqControl; -}; - -/* FIXME: pronto v1 apparently has 4 */ -#define WCN36XX_HAL_NUM_BSSID 2 - -/* Scan Entry to hold active BSS idx's */ -struct wcn36xx_hal_scan_entry { - u8 bss_index[WCN36XX_HAL_NUM_BSSID]; - u8 active_bss_count; -}; - -struct wcn36xx_hal_init_scan_req_msg { - struct wcn36xx_hal_msg_header header; - - /* LEARN - AP Role - SCAN - STA Role */ - enum wcn36xx_hal_sys_mode mode; - - /* BSSID of the BSS */ - u8 bssid[ETH_ALEN]; - - /* Whether BSS needs to be notified */ - u8 notify; - - /* Kind of frame to be used for notifying the BSS (Data Null, QoS - * Null, or CTS to Self). Must always be a valid frame type. */ - u8 frame_type; - - /* UMAC has the option of passing the MAC frame to be used for - * notifying the BSS. If non-zero, HAL will use the MAC frame - * buffer pointed to by macMgmtHdr. If zero, HAL will generate the - * appropriate MAC frame based on frameType. */ - u8 frame_len; - - /* Following the framelength there is a MAC frame buffer if - * frameLength is non-zero. */ - struct wcn36xx_hal_mac_mgmt_hdr mac_mgmt_hdr; - - /* Entry to hold number of active BSS idx's */ - struct wcn36xx_hal_scan_entry scan_entry; -}; - -struct wcn36xx_hal_init_scan_con_req_msg { - struct wcn36xx_hal_msg_header header; - - /* LEARN - AP Role - SCAN - STA Role */ - enum wcn36xx_hal_sys_mode mode; - - /* BSSID of the BSS */ - u8 bssid[ETH_ALEN]; - - /* Whether BSS needs to be notified */ - u8 notify; - - /* Kind of frame to be used for notifying the BSS (Data Null, QoS - * Null, or CTS to Self). Must always be a valid frame type. */ - u8 frame_type; - - /* UMAC has the option of passing the MAC frame to be used for - * notifying the BSS. If non-zero, HAL will use the MAC frame - * buffer pointed to by macMgmtHdr. If zero, HAL will generate the - * appropriate MAC frame based on frameType. */ - u8 frame_length; - - /* Following the framelength there is a MAC frame buffer if - * frameLength is non-zero. */ - struct wcn36xx_hal_mac_mgmt_hdr mac_mgmt_hdr; - - /* Entry to hold number of active BSS idx's */ - struct wcn36xx_hal_scan_entry scan_entry; - - /* Single NoA usage in Scanning */ - u8 use_noa; - - /* Indicates the scan duration (in ms) */ - u16 scan_duration; - -}; - -struct wcn36xx_hal_init_scan_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - -} __packed; - -struct wcn36xx_hal_start_scan_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Indicates the channel to scan */ - u8 scan_channel; -} __packed; - -struct wcn36xx_hal_start_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - - u32 start_tsf[2]; - u8 tx_mgmt_power; - -} __packed; - -struct wcn36xx_hal_end_scan_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Indicates the channel to stop scanning. Not used really. But - * retained for symmetry with "start Scan" message. It can also - * help in error check if needed. */ - u8 scan_channel; -} __packed; - -struct wcn36xx_hal_end_scan_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -} __packed; - -struct wcn36xx_hal_finish_scan_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Identifies the operational state of the AP/STA - * LEARN - AP Role SCAN - STA Role */ - enum wcn36xx_hal_sys_mode mode; - - /* Operating channel to tune to. */ - u8 oper_channel; - - /* Channel Bonding state If 20/40 MHz is operational, this will - * indicate the 40 MHz extension channel in combination with the - * control channel */ - enum phy_chan_bond_state cb_state; - - /* BSSID of the BSS */ - u8 bssid[ETH_ALEN]; - - /* Whether BSS needs to be notified */ - u8 notify; - - /* Kind of frame to be used for notifying the BSS (Data Null, QoS - * Null, or CTS to Self). Must always be a valid frame type. */ - u8 frame_type; - - /* UMAC has the option of passing the MAC frame to be used for - * notifying the BSS. If non-zero, HAL will use the MAC frame - * buffer pointed to by macMgmtHdr. If zero, HAL will generate the - * appropriate MAC frame based on frameType. */ - u8 frame_length; - - /* Following the framelength there is a MAC frame buffer if - * frameLength is non-zero. */ - struct wcn36xx_hal_mac_mgmt_hdr mac_mgmt_hdr; - - /* Entry to hold number of active BSS idx's */ - struct wcn36xx_hal_scan_entry scan_entry; - -} __packed; - -struct wcn36xx_hal_finish_scan_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - -} __packed; - -enum wcn36xx_hal_rate_index { - HW_RATE_INDEX_1MBPS = 0x82, - HW_RATE_INDEX_2MBPS = 0x84, - HW_RATE_INDEX_5_5MBPS = 0x8B, - HW_RATE_INDEX_6MBPS = 0x0C, - HW_RATE_INDEX_9MBPS = 0x12, - HW_RATE_INDEX_11MBPS = 0x96, - HW_RATE_INDEX_12MBPS = 0x18, - HW_RATE_INDEX_18MBPS = 0x24, - HW_RATE_INDEX_24MBPS = 0x30, - HW_RATE_INDEX_36MBPS = 0x48, - HW_RATE_INDEX_48MBPS = 0x60, - HW_RATE_INDEX_54MBPS = 0x6C -}; - -struct wcn36xx_hal_supported_rates { - /* - * For Self STA Entry: this represents Self Mode. - * For Peer Stations, this represents the mode of the peer. - * On Station: - * - * --this mode is updated when PE adds the Self Entry. - * - * -- OR when PE sends 'ADD_BSS' message and station context in BSS - * is used to indicate the mode of the AP. - * - * ON AP: - * - * -- this mode is updated when PE sends 'ADD_BSS' and Sta entry - * for that BSS is used to indicate the self mode of the AP. - * - * -- OR when a station is associated, PE sends 'ADD_STA' message - * with this mode updated. - */ - - enum sta_rate_mode op_rate_mode; - - /* 11b, 11a and aniLegacyRates are IE rates which gives rate in - * unit of 500Kbps */ - u16 dsss_rates[WCN36XX_HAL_NUM_DSSS_RATES]; - u16 ofdm_rates[WCN36XX_HAL_NUM_OFDM_RATES]; - u16 legacy_rates[WCN36XX_HAL_NUM_POLARIS_RATES]; - u16 reserved; - - /* Taurus only supports 26 Titan Rates(no ESF/concat Rates will be - * supported) First 26 bits are reserved for those Titan rates and - * the last 4 bits(bit28-31) for Taurus, 2(bit26-27) bits are - * reserved. */ - /* Titan and Taurus Rates */ - u32 enhanced_rate_bitmap; - - /* - * 0-76 bits used, remaining reserved - * bits 0-15 and 32 should be set. - */ - u8 supported_mcs_set[WCN36XX_HAL_MAC_MAX_SUPPORTED_MCS_SET]; - - /* - * RX Highest Supported Data Rate defines the highest data - * rate that the STA is able to receive, in unites of 1Mbps. - * This value is derived from "Supported MCS Set field" inside - * the HT capability element. - */ - u16 rx_highest_data_rate; - -} __packed; - -struct wcn36xx_hal_config_sta_params { - /* BSSID of STA */ - u8 bssid[ETH_ALEN]; - - /* ASSOC ID, as assigned by UMAC */ - u16 aid; - - /* STA entry Type: 0 - Self, 1 - Other/Peer, 2 - BSSID, 3 - BCAST */ - u8 type; - - /* Short Preamble Supported. */ - u8 short_preamble_supported; - - /* MAC Address of STA */ - u8 mac[ETH_ALEN]; - - /* Listen interval of the STA */ - u16 listen_interval; - - /* Support for 11e/WMM */ - u8 wmm_enabled; - - /* 11n HT capable STA */ - u8 ht_capable; - - /* TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz */ - u8 tx_channel_width_set; - - /* RIFS mode 0 - NA, 1 - Allowed */ - u8 rifs_mode; - - /* L-SIG TXOP Protection mechanism - 0 - No Support, 1 - Supported - SG - there is global field */ - u8 lsig_txop_protection; - - /* Max Ampdu Size supported by STA. TPE programming. - 0 : 8k , 1 : 16k, 2 : 32k, 3 : 64k */ - u8 max_ampdu_size; - - /* Max Ampdu density. Used by RA. 3 : 0~7 : 2^(11nAMPDUdensity -4) */ - u8 max_ampdu_density; - - /* Max AMSDU size 1 : 3839 bytes, 0 : 7935 bytes */ - u8 max_amsdu_size; - - /* Short GI support for 40Mhz packets */ - u8 sgi_40mhz; - - /* Short GI support for 20Mhz packets */ - u8 sgi_20Mhz; - - /* TODO move this parameter to the end for 3680 */ - /* These rates are the intersection of peer and self capabilities. */ - struct wcn36xx_hal_supported_rates supported_rates; - - /* Robust Management Frame (RMF) enabled/disabled */ - u8 rmf; - - /* The unicast encryption type in the association */ - u32 encrypt_type; - - /* HAL should update the existing STA entry, if this flag is set. UMAC - will set this flag in case of RE-ASSOC, where we want to reuse the - old STA ID. 0 = Add, 1 = Update */ - u8 action; - - /* U-APSD Flags: 1b per AC. Encoded as follows: - b7 b6 b5 b4 b3 b2 b1 b0 = - X X X X BE BK VI VO */ - u8 uapsd; - - /* Max SP Length */ - u8 max_sp_len; - - /* 11n Green Field preamble support - 0 - Not supported, 1 - Supported */ - u8 green_field_capable; - - /* MIMO Power Save mode */ - enum wcn36xx_hal_ht_mimo_state mimo_ps; - - /* Delayed BA Support */ - u8 delayed_ba_support; - - /* Max AMPDU duration in 32us */ - u8 max_ampdu_duration; - - /* HT STA should set it to 1 if it is enabled in BSS. HT STA should - * set it to 0 if AP does not support it. This indication is sent - * to HAL and HAL uses this flag to pickup up appropriate 40Mhz - * rates. */ - u8 dsss_cck_mode_40mhz; - - /* Valid STA Idx when action=Update. Set to 0xFF when invalid! - * Retained for backward compalibity with existing HAL code */ - u8 sta_index; - - /* BSSID of BSS to which station is associated. Set to 0xFF when - * invalid. Retained for backward compalibity with existing HAL - * code */ - u8 bssid_index; - - u8 p2p; - - /* TODO add this parameter for 3680. */ - /* Reserved to align next field on a dword boundary */ - /* u8 reserved; */ -} __packed; - -struct wcn36xx_hal_config_sta_req_msg { - struct wcn36xx_hal_msg_header header; - struct wcn36xx_hal_config_sta_params sta_params; -} __packed; - -struct wcn36xx_hal_config_sta_params_v1 { - /* BSSID of STA */ - u8 bssid[ETH_ALEN]; - - /* ASSOC ID, as assigned by UMAC */ - u16 aid; - - /* STA entry Type: 0 - Self, 1 - Other/Peer, 2 - BSSID, 3 - BCAST */ - u8 type; - - /* Short Preamble Supported. */ - u8 short_preamble_supported; - - /* MAC Address of STA */ - u8 mac[ETH_ALEN]; - - /* Listen interval of the STA */ - u16 listen_interval; - - /* Support for 11e/WMM */ - u8 wmm_enabled; - - /* 11n HT capable STA */ - u8 ht_capable; - - /* TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz */ - u8 tx_channel_width_set; - - /* RIFS mode 0 - NA, 1 - Allowed */ - u8 rifs_mode; - - /* L-SIG TXOP Protection mechanism - 0 - No Support, 1 - Supported - SG - there is global field */ - u8 lsig_txop_protection; - - /* Max Ampdu Size supported by STA. TPE programming. - 0 : 8k , 1 : 16k, 2 : 32k, 3 : 64k */ - u8 max_ampdu_size; - - /* Max Ampdu density. Used by RA. 3 : 0~7 : 2^(11nAMPDUdensity -4) */ - u8 max_ampdu_density; - - /* Max AMSDU size 1 : 3839 bytes, 0 : 7935 bytes */ - u8 max_amsdu_size; - - /* Short GI support for 40Mhz packets */ - u8 sgi_40mhz; - - /* Short GI support for 20Mhz packets */ - u8 sgi_20Mhz; - - /* Robust Management Frame (RMF) enabled/disabled */ - u8 rmf; - - /* The unicast encryption type in the association */ - u32 encrypt_type; - - /* HAL should update the existing STA entry, if this flag is set. UMAC - will set this flag in case of RE-ASSOC, where we want to reuse the - old STA ID. 0 = Add, 1 = Update */ - u8 action; - - /* U-APSD Flags: 1b per AC. Encoded as follows: - b7 b6 b5 b4 b3 b2 b1 b0 = - X X X X BE BK VI VO */ - u8 uapsd; - - /* Max SP Length */ - u8 max_sp_len; - - /* 11n Green Field preamble support - 0 - Not supported, 1 - Supported */ - u8 green_field_capable; - - /* MIMO Power Save mode */ - enum wcn36xx_hal_ht_mimo_state mimo_ps; - - /* Delayed BA Support */ - u8 delayed_ba_support; - - /* Max AMPDU duration in 32us */ - u8 max_ampdu_duration; - - /* HT STA should set it to 1 if it is enabled in BSS. HT STA should - * set it to 0 if AP does not support it. This indication is sent - * to HAL and HAL uses this flag to pickup up appropriate 40Mhz - * rates. */ - u8 dsss_cck_mode_40mhz; - - /* Valid STA Idx when action=Update. Set to 0xFF when invalid! - * Retained for backward compalibity with existing HAL code */ - u8 sta_index; - - /* BSSID of BSS to which station is associated. Set to 0xFF when - * invalid. Retained for backward compalibity with existing HAL - * code */ - u8 bssid_index; - - u8 p2p; - - /* Reserved to align next field on a dword boundary */ - u8 reserved; - - /* These rates are the intersection of peer and self capabilities. */ - struct wcn36xx_hal_supported_rates supported_rates; -} __packed; - -struct wcn36xx_hal_config_sta_req_msg_v1 { - struct wcn36xx_hal_msg_header header; - struct wcn36xx_hal_config_sta_params_v1 sta_params; -} __packed; - -struct config_sta_rsp_params { - /* success or failure */ - u32 status; - - /* Station index; valid only when 'status' field value SUCCESS */ - u8 sta_index; - - /* BSSID Index of BSS to which the station is associated */ - u8 bssid_index; - - /* DPU Index for PTK */ - u8 dpu_index; - - /* DPU Index for GTK */ - u8 bcast_dpu_index; - - /* DPU Index for IGTK */ - u8 bcast_mgmt_dpu_idx; - - /* PTK DPU signature */ - u8 uc_ucast_sig; - - /* GTK DPU isignature */ - u8 uc_bcast_sig; - - /* IGTK DPU signature */ - u8 uc_mgmt_sig; - - u8 p2p; - -} __packed; - -struct wcn36xx_hal_config_sta_rsp_msg { - struct wcn36xx_hal_msg_header header; - - struct config_sta_rsp_params params; -} __packed; - -/* Delete STA Request message */ -struct wcn36xx_hal_delete_sta_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Index of STA to delete */ - u8 sta_index; - -} __packed; - -/* Delete STA Response message */ -struct wcn36xx_hal_delete_sta_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - - /* Index of STA deleted */ - u8 sta_id; -} __packed; - -/* 12 Bytes long because this structure can be used to represent rate and - * extended rate set IEs. The parser assume this to be at least 12 */ -struct wcn36xx_hal_rate_set { - u8 num_rates; - u8 rate[WCN36XX_HAL_MAC_RATESET_EID_MAX]; -} __packed; - -/* access category record */ -struct wcn36xx_hal_aci_aifsn { -#ifndef ANI_LITTLE_BIT_ENDIAN - u8 rsvd:1; - u8 aci:2; - u8 acm:1; - u8 aifsn:4; -#else - u8 aifsn:4; - u8 acm:1; - u8 aci:2; - u8 rsvd:1; -#endif -} __packed; - -/* contention window size */ -struct wcn36xx_hal_mac_cw { -#ifndef ANI_LITTLE_BIT_ENDIAN - u8 max:4; - u8 min:4; -#else - u8 min:4; - u8 max:4; -#endif -} __packed; - -struct wcn36xx_hal_edca_param_record { - struct wcn36xx_hal_aci_aifsn aci; - struct wcn36xx_hal_mac_cw cw; - u16 txop_limit; -} __packed; - -struct wcn36xx_hal_mac_ssid { - u8 length; - u8 ssid[32]; -} __packed; - -/* Concurrency role. These are generic IDs that identify the various roles - * in the software system. */ -enum wcn36xx_hal_con_mode { - WCN36XX_HAL_STA_MODE = 0, - - /* to support softAp mode . This is misleading. - It means AP MODE only. */ - WCN36XX_HAL_STA_SAP_MODE = 1, - - WCN36XX_HAL_P2P_CLIENT_MODE, - WCN36XX_HAL_P2P_GO_MODE, - WCN36XX_HAL_MONITOR_MODE, -}; - -/* This is a bit pattern to be set for each mode - * bit 0 - sta mode - * bit 1 - ap mode - * bit 2 - p2p client mode - * bit 3 - p2p go mode */ -enum wcn36xx_hal_concurrency_mode { - HAL_STA = 1, - HAL_SAP = 2, - - /* to support sta, softAp mode . This means STA+AP mode */ - HAL_STA_SAP = 3, - - HAL_P2P_CLIENT = 4, - HAL_P2P_GO = 8, - HAL_MAX_CONCURRENCY_PERSONA = 4 -}; - -struct wcn36xx_hal_config_bss_params { - /* BSSID */ - u8 bssid[ETH_ALEN]; - - /* Self Mac Address */ - u8 self_mac_addr[ETH_ALEN]; - - /* BSS type */ - enum wcn36xx_hal_bss_type bss_type; - - /* Operational Mode: AP =0, STA = 1 */ - u8 oper_mode; - - /* Network Type */ - enum wcn36xx_hal_nw_type nw_type; - - /* Used to classify PURE_11G/11G_MIXED to program MTU */ - u8 short_slot_time_supported; - - /* Co-exist with 11a STA */ - u8 lla_coexist; - - /* Co-exist with 11b STA */ - u8 llb_coexist; - - /* Co-exist with 11g STA */ - u8 llg_coexist; - - /* Coexistence with 11n STA */ - u8 ht20_coexist; - - /* Non GF coexist flag */ - u8 lln_non_gf_coexist; - - /* TXOP protection support */ - u8 lsig_tx_op_protection_full_support; - - /* RIFS mode */ - u8 rifs_mode; - - /* Beacon Interval in TU */ - u16 beacon_interval; - - /* DTIM period */ - u8 dtim_period; - - /* TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz */ - u8 tx_channel_width_set; - - /* Operating channel */ - u8 oper_channel; - - /* Extension channel for channel bonding */ - u8 ext_channel; - - /* Reserved to align next field on a dword boundary */ - u8 reserved; - - /* TODO move sta to the end for 3680 */ - /* Context of the station being added in HW - * Add a STA entry for "itself" - - * - * On AP - Add the AP itself in an "STA context" - * - * On STA - Add the AP to which this STA is joining in an - * "STA context" - */ - struct wcn36xx_hal_config_sta_params sta; - /* SSID of the BSS */ - struct wcn36xx_hal_mac_ssid ssid; - - /* HAL should update the existing BSS entry, if this flag is set. - * UMAC will set this flag in case of reassoc, where we want to - * resue the the old BSSID and still return success 0 = Add, 1 = - * Update */ - u8 action; - - /* MAC Rate Set */ - struct wcn36xx_hal_rate_set rateset; - - /* Enable/Disable HT capabilities of the BSS */ - u8 ht; - - /* Enable/Disable OBSS protection */ - u8 obss_prot_enabled; - - /* RMF enabled/disabled */ - u8 rmf; - - /* HT Operating Mode operating mode of the 802.11n STA */ - enum wcn36xx_hal_ht_operating_mode ht_oper_mode; - - /* Dual CTS Protection: 0 - Unused, 1 - Used */ - u8 dual_cts_protection; - - /* Probe Response Max retries */ - u8 max_probe_resp_retry_limit; - - /* To Enable Hidden ssid */ - u8 hidden_ssid; - - /* To Enable Disable FW Proxy Probe Resp */ - u8 proxy_probe_resp; - - /* Boolean to indicate if EDCA params are valid. UMAC might not - * have valid EDCA params or might not desire to apply EDCA params - * during config BSS. 0 implies Not Valid ; Non-Zero implies - * valid */ - u8 edca_params_valid; - - /* EDCA Parameters for Best Effort Access Category */ - struct wcn36xx_hal_edca_param_record acbe; - - /* EDCA Parameters forBackground Access Category */ - struct wcn36xx_hal_edca_param_record acbk; - - /* EDCA Parameters for Video Access Category */ - struct wcn36xx_hal_edca_param_record acvi; - - /* EDCA Parameters for Voice Access Category */ - struct wcn36xx_hal_edca_param_record acvo; - - /* Ext Bss Config Msg if set */ - u8 ext_set_sta_key_param_valid; - - /* SetStaKeyParams for ext bss msg */ - struct wcn36xx_hal_set_sta_key_params ext_set_sta_key_param; - - /* Persona for the BSS can be STA,AP,GO,CLIENT value same as enum - * wcn36xx_hal_con_mode */ - u8 wcn36xx_hal_persona; - - u8 spectrum_mgt_enable; - - /* HAL fills in the tx power used for mgmt frames in txMgmtPower */ - s8 tx_mgmt_power; - - /* maxTxPower has max power to be used after applying the power - * constraint if any */ - s8 max_tx_power; -} __packed; - -struct wcn36xx_hal_config_bss_req_msg { - struct wcn36xx_hal_msg_header header; - struct wcn36xx_hal_config_bss_params bss_params; -} __packed; - -struct wcn36xx_hal_config_bss_params_v1 { - /* BSSID */ - u8 bssid[ETH_ALEN]; - - /* Self Mac Address */ - u8 self_mac_addr[ETH_ALEN]; - - /* BSS type */ - enum wcn36xx_hal_bss_type bss_type; - - /* Operational Mode: AP =0, STA = 1 */ - u8 oper_mode; - - /* Network Type */ - enum wcn36xx_hal_nw_type nw_type; - - /* Used to classify PURE_11G/11G_MIXED to program MTU */ - u8 short_slot_time_supported; - - /* Co-exist with 11a STA */ - u8 lla_coexist; - - /* Co-exist with 11b STA */ - u8 llb_coexist; - - /* Co-exist with 11g STA */ - u8 llg_coexist; - - /* Coexistence with 11n STA */ - u8 ht20_coexist; - - /* Non GF coexist flag */ - u8 lln_non_gf_coexist; - - /* TXOP protection support */ - u8 lsig_tx_op_protection_full_support; - - /* RIFS mode */ - u8 rifs_mode; - - /* Beacon Interval in TU */ - u16 beacon_interval; - - /* DTIM period */ - u8 dtim_period; - - /* TX Width Set: 0 - 20 MHz only, 1 - 20/40 MHz */ - u8 tx_channel_width_set; - - /* Operating channel */ - u8 oper_channel; - - /* Extension channel for channel bonding */ - u8 ext_channel; - - /* Reserved to align next field on a dword boundary */ - u8 reserved; - - /* SSID of the BSS */ - struct wcn36xx_hal_mac_ssid ssid; - - /* HAL should update the existing BSS entry, if this flag is set. - * UMAC will set this flag in case of reassoc, where we want to - * resue the the old BSSID and still return success 0 = Add, 1 = - * Update */ - u8 action; - - /* MAC Rate Set */ - struct wcn36xx_hal_rate_set rateset; - - /* Enable/Disable HT capabilities of the BSS */ - u8 ht; - - /* Enable/Disable OBSS protection */ - u8 obss_prot_enabled; - - /* RMF enabled/disabled */ - u8 rmf; - - /* HT Operating Mode operating mode of the 802.11n STA */ - enum wcn36xx_hal_ht_operating_mode ht_oper_mode; - - /* Dual CTS Protection: 0 - Unused, 1 - Used */ - u8 dual_cts_protection; - - /* Probe Response Max retries */ - u8 max_probe_resp_retry_limit; - - /* To Enable Hidden ssid */ - u8 hidden_ssid; - - /* To Enable Disable FW Proxy Probe Resp */ - u8 proxy_probe_resp; - - /* Boolean to indicate if EDCA params are valid. UMAC might not - * have valid EDCA params or might not desire to apply EDCA params - * during config BSS. 0 implies Not Valid ; Non-Zero implies - * valid */ - u8 edca_params_valid; - - /* EDCA Parameters for Best Effort Access Category */ - struct wcn36xx_hal_edca_param_record acbe; - - /* EDCA Parameters forBackground Access Category */ - struct wcn36xx_hal_edca_param_record acbk; - - /* EDCA Parameters for Video Access Category */ - struct wcn36xx_hal_edca_param_record acvi; - - /* EDCA Parameters for Voice Access Category */ - struct wcn36xx_hal_edca_param_record acvo; - - /* Ext Bss Config Msg if set */ - u8 ext_set_sta_key_param_valid; - - /* SetStaKeyParams for ext bss msg */ - struct wcn36xx_hal_set_sta_key_params ext_set_sta_key_param; - - /* Persona for the BSS can be STA,AP,GO,CLIENT value same as enum - * wcn36xx_hal_con_mode */ - u8 wcn36xx_hal_persona; - - u8 spectrum_mgt_enable; - - /* HAL fills in the tx power used for mgmt frames in txMgmtPower */ - s8 tx_mgmt_power; - - /* maxTxPower has max power to be used after applying the power - * constraint if any */ - s8 max_tx_power; - - /* Context of the station being added in HW - * Add a STA entry for "itself" - - * - * On AP - Add the AP itself in an "STA context" - * - * On STA - Add the AP to which this STA is joining in an - * "STA context" - */ - struct wcn36xx_hal_config_sta_params_v1 sta; -} __packed; - -struct wcn36xx_hal_config_bss_req_msg_v1 { - struct wcn36xx_hal_msg_header header; - struct wcn36xx_hal_config_bss_params_v1 bss_params; -} __packed; - -struct wcn36xx_hal_config_bss_rsp_params { - /* Success or Failure */ - u32 status; - - /* BSS index allocated by HAL */ - u8 bss_index; - - /* DPU descriptor index for PTK */ - u8 dpu_desc_index; - - /* PTK DPU signature */ - u8 ucast_dpu_signature; - - /* DPU descriptor index for GTK */ - u8 bcast_dpu_desc_indx; - - /* GTK DPU signature */ - u8 bcast_dpu_signature; - - /* DPU descriptor for IGTK */ - u8 mgmt_dpu_desc_index; - - /* IGTK DPU signature */ - u8 mgmt_dpu_signature; - - /* Station Index for BSS entry */ - u8 bss_sta_index; - - /* Self station index for this BSS */ - u8 bss_self_sta_index; - - /* Bcast station for buffering bcast frames in AP role */ - u8 bss_bcast_sta_idx; - - /* MAC Address of STA(PEER/SELF) in staContext of configBSSReq */ - u8 mac[ETH_ALEN]; - - /* HAL fills in the tx power used for mgmt frames in this field. */ - s8 tx_mgmt_power; - -} __packed; - -struct wcn36xx_hal_config_bss_rsp_msg { - struct wcn36xx_hal_msg_header header; - struct wcn36xx_hal_config_bss_rsp_params bss_rsp_params; -} __packed; - -struct wcn36xx_hal_delete_bss_req_msg { - struct wcn36xx_hal_msg_header header; - - /* BSS index to be deleted */ - u8 bss_index; - -} __packed; - -struct wcn36xx_hal_delete_bss_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* Success or Failure */ - u32 status; - - /* BSS index that has been deleted */ - u8 bss_index; - -} __packed; - -struct wcn36xx_hal_join_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Indicates the BSSID to which STA is going to associate */ - u8 bssid[ETH_ALEN]; - - /* Indicates the channel to switch to. */ - u8 channel; - - /* Self STA MAC */ - u8 self_sta_mac_addr[ETH_ALEN]; - - /* Local power constraint */ - u8 local_power_constraint; - - /* Secondary channel offset */ - enum phy_chan_bond_state secondary_channel_offset; - - /* link State */ - enum wcn36xx_hal_link_state link_state; - - /* Max TX power */ - s8 max_tx_power; -} __packed; - -struct wcn36xx_hal_join_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - - /* HAL fills in the tx power used for mgmt frames in this field */ - u8 tx_mgmt_power; -} __packed; - -struct post_assoc_req_msg { - struct wcn36xx_hal_msg_header header; - - struct wcn36xx_hal_config_sta_params sta_params; - struct wcn36xx_hal_config_bss_params bss_params; -}; - -struct post_assoc_rsp_msg { - struct wcn36xx_hal_msg_header header; - struct config_sta_rsp_params sta_rsp_params; - struct wcn36xx_hal_config_bss_rsp_params bss_rsp_params; -}; - -/* This is used to create a set of WEP keys for a given BSS. */ -struct wcn36xx_hal_set_bss_key_req_msg { - struct wcn36xx_hal_msg_header header; - - /* BSS Index of the BSS */ - u8 bss_idx; - - /* Encryption Type used with peer */ - enum ani_ed_type enc_type; - - /* Number of keys */ - u8 num_keys; - - /* Array of keys. */ - struct wcn36xx_hal_keys keys[WCN36XX_HAL_MAC_MAX_NUM_OF_DEFAULT_KEYS]; - - /* Control for Replay Count, 1= Single TID based replay count on Tx - * 0 = Per TID based replay count on TX */ - u8 single_tid_rc; -} __packed; - -/* tagged version of set bss key */ -struct wcn36xx_hal_set_bss_key_req_msg_tagged { - struct wcn36xx_hal_set_bss_key_req_msg Msg; - u32 tag; -} __packed; - -struct wcn36xx_hal_set_bss_key_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -} __packed; - -/* - * This is used configure the key information on a given station. - * When the sec_type is WEP40 or WEP104, the def_wep_idx is used to locate - * a preconfigured key from a BSS the station assoicated with; otherwise - * a new key descriptor is created based on the key field. - */ -struct wcn36xx_hal_set_sta_key_req_msg { - struct wcn36xx_hal_msg_header header; - struct wcn36xx_hal_set_sta_key_params set_sta_key_params; -} __packed; - -struct wcn36xx_hal_set_sta_key_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -} __packed; - -struct wcn36xx_hal_remove_bss_key_req_msg { - struct wcn36xx_hal_msg_header header; - - /* BSS Index of the BSS */ - u8 bss_idx; - - /* Encryption Type used with peer */ - enum ani_ed_type enc_type; - - /* Key Id */ - u8 key_id; - - /* STATIC/DYNAMIC. Used in Nullifying in Key Descriptors for - * Static/Dynamic keys */ - enum ani_wep_type wep_type; -} __packed; - -struct wcn36xx_hal_remove_bss_key_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -} __packed; - -/* - * This is used by PE to Remove the key information on a given station. - */ -struct wcn36xx_hal_remove_sta_key_req_msg { - struct wcn36xx_hal_msg_header header; - - /* STA Index */ - u16 sta_idx; - - /* Encryption Type used with peer */ - enum ani_ed_type enc_type; - - /* Key Id */ - u8 key_id; - - /* Whether to invalidate the Broadcast key or Unicast key. In case - * of WEP, the same key is used for both broadcast and unicast. */ - u8 unicast; - -} __packed; - -struct wcn36xx_hal_remove_sta_key_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /*success or failure */ - u32 status; - -} __packed; - -#ifdef FEATURE_OEM_DATA_SUPPORT - -#ifndef OEM_DATA_REQ_SIZE -#define OEM_DATA_REQ_SIZE 134 -#endif - -#ifndef OEM_DATA_RSP_SIZE -#define OEM_DATA_RSP_SIZE 1968 -#endif - -struct start_oem_data_req_msg { - struct wcn36xx_hal_msg_header header; - - u32 status; - tSirMacAddr self_mac_addr; - u8 oem_data_req[OEM_DATA_REQ_SIZE]; - -}; - -struct start_oem_data_rsp_msg { - struct wcn36xx_hal_msg_header header; - - u8 oem_data_rsp[OEM_DATA_RSP_SIZE]; -}; - -#endif - -struct wcn36xx_hal_switch_channel_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Channel number */ - u8 channel_number; - - /* Local power constraint */ - u8 local_power_constraint; - - /* Secondary channel offset */ - enum phy_chan_bond_state secondary_channel_offset; - - /* HAL fills in the tx power used for mgmt frames in this field. */ - u8 tx_mgmt_power; - - /* Max TX power */ - u8 max_tx_power; - - /* Self STA MAC */ - u8 self_sta_mac_addr[ETH_ALEN]; - - /* VO WIFI comment: BSSID needed to identify session. As the - * request has power constraints, this should be applied only to - * that session Since MTU timing and EDCA are sessionized, this - * struct needs to be sessionized and bssid needs to be out of the - * VOWifi feature flag V IMP: Keep bssId field at the end of this - * msg. It is used to mantain backward compatbility by way of - * ignoring if using new host/old FW or old host/new FW since it is - * at the end of this struct - */ - u8 bssid[ETH_ALEN]; -} __packed; - -struct wcn36xx_hal_switch_channel_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* Status */ - u32 status; - - /* Channel number - same as in request */ - u8 channel_number; - - /* HAL fills in the tx power used for mgmt frames in this field */ - u8 tx_mgmt_power; - - /* BSSID needed to identify session - same as in request */ - u8 bssid[ETH_ALEN]; - -} __packed; - -struct update_edca_params_req_msg { - struct wcn36xx_hal_msg_header header; - - /*BSS Index */ - u16 bss_index; - - /* Best Effort */ - struct wcn36xx_hal_edca_param_record acbe; - - /* Background */ - struct wcn36xx_hal_edca_param_record acbk; - - /* Video */ - struct wcn36xx_hal_edca_param_record acvi; - - /* Voice */ - struct wcn36xx_hal_edca_param_record acvo; -}; - -struct update_edca_params_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct dpu_stats_params { - /* Index of STA to which the statistics */ - u16 sta_index; - - /* Encryption mode */ - u8 enc_mode; - - /* status */ - u32 status; - - /* Statistics */ - u32 send_blocks; - u32 recv_blocks; - u32 replays; - u8 mic_error_cnt; - u32 prot_excl_cnt; - u16 format_err_cnt; - u16 un_decryptable_cnt; - u32 decrypt_err_cnt; - u32 decrypt_ok_cnt; -}; - -struct wcn36xx_hal_stats_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Valid STA Idx for per STA stats request */ - u32 sta_id; - - /* Categories of stats requested as specified in eHalStatsMask */ - u32 stats_mask; -}; - -struct ani_summary_stats_info { - /* Total number of packets(per AC) that were successfully - * transmitted with retries */ - u32 retry_cnt[4]; - - /* The number of MSDU packets and MMPDU frames per AC that the - * 802.11 station successfully transmitted after more than one - * retransmission attempt */ - u32 multiple_retry_cnt[4]; - - /* Total number of packets(per AC) that were successfully - * transmitted (with and without retries, including multi-cast, - * broadcast) */ - u32 tx_frm_cnt[4]; - - /* Total number of packets that were successfully received (after - * appropriate filter rules including multi-cast, broadcast) */ - u32 rx_frm_cnt; - - /* Total number of duplicate frames received successfully */ - u32 frm_dup_cnt; - - /* Total number packets(per AC) failed to transmit */ - u32 fail_cnt[4]; - - /* Total number of RTS/CTS sequence failures for transmission of a - * packet */ - u32 rts_fail_cnt; - - /* Total number packets failed transmit because of no ACK from the - * remote entity */ - u32 ack_fail_cnt; - - /* Total number of RTS/CTS sequence success for transmission of a - * packet */ - u32 rts_succ_cnt; - - /* The sum of the receive error count and dropped-receive-buffer - * error count. HAL will provide this as a sum of (FCS error) + - * (Fail get BD/PDU in HW) */ - u32 rx_discard_cnt; - - /* - * The receive error count. HAL will provide the RxP FCS error - * global counter. */ - u32 rx_error_cnt; - - /* The sum of the transmit-directed byte count, transmit-multicast - * byte count and transmit-broadcast byte count. HAL will sum TPE - * UC/MC/BCAST global counters to provide this. */ - u32 tx_byte_cnt; -}; - -/* defines tx_rate_flags */ -enum tx_rate_info { - /* Legacy rates */ - HAL_TX_RATE_LEGACY = 0x1, - - /* HT20 rates */ - HAL_TX_RATE_HT20 = 0x2, - - /* HT40 rates */ - HAL_TX_RATE_HT40 = 0x4, - - /* Rate with Short guard interval */ - HAL_TX_RATE_SGI = 0x8, - - /* Rate with Long guard interval */ - HAL_TX_RATE_LGI = 0x10 -}; - -struct ani_global_class_a_stats_info { - /* The number of MPDU frames received by the 802.11 station for - * MSDU packets or MMPDU frames */ - u32 rx_frag_cnt; - - /* The number of MPDU frames received by the 802.11 station for - * MSDU packets or MMPDU frames when a promiscuous packet filter - * was enabled */ - u32 promiscuous_rx_frag_cnt; - - /* The receiver input sensitivity referenced to a FER of 8% at an - * MPDU length of 1024 bytes at the antenna connector. Each element - * of the array shall correspond to a supported rate and the order - * shall be the same as the supporteRates parameter. */ - u32 rx_input_sensitivity; - - /* The maximum transmit power in dBm upto one decimal. for eg: if - * it is 10.5dBm, the value would be 105 */ - u32 max_pwr; - - /* Number of times the receiver failed to synchronize with the - * incoming signal after detecting the sync in the preamble of the - * transmitted PLCP protocol data unit. */ - u32 sync_fail_cnt; - - /* Legacy transmit rate, in units of 500 kbit/sec, for the most - * recently transmitted frame */ - u32 tx_rate; - - /* mcs index for HT20 and HT40 rates */ - u32 mcs_index; - - /* to differentiate between HT20 and HT40 rates; short and long - * guard interval */ - u32 tx_rate_flags; -}; - -struct ani_global_security_stats { - /* The number of unencrypted received MPDU frames that the MAC - * layer discarded when the IEEE 802.11 dot11ExcludeUnencrypted - * management information base (MIB) object is enabled */ - u32 rx_wep_unencrypted_frm_cnt; - - /* The number of received MSDU packets that that the 802.11 station - * discarded because of MIC failures */ - u32 rx_mic_fail_cnt; - - /* The number of encrypted MPDU frames that the 802.11 station - * failed to decrypt because of a TKIP ICV error */ - u32 tkip_icv_err; - - /* The number of received MPDU frames that the 802.11 discarded - * because of an invalid AES-CCMP format */ - u32 aes_ccmp_format_err; - - /* The number of received MPDU frames that the 802.11 station - * discarded because of the AES-CCMP replay protection procedure */ - u32 aes_ccmp_replay_cnt; - - /* The number of received MPDU frames that the 802.11 station - * discarded because of errors detected by the AES-CCMP decryption - * algorithm */ - u32 aes_ccmp_decrpt_err; - - /* The number of encrypted MPDU frames received for which a WEP - * decryption key was not available on the 802.11 station */ - u32 wep_undecryptable_cnt; - - /* The number of encrypted MPDU frames that the 802.11 station - * failed to decrypt because of a WEP ICV error */ - u32 wep_icv_err; - - /* The number of received encrypted packets that the 802.11 station - * successfully decrypted */ - u32 rx_decrypt_succ_cnt; - - /* The number of encrypted packets that the 802.11 station failed - * to decrypt */ - u32 rx_decrypt_fail_cnt; -}; - -struct ani_global_class_b_stats_info { - struct ani_global_security_stats uc_stats; - struct ani_global_security_stats mc_bc_stats; -}; - -struct ani_global_class_c_stats_info { - /* This counter shall be incremented for a received A-MSDU frame - * with the stations MAC address in the address 1 field or an - * A-MSDU frame with a group address in the address 1 field */ - u32 rx_amsdu_cnt; - - /* This counter shall be incremented when the MAC receives an AMPDU - * from the PHY */ - u32 rx_ampdu_cnt; - - /* This counter shall be incremented when a Frame is transmitted - * only on the primary channel */ - u32 tx_20_frm_cnt; - - /* This counter shall be incremented when a Frame is received only - * on the primary channel */ - u32 rx_20_frm_cnt; - - /* This counter shall be incremented by the number of MPDUs - * received in the A-MPDU when an A-MPDU is received */ - u32 rx_mpdu_in_ampdu_cnt; - - /* This counter shall be incremented when an MPDU delimiter has a - * CRC error when this is the first CRC error in the received AMPDU - * or when the previous delimiter has been decoded correctly */ - u32 ampdu_delimiter_crc_err; -}; - -struct ani_per_sta_stats_info { - /* The number of MPDU frames that the 802.11 station transmitted - * and acknowledged through a received 802.11 ACK frame */ - u32 tx_frag_cnt[4]; - - /* This counter shall be incremented when an A-MPDU is transmitted */ - u32 tx_ampdu_cnt; - - /* This counter shall increment by the number of MPDUs in the AMPDU - * when an A-MPDU is transmitted */ - u32 tx_mpdu_in_ampdu_cnt; -}; - -struct wcn36xx_hal_stats_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* Success or Failure */ - u32 status; - - /* STA Idx */ - u32 sta_index; - - /* Categories of STATS being returned as per eHalStatsMask */ - u32 stats_mask; - - /* message type is same as the request type */ - u16 msg_type; - - /* length of the entire request, includes the pStatsBuf length too */ - u16 msg_len; -}; - -struct wcn36xx_hal_set_link_state_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 bssid[ETH_ALEN]; - enum wcn36xx_hal_link_state state; - u8 self_mac_addr[ETH_ALEN]; - -} __packed; - -struct set_link_state_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -/* TSPEC Params */ -struct wcn36xx_hal_ts_info_tfc { -#ifndef ANI_LITTLE_BIT_ENDIAN - u16 ackPolicy:2; - u16 userPrio:3; - u16 psb:1; - u16 aggregation:1; - u16 accessPolicy:2; - u16 direction:2; - u16 tsid:4; - u16 trafficType:1; -#else - u16 trafficType:1; - u16 tsid:4; - u16 direction:2; - u16 accessPolicy:2; - u16 aggregation:1; - u16 psb:1; - u16 userPrio:3; - u16 ackPolicy:2; -#endif -}; - -/* Flag to schedule the traffic type */ -struct wcn36xx_hal_ts_info_sch { -#ifndef ANI_LITTLE_BIT_ENDIAN - u8 rsvd:7; - u8 schedule:1; -#else - u8 schedule:1; - u8 rsvd:7; -#endif -}; - -/* Traffic and scheduling info */ -struct wcn36xx_hal_ts_info { - struct wcn36xx_hal_ts_info_tfc traffic; - struct wcn36xx_hal_ts_info_sch schedule; -}; - -/* Information elements */ -struct wcn36xx_hal_tspec_ie { - u8 type; - u8 length; - struct wcn36xx_hal_ts_info ts_info; - u16 nom_msdu_size; - u16 max_msdu_size; - u32 min_svc_interval; - u32 max_svc_interval; - u32 inact_interval; - u32 suspend_interval; - u32 svc_start_time; - u32 min_data_rate; - u32 mean_data_rate; - u32 peak_data_rate; - u32 max_burst_sz; - u32 delay_bound; - u32 min_phy_rate; - u16 surplus_bw; - u16 medium_time; -}; - -struct add_ts_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Station Index */ - u16 sta_index; - - /* TSPEC handler uniquely identifying a TSPEC for a STA in a BSS */ - u16 tspec_index; - - /* To program TPE with required parameters */ - struct wcn36xx_hal_tspec_ie tspec; - - /* U-APSD Flags: 1b per AC. Encoded as follows: - b7 b6 b5 b4 b3 b2 b1 b0 = - X X X X BE BK VI VO */ - u8 uapsd; - - /* These parameters are for all the access categories */ - - /* Service Interval */ - u32 service_interval[WCN36XX_HAL_MAX_AC]; - - /* Suspend Interval */ - u32 suspend_interval[WCN36XX_HAL_MAX_AC]; - - /* Delay Interval */ - u32 delay_interval[WCN36XX_HAL_MAX_AC]; -}; - -struct add_rs_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct del_ts_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Station Index */ - u16 sta_index; - - /* TSPEC identifier uniquely identifying a TSPEC for a STA in a BSS */ - u16 tspec_index; - - /* To lookup station id using the mac address */ - u8 bssid[ETH_ALEN]; -}; - -struct del_ts_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -/* End of TSpec Parameters */ - -/* Start of BLOCK ACK related Parameters */ - -struct wcn36xx_hal_add_ba_session_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Station Index */ - u16 sta_index; - - /* Peer MAC Address */ - u8 mac_addr[ETH_ALEN]; - - /* ADDBA Action Frame dialog token - HAL will not interpret this object */ - u8 dialog_token; - - /* TID for which the BA is being setup - This identifies the TC or TS of interest */ - u8 tid; - - /* 0 - Delayed BA (Not supported) - 1 - Immediate BA */ - u8 policy; - - /* Indicates the number of buffers for this TID (baTID) - NOTE - This is the requested buffer size. When this - is processed by HAL and subsequently by HDD, it is - possible that HDD may change this buffer size. Any - change in the buffer size should be noted by PE and - advertized appropriately in the ADDBA response */ - u16 buffer_size; - - /* BA timeout in TU's 0 means no timeout will occur */ - u16 timeout; - - /* b0..b3 - Fragment Number - Always set to 0 - b4..b15 - Starting Sequence Number of first MSDU - for which this BA is setup */ - u16 ssn; - - /* ADDBA direction - 1 - Originator - 0 - Recipient */ - u8 direction; -} __packed; - -struct wcn36xx_hal_add_ba_session_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - - /* Dialog token */ - u8 dialog_token; - - /* TID for which the BA session has been setup */ - u8 ba_tid; - - /* BA Buffer Size allocated for the current BA session */ - u8 ba_buffer_size; - - u8 ba_session_id; - - /* Reordering Window buffer */ - u8 win_size; - - /* Station Index to id the sta */ - u8 sta_index; - - /* Starting Sequence Number */ - u16 ssn; -} __packed; - -struct wcn36xx_hal_add_ba_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Session Id */ - u8 session_id; - - /* Reorder Window Size */ - u8 win_size; -/* Old FW 1.2.2.4 does not support this*/ -#ifdef FEATURE_ON_CHIP_REORDERING - u8 reordering_done_on_chip; -#endif -} __packed; - -struct wcn36xx_hal_add_ba_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - - /* Dialog token */ - u8 dialog_token; -} __packed; - -struct add_ba_info { - u16 ba_enable:1; - u16 starting_seq_num:12; - u16 reserved:3; -}; - -struct wcn36xx_hal_trigger_ba_rsp_candidate { - u8 sta_addr[ETH_ALEN]; - struct add_ba_info ba_info[STACFG_MAX_TC]; -} __packed; - -struct wcn36xx_hal_trigget_ba_req_candidate { - u8 sta_index; - u8 tid_bitmap; -} __packed; - -struct wcn36xx_hal_trigger_ba_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Session Id */ - u8 session_id; - - /* baCandidateCnt is followed by trigger BA - * Candidate List(tTriggerBaCandidate) - */ - u16 candidate_cnt; - -} __packed; - -struct wcn36xx_hal_trigger_ba_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* TO SUPPORT BT-AMP */ - u8 bssid[ETH_ALEN]; - - /* success or failure */ - u32 status; - - /* baCandidateCnt is followed by trigger BA - * Rsp Candidate List(tTriggerRspBaCandidate) - */ - u16 candidate_cnt; -} __packed; - -struct wcn36xx_hal_del_ba_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Station Index */ - u16 sta_index; - - /* TID for which the BA session is being deleted */ - u8 tid; - - /* DELBA direction - 1 - Originator - 0 - Recipient */ - u8 direction; -} __packed; - -struct wcn36xx_hal_del_ba_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -} __packed; - -struct tsm_stats_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Traffic Id */ - u8 tid; - - u8 bssid[ETH_ALEN]; -}; - -struct tsm_stats_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /*success or failure */ - u32 status; - - /* Uplink Packet Queue delay */ - u16 uplink_pkt_queue_delay; - - /* Uplink Packet Queue delay histogram */ - u16 uplink_pkt_queue_delay_hist[4]; - - /* Uplink Packet Transmit delay */ - u32 uplink_pkt_tx_delay; - - /* Uplink Packet loss */ - u16 uplink_pkt_loss; - - /* Uplink Packet count */ - u16 uplink_pkt_count; - - /* Roaming count */ - u8 roaming_count; - - /* Roaming Delay */ - u16 roaming_delay; -}; - -struct set_key_done_msg { - struct wcn36xx_hal_msg_header header; - - /*bssid of the keys */ - u8 bssidx; - u8 enc_type; -}; - -struct wcn36xx_hal_nv_img_download_req_msg { - /* Note: The length specified in wcn36xx_hal_nv_img_download_req_msg - * messages should be - * header.len = sizeof(wcn36xx_hal_nv_img_download_req_msg) + - * nv_img_buffer_size */ - struct wcn36xx_hal_msg_header header; - - /* Fragment sequence number of the NV Image. Note that NV Image - * might not fit into one message due to size limitation of the SMD - * channel FIFO. UMAC can hence choose to chop the NV blob into - * multiple fragments starting with seqeunce number 0, 1, 2 etc. - * The last fragment MUST be indicated by marking the - * isLastFragment field to 1. Note that all the NV blobs would be - * concatenated together by HAL without any padding bytes in - * between.*/ - u16 frag_number; - - /* Is this the last fragment? When set to 1 it indicates that no - * more fragments will be sent by UMAC and HAL can concatenate all - * the NV blobs rcvd & proceed with the parsing. HAL would generate - * a WCN36XX_HAL_DOWNLOAD_NV_RSP to the WCN36XX_HAL_DOWNLOAD_NV_REQ - * after it receives each fragment */ - u16 last_fragment; - - /* NV Image size (number of bytes) */ - u32 nv_img_buffer_size; - - /* Following the 'nv_img_buffer_size', there should be - * nv_img_buffer_size bytes of NV Image i.e. - * u8[nv_img_buffer_size] */ -} __packed; - -struct wcn36xx_hal_nv_img_download_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* Success or Failure. HAL would generate a - * WCN36XX_HAL_DOWNLOAD_NV_RSP after each fragment */ - u32 status; -} __packed; - -struct wcn36xx_hal_nv_store_ind { - /* Note: The length specified in tHalNvStoreInd messages should be - * header.msgLen = sizeof(tHalNvStoreInd) + nvBlobSize */ - struct wcn36xx_hal_msg_header header; - - /* NV Item */ - u32 table_id; - - /* Size of NV Blob */ - u32 nv_blob_size; - - /* Following the 'nvBlobSize', there should be nvBlobSize bytes of - * NV blob i.e. u8[nvBlobSize] */ -}; - -/* End of Block Ack Related Parameters */ - -#define WCN36XX_HAL_CIPHER_SEQ_CTR_SIZE 6 - -/* Definition for MIC failure indication MAC reports this each time a MIC - * failure occures on Rx TKIP packet - */ -struct mic_failure_ind_msg { - struct wcn36xx_hal_msg_header header; - - u8 bssid[ETH_ALEN]; - - /* address used to compute MIC */ - u8 src_addr[ETH_ALEN]; - - /* transmitter address */ - u8 ta_addr[ETH_ALEN]; - - u8 dst_addr[ETH_ALEN]; - - u8 multicast; - - /* first byte of IV */ - u8 iv1; - - /* second byte of IV */ - u8 key_id; - - /* sequence number */ - u8 tsc[WCN36XX_HAL_CIPHER_SEQ_CTR_SIZE]; - - /* receive address */ - u8 rx_addr[ETH_ALEN]; -}; - -struct update_vht_op_mode_req_msg { - struct wcn36xx_hal_msg_header header; - - u16 op_mode; - u16 sta_id; -}; - -struct update_vht_op_mode_params_rsp_msg { - struct wcn36xx_hal_msg_header header; - - u32 status; -}; - -struct update_beacon_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 bss_index; - - /* shortPreamble mode. HAL should update all the STA rates when it - * receives this message */ - u8 short_preamble; - - /* short Slot time. */ - u8 short_slot_time; - - /* Beacon Interval */ - u16 beacon_interval; - - /* Protection related */ - u8 lla_coexist; - u8 llb_coexist; - u8 llg_coexist; - u8 ht20_coexist; - u8 lln_non_gf_coexist; - u8 lsig_tx_op_protection_full_support; - u8 rifs_mode; - - u16 param_change_bitmap; -}; - -struct update_beacon_rsp_msg { - struct wcn36xx_hal_msg_header header; - u32 status; -}; - -struct wcn36xx_hal_send_beacon_req_msg { - struct wcn36xx_hal_msg_header header; - - /* length of the template. */ - u32 beacon_length; - - /* Beacon data. */ - u8 beacon[BEACON_TEMPLATE_SIZE]; - - u8 bssid[ETH_ALEN]; - - /* TIM IE offset from the beginning of the template. */ - u32 tim_ie_offset; - - /* P2P IE offset from the begining of the template */ - u16 p2p_ie_offset; -} __packed; - -struct send_beacon_rsp_msg { - struct wcn36xx_hal_msg_header header; - u32 status; -} __packed; - -struct enable_radar_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 bssid[ETH_ALEN]; - u8 channel; -}; - -struct enable_radar_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* Link Parameters */ - u8 bssid[ETH_ALEN]; - - /* success or failure */ - u32 status; -}; - -struct radar_detect_intr_ind_msg { - struct wcn36xx_hal_msg_header header; - - u8 radar_det_channel; -}; - -struct radar_detect_ind_msg { - struct wcn36xx_hal_msg_header header; - - /* channel number in which the RADAR detected */ - u8 channel_number; - - /* RADAR pulse width in usecond */ - u16 radar_pulse_width; - - /* Number of RADAR pulses */ - u16 num_radar_pulse; -}; - -struct wcn36xx_hal_get_tpc_report_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 sta[ETH_ALEN]; - u8 dialog_token; - u8 txpower; -}; - -struct wcn36xx_hal_get_tpc_report_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct wcn36xx_hal_send_probe_resp_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 probe_resp_template[BEACON_TEMPLATE_SIZE]; - u32 probe_resp_template_len; - u32 proxy_probe_req_valid_ie_bmap[8]; - u8 bssid[ETH_ALEN]; -}; - -struct send_probe_resp_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct send_unknown_frame_rx_ind_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct wcn36xx_hal_delete_sta_context_ind_msg { - struct wcn36xx_hal_msg_header header; - - u16 aid; - u16 sta_id; - - /* TO SUPPORT BT-AMP */ - u8 bssid[ETH_ALEN]; - - /* HAL copies bssid from the sta table. */ - u8 addr2[ETH_ALEN]; - - /* To unify the keepalive / unknown A2 / tim-based disa */ - u16 reason_code; -} __packed; - -struct indicate_del_sta { - struct wcn36xx_hal_msg_header header; - u8 aid; - u8 sta_index; - u8 bss_index; - u8 reason_code; - u32 status; -}; - -struct bt_amp_event_msg { - struct wcn36xx_hal_msg_header header; - - enum bt_amp_event_type btAmpEventType; -}; - -struct bt_amp_event_rsp { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct tl_hal_flush_ac_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Station Index. originates from HAL */ - u8 sta_id; - - /* TID for which the transmit queue is being flushed */ - u8 tid; -}; - -struct tl_hal_flush_ac_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* Station Index. originates from HAL */ - u8 sta_id; - - /* TID for which the transmit queue is being flushed */ - u8 tid; - - /* success or failure */ - u32 status; -}; - -struct wcn36xx_hal_enter_imps_req_msg { - struct wcn36xx_hal_msg_header header; -}; - -struct wcn36xx_hal_exit_imps_req { - struct wcn36xx_hal_msg_header header; -}; - -struct wcn36xx_hal_enter_bmps_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 bss_index; - - /* TBTT value derived from the last beacon */ -#ifndef BUILD_QWPTTSTATIC - u64 tbtt; -#endif - u8 dtim_count; - - /* DTIM period given to HAL during association may not be valid, if - * association is based on ProbeRsp instead of beacon. */ - u8 dtim_period; - - /* For CCX and 11R Roaming */ - u32 rssi_filter_period; - - u32 num_beacon_per_rssi_average; - u8 rssi_filter_enable; -} __packed; - -struct wcn36xx_hal_exit_bmps_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 send_data_null; - u8 bss_index; -} __packed; - -struct wcn36xx_hal_missed_beacon_ind_msg { - struct wcn36xx_hal_msg_header header; - - u8 bss_index; -} __packed; - -/* Beacon Filtering data structures */ - -/* The above structure would be followed by multiple of below mentioned - * structure - */ -struct beacon_filter_ie { - u8 element_id; - u8 check_ie_presence; - u8 offset; - u8 value; - u8 bitmask; - u8 ref; -}; - -struct wcn36xx_hal_add_bcn_filter_req_msg { - struct wcn36xx_hal_msg_header header; - - u16 capability_info; - u16 capability_mask; - u16 beacon_interval; - u16 ie_num; - u8 bss_index; - u8 reserved; -}; - -struct wcn36xx_hal_rem_bcn_filter_req { - struct wcn36xx_hal_msg_header header; - - u8 ie_Count; - u8 rem_ie_id[1]; -}; - -#define WCN36XX_HAL_IPV4_ARP_REPLY_OFFLOAD 0 -#define WCN36XX_HAL_IPV6_NEIGHBOR_DISCOVERY_OFFLOAD 1 -#define WCN36XX_HAL_IPV6_NS_OFFLOAD 2 -#define WCN36XX_HAL_IPV6_ADDR_LEN 16 -#define WCN36XX_HAL_OFFLOAD_DISABLE 0 -#define WCN36XX_HAL_OFFLOAD_ENABLE 1 -#define WCN36XX_HAL_OFFLOAD_BCAST_FILTER_ENABLE 0x2 -#define WCN36XX_HAL_OFFLOAD_ARP_AND_BCAST_FILTER_ENABLE \ - (HAL_OFFLOAD_ENABLE|HAL_OFFLOAD_BCAST_FILTER_ENABLE) - -struct wcn36xx_hal_ns_offload_params { - u8 src_ipv6_addr[WCN36XX_HAL_IPV6_ADDR_LEN]; - u8 self_ipv6_addr[WCN36XX_HAL_IPV6_ADDR_LEN]; - - /* Only support 2 possible Network Advertisement IPv6 address */ - u8 target_ipv6_addr1[WCN36XX_HAL_IPV6_ADDR_LEN]; - u8 target_ipv6_addr2[WCN36XX_HAL_IPV6_ADDR_LEN]; - - u8 self_addr[ETH_ALEN]; - u8 src_ipv6_addr_valid:1; - u8 target_ipv6_addr1_valid:1; - u8 target_ipv6_addr2_valid:1; - u8 reserved1:5; - - /* make it DWORD aligned */ - u8 reserved2; - - /* slot index for this offload */ - u32 slot_index; - u8 bss_index; -}; - -struct wcn36xx_hal_host_offload_req { - u8 offload_Type; - - /* enable or disable */ - u8 enable; - - union { - u8 host_ipv4_addr[4]; - u8 host_ipv6_addr[WCN36XX_HAL_IPV6_ADDR_LEN]; - } u; -}; - -struct wcn36xx_hal_host_offload_req_msg { - struct wcn36xx_hal_msg_header header; - struct wcn36xx_hal_host_offload_req host_offload_params; - struct wcn36xx_hal_ns_offload_params ns_offload_params; -}; - -/* Packet Types. */ -#define WCN36XX_HAL_KEEP_ALIVE_NULL_PKT 1 -#define WCN36XX_HAL_KEEP_ALIVE_UNSOLICIT_ARP_RSP 2 - -/* Enable or disable keep alive */ -#define WCN36XX_HAL_KEEP_ALIVE_DISABLE 0 -#define WCN36XX_HAL_KEEP_ALIVE_ENABLE 1 -#define WCN36XX_KEEP_ALIVE_TIME_PERIOD 30 /* unit: s */ - -/* Keep Alive request. */ -struct wcn36xx_hal_keep_alive_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 packet_type; - u32 time_period; - u8 host_ipv4_addr[WCN36XX_HAL_IPV4_ADDR_LEN]; - u8 dest_ipv4_addr[WCN36XX_HAL_IPV4_ADDR_LEN]; - u8 dest_addr[ETH_ALEN]; - u8 bss_index; -} __packed; - -struct wcn36xx_hal_rssi_threshold_req_msg { - struct wcn36xx_hal_msg_header header; - - s8 threshold1:8; - s8 threshold2:8; - s8 threshold3:8; - u8 thres1_pos_notify:1; - u8 thres1_neg_notify:1; - u8 thres2_pos_notify:1; - u8 thres2_neg_notify:1; - u8 thres3_pos_notify:1; - u8 thres3_neg_notify:1; - u8 reserved10:2; -}; - -struct wcn36xx_hal_enter_uapsd_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 bk_delivery:1; - u8 be_delivery:1; - u8 vi_delivery:1; - u8 vo_delivery:1; - u8 bk_trigger:1; - u8 be_trigger:1; - u8 vi_trigger:1; - u8 vo_trigger:1; - u8 bss_index; -}; - -struct wcn36xx_hal_exit_uapsd_req_msg { - struct wcn36xx_hal_msg_header header; - u8 bss_index; -}; - -#define WCN36XX_HAL_WOWL_BCAST_PATTERN_MAX_SIZE 128 -#define WCN36XX_HAL_WOWL_BCAST_MAX_NUM_PATTERNS 16 - -struct wcn36xx_hal_wowl_add_bcast_ptrn_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Pattern ID */ - u8 id; - - /* Pattern byte offset from beginning of the 802.11 packet to start - * of the wake-up pattern */ - u8 byte_Offset; - - /* Non-Zero Pattern size */ - u8 size; - - /* Pattern */ - u8 pattern[WCN36XX_HAL_WOWL_BCAST_PATTERN_MAX_SIZE]; - - /* Non-zero pattern mask size */ - u8 mask_size; - - /* Pattern mask */ - u8 mask[WCN36XX_HAL_WOWL_BCAST_PATTERN_MAX_SIZE]; - - /* Extra pattern */ - u8 extra[WCN36XX_HAL_WOWL_BCAST_PATTERN_MAX_SIZE]; - - /* Extra pattern mask */ - u8 mask_extra[WCN36XX_HAL_WOWL_BCAST_PATTERN_MAX_SIZE]; - - u8 bss_index; -}; - -struct wcn36xx_hal_wow_del_bcast_ptrn_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Pattern ID of the wakeup pattern to be deleted */ - u8 id; - u8 bss_index; -}; - -struct wcn36xx_hal_wowl_enter_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Enables/disables magic packet filtering */ - u8 magic_packet_enable; - - /* Magic pattern */ - u8 magic_pattern[ETH_ALEN]; - - /* Enables/disables packet pattern filtering in firmware. Enabling - * this flag enables broadcast pattern matching in Firmware. If - * unicast pattern matching is also desired, - * ucUcastPatternFilteringEnable flag must be set tot true as well - */ - u8 pattern_filtering_enable; - - /* Enables/disables unicast packet pattern filtering. This flag - * specifies whether we want to do pattern match on unicast packets - * as well and not just broadcast packets. This flag has no effect - * if the ucPatternFilteringEnable (main controlling flag) is set - * to false - */ - u8 ucast_pattern_filtering_enable; - - /* This configuration is valid only when magicPktEnable=1. It - * requests hardware to wake up when it receives the Channel Switch - * Action Frame. - */ - u8 wow_channel_switch_receive; - - /* This configuration is valid only when magicPktEnable=1. It - * requests hardware to wake up when it receives the - * Deauthentication Frame. - */ - u8 wow_deauth_receive; - - /* This configuration is valid only when magicPktEnable=1. It - * requests hardware to wake up when it receives the Disassociation - * Frame. - */ - u8 wow_disassoc_receive; - - /* This configuration is valid only when magicPktEnable=1. It - * requests hardware to wake up when it has missed consecutive - * beacons. This is a hardware register configuration (NOT a - * firmware configuration). - */ - u8 wow_max_missed_beacons; - - /* This configuration is valid only when magicPktEnable=1. This is - * a timeout value in units of microsec. It requests hardware to - * unconditionally wake up after it has stayed in WoWLAN mode for - * some time. Set 0 to disable this feature. - */ - u8 wow_max_sleep; - - /* This configuration directs the WoW packet filtering to look for - * EAP-ID requests embedded in EAPOL frames and use this as a wake - * source. - */ - u8 wow_eap_id_request_enable; - - /* This configuration directs the WoW packet filtering to look for - * EAPOL-4WAY requests and use this as a wake source. - */ - u8 wow_eapol_4way_enable; - - /* This configuration allows a host wakeup on an network scan - * offload match. - */ - u8 wow_net_scan_offload_match; - - /* This configuration allows a host wakeup on any GTK rekeying - * error. - */ - u8 wow_gtk_rekey_error; - - /* This configuration allows a host wakeup on BSS connection loss. - */ - u8 wow_bss_connection_loss; - - u8 bss_index; -}; - -struct wcn36xx_hal_wowl_exit_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 bss_index; -}; - -struct wcn36xx_hal_get_rssi_req_msg { - struct wcn36xx_hal_msg_header header; -}; - -struct wcn36xx_hal_get_roam_rssi_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Valid STA Idx for per STA stats request */ - u32 sta_id; -}; - -struct wcn36xx_hal_set_uapsd_ac_params_req_msg { - struct wcn36xx_hal_msg_header header; - - /* STA index */ - u8 sta_idx; - - /* Access Category */ - u8 ac; - - /* User Priority */ - u8 up; - - /* Service Interval */ - u32 service_interval; - - /* Suspend Interval */ - u32 suspend_interval; - - /* Delay Interval */ - u32 delay_interval; -}; - -struct wcn36xx_hal_configure_rxp_filter_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 set_mcst_bcst_filter_setting; - u8 set_mcst_bcst_filter; -}; - -struct wcn36xx_hal_enter_imps_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct wcn36xx_hal_exit_imps_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct wcn36xx_hal_enter_bmps_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - - u8 bss_index; -} __packed; - -struct wcn36xx_hal_exit_bmps_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - - u8 bss_index; -} __packed; - -struct wcn36xx_hal_enter_uapsd_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - - u8 bss_index; -}; - -struct wcn36xx_hal_exit_uapsd_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - - u8 bss_index; -}; - -struct wcn36xx_hal_rssi_notification_ind_msg { - struct wcn36xx_hal_msg_header header; - - u32 rssi_thres1_pos_cross:1; - u32 rssi_thres1_neg_cross:1; - u32 rssi_thres2_pos_cross:1; - u32 rssi_thres2_neg_cross:1; - u32 rssi_thres3_pos_cross:1; - u32 rssi_thres3_neg_cross:1; - u32 avg_rssi:8; - u32 reserved:18; - -}; - -struct wcn36xx_hal_get_rssio_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - s8 rssi; - -}; - -struct wcn36xx_hal_get_roam_rssi_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - - u8 sta_id; - s8 rssi; -}; - -struct wcn36xx_hal_wowl_enter_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - u8 bss_index; -}; - -struct wcn36xx_hal_wowl_exit_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - u8 bss_index; -}; - -struct wcn36xx_hal_add_bcn_filter_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct wcn36xx_hal_rem_bcn_filter_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct wcn36xx_hal_add_wowl_bcast_ptrn_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - u8 bss_index; -}; - -struct wcn36xx_hal_del_wowl_bcast_ptrn_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - u8 bss_index; -}; - -struct wcn36xx_hal_host_offload_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct wcn36xx_hal_keep_alive_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct wcn36xx_hal_set_rssi_thresh_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct wcn36xx_hal_set_uapsd_ac_params_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct wcn36xx_hal_configure_rxp_filter_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct set_max_tx_pwr_req { - struct wcn36xx_hal_msg_header header; - - /* BSSID is needed to identify which session issued this request. - * As the request has power constraints, this should be applied - * only to that session */ - u8 bssid[ETH_ALEN]; - - u8 self_addr[ETH_ALEN]; - - /* In request, power == MaxTx power to be used. */ - u8 power; -}; - -struct set_max_tx_pwr_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* power == tx power used for management frames */ - u8 power; - - /* success or failure */ - u32 status; -}; - -struct set_tx_pwr_req_msg { - struct wcn36xx_hal_msg_header header; - - /* TX Power in milli watts */ - u32 tx_power; - - u8 bss_index; -}; - -struct set_tx_pwr_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct get_tx_pwr_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 sta_id; -}; - -struct get_tx_pwr_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - - /* TX Power in milli watts */ - u32 tx_power; -}; - -struct set_p2p_gonoa_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 opp_ps; - u32 ct_window; - u8 count; - u32 duration; - u32 interval; - u32 single_noa_duration; - u8 ps_selection; -}; - -struct set_p2p_gonoa_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct wcn36xx_hal_add_sta_self_req { - struct wcn36xx_hal_msg_header header; - - u8 self_addr[ETH_ALEN]; - u32 status; -} __packed; - -struct wcn36xx_hal_add_sta_self_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - - /* Self STA Index */ - u8 self_sta_index; - - /* DPU Index (IGTK, PTK, GTK all same) */ - u8 dpu_index; - - /* DPU Signature */ - u8 dpu_signature; -} __packed; - -struct wcn36xx_hal_del_sta_self_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 self_addr[ETH_ALEN]; -} __packed; - -struct wcn36xx_hal_del_sta_self_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /*success or failure */ - u32 status; - - u8 self_addr[ETH_ALEN]; -} __packed; - -struct aggr_add_ts_req { - struct wcn36xx_hal_msg_header header; - - /* Station Index */ - u16 sta_idx; - - /* TSPEC handler uniquely identifying a TSPEC for a STA in a BSS. - * This will carry the bitmap with the bit positions representing - * different AC.s */ - u16 tspec_index; - - /* Tspec info per AC To program TPE with required parameters */ - struct wcn36xx_hal_tspec_ie tspec[WCN36XX_HAL_MAX_AC]; - - /* U-APSD Flags: 1b per AC. Encoded as follows: - b7 b6 b5 b4 b3 b2 b1 b0 = - X X X X BE BK VI VO */ - u8 uapsd; - - /* These parameters are for all the access categories */ - - /* Service Interval */ - u32 service_interval[WCN36XX_HAL_MAX_AC]; - - /* Suspend Interval */ - u32 suspend_interval[WCN36XX_HAL_MAX_AC]; - - /* Delay Interval */ - u32 delay_interval[WCN36XX_HAL_MAX_AC]; -}; - -struct aggr_add_ts_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status0; - - /* FIXME PRIMA for future use for 11R */ - u32 status1; -}; - -struct wcn36xx_hal_configure_apps_cpu_wakeup_state_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 is_apps_cpu_awake; -}; - -struct wcn36xx_hal_configure_apps_cpu_wakeup_state_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct wcn36xx_hal_dump_cmd_req_msg { - struct wcn36xx_hal_msg_header header; - - u32 arg1; - u32 arg2; - u32 arg3; - u32 arg4; - u32 arg5; -} __packed; - -struct wcn36xx_hal_dump_cmd_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - - /* Length of the responce message */ - u32 rsp_length; - - /* FIXME: Currently considering the the responce will be less than - * 100bytes */ - u8 rsp_buffer[DUMPCMD_RSP_BUFFER]; -} __packed; - -#define WLAN_COEX_IND_DATA_SIZE (4) -#define WLAN_COEX_IND_TYPE_DISABLE_HB_MONITOR (0) -#define WLAN_COEX_IND_TYPE_ENABLE_HB_MONITOR (1) - -struct coex_ind_msg { - struct wcn36xx_hal_msg_header header; - - /* Coex Indication Type */ - u32 type; - - /* Coex Indication Data */ - u32 data[WLAN_COEX_IND_DATA_SIZE]; -}; - -struct wcn36xx_hal_tx_compl_ind_msg { - struct wcn36xx_hal_msg_header header; - - /* Tx Complete Indication Success or Failure */ - u32 status; -}; - -struct wcn36xx_hal_wlan_host_suspend_ind_msg { - struct wcn36xx_hal_msg_header header; - - u32 configured_mcst_bcst_filter_setting; - u32 active_session_count; -}; - -struct wcn36xx_hal_wlan_exclude_unencrpted_ind_msg { - struct wcn36xx_hal_msg_header header; - - u8 dot11_exclude_unencrypted; - u8 bssid[ETH_ALEN]; -}; - -struct noa_attr_ind_msg { - struct wcn36xx_hal_msg_header header; - - u8 index; - u8 opp_ps_flag; - u16 ctwin; - - u16 noa1_interval_count; - u16 bss_index; - u32 noa1_duration; - u32 noa1_interval; - u32 noa1_starttime; - - u16 noa2_interval_count; - u16 reserved2; - u32 noa2_duration; - u32 noa2_interval; - u32 noa2_start_time; - - u32 status; -}; - -struct noa_start_ind_msg { - struct wcn36xx_hal_msg_header header; - - u32 status; - u32 bss_index; -}; - -struct wcn36xx_hal_wlan_host_resume_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 configured_mcst_bcst_filter_setting; -}; - -struct wcn36xx_hal_host_resume_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -struct wcn36xx_hal_del_ba_ind_msg { - struct wcn36xx_hal_msg_header header; - - u16 sta_idx; - - /* Peer MAC Address, whose BA session has timed out */ - u8 peer_addr[ETH_ALEN]; - - /* TID for which a BA session timeout is being triggered */ - u8 ba_tid; - - /* DELBA direction - * 1 - Originator - * 0 - Recipient - */ - u8 direction; - - u32 reason_code; - - /* TO SUPPORT BT-AMP */ - u8 bssid[ETH_ALEN]; -}; - -/* PNO Messages */ - -/* Max number of channels that a network can be found on */ -#define WCN36XX_HAL_PNO_MAX_NETW_CHANNELS 26 - -/* Max number of channels that a network can be found on */ -#define WCN36XX_HAL_PNO_MAX_NETW_CHANNELS_EX 60 - -/* Maximum numbers of networks supported by PNO */ -#define WCN36XX_HAL_PNO_MAX_SUPP_NETWORKS 16 - -/* The number of scan time intervals that can be programmed into PNO */ -#define WCN36XX_HAL_PNO_MAX_SCAN_TIMERS 10 - -/* Maximum size of the probe template */ -#define WCN36XX_HAL_PNO_MAX_PROBE_SIZE 450 - -/* Type of PNO enabling: - * - * Immediate - scanning will start immediately and PNO procedure will be - * repeated based on timer - * - * Suspend - scanning will start at suspend - * - * Resume - scanning will start on system resume - */ -enum pno_mode { - PNO_MODE_IMMEDIATE, - PNO_MODE_ON_SUSPEND, - PNO_MODE_ON_RESUME, - PNO_MODE_MAX = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -/* Authentication type */ -enum auth_type { - AUTH_TYPE_ANY = 0, - AUTH_TYPE_OPEN_SYSTEM = 1, - - /* Upper layer authentication types */ - AUTH_TYPE_WPA = 2, - AUTH_TYPE_WPA_PSK = 3, - - AUTH_TYPE_RSN = 4, - AUTH_TYPE_RSN_PSK = 5, - AUTH_TYPE_FT_RSN = 6, - AUTH_TYPE_FT_RSN_PSK = 7, - AUTH_TYPE_WAPI_WAI_CERTIFICATE = 8, - AUTH_TYPE_WAPI_WAI_PSK = 9, - - AUTH_TYPE_MAX = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -/* Encryption type */ -enum ed_type { - ED_ANY = 0, - ED_NONE = 1, - ED_WEP = 2, - ED_TKIP = 3, - ED_CCMP = 4, - ED_WPI = 5, - - ED_TYPE_MAX = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -/* SSID broadcast type */ -enum ssid_bcast_type { - BCAST_UNKNOWN = 0, - BCAST_NORMAL = 1, - BCAST_HIDDEN = 2, - - BCAST_TYPE_MAX = WCN36XX_HAL_MAX_ENUM_SIZE -}; - -/* The network description for which PNO will have to look for */ -struct network_type { - /* SSID of the BSS */ - struct wcn36xx_hal_mac_ssid ssid; - - /* Authentication type for the network */ - enum auth_type authentication; - - /* Encryption type for the network */ - enum ed_type encryption; - - /* Indicate the channel on which the Network can be found 0 - if - * all channels */ - u8 channel_count; - u8 channels[WCN36XX_HAL_PNO_MAX_NETW_CHANNELS]; - - /* Indicates the RSSI threshold for the network to be considered */ - u8 rssi_threshold; -}; - -struct scan_timer { - /* How much it should wait */ - u32 value; - - /* How many times it should repeat that wait value 0 - keep using - * this timer until PNO is disabled */ - u32 repeat; - - /* e.g: 2 3 4 0 - it will wait 2s between consecutive scans for 3 - * times - after that it will wait 4s between consecutive scans - * until disabled */ -}; - -/* The network parameters to be sent to the PNO algorithm */ -struct scan_timers_type { - /* set to 0 if you wish for PNO to use its default telescopic timer */ - u8 count; - - /* A set value represents the amount of time that PNO will wait - * between two consecutive scan procedures If the desired is for a - * uniform timer that fires always at the exact same interval - one - * single value is to be set If there is a desire for a more - * complex - telescopic like timer multiple values can be set - - * once PNO reaches the end of the array it will continue scanning - * at intervals presented by the last value */ - struct scan_timer values[WCN36XX_HAL_PNO_MAX_SCAN_TIMERS]; -}; - -/* Preferred network list request */ -struct set_pref_netw_list_req { - struct wcn36xx_hal_msg_header header; - - /* Enable PNO */ - u32 enable; - - /* Immediate, On Suspend, On Resume */ - enum pno_mode mode; - - /* Number of networks sent for PNO */ - u32 networks_count; - - /* The networks that PNO needs to look for */ - struct network_type networks[WCN36XX_HAL_PNO_MAX_SUPP_NETWORKS]; - - /* The scan timers required for PNO */ - struct scan_timers_type scan_timers; - - /* Probe template for 2.4GHz band */ - u16 band_24g_probe_size; - u8 band_24g_probe_template[WCN36XX_HAL_PNO_MAX_PROBE_SIZE]; - - /* Probe template for 5GHz band */ - u16 band_5g_probe_size; - u8 band_5g_probe_template[WCN36XX_HAL_PNO_MAX_PROBE_SIZE]; -}; - -/* The network description for which PNO will have to look for */ -struct network_type_new { - /* SSID of the BSS */ - struct wcn36xx_hal_mac_ssid ssid; - - /* Authentication type for the network */ - enum auth_type authentication; - - /* Encryption type for the network */ - enum ed_type encryption; - - /* SSID broadcast type, normal, hidden or unknown */ - enum ssid_bcast_type bcast_network_type; - - /* Indicate the channel on which the Network can be found 0 - if - * all channels */ - u8 channel_count; - u8 channels[WCN36XX_HAL_PNO_MAX_NETW_CHANNELS]; - - /* Indicates the RSSI threshold for the network to be considered */ - u8 rssi_threshold; -}; - -/* Preferred network list request new */ -struct set_pref_netw_list_req_new { - struct wcn36xx_hal_msg_header header; - - /* Enable PNO */ - u32 enable; - - /* Immediate, On Suspend, On Resume */ - enum pno_mode mode; - - /* Number of networks sent for PNO */ - u32 networks_count; - - /* The networks that PNO needs to look for */ - struct network_type_new networks[WCN36XX_HAL_PNO_MAX_SUPP_NETWORKS]; - - /* The scan timers required for PNO */ - struct scan_timers_type scan_timers; - - /* Probe template for 2.4GHz band */ - u16 band_24g_probe_size; - u8 band_24g_probe_template[WCN36XX_HAL_PNO_MAX_PROBE_SIZE]; - - /* Probe template for 5GHz band */ - u16 band_5g_probe_size; - u8 band_5g_probe_template[WCN36XX_HAL_PNO_MAX_PROBE_SIZE]; -}; - -/* Preferred network list response */ -struct set_pref_netw_list_resp { - struct wcn36xx_hal_msg_header header; - - /* status of the request - just to indicate that PNO has - * acknowledged the request and will start scanning */ - u32 status; -}; - -/* Preferred network found indication */ -struct pref_netw_found_ind { - - struct wcn36xx_hal_msg_header header; - - /* Network that was found with the highest RSSI */ - struct wcn36xx_hal_mac_ssid ssid; - - /* Indicates the RSSI */ - u8 rssi; -}; - -/* RSSI Filter request */ -struct set_rssi_filter_req { - struct wcn36xx_hal_msg_header header; - - /* RSSI Threshold */ - u8 rssi_threshold; -}; - -/* Set RSSI filter resp */ -struct set_rssi_filter_resp { - struct wcn36xx_hal_msg_header header; - - /* status of the request */ - u32 status; -}; - -/* Update scan params - sent from host to PNO to be used during PNO - * scanningx */ -struct wcn36xx_hal_update_scan_params_req { - - struct wcn36xx_hal_msg_header header; - - /* Host setting for 11d */ - u8 dot11d_enabled; - - /* Lets PNO know that host has determined the regulatory domain */ - u8 dot11d_resolved; - - /* Channels on which PNO is allowed to scan */ - u8 channel_count; - u8 channels[WCN36XX_HAL_PNO_MAX_NETW_CHANNELS]; - - /* Minimum channel time */ - u16 active_min_ch_time; - - /* Maximum channel time */ - u16 active_max_ch_time; - - /* Minimum channel time */ - u16 passive_min_ch_time; - - /* Maximum channel time */ - u16 passive_max_ch_time; - - /* Cb State */ - enum phy_chan_bond_state state; -} __packed; - -/* Update scan params - sent from host to PNO to be used during PNO - * scanningx */ -struct update_scan_params_req_ex { - - struct wcn36xx_hal_msg_header header; - - /* Host setting for 11d */ - u8 dot11d_enabled; - - /* Lets PNO know that host has determined the regulatory domain */ - u8 dot11d_resolved; - - /* Channels on which PNO is allowed to scan */ - u8 channel_count; - u8 channels[WCN36XX_HAL_PNO_MAX_NETW_CHANNELS_EX]; - - /* Minimum channel time */ - u16 active_min_ch_time; - - /* Maximum channel time */ - u16 active_max_ch_time; - - /* Minimum channel time */ - u16 passive_min_ch_time; - - /* Maximum channel time */ - u16 passive_max_ch_time; - - /* Cb State */ - enum phy_chan_bond_state state; -}; - -/* Update scan params - sent from host to PNO to be used during PNO - * scanningx */ -struct wcn36xx_hal_update_scan_params_resp { - - struct wcn36xx_hal_msg_header header; - - /* status of the request */ - u32 status; -} __packed; - -struct wcn36xx_hal_set_tx_per_tracking_req_msg { - struct wcn36xx_hal_msg_header header; - - /* 0: disable, 1:enable */ - u8 tx_per_tracking_enable; - - /* Check period, unit is sec. */ - u8 tx_per_tracking_period; - - /* (Fail TX packet)/(Total TX packet) ratio, the unit is 10%. */ - u8 tx_per_tracking_ratio; - - /* A watermark of check number, once the tx packet exceed this - * number, we do the check, default is 5 */ - u32 tx_per_tracking_watermark; -}; - -struct wcn36xx_hal_set_tx_per_tracking_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - -}; - -struct tx_per_hit_ind_msg { - struct wcn36xx_hal_msg_header header; -}; - -/* Packet Filtering Definitions Begin */ -#define WCN36XX_HAL_PROTOCOL_DATA_LEN 8 -#define WCN36XX_HAL_MAX_NUM_MULTICAST_ADDRESS 240 -#define WCN36XX_HAL_MAX_NUM_FILTERS 20 -#define WCN36XX_HAL_MAX_CMP_PER_FILTER 10 - -enum wcn36xx_hal_receive_packet_filter_type { - HAL_RCV_FILTER_TYPE_INVALID, - HAL_RCV_FILTER_TYPE_FILTER_PKT, - HAL_RCV_FILTER_TYPE_BUFFER_PKT, - HAL_RCV_FILTER_TYPE_MAX_ENUM_SIZE -}; - -enum wcn36xx_hal_rcv_pkt_flt_protocol_type { - HAL_FILTER_PROTO_TYPE_INVALID, - HAL_FILTER_PROTO_TYPE_MAC, - HAL_FILTER_PROTO_TYPE_ARP, - HAL_FILTER_PROTO_TYPE_IPV4, - HAL_FILTER_PROTO_TYPE_IPV6, - HAL_FILTER_PROTO_TYPE_UDP, - HAL_FILTER_PROTO_TYPE_MAX -}; - -enum wcn36xx_hal_rcv_pkt_flt_cmp_flag_type { - HAL_FILTER_CMP_TYPE_INVALID, - HAL_FILTER_CMP_TYPE_EQUAL, - HAL_FILTER_CMP_TYPE_MASK_EQUAL, - HAL_FILTER_CMP_TYPE_NOT_EQUAL, - HAL_FILTER_CMP_TYPE_MAX -}; - -struct wcn36xx_hal_rcv_pkt_filter_params { - u8 protocol_layer; - u8 cmp_flag; - - /* Length of the data to compare */ - u16 data_length; - - /* from start of the respective frame header */ - u8 data_offset; - - /* Reserved field */ - u8 reserved; - - /* Data to compare */ - u8 compare_data[WCN36XX_HAL_PROTOCOL_DATA_LEN]; - - /* Mask to be applied on the received packet data before compare */ - u8 data_mask[WCN36XX_HAL_PROTOCOL_DATA_LEN]; -}; - -struct wcn36xx_hal_sessionized_rcv_pkt_filter_cfg_type { - u8 id; - u8 type; - u8 params_count; - u32 coleasce_time; - u8 bss_index; - struct wcn36xx_hal_rcv_pkt_filter_params params[1]; -}; - -struct wcn36xx_hal_set_rcv_pkt_filter_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 id; - u8 type; - u8 params_count; - u32 coalesce_time; - struct wcn36xx_hal_rcv_pkt_filter_params params[1]; -}; - -struct wcn36xx_hal_rcv_flt_mc_addr_list_type { - /* from start of the respective frame header */ - u8 data_offset; - - u32 mc_addr_count; - u8 mc_addr[ETH_ALEN][WCN36XX_HAL_MAX_NUM_MULTICAST_ADDRESS]; - u8 bss_index; -}; - -struct wcn36xx_hal_set_pkt_filter_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - - u8 bss_index; -}; - -struct wcn36xx_hal_rcv_flt_pkt_match_cnt_req_msg { - struct wcn36xx_hal_msg_header header; - - u8 bss_index; -}; - -struct wcn36xx_hal_rcv_flt_pkt_match_cnt { - u8 id; - u32 match_cnt; -}; - -struct wcn36xx_hal_rcv_flt_pkt_match_cnt_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* Success or Failure */ - u32 status; - - u32 match_count; - struct wcn36xx_hal_rcv_flt_pkt_match_cnt - matches[WCN36XX_HAL_MAX_NUM_FILTERS]; - u8 bss_index; -}; - -struct wcn36xx_hal_rcv_flt_pkt_clear_param { - /* only valid for response message */ - u32 status; - u8 id; - u8 bss_index; -}; - -struct wcn36xx_hal_rcv_flt_pkt_clear_req_msg { - struct wcn36xx_hal_msg_header header; - struct wcn36xx_hal_rcv_flt_pkt_clear_param param; -}; - -struct wcn36xx_hal_rcv_flt_pkt_clear_rsp_msg { - struct wcn36xx_hal_msg_header header; - struct wcn36xx_hal_rcv_flt_pkt_clear_param param; -}; - -struct wcn36xx_hal_rcv_flt_pkt_set_mc_list_req_msg { - struct wcn36xx_hal_msg_header header; - struct wcn36xx_hal_rcv_flt_mc_addr_list_type mc_addr_list; -}; - -struct wcn36xx_hal_rcv_flt_pkt_set_mc_list_rsp_msg { - struct wcn36xx_hal_msg_header header; - u32 status; - u8 bss_index; -}; - -/* Packet Filtering Definitions End */ - -struct wcn36xx_hal_set_power_params_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Ignore DTIM */ - u32 ignore_dtim; - - /* DTIM Period */ - u32 dtim_period; - - /* Listen Interval */ - u32 listen_interval; - - /* Broadcast Multicast Filter */ - u32 bcast_mcast_filter; - - /* Beacon Early Termination */ - u32 enable_bet; - - /* Beacon Early Termination Interval */ - u32 bet_interval; -} __packed; - -struct wcn36xx_hal_set_power_params_resp { - - struct wcn36xx_hal_msg_header header; - - /* status of the request */ - u32 status; -} __packed; - -/* Capability bitmap exchange definitions and macros starts */ - -enum place_holder_in_cap_bitmap { - MCC = 0, - P2P = 1, - DOT11AC = 2, - SLM_SESSIONIZATION = 3, - DOT11AC_OPMODE = 4, - SAP32STA = 5, - TDLS = 6, - P2P_GO_NOA_DECOUPLE_INIT_SCAN = 7, - WLANACTIVE_OFFLOAD = 8, - BEACON_OFFLOAD = 9, - SCAN_OFFLOAD = 10, - ROAM_OFFLOAD = 11, - BCN_MISS_OFFLOAD = 12, - STA_POWERSAVE = 13, - STA_ADVANCED_PWRSAVE = 14, - AP_UAPSD = 15, - AP_DFS = 16, - BLOCKACK = 17, - PHY_ERR = 18, - BCN_FILTER = 19, - RTT = 20, - RATECTRL = 21, - WOW = 22, - MAX_FEATURE_SUPPORTED = 128, -}; - -struct wcn36xx_hal_feat_caps_msg { - - struct wcn36xx_hal_msg_header header; - - u32 feat_caps[4]; -} __packed; - -/* status codes to help debug rekey failures */ -enum gtk_rekey_status { - WCN36XX_HAL_GTK_REKEY_STATUS_SUCCESS = 0, - - /* rekey detected, but not handled */ - WCN36XX_HAL_GTK_REKEY_STATUS_NOT_HANDLED = 1, - - /* MIC check error on M1 */ - WCN36XX_HAL_GTK_REKEY_STATUS_MIC_ERROR = 2, - - /* decryption error on M1 */ - WCN36XX_HAL_GTK_REKEY_STATUS_DECRYPT_ERROR = 3, - - /* M1 replay detected */ - WCN36XX_HAL_GTK_REKEY_STATUS_REPLAY_ERROR = 4, - - /* missing GTK key descriptor in M1 */ - WCN36XX_HAL_GTK_REKEY_STATUS_MISSING_KDE = 5, - - /* missing iGTK key descriptor in M1 */ - WCN36XX_HAL_GTK_REKEY_STATUS_MISSING_IGTK_KDE = 6, - - /* key installation error */ - WCN36XX_HAL_GTK_REKEY_STATUS_INSTALL_ERROR = 7, - - /* iGTK key installation error */ - WCN36XX_HAL_GTK_REKEY_STATUS_IGTK_INSTALL_ERROR = 8, - - /* GTK rekey M2 response TX error */ - WCN36XX_HAL_GTK_REKEY_STATUS_RESP_TX_ERROR = 9, - - /* non-specific general error */ - WCN36XX_HAL_GTK_REKEY_STATUS_GEN_ERROR = 255 -}; - -/* wake reason types */ -enum wake_reason_type { - WCN36XX_HAL_WAKE_REASON_NONE = 0, - - /* magic packet match */ - WCN36XX_HAL_WAKE_REASON_MAGIC_PACKET = 1, - - /* host defined pattern match */ - WCN36XX_HAL_WAKE_REASON_PATTERN_MATCH = 2, - - /* EAP-ID frame detected */ - WCN36XX_HAL_WAKE_REASON_EAPID_PACKET = 3, - - /* start of EAPOL 4-way handshake detected */ - WCN36XX_HAL_WAKE_REASON_EAPOL4WAY_PACKET = 4, - - /* network scan offload match */ - WCN36XX_HAL_WAKE_REASON_NETSCAN_OFFL_MATCH = 5, - - /* GTK rekey status wakeup (see status) */ - WCN36XX_HAL_WAKE_REASON_GTK_REKEY_STATUS = 6, - - /* BSS connection lost */ - WCN36XX_HAL_WAKE_REASON_BSS_CONN_LOST = 7, -}; - -/* - Wake Packet which is saved at tWakeReasonParams.DataStart - This data is sent for any wake reasons that involve a packet-based wakeup : - - WCN36XX_HAL_WAKE_REASON_TYPE_MAGIC_PACKET - WCN36XX_HAL_WAKE_REASON_TYPE_PATTERN_MATCH - WCN36XX_HAL_WAKE_REASON_TYPE_EAPID_PACKET - WCN36XX_HAL_WAKE_REASON_TYPE_EAPOL4WAY_PACKET - WCN36XX_HAL_WAKE_REASON_TYPE_GTK_REKEY_STATUS - - The information is provided to the host for auditing and debug purposes - -*/ - -/* Wake reason indication */ -struct wcn36xx_hal_wake_reason_ind { - struct wcn36xx_hal_msg_header header; - - /* see tWakeReasonType */ - u32 reason; - - /* argument specific to the reason type */ - u32 reason_arg; - - /* length of optional data stored in this message, in case HAL - * truncates the data (i.e. data packets) this length will be less - * than the actual length */ - u32 stored_data_len; - - /* actual length of data */ - u32 actual_data_len; - - /* variable length start of data (length == storedDataLen) see - * specific wake type */ - u8 data_start[1]; - - u32 bss_index:8; - u32 reserved:24; -}; - -#define WCN36XX_HAL_GTK_KEK_BYTES 16 -#define WCN36XX_HAL_GTK_KCK_BYTES 16 - -#define WCN36XX_HAL_GTK_OFFLOAD_FLAGS_DISABLE (1 << 0) - -#define GTK_SET_BSS_KEY_TAG 0x1234AA55 - -struct wcn36xx_hal_gtk_offload_req_msg { - struct wcn36xx_hal_msg_header header; - - /* optional flags */ - u32 flags; - - /* Key confirmation key */ - u8 kck[WCN36XX_HAL_GTK_KCK_BYTES]; - - /* key encryption key */ - u8 kek[WCN36XX_HAL_GTK_KEK_BYTES]; - - /* replay counter */ - u64 key_replay_counter; - - u8 bss_index; -}; - -struct wcn36xx_hal_gtk_offload_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - - u8 bss_index; -}; - -struct wcn36xx_hal_gtk_offload_get_info_req_msg { - struct wcn36xx_hal_msg_header header; - u8 bss_index; -}; - -struct wcn36xx_hal_gtk_offload_get_info_rsp_msg { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; - - /* last rekey status when the rekey was offloaded */ - u32 last_rekey_status; - - /* current replay counter value */ - u64 key_replay_counter; - - /* total rekey attempts */ - u32 total_rekey_count; - - /* successful GTK rekeys */ - u32 gtk_rekey_count; - - /* successful iGTK rekeys */ - u32 igtk_rekey_count; - - u8 bss_index; -}; - -struct dhcp_info { - /* Indicates the device mode which indicates about the DHCP activity */ - u8 device_mode; - - u8 addr[ETH_ALEN]; -}; - -struct dhcp_ind_status { - struct wcn36xx_hal_msg_header header; - - /* success or failure */ - u32 status; -}; - -/* - * Thermal Mitigation mode of operation. - * - * WCN36XX_HAL_THERMAL_MITIGATION_MODE_0 - Based on AMPDU disabling aggregation - * - * WCN36XX_HAL_THERMAL_MITIGATION_MODE_1 - Based on AMPDU disabling aggregation - * and reducing transmit power - * - * WCN36XX_HAL_THERMAL_MITIGATION_MODE_2 - Not supported */ -enum wcn36xx_hal_thermal_mitigation_mode_type { - HAL_THERMAL_MITIGATION_MODE_INVALID = -1, - HAL_THERMAL_MITIGATION_MODE_0, - HAL_THERMAL_MITIGATION_MODE_1, - HAL_THERMAL_MITIGATION_MODE_2, - HAL_THERMAL_MITIGATION_MODE_MAX = WCN36XX_HAL_MAX_ENUM_SIZE, -}; - - -/* - * Thermal Mitigation level. - * Note the levels are incremental i.e WCN36XX_HAL_THERMAL_MITIGATION_LEVEL_2 = - * WCN36XX_HAL_THERMAL_MITIGATION_LEVEL_0 + - * WCN36XX_HAL_THERMAL_MITIGATION_LEVEL_1 - * - * WCN36XX_HAL_THERMAL_MITIGATION_LEVEL_0 - lowest level of thermal mitigation. - * This level indicates normal mode of operation - * - * WCN36XX_HAL_THERMAL_MITIGATION_LEVEL_1 - 1st level of thermal mitigation - * - * WCN36XX_HAL_THERMAL_MITIGATION_LEVEL_2 - 2nd level of thermal mitigation - * - * WCN36XX_HAL_THERMAL_MITIGATION_LEVEL_3 - 3rd level of thermal mitigation - * - * WCN36XX_HAL_THERMAL_MITIGATION_LEVEL_4 - 4th level of thermal mitigation - */ -enum wcn36xx_hal_thermal_mitigation_level_type { - HAL_THERMAL_MITIGATION_LEVEL_INVALID = -1, - HAL_THERMAL_MITIGATION_LEVEL_0, - HAL_THERMAL_MITIGATION_LEVEL_1, - HAL_THERMAL_MITIGATION_LEVEL_2, - HAL_THERMAL_MITIGATION_LEVEL_3, - HAL_THERMAL_MITIGATION_LEVEL_4, - HAL_THERMAL_MITIGATION_LEVEL_MAX = WCN36XX_HAL_MAX_ENUM_SIZE, -}; - - -/* WCN36XX_HAL_SET_THERMAL_MITIGATION_REQ */ -struct set_thermal_mitigation_req_msg { - struct wcn36xx_hal_msg_header header; - - /* Thermal Mitigation Operation Mode */ - enum wcn36xx_hal_thermal_mitigation_mode_type mode; - - /* Thermal Mitigation Level */ - enum wcn36xx_hal_thermal_mitigation_level_type level; -}; - -struct set_thermal_mitigation_resp { - - struct wcn36xx_hal_msg_header header; - - /* status of the request */ - u32 status; -}; - -/* Per STA Class B Statistics. Class B statistics are STA TX/RX stats - * provided to FW from Host via periodic messages */ -struct stats_class_b_ind { - struct wcn36xx_hal_msg_header header; - - /* Duration over which this stats was collected */ - u32 duration; - - /* Per STA Stats */ - - /* TX stats */ - u32 tx_bytes_pushed; - u32 tx_packets_pushed; - - /* RX stats */ - u32 rx_bytes_rcvd; - u32 rx_packets_rcvd; - u32 rx_time_total; -}; - -#endif /* _HAL_H_ */ diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c deleted file mode 100644 index 7839b31..0000000 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ /dev/null @@ -1,1036 +0,0 @@ -/* - * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/module.h> -#include <linux/platform_device.h> -#include "wcn36xx.h" - -unsigned int wcn36xx_dbg_mask; -module_param_named(debug_mask, wcn36xx_dbg_mask, uint, 0644); -MODULE_PARM_DESC(debug_mask, "Debugging mask"); - -#define CHAN2G(_freq, _idx) { \ - .band = IEEE80211_BAND_2GHZ, \ - .center_freq = (_freq), \ - .hw_value = (_idx), \ - .max_power = 25, \ -} - -#define CHAN5G(_freq, _idx) { \ - .band = IEEE80211_BAND_5GHZ, \ - .center_freq = (_freq), \ - .hw_value = (_idx), \ - .max_power = 25, \ -} - -/* The wcn firmware expects channel values to matching - * their mnemonic values. So use these for .hw_value. */ -static struct ieee80211_channel wcn_2ghz_channels[] = { - CHAN2G(2412, 1), /* Channel 1 */ - CHAN2G(2417, 2), /* Channel 2 */ - CHAN2G(2422, 3), /* Channel 3 */ - CHAN2G(2427, 4), /* Channel 4 */ - CHAN2G(2432, 5), /* Channel 5 */ - CHAN2G(2437, 6), /* Channel 6 */ - CHAN2G(2442, 7), /* Channel 7 */ - CHAN2G(2447, 8), /* Channel 8 */ - CHAN2G(2452, 9), /* Channel 9 */ - CHAN2G(2457, 10), /* Channel 10 */ - CHAN2G(2462, 11), /* Channel 11 */ - CHAN2G(2467, 12), /* Channel 12 */ - CHAN2G(2472, 13), /* Channel 13 */ - CHAN2G(2484, 14) /* Channel 14 */ - -}; - -static struct ieee80211_channel wcn_5ghz_channels[] = { - CHAN5G(5180, 36), - CHAN5G(5200, 40), - CHAN5G(5220, 44), - CHAN5G(5240, 48), - CHAN5G(5260, 52), - CHAN5G(5280, 56), - CHAN5G(5300, 60), - CHAN5G(5320, 64), - CHAN5G(5500, 100), - CHAN5G(5520, 104), - CHAN5G(5540, 108), - CHAN5G(5560, 112), - CHAN5G(5580, 116), - CHAN5G(5600, 120), - CHAN5G(5620, 124), - CHAN5G(5640, 128), - CHAN5G(5660, 132), - CHAN5G(5700, 140), - CHAN5G(5745, 149), - CHAN5G(5765, 153), - CHAN5G(5785, 157), - CHAN5G(5805, 161), - CHAN5G(5825, 165) -}; - -#define RATE(_bitrate, _hw_rate, _flags) { \ - .bitrate = (_bitrate), \ - .flags = (_flags), \ - .hw_value = (_hw_rate), \ - .hw_value_short = (_hw_rate) \ -} - -static struct ieee80211_rate wcn_2ghz_rates[] = { - RATE(10, HW_RATE_INDEX_1MBPS, 0), - RATE(20, HW_RATE_INDEX_2MBPS, IEEE80211_RATE_SHORT_PREAMBLE), - RATE(55, HW_RATE_INDEX_5_5MBPS, IEEE80211_RATE_SHORT_PREAMBLE), - RATE(110, HW_RATE_INDEX_11MBPS, IEEE80211_RATE_SHORT_PREAMBLE), - RATE(60, HW_RATE_INDEX_6MBPS, 0), - RATE(90, HW_RATE_INDEX_9MBPS, 0), - RATE(120, HW_RATE_INDEX_12MBPS, 0), - RATE(180, HW_RATE_INDEX_18MBPS, 0), - RATE(240, HW_RATE_INDEX_24MBPS, 0), - RATE(360, HW_RATE_INDEX_36MBPS, 0), - RATE(480, HW_RATE_INDEX_48MBPS, 0), - RATE(540, HW_RATE_INDEX_54MBPS, 0) -}; - -static struct ieee80211_rate wcn_5ghz_rates[] = { - RATE(60, HW_RATE_INDEX_6MBPS, 0), - RATE(90, HW_RATE_INDEX_9MBPS, 0), - RATE(120, HW_RATE_INDEX_12MBPS, 0), - RATE(180, HW_RATE_INDEX_18MBPS, 0), - RATE(240, HW_RATE_INDEX_24MBPS, 0), - RATE(360, HW_RATE_INDEX_36MBPS, 0), - RATE(480, HW_RATE_INDEX_48MBPS, 0), - RATE(540, HW_RATE_INDEX_54MBPS, 0) -}; - -static struct ieee80211_supported_band wcn_band_2ghz = { - .channels = wcn_2ghz_channels, - .n_channels = ARRAY_SIZE(wcn_2ghz_channels), - .bitrates = wcn_2ghz_rates, - .n_bitrates = ARRAY_SIZE(wcn_2ghz_rates), - .ht_cap = { - .cap = IEEE80211_HT_CAP_GRN_FLD | - IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_DSSSCCK40 | - IEEE80211_HT_CAP_LSIG_TXOP_PROT, - .ht_supported = true, - .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, - .mcs = { - .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, - .rx_highest = cpu_to_le16(72), - .tx_params = IEEE80211_HT_MCS_TX_DEFINED, - } - } -}; - -static struct ieee80211_supported_band wcn_band_5ghz = { - .channels = wcn_5ghz_channels, - .n_channels = ARRAY_SIZE(wcn_5ghz_channels), - .bitrates = wcn_5ghz_rates, - .n_bitrates = ARRAY_SIZE(wcn_5ghz_rates), - .ht_cap = { - .cap = IEEE80211_HT_CAP_GRN_FLD | - IEEE80211_HT_CAP_SGI_20 | - IEEE80211_HT_CAP_DSSSCCK40 | - IEEE80211_HT_CAP_LSIG_TXOP_PROT | - IEEE80211_HT_CAP_SGI_40 | - IEEE80211_HT_CAP_SUP_WIDTH_20_40, - .ht_supported = true, - .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, - .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, - .mcs = { - .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, - .rx_highest = cpu_to_le16(72), - .tx_params = IEEE80211_HT_MCS_TX_DEFINED, - } - } -}; - -#ifdef CONFIG_PM - -static const struct wiphy_wowlan_support wowlan_support = { - .flags = WIPHY_WOWLAN_ANY -}; - -#endif - -static inline u8 get_sta_index(struct ieee80211_vif *vif, - struct wcn36xx_sta *sta_priv) -{ - return NL80211_IFTYPE_STATION == vif->type ? - sta_priv->bss_sta_index : - sta_priv->sta_index; -} - -static int wcn36xx_start(struct ieee80211_hw *hw) -{ - struct wcn36xx *wcn = hw->priv; - int ret; - - wcn36xx_dbg(WCN36XX_DBG_MAC, "mac start\n"); - - /* SMD initialization */ - ret = wcn36xx_smd_open(wcn); - if (ret) { - wcn36xx_err("Failed to open smd channel: %d\n", ret); - goto out_err; - } - - /* Allocate memory pools for Mgmt BD headers and Data BD headers */ - ret = wcn36xx_dxe_allocate_mem_pools(wcn); - if (ret) { - wcn36xx_err("Failed to alloc DXE mempool: %d\n", ret); - goto out_smd_close; - } - - ret = wcn36xx_dxe_alloc_ctl_blks(wcn); - if (ret) { - wcn36xx_err("Failed to alloc DXE ctl blocks: %d\n", ret); - goto out_free_dxe_pool; - } - - wcn->hal_buf = kmalloc(WCN36XX_HAL_BUF_SIZE, GFP_KERNEL); - if (!wcn->hal_buf) { - wcn36xx_err("Failed to allocate smd buf\n"); - ret = -ENOMEM; - goto out_free_dxe_ctl; - } - - ret = wcn36xx_smd_load_nv(wcn); - if (ret) { - wcn36xx_err("Failed to push NV to chip\n"); - goto out_free_smd_buf; - } - - ret = wcn36xx_smd_start(wcn); - if (ret) { - wcn36xx_err("Failed to start chip\n"); - goto out_free_smd_buf; - } - - /* DMA channel initialization */ - ret = wcn36xx_dxe_init(wcn); - if (ret) { - wcn36xx_err("DXE init failed\n"); - goto out_smd_stop; - } - - wcn36xx_debugfs_init(wcn); - - if (!wcn36xx_is_fw_version(wcn, 1, 2, 2, 24)) { - ret = wcn36xx_smd_feature_caps_exchange(wcn); - if (ret) - wcn36xx_warn("Exchange feature caps failed\n"); - } - INIT_LIST_HEAD(&wcn->vif_list); - return 0; - -out_smd_stop: - wcn36xx_smd_stop(wcn); -out_free_smd_buf: - kfree(wcn->hal_buf); -out_free_dxe_pool: - wcn36xx_dxe_free_mem_pools(wcn); -out_free_dxe_ctl: - wcn36xx_dxe_free_ctl_blks(wcn); -out_smd_close: - wcn36xx_smd_close(wcn); -out_err: - return ret; -} - -static void wcn36xx_stop(struct ieee80211_hw *hw) -{ - struct wcn36xx *wcn = hw->priv; - - wcn36xx_dbg(WCN36XX_DBG_MAC, "mac stop\n"); - - wcn36xx_debugfs_exit(wcn); - wcn36xx_smd_stop(wcn); - wcn36xx_dxe_deinit(wcn); - wcn36xx_smd_close(wcn); - - wcn36xx_dxe_free_mem_pools(wcn); - wcn36xx_dxe_free_ctl_blks(wcn); - - kfree(wcn->hal_buf); -} - -static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed) -{ - struct wcn36xx *wcn = hw->priv; - struct ieee80211_vif *vif = NULL; - struct wcn36xx_vif *tmp; - - wcn36xx_dbg(WCN36XX_DBG_MAC, "mac config changed 0x%08x\n", changed); - - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - int ch = WCN36XX_HW_CHANNEL(wcn); - wcn36xx_dbg(WCN36XX_DBG_MAC, "wcn36xx_config channel switch=%d\n", - ch); - list_for_each_entry(tmp, &wcn->vif_list, list) { - vif = container_of((void *)tmp, - struct ieee80211_vif, - drv_priv); - wcn36xx_smd_switch_channel(wcn, vif, ch); - } - } - - return 0; -} - -#define WCN36XX_SUPPORTED_FILTERS (0) - -static void wcn36xx_configure_filter(struct ieee80211_hw *hw, - unsigned int changed, - unsigned int *total, u64 multicast) -{ - wcn36xx_dbg(WCN36XX_DBG_MAC, "mac configure filter\n"); - - *total &= WCN36XX_SUPPORTED_FILTERS; -} - -static void wcn36xx_tx(struct ieee80211_hw *hw, - struct ieee80211_tx_control *control, - struct sk_buff *skb) -{ - struct wcn36xx *wcn = hw->priv; - struct wcn36xx_sta *sta_priv = NULL; - - if (control->sta) - sta_priv = (struct wcn36xx_sta *)control->sta->drv_priv; - - if (wcn36xx_start_tx(wcn, sta_priv, skb)) - ieee80211_free_txskb(wcn->hw, skb); -} - -static int wcn36xx_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct ieee80211_key_conf *key_conf) -{ - struct wcn36xx *wcn = hw->priv; - struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; - struct wcn36xx_sta *sta_priv = vif_priv->sta; - int ret = 0; - u8 key[WLAN_MAX_KEY_LEN]; - - wcn36xx_dbg(WCN36XX_DBG_MAC, "mac80211 set key\n"); - wcn36xx_dbg(WCN36XX_DBG_MAC, "Key: cmd=0x%x algo:0x%x, id:%d, len:%d flags 0x%x\n", - cmd, key_conf->cipher, key_conf->keyidx, - key_conf->keylen, key_conf->flags); - wcn36xx_dbg_dump(WCN36XX_DBG_MAC, "KEY: ", - key_conf->key, - key_conf->keylen); - - switch (key_conf->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - vif_priv->encrypt_type = WCN36XX_HAL_ED_WEP40; - break; - case WLAN_CIPHER_SUITE_WEP104: - vif_priv->encrypt_type = WCN36XX_HAL_ED_WEP40; - break; - case WLAN_CIPHER_SUITE_CCMP: - vif_priv->encrypt_type = WCN36XX_HAL_ED_CCMP; - break; - case WLAN_CIPHER_SUITE_TKIP: - vif_priv->encrypt_type = WCN36XX_HAL_ED_TKIP; - break; - default: - wcn36xx_err("Unsupported key type 0x%x\n", - key_conf->cipher); - ret = -EOPNOTSUPP; - goto out; - } - - switch (cmd) { - case SET_KEY: - if (WCN36XX_HAL_ED_TKIP == vif_priv->encrypt_type) { - /* - * Supplicant is sending key in the wrong order: - * Temporal Key (16 b) - TX MIC (8 b) - RX MIC (8 b) - * but HW expects it to be in the order as described in - * IEEE 802.11 spec (see chapter 11.7) like this: - * Temporal Key (16 b) - RX MIC (8 b) - TX MIC (8 b) - */ - memcpy(key, key_conf->key, 16); - memcpy(key + 16, key_conf->key + 24, 8); - memcpy(key + 24, key_conf->key + 16, 8); - } else { - memcpy(key, key_conf->key, key_conf->keylen); - } - - if (IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags) { - sta_priv->is_data_encrypted = true; - /* Reconfigure bss with encrypt_type */ - if (NL80211_IFTYPE_STATION == vif->type) - wcn36xx_smd_config_bss(wcn, - vif, - sta, - sta->addr, - true); - - wcn36xx_smd_set_stakey(wcn, - vif_priv->encrypt_type, - key_conf->keyidx, - key_conf->keylen, - key, - get_sta_index(vif, sta_priv)); - } else { - wcn36xx_smd_set_bsskey(wcn, - vif_priv->encrypt_type, - key_conf->keyidx, - key_conf->keylen, - key); - if ((WLAN_CIPHER_SUITE_WEP40 == key_conf->cipher) || - (WLAN_CIPHER_SUITE_WEP104 == key_conf->cipher)) { - sta_priv->is_data_encrypted = true; - wcn36xx_smd_set_stakey(wcn, - vif_priv->encrypt_type, - key_conf->keyidx, - key_conf->keylen, - key, - get_sta_index(vif, sta_priv)); - } - } - break; - case DISABLE_KEY: - if (!(IEEE80211_KEY_FLAG_PAIRWISE & key_conf->flags)) { - wcn36xx_smd_remove_bsskey(wcn, - vif_priv->encrypt_type, - key_conf->keyidx); - } else { - sta_priv->is_data_encrypted = false; - /* do not remove key if disassociated */ - if (sta_priv->aid) - wcn36xx_smd_remove_stakey(wcn, - vif_priv->encrypt_type, - key_conf->keyidx, - get_sta_index(vif, sta_priv)); - } - break; - default: - wcn36xx_err("Unsupported key cmd 0x%x\n", cmd); - ret = -EOPNOTSUPP; - goto out; - break; - } - -out: - return ret; -} - -static void wcn36xx_sw_scan_start(struct ieee80211_hw *hw) -{ - struct wcn36xx *wcn = hw->priv; - - wcn36xx_smd_init_scan(wcn, HAL_SYS_MODE_SCAN); - wcn36xx_smd_start_scan(wcn); -} - -static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw) -{ - struct wcn36xx *wcn = hw->priv; - - wcn36xx_smd_end_scan(wcn); - wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN); -} - -static void wcn36xx_update_allowed_rates(struct ieee80211_sta *sta, - enum ieee80211_band band) -{ - int i, size; - u16 *rates_table; - struct wcn36xx_sta *sta_priv = (struct wcn36xx_sta *)sta->drv_priv; - u32 rates = sta->supp_rates[band]; - - memset(&sta_priv->supported_rates, 0, - sizeof(sta_priv->supported_rates)); - sta_priv->supported_rates.op_rate_mode = STA_11n; - - size = ARRAY_SIZE(sta_priv->supported_rates.dsss_rates); - rates_table = sta_priv->supported_rates.dsss_rates; - if (band == IEEE80211_BAND_2GHZ) { - for (i = 0; i < size; i++) { - if (rates & 0x01) { - rates_table[i] = wcn_2ghz_rates[i].hw_value; - rates = rates >> 1; - } - } - } - - size = ARRAY_SIZE(sta_priv->supported_rates.ofdm_rates); - rates_table = sta_priv->supported_rates.ofdm_rates; - for (i = 0; i < size; i++) { - if (rates & 0x01) { - rates_table[i] = wcn_5ghz_rates[i].hw_value; - rates = rates >> 1; - } - } - - if (sta->ht_cap.ht_supported) { - BUILD_BUG_ON(sizeof(sta->ht_cap.mcs.rx_mask) > - sizeof(sta_priv->supported_rates.supported_mcs_set)); - memcpy(sta_priv->supported_rates.supported_mcs_set, - sta->ht_cap.mcs.rx_mask, - sizeof(sta->ht_cap.mcs.rx_mask)); - } -} -void wcn36xx_set_default_rates(struct wcn36xx_hal_supported_rates *rates) -{ - u16 ofdm_rates[WCN36XX_HAL_NUM_OFDM_RATES] = { - HW_RATE_INDEX_6MBPS, - HW_RATE_INDEX_9MBPS, - HW_RATE_INDEX_12MBPS, - HW_RATE_INDEX_18MBPS, - HW_RATE_INDEX_24MBPS, - HW_RATE_INDEX_36MBPS, - HW_RATE_INDEX_48MBPS, - HW_RATE_INDEX_54MBPS - }; - u16 dsss_rates[WCN36XX_HAL_NUM_DSSS_RATES] = { - HW_RATE_INDEX_1MBPS, - HW_RATE_INDEX_2MBPS, - HW_RATE_INDEX_5_5MBPS, - HW_RATE_INDEX_11MBPS - }; - - rates->op_rate_mode = STA_11n; - memcpy(rates->dsss_rates, dsss_rates, - sizeof(*dsss_rates) * WCN36XX_HAL_NUM_DSSS_RATES); - memcpy(rates->ofdm_rates, ofdm_rates, - sizeof(*ofdm_rates) * WCN36XX_HAL_NUM_OFDM_RATES); - rates->supported_mcs_set[0] = 0xFF; -} -static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changed) -{ - struct wcn36xx *wcn = hw->priv; - struct sk_buff *skb = NULL; - u16 tim_off, tim_len; - enum wcn36xx_hal_link_state link_state; - struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; - - wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss info changed vif %p changed 0x%08x\n", - vif, changed); - - if (changed & BSS_CHANGED_BEACON_INFO) { - wcn36xx_dbg(WCN36XX_DBG_MAC, - "mac bss changed dtim period %d\n", - bss_conf->dtim_period); - - vif_priv->dtim_period = bss_conf->dtim_period; - } - - if (changed & BSS_CHANGED_PS) { - wcn36xx_dbg(WCN36XX_DBG_MAC, - "mac bss PS set %d\n", - bss_conf->ps); - if (bss_conf->ps) { - wcn36xx_pmc_enter_bmps_state(wcn, vif); - } else { - wcn36xx_pmc_exit_bmps_state(wcn, vif); - } - } - - if (changed & BSS_CHANGED_BSSID) { - wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss changed_bssid %pM\n", - bss_conf->bssid); - - if (!is_zero_ether_addr(bss_conf->bssid)) { - vif_priv->is_joining = true; - vif_priv->bss_index = 0xff; - wcn36xx_smd_join(wcn, bss_conf->bssid, - vif->addr, WCN36XX_HW_CHANNEL(wcn)); - wcn36xx_smd_config_bss(wcn, vif, NULL, - bss_conf->bssid, false); - } else { - vif_priv->is_joining = false; - wcn36xx_smd_delete_bss(wcn, vif); - } - } - - if (changed & BSS_CHANGED_SSID) { - wcn36xx_dbg(WCN36XX_DBG_MAC, - "mac bss changed ssid\n"); - wcn36xx_dbg_dump(WCN36XX_DBG_MAC, "ssid ", - bss_conf->ssid, bss_conf->ssid_len); - - vif_priv->ssid.length = bss_conf->ssid_len; - memcpy(&vif_priv->ssid.ssid, - bss_conf->ssid, - bss_conf->ssid_len); - } - - if (changed & BSS_CHANGED_ASSOC) { - vif_priv->is_joining = false; - if (bss_conf->assoc) { - struct ieee80211_sta *sta; - struct wcn36xx_sta *sta_priv; - - wcn36xx_dbg(WCN36XX_DBG_MAC, - "mac assoc bss %pM vif %pM AID=%d\n", - bss_conf->bssid, - vif->addr, - bss_conf->aid); - - rcu_read_lock(); - sta = ieee80211_find_sta(vif, bss_conf->bssid); - if (!sta) { - wcn36xx_err("sta %pM is not found\n", - bss_conf->bssid); - rcu_read_unlock(); - goto out; - } - sta_priv = (struct wcn36xx_sta *)sta->drv_priv; - - wcn36xx_update_allowed_rates(sta, WCN36XX_BAND(wcn)); - - wcn36xx_smd_set_link_st(wcn, bss_conf->bssid, - vif->addr, - WCN36XX_HAL_LINK_POSTASSOC_STATE); - wcn36xx_smd_config_bss(wcn, vif, sta, - bss_conf->bssid, - true); - sta_priv->aid = bss_conf->aid; - /* - * config_sta must be called from because this is the - * place where AID is available. - */ - wcn36xx_smd_config_sta(wcn, vif, sta); - rcu_read_unlock(); - } else { - wcn36xx_dbg(WCN36XX_DBG_MAC, - "disassociated bss %pM vif %pM AID=%d\n", - bss_conf->bssid, - vif->addr, - bss_conf->aid); - wcn36xx_smd_set_link_st(wcn, - bss_conf->bssid, - vif->addr, - WCN36XX_HAL_LINK_IDLE_STATE); - } - } - - if (changed & BSS_CHANGED_AP_PROBE_RESP) { - wcn36xx_dbg(WCN36XX_DBG_MAC, "mac bss changed ap probe resp\n"); - skb = ieee80211_proberesp_get(hw, vif); - if (!skb) { - wcn36xx_err("failed to alloc probereq skb\n"); - goto out; - } - - wcn36xx_smd_update_proberesp_tmpl(wcn, vif, skb); - dev_kfree_skb(skb); - } - - if (changed & BSS_CHANGED_BEACON_ENABLED) { - wcn36xx_dbg(WCN36XX_DBG_MAC, - "mac bss changed beacon enabled %d\n", - bss_conf->enable_beacon); - - if (bss_conf->enable_beacon) { - vif_priv->bss_index = 0xff; - wcn36xx_smd_config_bss(wcn, vif, NULL, - vif->addr, false); - skb = ieee80211_beacon_get_tim(hw, vif, &tim_off, - &tim_len); - if (!skb) { - wcn36xx_err("failed to alloc beacon skb\n"); - goto out; - } - wcn36xx_smd_send_beacon(wcn, vif, skb, tim_off, 0); - dev_kfree_skb(skb); - - if (vif->type == NL80211_IFTYPE_ADHOC || - vif->type == NL80211_IFTYPE_MESH_POINT) - link_state = WCN36XX_HAL_LINK_IBSS_STATE; - else - link_state = WCN36XX_HAL_LINK_AP_STATE; - - wcn36xx_smd_set_link_st(wcn, vif->addr, vif->addr, - link_state); - } else { - wcn36xx_smd_set_link_st(wcn, vif->addr, vif->addr, - WCN36XX_HAL_LINK_IDLE_STATE); - wcn36xx_smd_delete_bss(wcn, vif); - } - } -out: - return; -} - -/* this is required when using IEEE80211_HW_HAS_RATE_CONTROL */ -static int wcn36xx_set_rts_threshold(struct ieee80211_hw *hw, u32 value) -{ - struct wcn36xx *wcn = hw->priv; - wcn36xx_dbg(WCN36XX_DBG_MAC, "mac set RTS threshold %d\n", value); - - wcn36xx_smd_update_cfg(wcn, WCN36XX_HAL_CFG_RTS_THRESHOLD, value); - return 0; -} - -static void wcn36xx_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct wcn36xx *wcn = hw->priv; - struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; - wcn36xx_dbg(WCN36XX_DBG_MAC, "mac remove interface vif %p\n", vif); - - list_del(&vif_priv->list); - wcn36xx_smd_delete_sta_self(wcn, vif->addr); -} - -static int wcn36xx_add_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct wcn36xx *wcn = hw->priv; - struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; - - wcn36xx_dbg(WCN36XX_DBG_MAC, "mac add interface vif %p type %d\n", - vif, vif->type); - - if (!(NL80211_IFTYPE_STATION == vif->type || - NL80211_IFTYPE_AP == vif->type || - NL80211_IFTYPE_ADHOC == vif->type || - NL80211_IFTYPE_MESH_POINT == vif->type)) { - wcn36xx_warn("Unsupported interface type requested: %d\n", - vif->type); - return -EOPNOTSUPP; - } - - list_add(&vif_priv->list, &wcn->vif_list); - wcn36xx_smd_add_sta_self(wcn, vif); - - return 0; -} - -static int wcn36xx_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct wcn36xx *wcn = hw->priv; - struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; - struct wcn36xx_sta *sta_priv = (struct wcn36xx_sta *)sta->drv_priv; - wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta add vif %p sta %pM\n", - vif, sta->addr); - - vif_priv->sta = sta_priv; - sta_priv->vif = vif_priv; - /* - * For STA mode HW will be configured on BSS_CHANGED_ASSOC because - * at this stage AID is not available yet. - */ - if (NL80211_IFTYPE_STATION != vif->type) { - wcn36xx_update_allowed_rates(sta, WCN36XX_BAND(wcn)); - sta_priv->aid = sta->aid; - wcn36xx_smd_config_sta(wcn, vif, sta); - } - return 0; -} - -static int wcn36xx_sta_remove(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct wcn36xx *wcn = hw->priv; - struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; - struct wcn36xx_sta *sta_priv = (struct wcn36xx_sta *)sta->drv_priv; - - wcn36xx_dbg(WCN36XX_DBG_MAC, "mac sta remove vif %p sta %pM index %d\n", - vif, sta->addr, sta_priv->sta_index); - - wcn36xx_smd_delete_sta(wcn, sta_priv->sta_index); - vif_priv->sta = NULL; - sta_priv->vif = NULL; - return 0; -} - -#ifdef CONFIG_PM - -static int wcn36xx_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wow) -{ - struct wcn36xx *wcn = hw->priv; - - wcn36xx_dbg(WCN36XX_DBG_MAC, "mac suspend\n"); - - flush_workqueue(wcn->hal_ind_wq); - wcn36xx_smd_set_power_params(wcn, true); - return 0; -} - -static int wcn36xx_resume(struct ieee80211_hw *hw) -{ - struct wcn36xx *wcn = hw->priv; - - wcn36xx_dbg(WCN36XX_DBG_MAC, "mac resume\n"); - - flush_workqueue(wcn->hal_ind_wq); - wcn36xx_smd_set_power_params(wcn, false); - return 0; -} - -#endif - -static int wcn36xx_ampdu_action(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - enum ieee80211_ampdu_mlme_action action, - struct ieee80211_sta *sta, u16 tid, u16 *ssn, - u8 buf_size) -{ - struct wcn36xx *wcn = hw->priv; - struct wcn36xx_sta *sta_priv = NULL; - - wcn36xx_dbg(WCN36XX_DBG_MAC, "mac ampdu action action %d tid %d\n", - action, tid); - - sta_priv = (struct wcn36xx_sta *)sta->drv_priv; - - switch (action) { - case IEEE80211_AMPDU_RX_START: - sta_priv->tid = tid; - wcn36xx_smd_add_ba_session(wcn, sta, tid, ssn, 0, - get_sta_index(vif, sta_priv)); - wcn36xx_smd_add_ba(wcn); - wcn36xx_smd_trigger_ba(wcn, get_sta_index(vif, sta_priv)); - ieee80211_start_tx_ba_session(sta, tid, 0); - break; - case IEEE80211_AMPDU_RX_STOP: - wcn36xx_smd_del_ba(wcn, tid, get_sta_index(vif, sta_priv)); - break; - case IEEE80211_AMPDU_TX_START: - ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; - case IEEE80211_AMPDU_TX_OPERATIONAL: - wcn36xx_smd_add_ba_session(wcn, sta, tid, ssn, 1, - get_sta_index(vif, sta_priv)); - break; - case IEEE80211_AMPDU_TX_STOP_FLUSH: - case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: - case IEEE80211_AMPDU_TX_STOP_CONT: - ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); - break; - default: - wcn36xx_err("Unknown AMPDU action\n"); - } - - return 0; -} - -static const struct ieee80211_ops wcn36xx_ops = { - .start = wcn36xx_start, - .stop = wcn36xx_stop, - .add_interface = wcn36xx_add_interface, - .remove_interface = wcn36xx_remove_interface, -#ifdef CONFIG_PM - .suspend = wcn36xx_suspend, - .resume = wcn36xx_resume, -#endif - .config = wcn36xx_config, - .configure_filter = wcn36xx_configure_filter, - .tx = wcn36xx_tx, - .set_key = wcn36xx_set_key, - .sw_scan_start = wcn36xx_sw_scan_start, - .sw_scan_complete = wcn36xx_sw_scan_complete, - .bss_info_changed = wcn36xx_bss_info_changed, - .set_rts_threshold = wcn36xx_set_rts_threshold, - .sta_add = wcn36xx_sta_add, - .sta_remove = wcn36xx_sta_remove, - .ampdu_action = wcn36xx_ampdu_action, -}; - -static int wcn36xx_init_ieee80211(struct wcn36xx *wcn) -{ - int ret = 0; - - static const u32 cipher_suites[] = { - WLAN_CIPHER_SUITE_WEP40, - WLAN_CIPHER_SUITE_WEP104, - WLAN_CIPHER_SUITE_TKIP, - WLAN_CIPHER_SUITE_CCMP, - }; - - wcn->hw->flags = IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_HAS_RATE_CONTROL | - IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_CONNECTION_MONITOR | - IEEE80211_HW_AMPDU_AGGREGATION | - IEEE80211_HW_TIMING_BEACON_ONLY; - - wcn->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_MESH_POINT); - - wcn->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wcn_band_2ghz; - wcn->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wcn_band_5ghz; - - wcn->hw->wiphy->cipher_suites = cipher_suites; - wcn->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); - - wcn->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; - -#ifdef CONFIG_PM - wcn->hw->wiphy->wowlan = &wowlan_support; -#endif - - wcn->hw->max_listen_interval = 200; - - wcn->hw->queues = 4; - - SET_IEEE80211_DEV(wcn->hw, wcn->dev); - - wcn->hw->sta_data_size = sizeof(struct wcn36xx_sta); - wcn->hw->vif_data_size = sizeof(struct wcn36xx_vif); - - return ret; -} - -static int wcn36xx_platform_get_resources(struct wcn36xx *wcn, - struct platform_device *pdev) -{ - struct resource *res; - /* Set TX IRQ */ - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, - "wcnss_wlantx_irq"); - if (!res) { - wcn36xx_err("failed to get tx_irq\n"); - return -ENOENT; - } - wcn->tx_irq = res->start; - - /* Set RX IRQ */ - res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, - "wcnss_wlanrx_irq"); - if (!res) { - wcn36xx_err("failed to get rx_irq\n"); - return -ENOENT; - } - wcn->rx_irq = res->start; - - /* Map the memory */ - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "wcnss_mmio"); - if (!res) { - wcn36xx_err("failed to get mmio\n"); - return -ENOENT; - } - wcn->mmio = ioremap(res->start, resource_size(res)); - if (!wcn->mmio) { - wcn36xx_err("failed to map io memory\n"); - return -ENOMEM; - } - return 0; -} - -static int wcn36xx_probe(struct platform_device *pdev) -{ - struct ieee80211_hw *hw; - struct wcn36xx *wcn; - int ret; - u8 addr[ETH_ALEN]; - - wcn36xx_dbg(WCN36XX_DBG_MAC, "platform probe\n"); - - hw = ieee80211_alloc_hw(sizeof(struct wcn36xx), &wcn36xx_ops); - if (!hw) { - wcn36xx_err("failed to alloc hw\n"); - ret = -ENOMEM; - goto out_err; - } - platform_set_drvdata(pdev, hw); - wcn = hw->priv; - wcn->hw = hw; - wcn->dev = &pdev->dev; - wcn->ctrl_ops = pdev->dev.platform_data; - - mutex_init(&wcn->hal_mutex); - - if (!wcn->ctrl_ops->get_hw_mac(addr)) { - wcn36xx_info("mac address: %pM\n", addr); - SET_IEEE80211_PERM_ADDR(wcn->hw, addr); - } - - ret = wcn36xx_platform_get_resources(wcn, pdev); - if (ret) - goto out_wq; - - wcn36xx_init_ieee80211(wcn); - ret = ieee80211_register_hw(wcn->hw); - if (ret) - goto out_unmap; - - return 0; - -out_unmap: - iounmap(wcn->mmio); -out_wq: - ieee80211_free_hw(hw); -out_err: - return ret; -} -static int wcn36xx_remove(struct platform_device *pdev) -{ - struct ieee80211_hw *hw = platform_get_drvdata(pdev); - struct wcn36xx *wcn = hw->priv; - wcn36xx_dbg(WCN36XX_DBG_MAC, "platform remove\n"); - - mutex_destroy(&wcn->hal_mutex); - - ieee80211_unregister_hw(hw); - iounmap(wcn->mmio); - ieee80211_free_hw(hw); - - return 0; -} -static const struct platform_device_id wcn36xx_platform_id_table[] = { - { - .name = "wcn36xx", - .driver_data = 0 - }, - {} -}; -MODULE_DEVICE_TABLE(platform, wcn36xx_platform_id_table); - -static struct platform_driver wcn36xx_driver = { - .probe = wcn36xx_probe, - .remove = wcn36xx_remove, - .driver = { - .name = "wcn36xx", - .owner = THIS_MODULE, - }, - .id_table = wcn36xx_platform_id_table, -}; - -static int __init wcn36xx_init(void) -{ - platform_driver_register(&wcn36xx_driver); - return 0; -} -module_init(wcn36xx_init); - -static void __exit wcn36xx_exit(void) -{ - platform_driver_unregister(&wcn36xx_driver); -} -module_exit(wcn36xx_exit); - -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_AUTHOR("Eugene Krasnikov k.eugene.e@gmail.com"); -MODULE_FIRMWARE(WLAN_NV_FILE); diff --git a/drivers/net/wireless/ath/wcn36xx/pmc.c b/drivers/net/wireless/ath/wcn36xx/pmc.c deleted file mode 100644 index 28b515c..0000000 --- a/drivers/net/wireless/ath/wcn36xx/pmc.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "wcn36xx.h" - -int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn, - struct ieee80211_vif *vif) -{ - int ret = 0; - struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; - /* TODO: Make sure the TX chain clean */ - ret = wcn36xx_smd_enter_bmps(wcn, vif); - if (!ret) { - wcn36xx_dbg(WCN36XX_DBG_PMC, "Entered BMPS\n"); - vif_priv->pw_state = WCN36XX_BMPS; - } else { - /* - * One of the reasons why HW will not enter BMPS is because - * driver is trying to enter bmps before first beacon was - * received just after auth complete - */ - wcn36xx_err("Can not enter BMPS!\n"); - } - return ret; -} - -int wcn36xx_pmc_exit_bmps_state(struct wcn36xx *wcn, - struct ieee80211_vif *vif) -{ - struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; - - if (WCN36XX_BMPS != vif_priv->pw_state) { - wcn36xx_err("Not in BMPS mode, no need to exit from BMPS mode!\n"); - return -EINVAL; - } - wcn36xx_smd_exit_bmps(wcn, vif); - vif_priv->pw_state = WCN36XX_FULL_POWER; - return 0; -} - -int wcn36xx_enable_keep_alive_null_packet(struct wcn36xx *wcn, - struct ieee80211_vif *vif) -{ - wcn36xx_dbg(WCN36XX_DBG_PMC, "%s\n", __func__); - return wcn36xx_smd_keep_alive_req(wcn, vif, - WCN36XX_HAL_KEEP_ALIVE_NULL_PKT); -} diff --git a/drivers/net/wireless/ath/wcn36xx/pmc.h b/drivers/net/wireless/ath/wcn36xx/pmc.h deleted file mode 100644 index f72ed68..0000000 --- a/drivers/net/wireless/ath/wcn36xx/pmc.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _WCN36XX_PMC_H_ -#define _WCN36XX_PMC_H_ - -struct wcn36xx; - -enum wcn36xx_power_state { - WCN36XX_FULL_POWER, - WCN36XX_BMPS -}; - -int wcn36xx_pmc_enter_bmps_state(struct wcn36xx *wcn, - struct ieee80211_vif *vif); -int wcn36xx_pmc_exit_bmps_state(struct wcn36xx *wcn, - struct ieee80211_vif *vif); -int wcn36xx_enable_keep_alive_null_packet(struct wcn36xx *wcn, - struct ieee80211_vif *vif); -#endif /* _WCN36XX_PMC_H_ */ diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c deleted file mode 100644 index de9eb2c..0000000 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ /dev/null @@ -1,2129 +0,0 @@ -/* - * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/etherdevice.h> -#include <linux/firmware.h> -#include <linux/bitops.h> -#include "smd.h" - -static int put_cfg_tlv_u32(struct wcn36xx *wcn, size_t *len, u32 id, u32 value) -{ - struct wcn36xx_hal_cfg *entry; - u32 *val; - - if (*len + sizeof(*entry) + sizeof(u32) >= WCN36XX_HAL_BUF_SIZE) { - wcn36xx_err("Not enough room for TLV entry\n"); - return -ENOMEM; - } - - entry = (struct wcn36xx_hal_cfg *) (wcn->hal_buf + *len); - entry->id = id; - entry->len = sizeof(u32); - entry->pad_bytes = 0; - entry->reserve = 0; - - val = (u32 *) (entry + 1); - *val = value; - - *len += sizeof(*entry) + sizeof(u32); - - return 0; -} - -static void wcn36xx_smd_set_bss_nw_type(struct wcn36xx *wcn, - struct ieee80211_sta *sta, - struct wcn36xx_hal_config_bss_params *bss_params) -{ - if (IEEE80211_BAND_5GHZ == WCN36XX_BAND(wcn)) - bss_params->nw_type = WCN36XX_HAL_11A_NW_TYPE; - else if (sta && sta->ht_cap.ht_supported) - bss_params->nw_type = WCN36XX_HAL_11N_NW_TYPE; - else if (sta && (sta->supp_rates[IEEE80211_BAND_2GHZ] & 0x7f)) - bss_params->nw_type = WCN36XX_HAL_11G_NW_TYPE; - else - bss_params->nw_type = WCN36XX_HAL_11B_NW_TYPE; -} - -static inline u8 is_cap_supported(unsigned long caps, unsigned long flag) -{ - return caps & flag ? 1 : 0; -} -static void wcn36xx_smd_set_bss_ht_params(struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct wcn36xx_hal_config_bss_params *bss_params) -{ - if (sta && sta->ht_cap.ht_supported) { - unsigned long caps = sta->ht_cap.cap; - bss_params->ht = sta->ht_cap.ht_supported; - bss_params->tx_channel_width_set = is_cap_supported(caps, - IEEE80211_HT_CAP_SUP_WIDTH_20_40); - bss_params->lsig_tx_op_protection_full_support = - is_cap_supported(caps, - IEEE80211_HT_CAP_LSIG_TXOP_PROT); - - bss_params->ht_oper_mode = vif->bss_conf.ht_operation_mode; - bss_params->lln_non_gf_coexist = - !!(vif->bss_conf.ht_operation_mode & - IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT); - /* IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT */ - bss_params->dual_cts_protection = 0; - /* IEEE80211_HT_OP_MODE_PROTECTION_20MHZ */ - bss_params->ht20_coexist = 0; - } -} - -static void wcn36xx_smd_set_sta_ht_params(struct ieee80211_sta *sta, - struct wcn36xx_hal_config_sta_params *sta_params) -{ - if (sta->ht_cap.ht_supported) { - unsigned long caps = sta->ht_cap.cap; - sta_params->ht_capable = sta->ht_cap.ht_supported; - sta_params->tx_channel_width_set = is_cap_supported(caps, - IEEE80211_HT_CAP_SUP_WIDTH_20_40); - sta_params->lsig_txop_protection = is_cap_supported(caps, - IEEE80211_HT_CAP_LSIG_TXOP_PROT); - - sta_params->max_ampdu_size = sta->ht_cap.ampdu_factor; - sta_params->max_ampdu_density = sta->ht_cap.ampdu_density; - sta_params->max_amsdu_size = is_cap_supported(caps, - IEEE80211_HT_CAP_MAX_AMSDU); - sta_params->sgi_20Mhz = is_cap_supported(caps, - IEEE80211_HT_CAP_SGI_20); - sta_params->sgi_40mhz = is_cap_supported(caps, - IEEE80211_HT_CAP_SGI_40); - sta_params->green_field_capable = is_cap_supported(caps, - IEEE80211_HT_CAP_GRN_FLD); - sta_params->delayed_ba_support = is_cap_supported(caps, - IEEE80211_HT_CAP_DELAY_BA); - sta_params->dsss_cck_mode_40mhz = is_cap_supported(caps, - IEEE80211_HT_CAP_DSSSCCK40); - } -} - -static void wcn36xx_smd_set_sta_params(struct wcn36xx *wcn, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct wcn36xx_hal_config_sta_params *sta_params) -{ - struct wcn36xx_vif *priv_vif = (struct wcn36xx_vif *)vif->drv_priv; - struct wcn36xx_sta *priv_sta = NULL; - if (vif->type == NL80211_IFTYPE_ADHOC || - vif->type == NL80211_IFTYPE_AP || - vif->type == NL80211_IFTYPE_MESH_POINT) { - sta_params->type = 1; - sta_params->sta_index = 0xFF; - } else { - sta_params->type = 0; - sta_params->sta_index = 1; - } - - sta_params->listen_interval = WCN36XX_LISTEN_INTERVAL(wcn); - - /* - * In STA mode ieee80211_sta contains bssid and ieee80211_vif - * contains our mac address. In AP mode we are bssid so vif - * contains bssid and ieee80211_sta contains mac. - */ - if (NL80211_IFTYPE_STATION == vif->type) - memcpy(&sta_params->mac, vif->addr, ETH_ALEN); - else - memcpy(&sta_params->bssid, vif->addr, ETH_ALEN); - - sta_params->encrypt_type = priv_vif->encrypt_type; - sta_params->short_preamble_supported = - !(WCN36XX_FLAGS(wcn) & - IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE); - - sta_params->rifs_mode = 0; - sta_params->rmf = 0; - sta_params->action = 0; - sta_params->uapsd = 0; - sta_params->mimo_ps = WCN36XX_HAL_HT_MIMO_PS_STATIC; - sta_params->max_ampdu_duration = 0; - sta_params->bssid_index = priv_vif->bss_index; - sta_params->p2p = 0; - - if (sta) { - priv_sta = (struct wcn36xx_sta *)sta->drv_priv; - if (NL80211_IFTYPE_STATION == vif->type) - memcpy(&sta_params->bssid, sta->addr, ETH_ALEN); - else - memcpy(&sta_params->mac, sta->addr, ETH_ALEN); - sta_params->wmm_enabled = sta->wme; - sta_params->max_sp_len = sta->max_sp; - sta_params->aid = priv_sta->aid; - wcn36xx_smd_set_sta_ht_params(sta, sta_params); - memcpy(&sta_params->supported_rates, &priv_sta->supported_rates, - sizeof(priv_sta->supported_rates)); - } else { - wcn36xx_set_default_rates(&sta_params->supported_rates); - } -} - -static int wcn36xx_smd_send_and_wait(struct wcn36xx *wcn, size_t len) -{ - int ret = 0; - wcn36xx_dbg_dump(WCN36XX_DBG_SMD_DUMP, "HAL >>> ", wcn->hal_buf, len); - - init_completion(&wcn->hal_rsp_compl); - ret = wcn->ctrl_ops->tx(wcn->hal_buf, len); - if (ret) { - wcn36xx_err("HAL TX failed\n"); - goto out; - } - if (wait_for_completion_timeout(&wcn->hal_rsp_compl, - msecs_to_jiffies(HAL_MSG_TIMEOUT)) <= 0) { - wcn36xx_err("Timeout while waiting SMD response\n"); - ret = -ETIME; - goto out; - } -out: - return ret; -} - -#define INIT_HAL_MSG(msg_body, type) \ - do { \ - memset(&msg_body, 0, sizeof(msg_body)); \ - msg_body.header.msg_type = type; \ - msg_body.header.msg_version = WCN36XX_HAL_MSG_VERSION0; \ - msg_body.header.len = sizeof(msg_body); \ - } while (0) \ - -#define PREPARE_HAL_BUF(send_buf, msg_body) \ - do { \ - memset(send_buf, 0, msg_body.header.len); \ - memcpy(send_buf, &msg_body, sizeof(msg_body)); \ - } while (0) \ - -static int wcn36xx_smd_rsp_status_check(void *buf, size_t len) -{ - struct wcn36xx_fw_msg_status_rsp *rsp; - - if (len < sizeof(struct wcn36xx_hal_msg_header) + - sizeof(struct wcn36xx_fw_msg_status_rsp)) - return -EIO; - - rsp = (struct wcn36xx_fw_msg_status_rsp *) - (buf + sizeof(struct wcn36xx_hal_msg_header)); - - if (WCN36XX_FW_MSG_RESULT_SUCCESS != rsp->status) - return rsp->status; - - return 0; -} - -int wcn36xx_smd_load_nv(struct wcn36xx *wcn) -{ - const struct firmware *nv; - struct nv_data *nv_d; - struct wcn36xx_hal_nv_img_download_req_msg msg_body; - int fw_bytes_left; - int ret; - u16 fm_offset = 0; - - ret = request_firmware(&nv, WLAN_NV_FILE, wcn->dev); - if (ret) { - wcn36xx_err("Failed to load nv file %s: %d\n", - WLAN_NV_FILE, ret); - goto out_free_nv; - } - - nv_d = (struct nv_data *)nv->data; - INIT_HAL_MSG(msg_body, WCN36XX_HAL_DOWNLOAD_NV_REQ); - - msg_body.header.len += WCN36XX_NV_FRAGMENT_SIZE; - - msg_body.frag_number = 0; - /* hal_buf must be protected with mutex */ - mutex_lock(&wcn->hal_mutex); - - do { - fw_bytes_left = nv->size - fm_offset - 4; - if (fw_bytes_left > WCN36XX_NV_FRAGMENT_SIZE) { - msg_body.last_fragment = 0; - msg_body.nv_img_buffer_size = WCN36XX_NV_FRAGMENT_SIZE; - } else { - msg_body.last_fragment = 1; - msg_body.nv_img_buffer_size = fw_bytes_left; - - /* Do not forget update general message len */ - msg_body.header.len = sizeof(msg_body) + fw_bytes_left; - - } - - /* Add load NV request message header */ - memcpy(wcn->hal_buf, &msg_body, sizeof(msg_body)); - - /* Add NV body itself */ - memcpy(wcn->hal_buf + sizeof(msg_body), - &nv_d->table + fm_offset, - msg_body.nv_img_buffer_size); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) - goto out_unlock; - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, - wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_load_nv response failed err=%d\n", - ret); - goto out_unlock; - } - msg_body.frag_number++; - fm_offset += WCN36XX_NV_FRAGMENT_SIZE; - - } while (msg_body.last_fragment != 1); - -out_unlock: - mutex_unlock(&wcn->hal_mutex); -out_free_nv: - release_firmware(nv); - - return ret; -} - -static int wcn36xx_smd_start_rsp(struct wcn36xx *wcn, void *buf, size_t len) -{ - struct wcn36xx_hal_mac_start_rsp_msg *rsp; - - if (len < sizeof(*rsp)) - return -EIO; - - rsp = (struct wcn36xx_hal_mac_start_rsp_msg *)buf; - - if (WCN36XX_FW_MSG_RESULT_SUCCESS != rsp->start_rsp_params.status) - return -EIO; - - memcpy(wcn->crm_version, rsp->start_rsp_params.crm_version, - WCN36XX_HAL_VERSION_LENGTH); - memcpy(wcn->wlan_version, rsp->start_rsp_params.wlan_version, - WCN36XX_HAL_VERSION_LENGTH); - - /* null terminate the strings, just in case */ - wcn->crm_version[WCN36XX_HAL_VERSION_LENGTH] = '\0'; - wcn->wlan_version[WCN36XX_HAL_VERSION_LENGTH] = '\0'; - - wcn->fw_revision = rsp->start_rsp_params.version.revision; - wcn->fw_version = rsp->start_rsp_params.version.version; - wcn->fw_minor = rsp->start_rsp_params.version.minor; - wcn->fw_major = rsp->start_rsp_params.version.major; - - wcn36xx_info("firmware WLAN version '%s' and CRM version '%s'\n", - wcn->wlan_version, wcn->crm_version); - - wcn36xx_info("firmware API %u.%u.%u.%u, %u stations, %u bssids\n", - wcn->fw_major, wcn->fw_minor, - wcn->fw_version, wcn->fw_revision, - rsp->start_rsp_params.stations, - rsp->start_rsp_params.bssids); - - return 0; -} - -int wcn36xx_smd_start(struct wcn36xx *wcn) -{ - struct wcn36xx_hal_mac_start_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_START_REQ); - - msg_body.params.type = DRIVER_TYPE_PRODUCTION; - msg_body.params.len = 0; - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - wcn36xx_dbg(WCN36XX_DBG_HAL, "hal start type %d\n", - msg_body.params.type); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_start failed\n"); - goto out; - } - - ret = wcn36xx_smd_start_rsp(wcn, wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_start response failed err=%d\n", ret); - goto out; - } - -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_stop(struct wcn36xx *wcn) -{ - struct wcn36xx_hal_mac_stop_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_STOP_REQ); - - msg_body.stop_req_params.reason = HAL_STOP_TYPE_RF_KILL; - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_stop failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_stop response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode) -{ - struct wcn36xx_hal_init_scan_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_INIT_SCAN_REQ); - - msg_body.mode = mode; - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - wcn36xx_dbg(WCN36XX_DBG_HAL, "hal init scan mode %d\n", msg_body.mode); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_init_scan failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_init_scan response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_start_scan(struct wcn36xx *wcn) -{ - struct wcn36xx_hal_start_scan_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_START_SCAN_REQ); - - msg_body.scan_channel = WCN36XX_HW_CHANNEL(wcn); - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - wcn36xx_dbg(WCN36XX_DBG_HAL, "hal start scan channel %d\n", - msg_body.scan_channel); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_start_scan failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_start_scan response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_end_scan(struct wcn36xx *wcn) -{ - struct wcn36xx_hal_end_scan_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_END_SCAN_REQ); - - msg_body.scan_channel = WCN36XX_HW_CHANNEL(wcn); - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - wcn36xx_dbg(WCN36XX_DBG_HAL, "hal end scan channel %d\n", - msg_body.scan_channel); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_end_scan failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_end_scan response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_finish_scan(struct wcn36xx *wcn, - enum wcn36xx_hal_sys_mode mode) -{ - struct wcn36xx_hal_finish_scan_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_FINISH_SCAN_REQ); - - msg_body.mode = mode; - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - wcn36xx_dbg(WCN36XX_DBG_HAL, "hal finish scan mode %d\n", - msg_body.mode); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_finish_scan failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_finish_scan response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -static int wcn36xx_smd_switch_channel_rsp(void *buf, size_t len) -{ - struct wcn36xx_hal_switch_channel_rsp_msg *rsp; - int ret = 0; - - ret = wcn36xx_smd_rsp_status_check(buf, len); - if (ret) - return ret; - rsp = (struct wcn36xx_hal_switch_channel_rsp_msg *)buf; - wcn36xx_dbg(WCN36XX_DBG_HAL, "channel switched to: %d, status: %d\n", - rsp->channel_number, rsp->status); - return ret; -} - -int wcn36xx_smd_switch_channel(struct wcn36xx *wcn, - struct ieee80211_vif *vif, int ch) -{ - struct wcn36xx_hal_switch_channel_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_CH_SWITCH_REQ); - - msg_body.channel_number = (u8)ch; - msg_body.tx_mgmt_power = 0xbf; - msg_body.max_tx_power = 0xbf; - memcpy(msg_body.self_sta_mac_addr, vif->addr, ETH_ALEN); - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_switch_channel failed\n"); - goto out; - } - ret = wcn36xx_smd_switch_channel_rsp(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_switch_channel response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -static int wcn36xx_smd_update_scan_params_rsp(void *buf, size_t len) -{ - struct wcn36xx_hal_update_scan_params_resp *rsp; - - rsp = (struct wcn36xx_hal_update_scan_params_resp *)buf; - - /* Remove the PNO version bit */ - rsp->status &= (~(WCN36XX_FW_MSG_PNO_VERSION_MASK)); - - if (WCN36XX_FW_MSG_RESULT_SUCCESS != rsp->status) { - wcn36xx_warn("error response from update scan\n"); - return rsp->status; - } - - return 0; -} - -int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn) -{ - struct wcn36xx_hal_update_scan_params_req msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_UPDATE_SCAN_PARAM_REQ); - - msg_body.dot11d_enabled = 0; - msg_body.dot11d_resolved = 0; - msg_body.channel_count = 26; - msg_body.active_min_ch_time = 60; - msg_body.active_max_ch_time = 120; - msg_body.passive_min_ch_time = 60; - msg_body.passive_max_ch_time = 110; - msg_body.state = 0; - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - wcn36xx_dbg(WCN36XX_DBG_HAL, - "hal update scan params channel_count %d\n", - msg_body.channel_count); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_update_scan_params failed\n"); - goto out; - } - ret = wcn36xx_smd_update_scan_params_rsp(wcn->hal_buf, - wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_update_scan_params response failed err=%d\n", - ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -static int wcn36xx_smd_add_sta_self_rsp(struct wcn36xx *wcn, - struct ieee80211_vif *vif, - void *buf, - size_t len) -{ - struct wcn36xx_hal_add_sta_self_rsp_msg *rsp; - struct wcn36xx_vif *priv_vif = (struct wcn36xx_vif *)vif->drv_priv; - - if (len < sizeof(*rsp)) - return -EINVAL; - - rsp = (struct wcn36xx_hal_add_sta_self_rsp_msg *)buf; - - if (rsp->status != WCN36XX_FW_MSG_RESULT_SUCCESS) { - wcn36xx_warn("hal add sta self failure: %d\n", - rsp->status); - return rsp->status; - } - - wcn36xx_dbg(WCN36XX_DBG_HAL, - "hal add sta self status %d self_sta_index %d dpu_index %d\n", - rsp->status, rsp->self_sta_index, rsp->dpu_index); - - priv_vif->self_sta_index = rsp->self_sta_index; - priv_vif->self_dpu_desc_index = rsp->dpu_index; - - return 0; -} - -int wcn36xx_smd_add_sta_self(struct wcn36xx *wcn, struct ieee80211_vif *vif) -{ - struct wcn36xx_hal_add_sta_self_req msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_ADD_STA_SELF_REQ); - - memcpy(&msg_body.self_addr, vif->addr, ETH_ALEN); - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - wcn36xx_dbg(WCN36XX_DBG_HAL, - "hal add sta self self_addr %pM status %d\n", - msg_body.self_addr, msg_body.status); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_add_sta_self failed\n"); - goto out; - } - ret = wcn36xx_smd_add_sta_self_rsp(wcn, - vif, - wcn->hal_buf, - wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_add_sta_self response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_delete_sta_self(struct wcn36xx *wcn, u8 *addr) -{ - struct wcn36xx_hal_del_sta_self_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_DEL_STA_SELF_REQ); - - memcpy(&msg_body.self_addr, addr, ETH_ALEN); - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_delete_sta_self failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_delete_sta_self response failed err=%d\n", - ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_delete_sta(struct wcn36xx *wcn, u8 sta_index) -{ - struct wcn36xx_hal_delete_sta_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_DELETE_STA_REQ); - - msg_body.sta_index = sta_index; - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - wcn36xx_dbg(WCN36XX_DBG_HAL, - "hal delete sta sta_index %d\n", - msg_body.sta_index); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_delete_sta failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_delete_sta response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -static int wcn36xx_smd_join_rsp(void *buf, size_t len) -{ - struct wcn36xx_hal_join_rsp_msg *rsp; - - if (wcn36xx_smd_rsp_status_check(buf, len)) - return -EIO; - - rsp = (struct wcn36xx_hal_join_rsp_msg *)buf; - - wcn36xx_dbg(WCN36XX_DBG_HAL, - "hal rsp join status %d tx_mgmt_power %d\n", - rsp->status, rsp->tx_mgmt_power); - - return 0; -} - -int wcn36xx_smd_join(struct wcn36xx *wcn, const u8 *bssid, u8 *vif, u8 ch) -{ - struct wcn36xx_hal_join_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_JOIN_REQ); - - memcpy(&msg_body.bssid, bssid, ETH_ALEN); - memcpy(&msg_body.self_sta_mac_addr, vif, ETH_ALEN); - msg_body.channel = ch; - - if (conf_is_ht40_minus(&wcn->hw->conf)) - msg_body.secondary_channel_offset = - PHY_DOUBLE_CHANNEL_HIGH_PRIMARY; - else if (conf_is_ht40_plus(&wcn->hw->conf)) - msg_body.secondary_channel_offset = - PHY_DOUBLE_CHANNEL_LOW_PRIMARY; - else - msg_body.secondary_channel_offset = - PHY_SINGLE_CHANNEL_CENTERED; - - msg_body.link_state = WCN36XX_HAL_LINK_PREASSOC_STATE; - - msg_body.max_tx_power = 0xbf; - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - wcn36xx_dbg(WCN36XX_DBG_HAL, - "hal join req bssid %pM self_sta_mac_addr %pM channel %d link_state %d\n", - msg_body.bssid, msg_body.self_sta_mac_addr, - msg_body.channel, msg_body.link_state); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_join failed\n"); - goto out; - } - ret = wcn36xx_smd_join_rsp(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_join response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_set_link_st(struct wcn36xx *wcn, const u8 *bssid, - const u8 *sta_mac, - enum wcn36xx_hal_link_state state) -{ - struct wcn36xx_hal_set_link_state_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_SET_LINK_ST_REQ); - - memcpy(&msg_body.bssid, bssid, ETH_ALEN); - memcpy(&msg_body.self_mac_addr, sta_mac, ETH_ALEN); - msg_body.state = state; - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - wcn36xx_dbg(WCN36XX_DBG_HAL, - "hal set link state bssid %pM self_mac_addr %pM state %d\n", - msg_body.bssid, msg_body.self_mac_addr, msg_body.state); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_set_link_st failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_set_link_st response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -static void wcn36xx_smd_convert_sta_to_v1(struct wcn36xx *wcn, - const struct wcn36xx_hal_config_sta_params *orig, - struct wcn36xx_hal_config_sta_params_v1 *v1) -{ - /* convert orig to v1 format */ - memcpy(&v1->bssid, orig->bssid, ETH_ALEN); - memcpy(&v1->mac, orig->mac, ETH_ALEN); - v1->aid = orig->aid; - v1->type = orig->type; - v1->listen_interval = orig->listen_interval; - v1->ht_capable = orig->ht_capable; - - v1->max_ampdu_size = orig->max_ampdu_size; - v1->max_ampdu_density = orig->max_ampdu_density; - v1->sgi_40mhz = orig->sgi_40mhz; - v1->sgi_20Mhz = orig->sgi_20Mhz; - - memcpy(&v1->supported_rates, &orig->supported_rates, - sizeof(orig->supported_rates)); - v1->sta_index = orig->sta_index; -} - -static int wcn36xx_smd_config_sta_rsp(struct wcn36xx *wcn, - struct ieee80211_sta *sta, - void *buf, - size_t len) -{ - struct wcn36xx_hal_config_sta_rsp_msg *rsp; - struct config_sta_rsp_params *params; - struct wcn36xx_sta *sta_priv = (struct wcn36xx_sta *)sta->drv_priv; - - if (len < sizeof(*rsp)) - return -EINVAL; - - rsp = (struct wcn36xx_hal_config_sta_rsp_msg *)buf; - params = &rsp->params; - - if (params->status != WCN36XX_FW_MSG_RESULT_SUCCESS) { - wcn36xx_warn("hal config sta response failure: %d\n", - params->status); - return -EIO; - } - - sta_priv->sta_index = params->sta_index; - sta_priv->dpu_desc_index = params->dpu_index; - - wcn36xx_dbg(WCN36XX_DBG_HAL, - "hal config sta rsp status %d sta_index %d bssid_index %d p2p %d\n", - params->status, params->sta_index, params->bssid_index, - params->p2p); - - return 0; -} - -static int wcn36xx_smd_config_sta_v1(struct wcn36xx *wcn, - const struct wcn36xx_hal_config_sta_req_msg *orig) -{ - struct wcn36xx_hal_config_sta_req_msg_v1 msg_body; - struct wcn36xx_hal_config_sta_params_v1 *sta = &msg_body.sta_params; - - INIT_HAL_MSG(msg_body, WCN36XX_HAL_CONFIG_STA_REQ); - - wcn36xx_smd_convert_sta_to_v1(wcn, &orig->sta_params, - &msg_body.sta_params); - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - wcn36xx_dbg(WCN36XX_DBG_HAL, - "hal config sta v1 action %d sta_index %d bssid_index %d bssid %pM type %d mac %pM aid %d\n", - sta->action, sta->sta_index, sta->bssid_index, - sta->bssid, sta->type, sta->mac, sta->aid); - - return wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); -} - -int wcn36xx_smd_config_sta(struct wcn36xx *wcn, struct ieee80211_vif *vif, - struct ieee80211_sta *sta) -{ - struct wcn36xx_hal_config_sta_req_msg msg; - struct wcn36xx_hal_config_sta_params *sta_params; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg, WCN36XX_HAL_CONFIG_STA_REQ); - - sta_params = &msg.sta_params; - - wcn36xx_smd_set_sta_params(wcn, vif, sta, sta_params); - - if (!wcn36xx_is_fw_version(wcn, 1, 2, 2, 24)) { - ret = wcn36xx_smd_config_sta_v1(wcn, &msg); - } else { - PREPARE_HAL_BUF(wcn->hal_buf, msg); - - wcn36xx_dbg(WCN36XX_DBG_HAL, - "hal config sta action %d sta_index %d bssid_index %d bssid %pM type %d mac %pM aid %d\n", - sta_params->action, sta_params->sta_index, - sta_params->bssid_index, sta_params->bssid, - sta_params->type, sta_params->mac, sta_params->aid); - - ret = wcn36xx_smd_send_and_wait(wcn, msg.header.len); - } - if (ret) { - wcn36xx_err("Sending hal_config_sta failed\n"); - goto out; - } - ret = wcn36xx_smd_config_sta_rsp(wcn, - sta, - wcn->hal_buf, - wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_config_sta response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -static int wcn36xx_smd_config_bss_v1(struct wcn36xx *wcn, - const struct wcn36xx_hal_config_bss_req_msg *orig) -{ - struct wcn36xx_hal_config_bss_req_msg_v1 msg_body; - struct wcn36xx_hal_config_bss_params_v1 *bss = &msg_body.bss_params; - struct wcn36xx_hal_config_sta_params_v1 *sta = &bss->sta; - - INIT_HAL_MSG(msg_body, WCN36XX_HAL_CONFIG_BSS_REQ); - - /* convert orig to v1 */ - memcpy(&msg_body.bss_params.bssid, - &orig->bss_params.bssid, ETH_ALEN); - memcpy(&msg_body.bss_params.self_mac_addr, - &orig->bss_params.self_mac_addr, ETH_ALEN); - - msg_body.bss_params.bss_type = orig->bss_params.bss_type; - msg_body.bss_params.oper_mode = orig->bss_params.oper_mode; - msg_body.bss_params.nw_type = orig->bss_params.nw_type; - - msg_body.bss_params.short_slot_time_supported = - orig->bss_params.short_slot_time_supported; - msg_body.bss_params.lla_coexist = orig->bss_params.lla_coexist; - msg_body.bss_params.llb_coexist = orig->bss_params.llb_coexist; - msg_body.bss_params.llg_coexist = orig->bss_params.llg_coexist; - msg_body.bss_params.ht20_coexist = orig->bss_params.ht20_coexist; - msg_body.bss_params.lln_non_gf_coexist = - orig->bss_params.lln_non_gf_coexist; - - msg_body.bss_params.lsig_tx_op_protection_full_support = - orig->bss_params.lsig_tx_op_protection_full_support; - msg_body.bss_params.rifs_mode = orig->bss_params.rifs_mode; - msg_body.bss_params.beacon_interval = orig->bss_params.beacon_interval; - msg_body.bss_params.dtim_period = orig->bss_params.dtim_period; - msg_body.bss_params.tx_channel_width_set = - orig->bss_params.tx_channel_width_set; - msg_body.bss_params.oper_channel = orig->bss_params.oper_channel; - msg_body.bss_params.ext_channel = orig->bss_params.ext_channel; - - msg_body.bss_params.reserved = orig->bss_params.reserved; - - memcpy(&msg_body.bss_params.ssid, - &orig->bss_params.ssid, - sizeof(orig->bss_params.ssid)); - - msg_body.bss_params.action = orig->bss_params.action; - msg_body.bss_params.rateset = orig->bss_params.rateset; - msg_body.bss_params.ht = orig->bss_params.ht; - msg_body.bss_params.obss_prot_enabled = - orig->bss_params.obss_prot_enabled; - msg_body.bss_params.rmf = orig->bss_params.rmf; - msg_body.bss_params.ht_oper_mode = orig->bss_params.ht_oper_mode; - msg_body.bss_params.dual_cts_protection = - orig->bss_params.dual_cts_protection; - - msg_body.bss_params.max_probe_resp_retry_limit = - orig->bss_params.max_probe_resp_retry_limit; - msg_body.bss_params.hidden_ssid = orig->bss_params.hidden_ssid; - msg_body.bss_params.proxy_probe_resp = - orig->bss_params.proxy_probe_resp; - msg_body.bss_params.edca_params_valid = - orig->bss_params.edca_params_valid; - - memcpy(&msg_body.bss_params.acbe, - &orig->bss_params.acbe, - sizeof(orig->bss_params.acbe)); - memcpy(&msg_body.bss_params.acbk, - &orig->bss_params.acbk, - sizeof(orig->bss_params.acbk)); - memcpy(&msg_body.bss_params.acvi, - &orig->bss_params.acvi, - sizeof(orig->bss_params.acvi)); - memcpy(&msg_body.bss_params.acvo, - &orig->bss_params.acvo, - sizeof(orig->bss_params.acvo)); - - msg_body.bss_params.ext_set_sta_key_param_valid = - orig->bss_params.ext_set_sta_key_param_valid; - - memcpy(&msg_body.bss_params.ext_set_sta_key_param, - &orig->bss_params.ext_set_sta_key_param, - sizeof(orig->bss_params.acvo)); - - msg_body.bss_params.wcn36xx_hal_persona = - orig->bss_params.wcn36xx_hal_persona; - msg_body.bss_params.spectrum_mgt_enable = - orig->bss_params.spectrum_mgt_enable; - msg_body.bss_params.tx_mgmt_power = orig->bss_params.tx_mgmt_power; - msg_body.bss_params.max_tx_power = orig->bss_params.max_tx_power; - - wcn36xx_smd_convert_sta_to_v1(wcn, &orig->bss_params.sta, - &msg_body.bss_params.sta); - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - wcn36xx_dbg(WCN36XX_DBG_HAL, - "hal config bss v1 bssid %pM self_mac_addr %pM bss_type %d oper_mode %d nw_type %d\n", - bss->bssid, bss->self_mac_addr, bss->bss_type, - bss->oper_mode, bss->nw_type); - - wcn36xx_dbg(WCN36XX_DBG_HAL, - "- sta bssid %pM action %d sta_index %d bssid_index %d aid %d type %d mac %pM\n", - sta->bssid, sta->action, sta->sta_index, - sta->bssid_index, sta->aid, sta->type, sta->mac); - - return wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); -} - - -static int wcn36xx_smd_config_bss_rsp(struct wcn36xx *wcn, - struct ieee80211_vif *vif, - void *buf, - size_t len) -{ - struct wcn36xx_hal_config_bss_rsp_msg *rsp; - struct wcn36xx_hal_config_bss_rsp_params *params; - struct wcn36xx_vif *priv_vif = (struct wcn36xx_vif *)vif->drv_priv; - - if (len < sizeof(*rsp)) - return -EINVAL; - - rsp = (struct wcn36xx_hal_config_bss_rsp_msg *)buf; - params = &rsp->bss_rsp_params; - - if (params->status != WCN36XX_FW_MSG_RESULT_SUCCESS) { - wcn36xx_warn("hal config bss response failure: %d\n", - params->status); - return -EIO; - } - - wcn36xx_dbg(WCN36XX_DBG_HAL, - "hal config bss rsp status %d bss_idx %d dpu_desc_index %d" - " sta_idx %d self_idx %d bcast_idx %d mac %pM" - " power %d ucast_dpu_signature %d\n", - params->status, params->bss_index, params->dpu_desc_index, - params->bss_sta_index, params->bss_self_sta_index, - params->bss_bcast_sta_idx, params->mac, - params->tx_mgmt_power, params->ucast_dpu_signature); - - priv_vif->bss_index = params->bss_index; - - if (priv_vif->sta) { - priv_vif->sta->bss_sta_index = params->bss_sta_index; - priv_vif->sta->bss_dpu_desc_index = params->dpu_desc_index; - } - - priv_vif->ucast_dpu_signature = params->ucast_dpu_signature; - - return 0; -} - -int wcn36xx_smd_config_bss(struct wcn36xx *wcn, struct ieee80211_vif *vif, - struct ieee80211_sta *sta, const u8 *bssid, - bool update) -{ - struct wcn36xx_hal_config_bss_req_msg msg; - struct wcn36xx_hal_config_bss_params *bss; - struct wcn36xx_hal_config_sta_params *sta_params; - struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg, WCN36XX_HAL_CONFIG_BSS_REQ); - - bss = &msg.bss_params; - sta_params = &bss->sta; - - WARN_ON(is_zero_ether_addr(bssid)); - - memcpy(&bss->bssid, bssid, ETH_ALEN); - - memcpy(bss->self_mac_addr, vif->addr, ETH_ALEN); - - if (vif->type == NL80211_IFTYPE_STATION) { - bss->bss_type = WCN36XX_HAL_INFRASTRUCTURE_MODE; - - /* STA */ - bss->oper_mode = 1; - bss->wcn36xx_hal_persona = WCN36XX_HAL_STA_MODE; - } else if (vif->type == NL80211_IFTYPE_AP) { - bss->bss_type = WCN36XX_HAL_INFRA_AP_MODE; - - /* AP */ - bss->oper_mode = 0; - bss->wcn36xx_hal_persona = WCN36XX_HAL_STA_SAP_MODE; - } else if (vif->type == NL80211_IFTYPE_ADHOC || - vif->type == NL80211_IFTYPE_MESH_POINT) { - bss->bss_type = WCN36XX_HAL_IBSS_MODE; - - /* STA */ - bss->oper_mode = 1; - } else { - wcn36xx_warn("Unknown type for bss config: %d\n", vif->type); - } - - if (vif->type == NL80211_IFTYPE_STATION) - wcn36xx_smd_set_bss_nw_type(wcn, sta, bss); - else - bss->nw_type = WCN36XX_HAL_11N_NW_TYPE; - - bss->short_slot_time_supported = vif->bss_conf.use_short_slot; - bss->lla_coexist = 0; - bss->llb_coexist = 0; - bss->llg_coexist = 0; - bss->rifs_mode = 0; - bss->beacon_interval = vif->bss_conf.beacon_int; - bss->dtim_period = vif_priv->dtim_period; - - wcn36xx_smd_set_bss_ht_params(vif, sta, bss); - - bss->oper_channel = WCN36XX_HW_CHANNEL(wcn); - - if (conf_is_ht40_minus(&wcn->hw->conf)) - bss->ext_channel = IEEE80211_HT_PARAM_CHA_SEC_BELOW; - else if (conf_is_ht40_plus(&wcn->hw->conf)) - bss->ext_channel = IEEE80211_HT_PARAM_CHA_SEC_ABOVE; - else - bss->ext_channel = IEEE80211_HT_PARAM_CHA_SEC_NONE; - - bss->reserved = 0; - wcn36xx_smd_set_sta_params(wcn, vif, sta, sta_params); - - /* wcn->ssid is only valid in AP and IBSS mode */ - bss->ssid.length = vif_priv->ssid.length; - memcpy(bss->ssid.ssid, vif_priv->ssid.ssid, vif_priv->ssid.length); - - bss->obss_prot_enabled = 0; - bss->rmf = 0; - bss->max_probe_resp_retry_limit = 0; - bss->hidden_ssid = vif->bss_conf.hidden_ssid; - bss->proxy_probe_resp = 0; - bss->edca_params_valid = 0; - - /* FIXME: set acbe, acbk, acvi and acvo */ - - bss->ext_set_sta_key_param_valid = 0; - - /* FIXME: set ext_set_sta_key_param */ - - bss->spectrum_mgt_enable = 0; - bss->tx_mgmt_power = 0; - bss->max_tx_power = WCN36XX_MAX_POWER(wcn); - - bss->action = update; - - wcn36xx_dbg(WCN36XX_DBG_HAL, - "hal config bss bssid %pM self_mac_addr %pM bss_type %d oper_mode %d nw_type %d\n", - bss->bssid, bss->self_mac_addr, bss->bss_type, - bss->oper_mode, bss->nw_type); - - wcn36xx_dbg(WCN36XX_DBG_HAL, - "- sta bssid %pM action %d sta_index %d bssid_index %d aid %d type %d mac %pM\n", - sta_params->bssid, sta_params->action, - sta_params->sta_index, sta_params->bssid_index, - sta_params->aid, sta_params->type, - sta_params->mac); - - if (!wcn36xx_is_fw_version(wcn, 1, 2, 2, 24)) { - ret = wcn36xx_smd_config_bss_v1(wcn, &msg); - } else { - PREPARE_HAL_BUF(wcn->hal_buf, msg); - - ret = wcn36xx_smd_send_and_wait(wcn, msg.header.len); - } - if (ret) { - wcn36xx_err("Sending hal_config_bss failed\n"); - goto out; - } - ret = wcn36xx_smd_config_bss_rsp(wcn, - vif, - wcn->hal_buf, - wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_config_bss response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_delete_bss(struct wcn36xx *wcn, struct ieee80211_vif *vif) -{ - struct wcn36xx_hal_delete_bss_req_msg msg_body; - struct wcn36xx_vif *priv_vif = (struct wcn36xx_vif *)vif->drv_priv; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_DELETE_BSS_REQ); - - msg_body.bss_index = priv_vif->bss_index; - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - wcn36xx_dbg(WCN36XX_DBG_HAL, "hal delete bss %d\n", msg_body.bss_index); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_delete_bss failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_delete_bss response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_send_beacon(struct wcn36xx *wcn, struct ieee80211_vif *vif, - struct sk_buff *skb_beacon, u16 tim_off, - u16 p2p_off) -{ - struct wcn36xx_hal_send_beacon_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_SEND_BEACON_REQ); - - /* TODO need to find out why this is needed? */ - msg_body.beacon_length = skb_beacon->len + 6; - - if (BEACON_TEMPLATE_SIZE > msg_body.beacon_length) { - memcpy(&msg_body.beacon, &skb_beacon->len, sizeof(u32)); - memcpy(&(msg_body.beacon[4]), skb_beacon->data, - skb_beacon->len); - } else { - wcn36xx_err("Beacon is to big: beacon size=%d\n", - msg_body.beacon_length); - ret = -ENOMEM; - goto out; - } - memcpy(msg_body.bssid, vif->addr, ETH_ALEN); - - /* TODO need to find out why this is needed? */ - msg_body.tim_ie_offset = tim_off+4; - msg_body.p2p_ie_offset = p2p_off; - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - wcn36xx_dbg(WCN36XX_DBG_HAL, - "hal send beacon beacon_length %d\n", - msg_body.beacon_length); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_send_beacon failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_send_beacon response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_update_proberesp_tmpl(struct wcn36xx *wcn, - struct ieee80211_vif *vif, - struct sk_buff *skb) -{ - struct wcn36xx_hal_send_probe_resp_req_msg msg; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg, WCN36XX_HAL_UPDATE_PROBE_RSP_TEMPLATE_REQ); - - if (skb->len > BEACON_TEMPLATE_SIZE) { - wcn36xx_warn("probe response template is too big: %d\n", - skb->len); - ret = -E2BIG; - goto out; - } - - msg.probe_resp_template_len = skb->len; - memcpy(&msg.probe_resp_template, skb->data, skb->len); - - memcpy(msg.bssid, vif->addr, ETH_ALEN); - - PREPARE_HAL_BUF(wcn->hal_buf, msg); - - wcn36xx_dbg(WCN36XX_DBG_HAL, - "hal update probe rsp len %d bssid %pM\n", - msg.probe_resp_template_len, msg.bssid); - - ret = wcn36xx_smd_send_and_wait(wcn, msg.header.len); - if (ret) { - wcn36xx_err("Sending hal_update_proberesp_tmpl failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_update_proberesp_tmpl response failed err=%d\n", - ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_set_stakey(struct wcn36xx *wcn, - enum ani_ed_type enc_type, - u8 keyidx, - u8 keylen, - u8 *key, - u8 sta_index) -{ - struct wcn36xx_hal_set_sta_key_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_SET_STAKEY_REQ); - - msg_body.set_sta_key_params.sta_index = sta_index; - msg_body.set_sta_key_params.enc_type = enc_type; - - msg_body.set_sta_key_params.key[0].id = keyidx; - msg_body.set_sta_key_params.key[0].unicast = 1; - msg_body.set_sta_key_params.key[0].direction = WCN36XX_HAL_TX_RX; - msg_body.set_sta_key_params.key[0].pae_role = 0; - msg_body.set_sta_key_params.key[0].length = keylen; - memcpy(msg_body.set_sta_key_params.key[0].key, key, keylen); - msg_body.set_sta_key_params.single_tid_rc = 1; - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_set_stakey failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_set_stakey response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_set_bsskey(struct wcn36xx *wcn, - enum ani_ed_type enc_type, - u8 keyidx, - u8 keylen, - u8 *key) -{ - struct wcn36xx_hal_set_bss_key_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_SET_BSSKEY_REQ); - msg_body.bss_idx = 0; - msg_body.enc_type = enc_type; - msg_body.num_keys = 1; - msg_body.keys[0].id = keyidx; - msg_body.keys[0].unicast = 0; - msg_body.keys[0].direction = WCN36XX_HAL_RX_ONLY; - msg_body.keys[0].pae_role = 0; - msg_body.keys[0].length = keylen; - memcpy(msg_body.keys[0].key, key, keylen); - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_set_bsskey failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_set_bsskey response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_remove_stakey(struct wcn36xx *wcn, - enum ani_ed_type enc_type, - u8 keyidx, - u8 sta_index) -{ - struct wcn36xx_hal_remove_sta_key_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_RMV_STAKEY_REQ); - - msg_body.sta_idx = sta_index; - msg_body.enc_type = enc_type; - msg_body.key_id = keyidx; - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_remove_stakey failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_remove_stakey response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_remove_bsskey(struct wcn36xx *wcn, - enum ani_ed_type enc_type, - u8 keyidx) -{ - struct wcn36xx_hal_remove_bss_key_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_RMV_BSSKEY_REQ); - msg_body.bss_idx = 0; - msg_body.enc_type = enc_type; - msg_body.key_id = keyidx; - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_remove_bsskey failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_remove_bsskey response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_enter_bmps(struct wcn36xx *wcn, struct ieee80211_vif *vif) -{ - struct wcn36xx_hal_enter_bmps_req_msg msg_body; - struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_ENTER_BMPS_REQ); - - msg_body.bss_index = vif_priv->bss_index; - msg_body.tbtt = vif->bss_conf.sync_tsf; - msg_body.dtim_period = vif_priv->dtim_period; - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_enter_bmps failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_enter_bmps response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_exit_bmps(struct wcn36xx *wcn, struct ieee80211_vif *vif) -{ - struct wcn36xx_hal_enter_bmps_req_msg msg_body; - struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_EXIT_BMPS_REQ); - - msg_body.bss_index = vif_priv->bss_index; - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_exit_bmps failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_exit_bmps response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} -int wcn36xx_smd_set_power_params(struct wcn36xx *wcn, bool ignore_dtim) -{ - struct wcn36xx_hal_set_power_params_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_SET_POWER_PARAMS_REQ); - - /* - * When host is down ignore every second dtim - */ - if (ignore_dtim) { - msg_body.ignore_dtim = 1; - msg_body.dtim_period = 2; - } - msg_body.listen_interval = WCN36XX_LISTEN_INTERVAL(wcn); - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_set_power_params failed\n"); - goto out; - } - -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} -/* Notice: This function should be called after associated, or else it - * will be invalid - */ -int wcn36xx_smd_keep_alive_req(struct wcn36xx *wcn, - struct ieee80211_vif *vif, - int packet_type) -{ - struct wcn36xx_hal_keep_alive_req_msg msg_body; - struct wcn36xx_vif *vif_priv = (struct wcn36xx_vif *)vif->drv_priv; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_KEEP_ALIVE_REQ); - - if (packet_type == WCN36XX_HAL_KEEP_ALIVE_NULL_PKT) { - msg_body.bss_index = vif_priv->bss_index; - msg_body.packet_type = WCN36XX_HAL_KEEP_ALIVE_NULL_PKT; - msg_body.time_period = WCN36XX_KEEP_ALIVE_TIME_PERIOD; - } else if (packet_type == WCN36XX_HAL_KEEP_ALIVE_UNSOLICIT_ARP_RSP) { - /* TODO: it also support ARP response type */ - } else { - wcn36xx_warn("unknow keep alive packet type %d\n", packet_type); - ret = -EINVAL; - goto out; - } - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_exit_bmps failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_exit_bmps response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_dump_cmd_req(struct wcn36xx *wcn, u32 arg1, u32 arg2, - u32 arg3, u32 arg4, u32 arg5) -{ - struct wcn36xx_hal_dump_cmd_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_DUMP_COMMAND_REQ); - - msg_body.arg1 = arg1; - msg_body.arg2 = arg2; - msg_body.arg3 = arg3; - msg_body.arg4 = arg4; - msg_body.arg5 = arg5; - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_dump_cmd failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_dump_cmd response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -static inline void set_feat_caps(u32 *bitmap, - enum place_holder_in_cap_bitmap cap) -{ - int arr_idx, bit_idx; - - if (cap < 0 || cap > 127) { - wcn36xx_warn("error cap idx %d\n", cap); - return; - } - - arr_idx = cap / 32; - bit_idx = cap % 32; - bitmap[arr_idx] |= (1 << bit_idx); -} - -static inline int get_feat_caps(u32 *bitmap, - enum place_holder_in_cap_bitmap cap) -{ - int arr_idx, bit_idx; - int ret = 0; - - if (cap < 0 || cap > 127) { - wcn36xx_warn("error cap idx %d\n", cap); - return -EINVAL; - } - - arr_idx = cap / 32; - bit_idx = cap % 32; - ret = (bitmap[arr_idx] & (1 << bit_idx)) ? 1 : 0; - return ret; -} - -static inline void clear_feat_caps(u32 *bitmap, - enum place_holder_in_cap_bitmap cap) -{ - int arr_idx, bit_idx; - - if (cap < 0 || cap > 127) { - wcn36xx_warn("error cap idx %d\n", cap); - return; - } - - arr_idx = cap / 32; - bit_idx = cap % 32; - bitmap[arr_idx] &= ~(1 << bit_idx); -} - -int wcn36xx_smd_feature_caps_exchange(struct wcn36xx *wcn) -{ - struct wcn36xx_hal_feat_caps_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_FEATURE_CAPS_EXCHANGE_REQ); - - set_feat_caps(msg_body.feat_caps, STA_POWERSAVE); - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_feature_caps_exchange failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_feature_caps_exchange response failed err=%d\n", - ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_add_ba_session(struct wcn36xx *wcn, - struct ieee80211_sta *sta, - u16 tid, - u16 *ssn, - u8 direction, - u8 sta_index) -{ - struct wcn36xx_hal_add_ba_session_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_ADD_BA_SESSION_REQ); - - msg_body.sta_index = sta_index; - memcpy(&msg_body.mac_addr, sta->addr, ETH_ALEN); - msg_body.dialog_token = 0x10; - msg_body.tid = tid; - - /* Immediate BA because Delayed BA is not supported */ - msg_body.policy = 1; - msg_body.buffer_size = WCN36XX_AGGR_BUFFER_SIZE; - msg_body.timeout = 0; - if (ssn) - msg_body.ssn = *ssn; - msg_body.direction = direction; - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_add_ba_session failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_add_ba_session response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_add_ba(struct wcn36xx *wcn) -{ - struct wcn36xx_hal_add_ba_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_ADD_BA_REQ); - - msg_body.session_id = 0; - msg_body.win_size = WCN36XX_AGGR_BUFFER_SIZE; - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_add_ba failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_add_ba response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_del_ba(struct wcn36xx *wcn, u16 tid, u8 sta_index) -{ - struct wcn36xx_hal_del_ba_req_msg msg_body; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_DEL_BA_REQ); - - msg_body.sta_index = sta_index; - msg_body.tid = tid; - msg_body.direction = 0; - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_del_ba failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_del_ba response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index) -{ - struct wcn36xx_hal_trigger_ba_req_msg msg_body; - struct wcn36xx_hal_trigget_ba_req_candidate *candidate; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_TRIGGER_BA_REQ); - - msg_body.session_id = 0; - msg_body.candidate_cnt = 1; - msg_body.header.len += sizeof(*candidate); - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - candidate = (struct wcn36xx_hal_trigget_ba_req_candidate *) - (wcn->hal_buf + sizeof(msg_body)); - candidate->sta_index = sta_index; - candidate->tid_bitmap = 1; - - ret = wcn36xx_smd_send_and_wait(wcn, msg_body.header.len); - if (ret) { - wcn36xx_err("Sending hal_trigger_ba failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_trigger_ba response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} - -static int wcn36xx_smd_tx_compl_ind(struct wcn36xx *wcn, void *buf, size_t len) -{ - struct wcn36xx_hal_tx_compl_ind_msg *rsp = buf; - - if (len != sizeof(*rsp)) { - wcn36xx_warn("Bad TX complete indication\n"); - return -EIO; - } - - wcn36xx_dxe_tx_ack_ind(wcn, rsp->status); - - return 0; -} - -static int wcn36xx_smd_missed_beacon_ind(struct wcn36xx *wcn, - void *buf, - size_t len) -{ - struct wcn36xx_hal_missed_beacon_ind_msg *rsp = buf; - struct ieee80211_vif *vif = NULL; - struct wcn36xx_vif *tmp; - - /* Old FW does not have bss index */ - if (wcn36xx_is_fw_version(wcn, 1, 2, 2, 24)) { - list_for_each_entry(tmp, &wcn->vif_list, list) { - wcn36xx_dbg(WCN36XX_DBG_HAL, "beacon missed bss_index %d\n", - tmp->bss_index); - vif = container_of((void *)tmp, - struct ieee80211_vif, - drv_priv); - ieee80211_connection_loss(vif); - } - return 0; - } - - if (len != sizeof(*rsp)) { - wcn36xx_warn("Corrupted missed beacon indication\n"); - return -EIO; - } - - list_for_each_entry(tmp, &wcn->vif_list, list) { - if (tmp->bss_index == rsp->bss_index) { - wcn36xx_dbg(WCN36XX_DBG_HAL, "beacon missed bss_index %d\n", - rsp->bss_index); - vif = container_of((void *)tmp, - struct ieee80211_vif, - drv_priv); - ieee80211_connection_loss(vif); - return 0; - } - } - - wcn36xx_warn("BSS index %d not found\n", rsp->bss_index); - return -ENOENT; -} - -static int wcn36xx_smd_delete_sta_context_ind(struct wcn36xx *wcn, - void *buf, - size_t len) -{ - struct wcn36xx_hal_delete_sta_context_ind_msg *rsp = buf; - struct wcn36xx_vif *tmp; - struct ieee80211_sta *sta = NULL; - - if (len != sizeof(*rsp)) { - wcn36xx_warn("Corrupted delete sta indication\n"); - return -EIO; - } - - list_for_each_entry(tmp, &wcn->vif_list, list) { - if (sta && (tmp->sta->sta_index == rsp->sta_id)) { - sta = container_of((void *)tmp->sta, - struct ieee80211_sta, - drv_priv); - wcn36xx_dbg(WCN36XX_DBG_HAL, - "delete station indication %pM index %d\n", - rsp->addr2, - rsp->sta_id); - ieee80211_report_low_ack(sta, 0); - return 0; - } - } - - wcn36xx_warn("STA with addr %pM and index %d not found\n", - rsp->addr2, - rsp->sta_id); - return -ENOENT; -} - -int wcn36xx_smd_update_cfg(struct wcn36xx *wcn, u32 cfg_id, u32 value) -{ - struct wcn36xx_hal_update_cfg_req_msg msg_body, *body; - size_t len; - int ret = 0; - - mutex_lock(&wcn->hal_mutex); - INIT_HAL_MSG(msg_body, WCN36XX_HAL_UPDATE_CFG_REQ); - - PREPARE_HAL_BUF(wcn->hal_buf, msg_body); - - body = (struct wcn36xx_hal_update_cfg_req_msg *) wcn->hal_buf; - len = msg_body.header.len; - - put_cfg_tlv_u32(wcn, &len, cfg_id, value); - body->header.len = len; - body->len = len - sizeof(*body); - - ret = wcn36xx_smd_send_and_wait(wcn, body->header.len); - if (ret) { - wcn36xx_err("Sending hal_update_cfg failed\n"); - goto out; - } - ret = wcn36xx_smd_rsp_status_check(wcn->hal_buf, wcn->hal_rsp_len); - if (ret) { - wcn36xx_err("hal_update_cfg response failed err=%d\n", ret); - goto out; - } -out: - mutex_unlock(&wcn->hal_mutex); - return ret; -} -static void wcn36xx_smd_rsp_process(struct wcn36xx *wcn, void *buf, size_t len) -{ - struct wcn36xx_hal_msg_header *msg_header = buf; - struct wcn36xx_hal_ind_msg *msg_ind; - wcn36xx_dbg_dump(WCN36XX_DBG_SMD_DUMP, "SMD <<< ", buf, len); - - switch (msg_header->msg_type) { - case WCN36XX_HAL_START_RSP: - case WCN36XX_HAL_CONFIG_STA_RSP: - case WCN36XX_HAL_CONFIG_BSS_RSP: - case WCN36XX_HAL_ADD_STA_SELF_RSP: - case WCN36XX_HAL_STOP_RSP: - case WCN36XX_HAL_DEL_STA_SELF_RSP: - case WCN36XX_HAL_DELETE_STA_RSP: - case WCN36XX_HAL_INIT_SCAN_RSP: - case WCN36XX_HAL_START_SCAN_RSP: - case WCN36XX_HAL_END_SCAN_RSP: - case WCN36XX_HAL_FINISH_SCAN_RSP: - case WCN36XX_HAL_DOWNLOAD_NV_RSP: - case WCN36XX_HAL_DELETE_BSS_RSP: - case WCN36XX_HAL_SEND_BEACON_RSP: - case WCN36XX_HAL_SET_LINK_ST_RSP: - case WCN36XX_HAL_UPDATE_PROBE_RSP_TEMPLATE_RSP: - case WCN36XX_HAL_SET_BSSKEY_RSP: - case WCN36XX_HAL_SET_STAKEY_RSP: - case WCN36XX_HAL_RMV_STAKEY_RSP: - case WCN36XX_HAL_RMV_BSSKEY_RSP: - case WCN36XX_HAL_ENTER_BMPS_RSP: - case WCN36XX_HAL_SET_POWER_PARAMS_RSP: - case WCN36XX_HAL_EXIT_BMPS_RSP: - case WCN36XX_HAL_KEEP_ALIVE_RSP: - case WCN36XX_HAL_DUMP_COMMAND_RSP: - case WCN36XX_HAL_ADD_BA_SESSION_RSP: - case WCN36XX_HAL_ADD_BA_RSP: - case WCN36XX_HAL_DEL_BA_RSP: - case WCN36XX_HAL_TRIGGER_BA_RSP: - case WCN36XX_HAL_UPDATE_CFG_RSP: - case WCN36XX_HAL_JOIN_RSP: - case WCN36XX_HAL_UPDATE_SCAN_PARAM_RSP: - case WCN36XX_HAL_CH_SWITCH_RSP: - case WCN36XX_HAL_FEATURE_CAPS_EXCHANGE_RSP: - memcpy(wcn->hal_buf, buf, len); - wcn->hal_rsp_len = len; - complete(&wcn->hal_rsp_compl); - break; - - case WCN36XX_HAL_OTA_TX_COMPL_IND: - case WCN36XX_HAL_MISSED_BEACON_IND: - case WCN36XX_HAL_DELETE_STA_CONTEXT_IND: - mutex_lock(&wcn->hal_ind_mutex); - msg_ind = kmalloc(sizeof(*msg_ind), GFP_KERNEL); - msg_ind->msg_len = len; - msg_ind->msg = kmalloc(len, GFP_KERNEL); - memcpy(msg_ind->msg, buf, len); - list_add_tail(&msg_ind->list, &wcn->hal_ind_queue); - queue_work(wcn->hal_ind_wq, &wcn->hal_ind_work); - wcn36xx_dbg(WCN36XX_DBG_HAL, "indication arrived\n"); - mutex_unlock(&wcn->hal_ind_mutex); - break; - default: - wcn36xx_err("SMD_EVENT (%d) not supported\n", - msg_header->msg_type); - } -} -static void wcn36xx_ind_smd_work(struct work_struct *work) -{ - struct wcn36xx *wcn = - container_of(work, struct wcn36xx, hal_ind_work); - struct wcn36xx_hal_msg_header *msg_header; - struct wcn36xx_hal_ind_msg *hal_ind_msg; - - mutex_lock(&wcn->hal_ind_mutex); - - hal_ind_msg = list_first_entry(&wcn->hal_ind_queue, - struct wcn36xx_hal_ind_msg, - list); - - msg_header = (struct wcn36xx_hal_msg_header *)hal_ind_msg->msg; - - switch (msg_header->msg_type) { - case WCN36XX_HAL_OTA_TX_COMPL_IND: - wcn36xx_smd_tx_compl_ind(wcn, - hal_ind_msg->msg, - hal_ind_msg->msg_len); - break; - case WCN36XX_HAL_MISSED_BEACON_IND: - wcn36xx_smd_missed_beacon_ind(wcn, - hal_ind_msg->msg, - hal_ind_msg->msg_len); - break; - case WCN36XX_HAL_DELETE_STA_CONTEXT_IND: - wcn36xx_smd_delete_sta_context_ind(wcn, - hal_ind_msg->msg, - hal_ind_msg->msg_len); - break; - default: - wcn36xx_err("SMD_EVENT (%d) not supported\n", - msg_header->msg_type); - } - list_del(wcn->hal_ind_queue.next); - kfree(hal_ind_msg->msg); - kfree(hal_ind_msg); - mutex_unlock(&wcn->hal_ind_mutex); -} -int wcn36xx_smd_open(struct wcn36xx *wcn) -{ - int ret = 0; - wcn->hal_ind_wq = create_freezable_workqueue("wcn36xx_smd_ind"); - if (!wcn->hal_ind_wq) { - wcn36xx_err("failed to allocate wq\n"); - ret = -ENOMEM; - goto out; - } - INIT_WORK(&wcn->hal_ind_work, wcn36xx_ind_smd_work); - INIT_LIST_HEAD(&wcn->hal_ind_queue); - mutex_init(&wcn->hal_ind_mutex); - - ret = wcn->ctrl_ops->open(wcn, wcn36xx_smd_rsp_process); - if (ret) { - wcn36xx_err("failed to open control channel\n"); - goto free_wq; - } - - return ret; - -free_wq: - destroy_workqueue(wcn->hal_ind_wq); -out: - return ret; -} - -void wcn36xx_smd_close(struct wcn36xx *wcn) -{ - wcn->ctrl_ops->close(); - destroy_workqueue(wcn->hal_ind_wq); - mutex_destroy(&wcn->hal_ind_mutex); -} diff --git a/drivers/net/wireless/ath/wcn36xx/smd.h b/drivers/net/wireless/ath/wcn36xx/smd.h deleted file mode 100644 index e7c3901..0000000 --- a/drivers/net/wireless/ath/wcn36xx/smd.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _SMD_H_ -#define _SMD_H_ - -#include "wcn36xx.h" - -/* Max shared size is 4k but we take less.*/ -#define WCN36XX_NV_FRAGMENT_SIZE 3072 - -#define WCN36XX_HAL_BUF_SIZE 4096 - -#define HAL_MSG_TIMEOUT 200 -#define WCN36XX_SMSM_WLAN_TX_ENABLE 0x00000400 -#define WCN36XX_SMSM_WLAN_TX_RINGS_EMPTY 0x00000200 -/* The PNO version info be contained in the rsp msg */ -#define WCN36XX_FW_MSG_PNO_VERSION_MASK 0x8000 - -enum wcn36xx_fw_msg_result { - WCN36XX_FW_MSG_RESULT_SUCCESS = 0, - WCN36XX_FW_MSG_RESULT_SUCCESS_SYNC = 1, - - WCN36XX_FW_MSG_RESULT_MEM_FAIL = 5, -}; - -/******************************/ -/* SMD requests and responses */ -/******************************/ -struct wcn36xx_fw_msg_status_rsp { - u32 status; -} __packed; - -struct wcn36xx_hal_ind_msg { - struct list_head list; - u8 *msg; - size_t msg_len; -}; - -struct wcn36xx; - -int wcn36xx_smd_open(struct wcn36xx *wcn); -void wcn36xx_smd_close(struct wcn36xx *wcn); - -int wcn36xx_smd_load_nv(struct wcn36xx *wcn); -int wcn36xx_smd_start(struct wcn36xx *wcn); -int wcn36xx_smd_stop(struct wcn36xx *wcn); -int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode); -int wcn36xx_smd_start_scan(struct wcn36xx *wcn); -int wcn36xx_smd_end_scan(struct wcn36xx *wcn); -int wcn36xx_smd_finish_scan(struct wcn36xx *wcn, - enum wcn36xx_hal_sys_mode mode); -int wcn36xx_smd_update_scan_params(struct wcn36xx *wcn); -int wcn36xx_smd_add_sta_self(struct wcn36xx *wcn, struct ieee80211_vif *vif); -int wcn36xx_smd_delete_sta_self(struct wcn36xx *wcn, u8 *addr); -int wcn36xx_smd_delete_sta(struct wcn36xx *wcn, u8 sta_index); -int wcn36xx_smd_join(struct wcn36xx *wcn, const u8 *bssid, u8 *vif, u8 ch); -int wcn36xx_smd_set_link_st(struct wcn36xx *wcn, const u8 *bssid, - const u8 *sta_mac, - enum wcn36xx_hal_link_state state); -int wcn36xx_smd_config_bss(struct wcn36xx *wcn, struct ieee80211_vif *vif, - struct ieee80211_sta *sta, const u8 *bssid, - bool update); -int wcn36xx_smd_delete_bss(struct wcn36xx *wcn, struct ieee80211_vif *vif); -int wcn36xx_smd_config_sta(struct wcn36xx *wcn, struct ieee80211_vif *vif, - struct ieee80211_sta *sta); -int wcn36xx_smd_send_beacon(struct wcn36xx *wcn, struct ieee80211_vif *vif, - struct sk_buff *skb_beacon, u16 tim_off, - u16 p2p_off); -int wcn36xx_smd_switch_channel(struct wcn36xx *wcn, - struct ieee80211_vif *vif, int ch); -int wcn36xx_smd_update_proberesp_tmpl(struct wcn36xx *wcn, - struct ieee80211_vif *vif, - struct sk_buff *skb); -int wcn36xx_smd_set_stakey(struct wcn36xx *wcn, - enum ani_ed_type enc_type, - u8 keyidx, - u8 keylen, - u8 *key, - u8 sta_index); -int wcn36xx_smd_set_bsskey(struct wcn36xx *wcn, - enum ani_ed_type enc_type, - u8 keyidx, - u8 keylen, - u8 *key); -int wcn36xx_smd_remove_stakey(struct wcn36xx *wcn, - enum ani_ed_type enc_type, - u8 keyidx, - u8 sta_index); -int wcn36xx_smd_remove_bsskey(struct wcn36xx *wcn, - enum ani_ed_type enc_type, - u8 keyidx); -int wcn36xx_smd_enter_bmps(struct wcn36xx *wcn, struct ieee80211_vif *vif); -int wcn36xx_smd_exit_bmps(struct wcn36xx *wcn, struct ieee80211_vif *vif); -int wcn36xx_smd_set_power_params(struct wcn36xx *wcn, bool ignore_dtim); -int wcn36xx_smd_keep_alive_req(struct wcn36xx *wcn, - struct ieee80211_vif *vif, - int packet_type); -int wcn36xx_smd_dump_cmd_req(struct wcn36xx *wcn, u32 arg1, u32 arg2, - u32 arg3, u32 arg4, u32 arg5); -int wcn36xx_smd_feature_caps_exchange(struct wcn36xx *wcn); - -int wcn36xx_smd_add_ba_session(struct wcn36xx *wcn, - struct ieee80211_sta *sta, - u16 tid, - u16 *ssn, - u8 direction, - u8 sta_index); -int wcn36xx_smd_add_ba(struct wcn36xx *wcn); -int wcn36xx_smd_del_ba(struct wcn36xx *wcn, u16 tid, u8 sta_index); -int wcn36xx_smd_trigger_ba(struct wcn36xx *wcn, u8 sta_index); - -int wcn36xx_smd_update_cfg(struct wcn36xx *wcn, u32 cfg_id, u32 value); -#endif /* _SMD_H_ */ diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c deleted file mode 100644 index b2b60e3..0000000 --- a/drivers/net/wireless/ath/wcn36xx/txrx.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include "txrx.h" - -static inline int get_rssi0(struct wcn36xx_rx_bd *bd) -{ - return 100 - ((bd->phy_stat0 >> 24) & 0xff); -} - -int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) -{ - struct ieee80211_rx_status status; - struct ieee80211_hdr *hdr; - struct wcn36xx_rx_bd *bd; - u16 fc, sn; - - /* - * All fields must be 0, otherwise it can lead to - * unexpected consequences. - */ - memset(&status, 0, sizeof(status)); - - bd = (struct wcn36xx_rx_bd *)skb->data; - buff_to_be((u32 *)bd, sizeof(*bd)/sizeof(u32)); - wcn36xx_dbg_dump(WCN36XX_DBG_RX_DUMP, - "BD <<< ", (char *)bd, - sizeof(struct wcn36xx_rx_bd)); - - skb_put(skb, bd->pdu.mpdu_header_off + bd->pdu.mpdu_len); - skb_pull(skb, bd->pdu.mpdu_header_off); - - status.mactime = 10; - status.freq = WCN36XX_CENTER_FREQ(wcn); - status.band = WCN36XX_BAND(wcn); - status.signal = -get_rssi0(bd); - status.antenna = 1; - status.rate_idx = 1; - status.flag = 0; - status.rx_flags = 0; - status.flag |= RX_FLAG_IV_STRIPPED | - RX_FLAG_MMIC_STRIPPED | - RX_FLAG_DECRYPTED; - - wcn36xx_dbg(WCN36XX_DBG_RX, "status.flags=%x status->vendor_radiotap_len=%x\n", - status.flag, status.vendor_radiotap_len); - - memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); - - hdr = (struct ieee80211_hdr *) skb->data; - fc = __le16_to_cpu(hdr->frame_control); - sn = IEEE80211_SEQ_TO_SN(__le16_to_cpu(hdr->seq_ctrl)); - - if (ieee80211_is_beacon(hdr->frame_control)) { - wcn36xx_dbg(WCN36XX_DBG_BEACON, "beacon skb %p len %d fc %04x sn %d\n", - skb, skb->len, fc, sn); - wcn36xx_dbg_dump(WCN36XX_DBG_BEACON_DUMP, "SKB <<< ", - (char *)skb->data, skb->len); - } else { - wcn36xx_dbg(WCN36XX_DBG_RX, "rx skb %p len %d fc %04x sn %d\n", - skb, skb->len, fc, sn); - wcn36xx_dbg_dump(WCN36XX_DBG_RX_DUMP, "SKB <<< ", - (char *)skb->data, skb->len); - } - - ieee80211_rx_irqsafe(wcn->hw, skb); - - return 0; -} - -static void wcn36xx_set_tx_pdu(struct wcn36xx_tx_bd *bd, - u32 mpdu_header_len, - u32 len, - u16 tid) -{ - bd->pdu.mpdu_header_len = mpdu_header_len; - bd->pdu.mpdu_header_off = sizeof(*bd); - bd->pdu.mpdu_data_off = bd->pdu.mpdu_header_len + - bd->pdu.mpdu_header_off; - bd->pdu.mpdu_len = len; - bd->pdu.tid = tid; -} - -static inline struct wcn36xx_vif *get_vif_by_addr(struct wcn36xx *wcn, - u8 *addr) -{ - struct wcn36xx_vif *vif_priv = NULL; - struct ieee80211_vif *vif = NULL; - list_for_each_entry(vif_priv, &wcn->vif_list, list) { - vif = container_of((void *)vif_priv, - struct ieee80211_vif, - drv_priv); - if (memcmp(vif->addr, addr, ETH_ALEN) == 0) - return vif_priv; - } - wcn36xx_warn("vif %pM not found\n", addr); - return NULL; -} -static void wcn36xx_set_tx_data(struct wcn36xx_tx_bd *bd, - struct wcn36xx *wcn, - struct wcn36xx_vif **vif_priv, - struct wcn36xx_sta *sta_priv, - struct ieee80211_hdr *hdr, - bool bcast) -{ - struct ieee80211_vif *vif = NULL; - struct wcn36xx_vif *__vif_priv = NULL; - bd->bd_rate = WCN36XX_BD_RATE_DATA; - - /* - * For not unicast frames mac80211 will not set sta pointer so use - * self_sta_index instead. - */ - if (sta_priv) { - __vif_priv = sta_priv->vif; - vif = container_of((void *)__vif_priv, - struct ieee80211_vif, - drv_priv); - - if (vif->type == NL80211_IFTYPE_STATION) { - bd->sta_index = sta_priv->bss_sta_index; - bd->dpu_desc_idx = sta_priv->bss_dpu_desc_index; - } else if (vif->type == NL80211_IFTYPE_AP || - vif->type == NL80211_IFTYPE_ADHOC || - vif->type == NL80211_IFTYPE_MESH_POINT) { - bd->sta_index = sta_priv->sta_index; - bd->dpu_desc_idx = sta_priv->dpu_desc_index; - } - } else { - __vif_priv = get_vif_by_addr(wcn, hdr->addr2); - bd->sta_index = __vif_priv->self_sta_index; - bd->dpu_desc_idx = __vif_priv->self_dpu_desc_index; - } - - bd->dpu_sign = __vif_priv->ucast_dpu_signature; - - if (ieee80211_is_nullfunc(hdr->frame_control) || - (sta_priv && !sta_priv->is_data_encrypted)) - bd->dpu_ne = 1; - - if (bcast) { - bd->ub = 1; - bd->ack_policy = 1; - } - *vif_priv = __vif_priv; -} - -static void wcn36xx_set_tx_mgmt(struct wcn36xx_tx_bd *bd, - struct wcn36xx *wcn, - struct wcn36xx_vif **vif_priv, - struct ieee80211_hdr *hdr, - bool bcast) -{ - struct wcn36xx_vif *__vif_priv = - get_vif_by_addr(wcn, hdr->addr2); - bd->sta_index = __vif_priv->self_sta_index; - bd->dpu_desc_idx = __vif_priv->self_dpu_desc_index; - bd->dpu_ne = 1; - - /* default rate for unicast */ - if (ieee80211_is_mgmt(hdr->frame_control)) - bd->bd_rate = (WCN36XX_BAND(wcn) == IEEE80211_BAND_5GHZ) ? - WCN36XX_BD_RATE_CTRL : - WCN36XX_BD_RATE_MGMT; - else if (ieee80211_is_ctl(hdr->frame_control)) - bd->bd_rate = WCN36XX_BD_RATE_CTRL; - else - wcn36xx_warn("frame control type unknown\n"); - - /* - * In joining state trick hardware that probe is sent as - * unicast even if address is broadcast. - */ - if (__vif_priv->is_joining && - ieee80211_is_probe_req(hdr->frame_control)) - bcast = false; - - if (bcast) { - /* broadcast */ - bd->ub = 1; - /* No ack needed not unicast */ - bd->ack_policy = 1; - bd->queue_id = WCN36XX_TX_B_WQ_ID; - } else - bd->queue_id = WCN36XX_TX_U_WQ_ID; - *vif_priv = __vif_priv; -} - -int wcn36xx_start_tx(struct wcn36xx *wcn, - struct wcn36xx_sta *sta_priv, - struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct wcn36xx_vif *vif_priv = NULL; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - unsigned long flags; - bool is_low = ieee80211_is_data(hdr->frame_control); - bool bcast = is_broadcast_ether_addr(hdr->addr1) || - is_multicast_ether_addr(hdr->addr1); - struct wcn36xx_tx_bd *bd = wcn36xx_dxe_get_next_bd(wcn, is_low); - - if (!bd) { - /* - * TX DXE are used in pairs. One for the BD and one for the - * actual frame. The BD DXE's has a preallocated buffer while - * the skb ones does not. If this isn't true something is really - * wierd. TODO: Recover from this situation - */ - - wcn36xx_err("bd address may not be NULL for BD DXE\n"); - return -EINVAL; - } - - memset(bd, 0, sizeof(*bd)); - - wcn36xx_dbg(WCN36XX_DBG_TX, - "tx skb %p len %d fc %04x sn %d %s %s\n", - skb, skb->len, __le16_to_cpu(hdr->frame_control), - IEEE80211_SEQ_TO_SN(__le16_to_cpu(hdr->seq_ctrl)), - is_low ? "low" : "high", bcast ? "bcast" : "ucast"); - - wcn36xx_dbg_dump(WCN36XX_DBG_TX_DUMP, "", skb->data, skb->len); - - bd->dpu_rf = WCN36XX_BMU_WQ_TX; - - bd->tx_comp = info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS; - if (bd->tx_comp) { - wcn36xx_dbg(WCN36XX_DBG_DXE, "TX_ACK status requested\n"); - spin_lock_irqsave(&wcn->dxe_lock, flags); - if (wcn->tx_ack_skb) { - spin_unlock_irqrestore(&wcn->dxe_lock, flags); - wcn36xx_warn("tx_ack_skb already set\n"); - return -EINVAL; - } - - wcn->tx_ack_skb = skb; - spin_unlock_irqrestore(&wcn->dxe_lock, flags); - - /* Only one at a time is supported by fw. Stop the TX queues - * until the ack status gets back. - * - * TODO: Add watchdog in case FW does not answer - */ - ieee80211_stop_queues(wcn->hw); - } - - /* Data frames served first*/ - if (is_low) { - wcn36xx_set_tx_data(bd, wcn, &vif_priv, sta_priv, hdr, bcast); - wcn36xx_set_tx_pdu(bd, - ieee80211_is_data_qos(hdr->frame_control) ? - sizeof(struct ieee80211_qos_hdr) : - sizeof(struct ieee80211_hdr_3addr), - skb->len, sta_priv ? sta_priv->tid : 0); - } else { - /* MGMT and CTRL frames are handeld here*/ - wcn36xx_set_tx_mgmt(bd, wcn, &vif_priv, hdr, bcast); - wcn36xx_set_tx_pdu(bd, - ieee80211_is_data_qos(hdr->frame_control) ? - sizeof(struct ieee80211_qos_hdr) : - sizeof(struct ieee80211_hdr_3addr), - skb->len, WCN36XX_TID); - } - - buff_to_be((u32 *)bd, sizeof(*bd)/sizeof(u32)); - bd->tx_bd_sign = 0xbdbdbdbd; - - return wcn36xx_dxe_tx_frame(wcn, vif_priv, skb, is_low); -} diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.h b/drivers/net/wireless/ath/wcn36xx/txrx.h deleted file mode 100644 index bbfbcf8..0000000 --- a/drivers/net/wireless/ath/wcn36xx/txrx.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _TXRX_H_ -#define _TXRX_H_ - -#include <linux/etherdevice.h> -#include "wcn36xx.h" - -/* TODO describe all properties */ -#define WCN36XX_802_11_HEADER_LEN 24 -#define WCN36XX_BMU_WQ_TX 25 -#define WCN36XX_TID 7 -/* broadcast wq ID */ -#define WCN36XX_TX_B_WQ_ID 0xA -#define WCN36XX_TX_U_WQ_ID 0x9 -/* bd_rate */ -#define WCN36XX_BD_RATE_DATA 0 -#define WCN36XX_BD_RATE_MGMT 2 -#define WCN36XX_BD_RATE_CTRL 3 - -struct wcn36xx_pdu { - u32 dpu_fb:8; - u32 adu_fb:8; - u32 pdu_id:16; - - /* 0x04*/ - u32 tail_pdu_idx:16; - u32 head_pdu_idx:16; - - /* 0x08*/ - u32 pdu_count:7; - u32 mpdu_data_off:9; - u32 mpdu_header_off:8; - u32 mpdu_header_len:8; - - /* 0x0c*/ - u32 reserved4:8; - u32 tid:4; - u32 reserved3:4; - u32 mpdu_len:16; -}; - -struct wcn36xx_rx_bd { - u32 bdt:2; - u32 ft:1; - u32 dpu_ne:1; - u32 rx_key_id:3; - u32 ub:1; - u32 rmf:1; - u32 uma_bypass:1; - u32 csr11:1; - u32 reserved0:1; - u32 scan_learn:1; - u32 rx_ch:4; - u32 rtsf:1; - u32 bsf:1; - u32 a2hf:1; - u32 st_auf:1; - u32 dpu_sign:3; - u32 dpu_rf:8; - - struct wcn36xx_pdu pdu; - - /* 0x14*/ - u32 addr3:8; - u32 addr2:8; - u32 addr1:8; - u32 dpu_desc_idx:8; - - /* 0x18*/ - u32 rxp_flags:23; - u32 rate_id:9; - - u32 phy_stat0; - u32 phy_stat1; - - /* 0x24 */ - u32 rx_times; - - u32 pmi_cmd[6]; - - /* 0x40 */ - u32 reserved7:4; - u32 reorder_slot_id:6; - u32 reorder_fwd_id:6; - u32 reserved6:12; - u32 reorder_code:4; - - /* 0x44 */ - u32 exp_seq_num:12; - u32 cur_seq_num:12; - u32 fr_type_subtype:8; - - /* 0x48 */ - u32 msdu_size:16; - u32 sub_fr_id:4; - u32 proc_order:4; - u32 reserved9:4; - u32 aef:1; - u32 lsf:1; - u32 esf:1; - u32 asf:1; -}; - -struct wcn36xx_tx_bd { - u32 bdt:2; - u32 ft:1; - u32 dpu_ne:1; - u32 fw_tx_comp:1; - u32 tx_comp:1; - u32 reserved1:1; - u32 ub:1; - u32 rmf:1; - u32 reserved0:12; - u32 dpu_sign:3; - u32 dpu_rf:8; - - struct wcn36xx_pdu pdu; - - /* 0x14*/ - u32 reserved5:7; - u32 queue_id:5; - u32 bd_rate:2; - u32 ack_policy:2; - u32 sta_index:8; - u32 dpu_desc_idx:8; - - u32 tx_bd_sign; - u32 reserved6; - u32 dxe_start_time; - u32 dxe_end_time; - - /*u32 tcp_udp_start_off:10; - u32 header_cks:16; - u32 reserved7:6;*/ -}; - -struct wcn36xx_sta; -struct wcn36xx; - -int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb); -int wcn36xx_start_tx(struct wcn36xx *wcn, - struct wcn36xx_sta *sta_priv, - struct sk_buff *skb); - -#endif /* _TXRX_H_ */ diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h deleted file mode 100644 index 58b6383..0000000 --- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _WCN36XX_H_ -#define _WCN36XX_H_ - -#include <linux/completion.h> -#include <linux/printk.h> -#include <linux/spinlock.h> -#include <net/mac80211.h> - -#include "hal.h" -#include "smd.h" -#include "txrx.h" -#include "dxe.h" -#include "pmc.h" -#include "debug.h" - -#define WLAN_NV_FILE "wlan/prima/WCNSS_qcom_wlan_nv.bin" -#define WCN36XX_AGGR_BUFFER_SIZE 64 - -extern unsigned int wcn36xx_dbg_mask; - -enum wcn36xx_debug_mask { - WCN36XX_DBG_DXE = 0x00000001, - WCN36XX_DBG_DXE_DUMP = 0x00000002, - WCN36XX_DBG_SMD = 0x00000004, - WCN36XX_DBG_SMD_DUMP = 0x00000008, - WCN36XX_DBG_RX = 0x00000010, - WCN36XX_DBG_RX_DUMP = 0x00000020, - WCN36XX_DBG_TX = 0x00000040, - WCN36XX_DBG_TX_DUMP = 0x00000080, - WCN36XX_DBG_HAL = 0x00000100, - WCN36XX_DBG_HAL_DUMP = 0x00000200, - WCN36XX_DBG_MAC = 0x00000400, - WCN36XX_DBG_BEACON = 0x00000800, - WCN36XX_DBG_BEACON_DUMP = 0x00001000, - WCN36XX_DBG_PMC = 0x00002000, - WCN36XX_DBG_PMC_DUMP = 0x00004000, - WCN36XX_DBG_ANY = 0xffffffff, -}; - -#define wcn36xx_err(fmt, arg...) \ - printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg); - -#define wcn36xx_warn(fmt, arg...) \ - printk(KERN_WARNING pr_fmt("WARNING " fmt), ##arg) - -#define wcn36xx_info(fmt, arg...) \ - printk(KERN_INFO pr_fmt(fmt), ##arg) - -#define wcn36xx_dbg(mask, fmt, arg...) do { \ - if (wcn36xx_dbg_mask & mask) \ - printk(KERN_DEBUG pr_fmt(fmt), ##arg); \ -} while (0) - -#define wcn36xx_dbg_dump(mask, prefix_str, buf, len) do { \ - if (wcn36xx_dbg_mask & mask) \ - print_hex_dump(KERN_DEBUG, pr_fmt(prefix_str), \ - DUMP_PREFIX_OFFSET, 32, 1, \ - buf, len, false); \ -} while (0) - -#define WCN36XX_HW_CHANNEL(__wcn) (__wcn->hw->conf.chandef.chan->hw_value) -#define WCN36XX_BAND(__wcn) (__wcn->hw->conf.chandef.chan->band) -#define WCN36XX_CENTER_FREQ(__wcn) (__wcn->hw->conf.chandef.chan->center_freq) -#define WCN36XX_LISTEN_INTERVAL(__wcn) (__wcn->hw->conf.listen_interval) -#define WCN36XX_FLAGS(__wcn) (__wcn->hw->flags) -#define WCN36XX_MAX_POWER(__wcn) (__wcn->hw->conf.chandef.chan->max_power) - -static inline void buff_to_be(u32 *buf, size_t len) -{ - int i; - for (i = 0; i < len; i++) - buf[i] = cpu_to_be32(buf[i]); -} - -struct nv_data { - int is_valid; - u8 table; -}; - -/* Interface for platform control path - * - * @open: hook must be called when wcn36xx wants to open control channel. - * @tx: sends a buffer. - */ -struct wcn36xx_platform_ctrl_ops { - int (*open)(void *drv_priv, void *rsp_cb); - void (*close)(void); - int (*tx)(char *buf, size_t len); - int (*get_hw_mac)(u8 *addr); - int (*smsm_change_state)(u32 clear_mask, u32 set_mask); -}; - -/** - * struct wcn36xx_vif - holds VIF related fields - * - * @bss_index: bss_index is initially set to 0xFF. bss_index is received from - * HW after first config_bss call and must be used in delete_bss and - * enter/exit_bmps. - */ -struct wcn36xx_vif { - struct list_head list; - struct wcn36xx_sta *sta; - u8 dtim_period; - enum ani_ed_type encrypt_type; - bool is_joining; - struct wcn36xx_hal_mac_ssid ssid; - - /* Power management */ - enum wcn36xx_power_state pw_state; - - u8 bss_index; - u8 ucast_dpu_signature; - /* Returned from WCN36XX_HAL_ADD_STA_SELF_RSP */ - u8 self_sta_index; - u8 self_dpu_desc_index; -}; - -/** - * struct wcn36xx_sta - holds STA related fields - * - * @tid: traffic ID that is used during AMPDU and in TX BD. - * @sta_index: STA index is returned from HW after config_sta call and is - * used in both SMD channel and TX BD. - * @dpu_desc_index: DPU descriptor index is returned from HW after config_sta - * call and is used in TX BD. - * @bss_sta_index: STA index is returned from HW after config_bss call and is - * used in both SMD channel and TX BD. See table bellow when it is used. - * @bss_dpu_desc_index: DPU descriptor index is returned from HW after - * config_bss call and is used in TX BD. - * ______________________________________________ - * | | STA | AP | - * |______________|_____________|_______________| - * | TX BD |bss_sta_index| sta_index | - * |______________|_____________|_______________| - * |all SMD calls |bss_sta_index| sta_index | - * |______________|_____________|_______________| - * |smd_delete_sta| sta_index | sta_index | - * |______________|_____________|_______________| - */ -struct wcn36xx_sta { - struct wcn36xx_vif *vif; - u16 aid; - u16 tid; - u8 sta_index; - u8 dpu_desc_index; - u8 bss_sta_index; - u8 bss_dpu_desc_index; - bool is_data_encrypted; - /* Rates */ - struct wcn36xx_hal_supported_rates supported_rates; -}; -struct wcn36xx_dxe_ch; -struct wcn36xx { - struct ieee80211_hw *hw; - struct device *dev; - struct list_head vif_list; - - u8 fw_revision; - u8 fw_version; - u8 fw_minor; - u8 fw_major; - - /* extra byte for the NULL termination */ - u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1]; - u8 wlan_version[WCN36XX_HAL_VERSION_LENGTH + 1]; - - /* IRQs */ - int tx_irq; - int rx_irq; - void __iomem *mmio; - - struct wcn36xx_platform_ctrl_ops *ctrl_ops; - /* - * smd_buf must be protected with smd_mutex to garantee - * that all messages are sent one after another - */ - u8 *hal_buf; - size_t hal_rsp_len; - struct mutex hal_mutex; - struct completion hal_rsp_compl; - struct workqueue_struct *hal_ind_wq; - struct work_struct hal_ind_work; - struct mutex hal_ind_mutex; - struct list_head hal_ind_queue; - - /* DXE channels */ - struct wcn36xx_dxe_ch dxe_tx_l_ch; /* TX low */ - struct wcn36xx_dxe_ch dxe_tx_h_ch; /* TX high */ - struct wcn36xx_dxe_ch dxe_rx_l_ch; /* RX low */ - struct wcn36xx_dxe_ch dxe_rx_h_ch; /* RX high */ - - /* For synchronization of DXE resources from BH, IRQ and WQ contexts */ - spinlock_t dxe_lock; - bool queues_stopped; - - /* Memory pools */ - struct wcn36xx_dxe_mem_pool mgmt_mem_pool; - struct wcn36xx_dxe_mem_pool data_mem_pool; - - struct sk_buff *tx_ack_skb; - -#ifdef CONFIG_WCN36XX_DEBUGFS - /* Debug file system entry */ - struct wcn36xx_dfs_entry dfs; -#endif /* CONFIG_WCN36XX_DEBUGFS */ - -}; - -static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn, - u8 major, - u8 minor, - u8 version, - u8 revision) -{ - return (wcn->fw_major == major && - wcn->fw_minor == minor && - wcn->fw_version == version && - wcn->fw_revision == revision); -} -void wcn36xx_set_default_rates(struct wcn36xx_hal_supported_rates *rates); - -#endif /* _WCN36XX_H_ */ diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 5b34076..61c302a 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -316,8 +316,8 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, } conn.channel = ch - 1; - memcpy(conn.bssid, bss->bssid, ETH_ALEN); - memcpy(conn.dst_mac, bss->bssid, ETH_ALEN); + memcpy(conn.bssid, bss->bssid, 6); + memcpy(conn.dst_mac, bss->bssid, 6); /* * FW don't support scan after connection attempt */ diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index fd30cdd..0a2844c 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c @@ -250,7 +250,7 @@ int wil_reset(struct wil6210_priv *wil) /* init after reset */ wil->pending_connect_cid = -1; - reinit_completion(&wil->wmi_ready); + INIT_COMPLETION(wil->wmi_ready); /* TODO: release MAC reset */ wil6210_enable_irq(wil); diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c index eeceab3..eb1dc7a 100644 --- a/drivers/net/wireless/ath/wil6210/pcie_bus.c +++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c @@ -197,6 +197,7 @@ static void wil_pcie_remove(struct pci_dev *pdev) pci_iounmap(pdev, wil->csr); pci_release_region(pdev, 0); pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); } static DEFINE_PCI_DEVICE_TABLE(wil6210_pcie_ids) = { diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 0d950f2..b827d51 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -844,18 +844,18 @@ static netdev_tx_t start_tx(struct sk_buff *skb, struct net_device *dev) if (priv->wep_is_on) frame_ctl |= IEEE80211_FCTL_PROTECTED; if (priv->operating_mode == IW_MODE_ADHOC) { - skb_copy_from_linear_data(skb, &header.addr1, ETH_ALEN); - memcpy(&header.addr2, dev->dev_addr, ETH_ALEN); - memcpy(&header.addr3, priv->BSSID, ETH_ALEN); + skb_copy_from_linear_data(skb, &header.addr1, 6); + memcpy(&header.addr2, dev->dev_addr, 6); + memcpy(&header.addr3, priv->BSSID, 6); } else { frame_ctl |= IEEE80211_FCTL_TODS; - memcpy(&header.addr1, priv->CurrentBSSID, ETH_ALEN); - memcpy(&header.addr2, dev->dev_addr, ETH_ALEN); - skb_copy_from_linear_data(skb, &header.addr3, ETH_ALEN); + memcpy(&header.addr1, priv->CurrentBSSID, 6); + memcpy(&header.addr2, dev->dev_addr, 6); + skb_copy_from_linear_data(skb, &header.addr3, 6); } if (priv->use_wpa) - memcpy(&header.addr4, SNAP_RFC1024, ETH_ALEN); + memcpy(&header.addr4, SNAP_RFC1024, 6); header.frame_control = cpu_to_le16(frame_ctl); /* Copy the wireless header into the card */ @@ -929,11 +929,11 @@ static void fast_rx_path(struct atmel_private *priv, } } - memcpy(skbp, header->addr1, ETH_ALEN); /* destination address */ + memcpy(skbp, header->addr1, 6); /* destination address */ if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS) - memcpy(&skbp[ETH_ALEN], header->addr3, ETH_ALEN); + memcpy(&skbp[6], header->addr3, 6); else - memcpy(&skbp[ETH_ALEN], header->addr2, ETH_ALEN); /* source address */ + memcpy(&skbp[6], header->addr2, 6); /* source address */ skb->protocol = eth_type_trans(skb, priv->dev); skb->ip_summed = CHECKSUM_NONE; @@ -969,14 +969,14 @@ static void frag_rx_path(struct atmel_private *priv, u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags) { - u8 mac4[ETH_ALEN]; - u8 source[ETH_ALEN]; + u8 mac4[6]; + u8 source[6]; struct sk_buff *skb; if (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FROMDS) - memcpy(source, header->addr3, ETH_ALEN); + memcpy(source, header->addr3, 6); else - memcpy(source, header->addr2, ETH_ALEN); + memcpy(source, header->addr2, 6); rx_packet_loc += 24; /* skip header */ @@ -984,9 +984,9 @@ static void frag_rx_path(struct atmel_private *priv, msdu_size -= 4; if (frag_no == 0) { /* first fragment */ - atmel_copy_to_host(priv->dev, mac4, rx_packet_loc, ETH_ALEN); - msdu_size -= ETH_ALEN; - rx_packet_loc += ETH_ALEN; + atmel_copy_to_host(priv->dev, mac4, rx_packet_loc, 6); + msdu_size -= 6; + rx_packet_loc += 6; if (priv->do_rx_crc) crc = crc32_le(crc, mac4, 6); @@ -994,9 +994,9 @@ static void frag_rx_path(struct atmel_private *priv, priv->frag_seq = seq_no; priv->frag_no = 1; priv->frag_len = msdu_size; - memcpy(priv->frag_source, source, ETH_ALEN); - memcpy(&priv->rx_buf[ETH_ALEN], source, ETH_ALEN); - memcpy(priv->rx_buf, header->addr1, ETH_ALEN); + memcpy(priv->frag_source, source, 6); + memcpy(&priv->rx_buf[6], source, 6); + memcpy(priv->rx_buf, header->addr1, 6); atmel_copy_to_host(priv->dev, &priv->rx_buf[12], rx_packet_loc, msdu_size); @@ -1006,13 +1006,13 @@ static void frag_rx_path(struct atmel_private *priv, atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4); if ((crc ^ 0xffffffff) != netcrc) { priv->dev->stats.rx_crc_errors++; - memset(priv->frag_source, 0xff, ETH_ALEN); + memset(priv->frag_source, 0xff, 6); } } } else if (priv->frag_no == frag_no && priv->frag_seq == seq_no && - memcmp(priv->frag_source, source, ETH_ALEN) == 0) { + memcmp(priv->frag_source, source, 6) == 0) { atmel_copy_to_host(priv->dev, &priv->rx_buf[12 + priv->frag_len], rx_packet_loc, msdu_size); @@ -1024,7 +1024,7 @@ static void frag_rx_path(struct atmel_private *priv, atmel_copy_to_host(priv->dev, (void *)&netcrc, rx_packet_loc + msdu_size, 4); if ((crc ^ 0xffffffff) != netcrc) { priv->dev->stats.rx_crc_errors++; - memset(priv->frag_source, 0xff, ETH_ALEN); + memset(priv->frag_source, 0xff, 6); more_frags = 1; /* don't send broken assembly */ } } @@ -1033,7 +1033,7 @@ static void frag_rx_path(struct atmel_private *priv, priv->frag_no++; if (!more_frags) { /* last one */ - memset(priv->frag_source, 0xff, ETH_ALEN); + memset(priv->frag_source, 0xff, 6); if (!(skb = dev_alloc_skb(priv->frag_len + 14))) { priv->dev->stats.rx_dropped++; } else { @@ -1129,7 +1129,7 @@ static void rx_done_irq(struct atmel_private *priv) atmel_copy_to_host(priv->dev, (unsigned char *)&priv->rx_buf, rx_packet_loc + 24, msdu_size); /* we use the same buffer for frag reassembly and control packets */ - memset(priv->frag_source, 0xff, ETH_ALEN); + memset(priv->frag_source, 0xff, 6); if (priv->do_rx_crc) { /* last 4 octets is crc */ @@ -1557,7 +1557,7 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port, priv->last_qual = jiffies; priv->last_beacon_timestamp = 0; memset(priv->frag_source, 0xff, sizeof(priv->frag_source)); - memset(priv->BSSID, 0, ETH_ALEN); + memset(priv->BSSID, 0, 6); priv->CurrentBSSID[0] = 0xFF; /* Initialize to something invalid.... */ priv->station_was_associated = 0; @@ -1718,7 +1718,7 @@ static int atmel_get_wap(struct net_device *dev, char *extra) { struct atmel_private *priv = netdev_priv(dev); - memcpy(awrq->sa_data, priv->CurrentBSSID, ETH_ALEN); + memcpy(awrq->sa_data, priv->CurrentBSSID, 6); awrq->sa_family = ARPHRD_ETHER; return 0; @@ -2356,7 +2356,7 @@ static int atmel_get_scan(struct net_device *dev, for (i = 0; i < priv->BSS_list_entries; i++) { iwe.cmd = SIOCGIWAP; iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, ETH_ALEN); + memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6); current_ev = iwe_stream_add_event(info, current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN); @@ -2760,7 +2760,7 @@ static void atmel_enter_state(struct atmel_private *priv, int new_state) static void atmel_scan(struct atmel_private *priv, int specific_ssid) { struct { - u8 BSSID[ETH_ALEN]; + u8 BSSID[6]; u8 SSID[MAX_SSID_LENGTH]; u8 scan_type; u8 channel; @@ -2771,7 +2771,7 @@ static void atmel_scan(struct atmel_private *priv, int specific_ssid) u8 SSID_size; } cmd; - memset(cmd.BSSID, 0xff, ETH_ALEN); + memset(cmd.BSSID, 0xff, 6); if (priv->fast_scan) { cmd.SSID_size = priv->SSID_size; @@ -2816,7 +2816,7 @@ static void join(struct atmel_private *priv, int type) cmd.SSID_size = priv->SSID_size; memcpy(cmd.SSID, priv->SSID, priv->SSID_size); - memcpy(cmd.BSSID, priv->CurrentBSSID, ETH_ALEN); + memcpy(cmd.BSSID, priv->CurrentBSSID, 6); cmd.channel = (priv->channel & 0x7f); cmd.BSS_type = type; cmd.timeout = cpu_to_le16(2000); @@ -2837,7 +2837,7 @@ static void start(struct atmel_private *priv, int type) cmd.SSID_size = priv->SSID_size; memcpy(cmd.SSID, priv->SSID, priv->SSID_size); - memcpy(cmd.BSSID, priv->BSSID, ETH_ALEN); + memcpy(cmd.BSSID, priv->BSSID, 6); cmd.BSS_type = type; cmd.channel = (priv->channel & 0x7f); @@ -2883,9 +2883,9 @@ static void send_authentication_request(struct atmel_private *priv, u16 system, header.frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH); header.duration_id = cpu_to_le16(0x8000); header.seq_ctrl = 0; - memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN); - memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN); - memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN); + memcpy(header.addr1, priv->CurrentBSSID, 6); + memcpy(header.addr2, priv->dev->dev_addr, 6); + memcpy(header.addr3, priv->CurrentBSSID, 6); if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1) /* no WEP for authentication frames with TrSeqNo 1 */ @@ -2916,7 +2916,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc) struct ass_req_format { __le16 capability; __le16 listen_interval; - u8 ap[ETH_ALEN]; /* nothing after here directly accessible */ + u8 ap[6]; /* nothing after here directly accessible */ u8 ssid_el_id; u8 ssid_len; u8 ssid[MAX_SSID_LENGTH]; @@ -2930,9 +2930,9 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc) header.duration_id = cpu_to_le16(0x8000); header.seq_ctrl = 0; - memcpy(header.addr1, priv->CurrentBSSID, ETH_ALEN); - memcpy(header.addr2, priv->dev->dev_addr, ETH_ALEN); - memcpy(header.addr3, priv->CurrentBSSID, ETH_ALEN); + memcpy(header.addr1, priv->CurrentBSSID, 6); + memcpy(header.addr2, priv->dev->dev_addr, 6); + memcpy(header.addr3, priv->CurrentBSSID, 6); body.capability = cpu_to_le16(WLAN_CAPABILITY_ESS); if (priv->wep_is_on) @@ -2944,7 +2944,7 @@ static void send_association_request(struct atmel_private *priv, int is_reassoc) /* current AP address - only in reassoc frame */ if (is_reassoc) { - memcpy(body.ap, priv->CurrentBSSID, ETH_ALEN); + memcpy(body.ap, priv->CurrentBSSID, 6); ssid_el_p = &body.ssid_el_id; bodysize = 18 + priv->SSID_size; } else { @@ -3021,7 +3021,7 @@ static void store_bss_info(struct atmel_private *priv, int i, index; for (index = -1, i = 0; i < priv->BSS_list_entries; i++) - if (memcmp(bss, priv->BSSinfo[i].BSSID, ETH_ALEN) == 0) + if (memcmp(bss, priv->BSSinfo[i].BSSID, 6) == 0) index = i; /* If we process a probe and an entry from this BSS exists @@ -3032,7 +3032,7 @@ static void store_bss_info(struct atmel_private *priv, if (priv->BSS_list_entries == MAX_BSS_ENTRIES) return; index = priv->BSS_list_entries++; - memcpy(priv->BSSinfo[index].BSSID, bss, ETH_ALEN); + memcpy(priv->BSSinfo[index].BSSID, bss, 6); priv->BSSinfo[index].RSSI = rssi; } else { if (rssi > priv->BSSinfo[index].RSSI) @@ -3212,7 +3212,7 @@ static void associate(struct atmel_private *priv, u16 frame_len, u16 subtype) if (subtype == IEEE80211_STYPE_REASSOC_RESP && status != WLAN_STATUS_ASSOC_DENIED_RATES && status != WLAN_STATUS_CAPS_UNSUPPORTED && - priv->ReAssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) { + priv->AssociationRequestRetryCnt < MAX_ASSOCIATION_RETRIES) { mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES); priv->ReAssociationRequestRetryCnt++; send_association_request(priv, 1); @@ -3235,7 +3235,7 @@ static void atmel_join_bss(struct atmel_private *priv, int bss_index) { struct bss_info *bss = &priv->BSSinfo[bss_index]; - memcpy(priv->CurrentBSSID, bss->BSSID, ETH_ALEN); + memcpy(priv->CurrentBSSID, bss->BSSID, 6); memcpy(priv->SSID, bss->SSID, priv->SSID_size = bss->SSIDsize); /* The WPA stuff cares about the current AP address */ @@ -3767,7 +3767,7 @@ static int probe_atmel_card(struct net_device *dev) 0x00, 0x04, 0x25, 0x00, 0x00, 0x00 }; printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name); - memcpy(dev->dev_addr, default_mac, ETH_ALEN); + memcpy(dev->dev_addr, default_mac, 6); } } @@ -3819,7 +3819,7 @@ static void build_wpa_mib(struct atmel_private *priv) struct { /* NB this is matched to the hardware, don't change. */ u8 cipher_default_key_value[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE]; - u8 receiver_address[ETH_ALEN]; + u8 receiver_address[6]; u8 wep_is_on; u8 default_key; /* 0..3 */ u8 group_key; @@ -3837,7 +3837,7 @@ static void build_wpa_mib(struct atmel_private *priv) mib.wep_is_on = priv->wep_is_on; mib.exclude_unencrypted = priv->exclude_unencrypted; - memcpy(mib.receiver_address, priv->CurrentBSSID, ETH_ALEN); + memcpy(mib.receiver_address, priv->CurrentBSSID, 6); /* zero all the keys before adding in valid ones. */ memset(mib.cipher_default_key_value, 0, sizeof(mib.cipher_default_key_value)); diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 1d7982a..c51d2dc 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -1065,9 +1065,12 @@ static int b43_dma_set_mask(struct b43_wldev *dev, u64 mask) /* Try to set the DMA mask. If it fails, try falling back to a * lower mask, as we can always also support a lower one. */ while (1) { - err = dma_set_mask_and_coherent(dev->dev->dma_dev, mask); - if (!err) - break; + err = dma_set_mask(dev->dev->dma_dev, mask); + if (!err) { + err = dma_set_coherent_mask(dev->dev->dma_dev, mask); + if (!err) + break; + } if (mask == DMA_BIT_MASK(64)) { mask = DMA_BIT_MASK(32); fallback = true; diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 05ee7f1..7c970d3 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -164,8 +164,7 @@ static void b43_nphy_rf_ctl_override_rev7(struct b43_wldev *dev, u16 field, } en_addr = en_addrs[override][i]; - if (e) - val_addr = (i == 0) ? e->val_addr_core0 : e->val_addr_core1; + val_addr = (i == 0) ? e->val_addr_core0 : e->val_addr_core1; if (off) { b43_phy_mask(dev, en_addr, ~en_mask); diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 4ae63f4..8cb206a 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c @@ -278,7 +278,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, else txhdr->phy_rate = b43_plcp_get_ratecode_cck(rate); txhdr->mac_frame_ctl = wlhdr->frame_control; - memcpy(txhdr->tx_receiver, wlhdr->addr1, ETH_ALEN); + memcpy(txhdr->tx_receiver, wlhdr->addr1, 6); /* Calculate duration for fallback rate */ if ((rate_fb == rate) || diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index b2ed179..42eb26c 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c @@ -806,9 +806,12 @@ static int b43legacy_dma_set_mask(struct b43legacy_wldev *dev, u64 mask) /* Try to set the DMA mask. If it fails, try falling back to a * lower mask, as we can always also support a lower one. */ while (1) { - err = dma_set_mask_and_coherent(dev->dev->dma_dev, mask); - if (!err) - break; + err = dma_set_mask(dev->dev->dma_dev, mask); + if (!err) { + err = dma_set_coherent_mask(dev->dev->dma_dev, mask); + if (!err) + break; + } if (mask == DMA_BIT_MASK(64)) { mask = DMA_BIT_MASK(32); fallback = true; diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index 86588c9..849a28c 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c @@ -215,7 +215,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value); txhdr->mac_frame_ctl = wlhdr->frame_control; - memcpy(txhdr->tx_receiver, wlhdr->addr1, ETH_ALEN); + memcpy(txhdr->tx_receiver, wlhdr->addr1, 6); /* Calculate duration for fallback rate */ if ((rate_fb->hw_value == rate) || diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 3e10b80..e13b1a6 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -26,6 +26,7 @@ #include <linux/mmc/sdio.h> #include <linux/mmc/sdio_func.h> #include <linux/mmc/card.h> +#include <linux/mmc/host.h> #include <linux/platform_data/brcmfmac-sdio.h> #include <defs.h> @@ -238,9 +239,7 @@ brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, func_num = SDIO_FUNC_1; reg_size = 4; - ret = brcmf_sdio_addrprep(sdiodev, reg_size, &addr); - if (ret) - goto done; + brcmf_sdio_addrprep(sdiodev, reg_size, &addr); } do { @@ -256,7 +255,6 @@ brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, func_num, addr, data, 4); } while (ret != 0 && retry++ < SDIOH_API_ACCESS_RETRY_LIMIT); -done: if (ret != 0) brcmf_err("failed with %d\n", ret); @@ -317,36 +315,8 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, *ret = retval; } -static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, - bool write, u32 addr, struct sk_buff *pkt) -{ - unsigned int req_sz; - - brcmf_pm_resume_wait(sdiodev, &sdiodev->request_buffer_wait); - if (brcmf_pm_resume_error(sdiodev)) - return -EIO; - - /* Single skb use the standard mmc interface */ - req_sz = pkt->len + 3; - req_sz &= (uint)~3; - - if (write) - return sdio_memcpy_toio(sdiodev->func[fn], addr, - ((u8 *)(pkt->data)), - req_sz); - else if (fn == 1) - return sdio_memcpy_fromio(sdiodev->func[fn], - ((u8 *)(pkt->data)), - addr, req_sz); - else - /* function 2 read is FIFO operation */ - return sdio_readsb(sdiodev->func[fn], - ((u8 *)(pkt->data)), addr, - req_sz); -} - /** - * brcmf_sdio_sglist_rw - SDIO interface function for block data access + * brcmf_sdio_buffrw - SDIO interface function for block data access * @sdiodev: brcmfmac sdio device * @fn: SDIO function number * @write: direction flag @@ -357,13 +327,12 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, * stack for block data access. It assumes that the skb passed down by the * caller has already been padded and aligned. */ -static int brcmf_sdio_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn, - bool write, u32 addr, - struct sk_buff_head *pktlist) +static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn, + bool write, u32 addr, struct sk_buff_head *pktlist) { unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset; - unsigned int max_req_sz, orig_offset, dst_offset; - unsigned short max_seg_cnt, seg_sz; + unsigned int max_blks, max_req_sz, orig_offset, dst_offset; + unsigned short max_seg_sz, seg_sz; unsigned char *pkt_data, *orig_data, *dst_data; struct sk_buff *pkt_next = NULL, *local_pkt_next; struct sk_buff_head local_list, *target_list; @@ -372,6 +341,7 @@ static int brcmf_sdio_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn, struct mmc_data mmc_dat; struct sg_table st; struct scatterlist *sgl; + struct mmc_host *host; int ret = 0; if (!pktlist->qlen) @@ -381,6 +351,27 @@ static int brcmf_sdio_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn, if (brcmf_pm_resume_error(sdiodev)) return -EIO; + /* Single skb use the standard mmc interface */ + if (pktlist->qlen == 1) { + pkt_next = pktlist->next; + req_sz = pkt_next->len + 3; + req_sz &= (uint)~3; + + if (write) + return sdio_memcpy_toio(sdiodev->func[fn], addr, + ((u8 *)(pkt_next->data)), + req_sz); + else if (fn == 1) + return sdio_memcpy_fromio(sdiodev->func[fn], + ((u8 *)(pkt_next->data)), + addr, req_sz); + else + /* function 2 read is FIFO operation */ + return sdio_readsb(sdiodev->func[fn], + ((u8 *)(pkt_next->data)), addr, + req_sz); + } + target_list = pktlist; /* for host with broken sg support, prepare a page aligned list */ __skb_queue_head_init(&local_list); @@ -407,46 +398,38 @@ static int brcmf_sdio_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn, target_list = &local_list; } + host = sdiodev->func[fn]->card->host; func_blk_sz = sdiodev->func[fn]->cur_blksize; - max_req_sz = sdiodev->max_request_size; - max_seg_cnt = min_t(unsigned short, sdiodev->max_segment_count, - target_list->qlen); + /* Blocks per command is limited by host count, host transfer + * size and the maximum for IO_RW_EXTENDED of 511 blocks. + */ + max_blks = min_t(unsigned int, host->max_blk_count, 511u); + max_req_sz = min_t(unsigned int, host->max_req_size, + max_blks * func_blk_sz); + max_seg_sz = min_t(unsigned short, host->max_segs, SG_MAX_SINGLE_ALLOC); + max_seg_sz = min_t(unsigned short, max_seg_sz, target_list->qlen); seg_sz = target_list->qlen; pkt_offset = 0; pkt_next = target_list->next; - if (sg_alloc_table(&st, max_seg_cnt, GFP_KERNEL)) { + if (sg_alloc_table(&st, max_seg_sz, GFP_KERNEL)) { ret = -ENOMEM; goto exit; } - memset(&mmc_req, 0, sizeof(struct mmc_request)); - memset(&mmc_cmd, 0, sizeof(struct mmc_command)); - memset(&mmc_dat, 0, sizeof(struct mmc_data)); - - mmc_dat.sg = st.sgl; - mmc_dat.blksz = func_blk_sz; - mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; - mmc_cmd.opcode = SD_IO_RW_EXTENDED; - mmc_cmd.arg = write ? 1<<31 : 0; /* write flag */ - mmc_cmd.arg |= (fn & 0x7) << 28; /* SDIO func num */ - mmc_cmd.arg |= 1<<27; /* block mode */ - /* for function 1 the addr will be incremented */ - mmc_cmd.arg |= (fn == 1) ? 1<<26 : 0; - mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; - mmc_req.cmd = &mmc_cmd; - mmc_req.data = &mmc_dat; - while (seg_sz) { req_sz = 0; sg_cnt = 0; + memset(&mmc_req, 0, sizeof(struct mmc_request)); + memset(&mmc_cmd, 0, sizeof(struct mmc_command)); + memset(&mmc_dat, 0, sizeof(struct mmc_data)); sgl = st.sgl; /* prep sg table */ while (pkt_next != (struct sk_buff *)target_list) { pkt_data = pkt_next->data + pkt_offset; sg_data_sz = pkt_next->len - pkt_offset; - if (sg_data_sz > sdiodev->max_segment_size) - sg_data_sz = sdiodev->max_segment_size; + if (sg_data_sz > host->max_seg_size) + sg_data_sz = host->max_seg_size; if (sg_data_sz > max_req_sz - req_sz) sg_data_sz = max_req_sz - req_sz; @@ -461,7 +444,7 @@ static int brcmf_sdio_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn, pkt_next = pkt_next->next; } - if (req_sz >= max_req_sz || sg_cnt >= max_seg_cnt) + if (req_sz >= max_req_sz || sg_cnt >= max_seg_sz) break; } seg_sz -= sg_cnt; @@ -472,17 +455,27 @@ static int brcmf_sdio_sglist_rw(struct brcmf_sdio_dev *sdiodev, uint fn, ret = -ENOTBLK; goto exit; } - + mmc_dat.sg = st.sgl; mmc_dat.sg_len = sg_cnt; + mmc_dat.blksz = func_blk_sz; mmc_dat.blocks = req_sz / func_blk_sz; + mmc_dat.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; + mmc_cmd.opcode = SD_IO_RW_EXTENDED; + mmc_cmd.arg = write ? 1<<31 : 0; /* write flag */ + mmc_cmd.arg |= (fn & 0x7) << 28; /* SDIO func num */ + mmc_cmd.arg |= 1<<27; /* block mode */ + /* incrementing addr for function 1 */ + mmc_cmd.arg |= (fn == 1) ? 1<<26 : 0; mmc_cmd.arg |= (addr & 0x1FFFF) << 9; /* address */ mmc_cmd.arg |= mmc_dat.blocks & 0x1FF; /* block count */ - /* incrementing addr for function 1 */ + mmc_cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; + mmc_req.cmd = &mmc_cmd; + mmc_req.data = &mmc_dat; if (fn == 1) addr += req_sz; mmc_set_data_timeout(&mmc_dat, sdiodev->func[fn]->card); - mmc_wait_for_req(sdiodev->func[fn]->card->host, &mmc_req); + mmc_wait_for_req(host, &mmc_req); ret = mmc_cmd.error ? mmc_cmd.error : mmc_dat.error; if (ret != 0) { @@ -553,6 +546,7 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, { uint width; int err = 0; + struct sk_buff_head pkt_list; brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, pkt->len); @@ -562,17 +556,19 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, if (err) goto done; - err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, pkt); + skb_queue_head_init(&pkt_list); + skb_queue_tail(&pkt_list, pkt); + err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, &pkt_list); + skb_dequeue_tail(&pkt_list); done: return err; } int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff_head *pktq, uint totlen) + uint flags, struct sk_buff_head *pktq) { - struct sk_buff *glom_skb; - struct sk_buff *skb; + uint incr_fix; uint width; int err = 0; @@ -584,22 +580,8 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, if (err) goto done; - if (pktq->qlen == 1) - err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, pktq->next); - else if (!sdiodev->sg_support) { - glom_skb = brcmu_pkt_buf_get_skb(totlen); - if (!glom_skb) - return -ENOMEM; - err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, glom_skb); - if (err) - goto done; - - skb_queue_walk(pktq, skb) { - memcpy(skb->data, glom_skb->data, skb->len); - skb_pull(glom_skb, skb->len); - } - } else - err = brcmf_sdio_sglist_rw(sdiodev, fn, false, addr, pktq); + incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; + err = brcmf_sdio_buffrw(sdiodev, fn, false, addr, pktq); done: return err; @@ -610,7 +592,7 @@ brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, uint flags, u8 *buf, uint nbytes) { struct sk_buff *mypkt; - uint width; + struct sk_buff_head pktq; int err; mypkt = brcmu_pkt_buf_get_skb(nbytes); @@ -621,12 +603,10 @@ brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, } memcpy(mypkt->data, buf, nbytes); - - width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - err = brcmf_sdio_addrprep(sdiodev, width, &addr); - - if (!err) - err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, mypkt); + __skb_queue_head_init(&pktq); + __skb_queue_tail(&pktq, mypkt); + err = brcmf_sdcard_send_pkt(sdiodev, addr, fn, flags, &pktq); + __skb_dequeue_tail(&pktq); brcmu_pkt_buf_free_skb(mypkt); return err; @@ -637,26 +617,16 @@ int brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, uint flags, struct sk_buff_head *pktq) { - struct sk_buff *skb; uint width; - int err; + int err = 0; brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, pktq->qlen); width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; - err = brcmf_sdio_addrprep(sdiodev, width, &addr); - if (err) - return err; + brcmf_sdio_addrprep(sdiodev, width, &addr); - if (pktq->qlen == 1 || !sdiodev->sg_support) - skb_queue_walk(pktq, skb) { - err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, skb); - if (err) - break; - } - else - err = brcmf_sdio_sglist_rw(sdiodev, fn, true, addr, pktq); + err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, pktq); return err; } @@ -669,6 +639,7 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, struct sk_buff *pkt; u32 sdaddr; uint dsize; + struct sk_buff_head pkt_list; dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size); pkt = dev_alloc_skb(dsize); @@ -677,6 +648,7 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, return -EIO; } pkt->priority = 0; + skb_queue_head_init(&pkt_list); /* Determine initial transfer parameters */ sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK; @@ -704,8 +676,10 @@ brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, skb_put(pkt, dsize); if (write) memcpy(pkt->data, data, dsize); + skb_queue_tail(&pkt_list, pkt); bcmerror = brcmf_sdio_buffrw(sdiodev, SDIO_FUNC_1, write, - sdaddr, pkt); + sdaddr, &pkt_list); + skb_dequeue_tail(&pkt_list); if (bcmerror) { brcmf_err("membytes transfer failed\n"); break; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 905704e..c3462b7 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -21,7 +21,6 @@ #include <linux/mmc/sdio_func.h> #include <linux/mmc/sdio_ids.h> #include <linux/mmc/card.h> -#include <linux/mmc/host.h> #include <linux/suspend.h> #include <linux/errno.h> #include <linux/sched.h> /* request_irq() */ @@ -35,7 +34,6 @@ #include <brcmu_utils.h> #include <brcmu_wifi.h> #include "sdio_host.h" -#include "sdio_chip.h" #include "dhd_dbg.h" #include "dhd_bus.h" @@ -43,6 +41,13 @@ #define DMA_ALIGN_MASK 0x03 +#define SDIO_DEVICE_ID_BROADCOM_43143 43143 +#define SDIO_DEVICE_ID_BROADCOM_43241 0x4324 +#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 +#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 +#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 +#define SDIO_DEVICE_ID_BROADCOM_4335 0x4335 + #define SDIO_FUNC1_BLOCKSIZE 64 #define SDIO_FUNC2_BLOCKSIZE 512 @@ -53,8 +58,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = { {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)}, {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, - SDIO_DEVICE_ID_BROADCOM_4335_4339)}, + {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4335)}, { /* end: all zeroes */ }, }; MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); @@ -316,8 +320,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, int err; struct brcmf_sdio_dev *sdiodev; struct brcmf_bus *bus_if; - struct mmc_host *host; - uint max_blocks; brcmf_dbg(SDIO, "Enter\n"); brcmf_dbg(SDIO, "Class=%x\n", func->class); @@ -364,20 +366,6 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, brcmf_err("F2 error, probe failed %d...\n", err); goto fail; } - - /* - * determine host related variables after brcmf_sdio_probe() - * as func->cur_blksize is properly set and F2 init has been - * completed successfully. - */ - host = func->card->host; - sdiodev->sg_support = host->max_segs > 1; - max_blocks = min_t(uint, host->max_blk_count, 511u); - sdiodev->max_request_size = min_t(uint, host->max_req_size, - max_blocks * func->cur_blksize); - sdiodev->max_segment_count = min_t(uint, host->max_segs, - SG_MAX_SINGLE_ALLOC); - sdiodev->max_segment_size = host->max_seg_size; brcmf_dbg(SDIO, "F2 init completed...\n"); return 0; @@ -478,7 +466,7 @@ static int brcmf_sdio_pd_probe(struct platform_device *pdev) { brcmf_dbg(SDIO, "Enter\n"); - brcmfmac_sdio_pdata = dev_get_platdata(&pdev->dev); + brcmfmac_sdio_pdata = pdev->dev.platform_data; if (brcmfmac_sdio_pdata->power_on) brcmfmac_sdio_pdata->power_on(); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 899a2ad..2eb9e64 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -97,6 +97,8 @@ #define WLC_PHY_TYPE_LCN 8 #define WLC_PHY_TYPE_NULL 0xf +#define BRCMF_EVENTING_MASK_LEN 16 + #define TOE_TX_CSUM_OL 0x00000001 #define TOE_RX_CSUM_OL 0x00000002 @@ -630,29 +632,29 @@ struct brcmf_skb_reorder_data { u8 *reorder; }; -int brcmf_netdev_wait_pend8021x(struct net_device *ndev); +extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); /* Return pointer to interface name */ -char *brcmf_ifname(struct brcmf_pub *drvr, int idx); +extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx); /* Query dongle */ -int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, - void *buf, uint len); -int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, - void *buf, uint len); +extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, + uint cmd, void *buf, uint len); +extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, + void *buf, uint len); /* Remove any protocol-specific data header. */ -int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, - struct sk_buff *rxp); +extern int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx, + struct sk_buff *rxp); -int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); -struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, - char *name, u8 *mac_addr); -void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx); +extern int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); +extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, + s32 ifidx, char *name, u8 *mac_addr); +extern void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx); void brcmf_txflowblock_if(struct brcmf_if *ifp, enum brcmf_netif_stop_reason reason, bool state); -u32 brcmf_get_chip_info(struct brcmf_if *ifp); -void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, - bool success); +extern u32 brcmf_get_chip_info(struct brcmf_if *ifp); +extern void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, + bool success); #endif /* _BRCMF_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index a6eb09e..74156f8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -132,34 +132,35 @@ struct pktq *brcmf_bus_gettxq(struct brcmf_bus *bus) * interface functions from common layer */ -bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt, - int prec); +extern bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, + struct sk_buff *pkt, int prec); /* Receive frame for delivery to OS. Callee disposes of rxp. */ -void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp); +extern void brcmf_rx_frames(struct device *dev, struct sk_buff_head *rxlist); /* Indication from bus module regarding presence/insertion of dongle. */ -int brcmf_attach(uint bus_hdrlen, struct device *dev); +extern int brcmf_attach(uint bus_hdrlen, struct device *dev); /* Indication from bus module regarding removal/absence of dongle */ -void brcmf_detach(struct device *dev); +extern void brcmf_detach(struct device *dev); /* Indication from bus module that dongle should be reset */ -void brcmf_dev_reset(struct device *dev); +extern void brcmf_dev_reset(struct device *dev); /* Indication from bus module to change flow-control state */ -void brcmf_txflowblock(struct device *dev, bool state); +extern void brcmf_txflowblock(struct device *dev, bool state); /* Notify the bus has transferred the tx packet to firmware */ -void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success); +extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, + bool success); -int brcmf_bus_start(struct device *dev); +extern int brcmf_bus_start(struct device *dev); #ifdef CONFIG_BRCMFMAC_SDIO -void brcmf_sdio_exit(void); -void brcmf_sdio_init(void); -void brcmf_sdio_register(void); +extern void brcmf_sdio_exit(void); +extern void brcmf_sdio_init(void); +extern void brcmf_sdio_register(void); #endif #ifdef CONFIG_BRCMFMAC_USB -void brcmf_usb_exit(void); -void brcmf_usb_register(void); +extern void brcmf_usb_exit(void); +extern void brcmf_usb_register(void); #endif #endif /* _BRCMF_BUS_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 64e9cff..40e7f85 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -509,8 +509,9 @@ netif_rx: } } -void brcmf_rx_frame(struct device *dev, struct sk_buff *skb) +void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) { + struct sk_buff *skb, *pnext; struct brcmf_if *ifp; struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_pub *drvr = bus_if->drvr; @@ -518,24 +519,29 @@ void brcmf_rx_frame(struct device *dev, struct sk_buff *skb) u8 ifidx; int ret; - brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb); + brcmf_dbg(DATA, "Enter: %s: count=%u\n", dev_name(dev), + skb_queue_len(skb_list)); - /* process and remove protocol-specific header */ - ret = brcmf_proto_hdrpull(drvr, true, &ifidx, skb); - ifp = drvr->iflist[ifidx]; + skb_queue_walk_safe(skb_list, skb, pnext) { + skb_unlink(skb, skb_list); - if (ret || !ifp || !ifp->ndev) { - if ((ret != -ENODATA) && ifp) - ifp->stats.rx_errors++; - brcmu_pkt_buf_free_skb(skb); - return; - } + /* process and remove protocol-specific header */ + ret = brcmf_proto_hdrpull(drvr, true, &ifidx, skb); + ifp = drvr->iflist[ifidx]; - rd = (struct brcmf_skb_reorder_data *)skb->cb; - if (rd->reorder) - brcmf_rxreorder_process_info(ifp, rd->reorder, skb); - else - brcmf_netif_rx(ifp, skb); + if (ret || !ifp || !ifp->ndev) { + if ((ret != -ENODATA) && ifp) + ifp->stats.rx_errors++; + brcmu_pkt_buf_free_skb(skb); + continue; + } + + rd = (struct brcmf_skb_reorder_data *)skb->cb; + if (rd->reorder) + brcmf_rxreorder_process_info(ifp, rd->reorder, skb); + else + brcmf_netif_rx(ifp, skb); + } } void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h index 53c6e71..ef91798 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h @@ -22,21 +22,21 @@ */ /* Linkage, sets prot link and updates hdrlen in pub */ -int brcmf_proto_attach(struct brcmf_pub *drvr); +extern int brcmf_proto_attach(struct brcmf_pub *drvr); /* Unlink, frees allocated protocol memory (including brcmf_proto) */ -void brcmf_proto_detach(struct brcmf_pub *drvr); +extern void brcmf_proto_detach(struct brcmf_pub *drvr); /* Stop protocol: sync w/dongle state. */ -void brcmf_proto_stop(struct brcmf_pub *drvr); +extern void brcmf_proto_stop(struct brcmf_pub *drvr); /* Add any protocol-specific data header. * Caller must reserve prot_hdrlen prepend space. */ -void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, u8 offset, - struct sk_buff *txp); +extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, u8 offset, + struct sk_buff *txp); /* Sets dongle media info (drv_version, mac address). */ -int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); +extern int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); #endif /* _BRCMF_PROTO_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index b02953c..1aa75d5 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -275,6 +275,11 @@ struct rte_console { /* Flags for SDH calls */ #define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED) +#define BRCMF_SDIO_FW_NAME "brcm/brcmfmac-sdio.bin" +#define BRCMF_SDIO_NV_NAME "brcm/brcmfmac-sdio.txt" +MODULE_FIRMWARE(BRCMF_SDIO_FW_NAME); +MODULE_FIRMWARE(BRCMF_SDIO_NV_NAME); + #define BRCMF_IDLE_IMMEDIATE (-1) /* Enter idle immediately */ #define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change * when idle @@ -449,6 +454,9 @@ struct brcmf_sdio { struct work_struct datawork; atomic_t dpc_tskcnt; + const struct firmware *firmware; + u32 fw_ptr; + bool txoff; /* Transmit flow-controlled */ struct brcmf_sdio_count sdcnt; bool sr_enabled; /* SaveRestore enabled */ @@ -485,100 +493,6 @@ enum brcmf_sdio_frmtype { BRCMF_SDIO_FT_SUB, }; -#define BCM43143_FIRMWARE_NAME "brcm/brcmfmac43143-sdio.bin" -#define BCM43143_NVRAM_NAME "brcm/brcmfmac43143-sdio.txt" -#define BCM43241B0_FIRMWARE_NAME "brcm/brcmfmac43241b0-sdio.bin" -#define BCM43241B0_NVRAM_NAME "brcm/brcmfmac43241b0-sdio.txt" -#define BCM43241B4_FIRMWARE_NAME "brcm/brcmfmac43241b4-sdio.bin" -#define BCM43241B4_NVRAM_NAME "brcm/brcmfmac43241b4-sdio.txt" -#define BCM4329_FIRMWARE_NAME "brcm/brcmfmac4329-sdio.bin" -#define BCM4329_NVRAM_NAME "brcm/brcmfmac4329-sdio.txt" -#define BCM4330_FIRMWARE_NAME "brcm/brcmfmac4330-sdio.bin" -#define BCM4330_NVRAM_NAME "brcm/brcmfmac4330-sdio.txt" -#define BCM4334_FIRMWARE_NAME "brcm/brcmfmac4334-sdio.bin" -#define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt" -#define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin" -#define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt" - -MODULE_FIRMWARE(BCM43143_FIRMWARE_NAME); -MODULE_FIRMWARE(BCM43143_NVRAM_NAME); -MODULE_FIRMWARE(BCM43241B0_FIRMWARE_NAME); -MODULE_FIRMWARE(BCM43241B0_NVRAM_NAME); -MODULE_FIRMWARE(BCM43241B4_FIRMWARE_NAME); -MODULE_FIRMWARE(BCM43241B4_NVRAM_NAME); -MODULE_FIRMWARE(BCM4329_FIRMWARE_NAME); -MODULE_FIRMWARE(BCM4329_NVRAM_NAME); -MODULE_FIRMWARE(BCM4330_FIRMWARE_NAME); -MODULE_FIRMWARE(BCM4330_NVRAM_NAME); -MODULE_FIRMWARE(BCM4334_FIRMWARE_NAME); -MODULE_FIRMWARE(BCM4334_NVRAM_NAME); -MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME); -MODULE_FIRMWARE(BCM4335_NVRAM_NAME); - -struct brcmf_firmware_names { - u32 chipid; - u32 revmsk; - const char *bin; - const char *nv; -}; - -enum brcmf_firmware_type { - BRCMF_FIRMWARE_BIN, - BRCMF_FIRMWARE_NVRAM -}; - -#define BRCMF_FIRMWARE_NVRAM(name) \ - name ## _FIRMWARE_NAME, name ## _NVRAM_NAME - -static const struct brcmf_firmware_names brcmf_fwname_data[] = { - { BCM43143_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43143) }, - { BCM43241_CHIP_ID, 0x0000001F, BRCMF_FIRMWARE_NVRAM(BCM43241B0) }, - { BCM43241_CHIP_ID, 0xFFFFFFE0, BRCMF_FIRMWARE_NVRAM(BCM43241B4) }, - { BCM4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) }, - { BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) }, - { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) }, - { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) } -}; - - -static const struct firmware *brcmf_sdbrcm_get_fw(struct brcmf_sdio *bus, - enum brcmf_firmware_type type) -{ - const struct firmware *fw; - const char *name; - int err, i; - - for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) { - if (brcmf_fwname_data[i].chipid == bus->ci->chip && - brcmf_fwname_data[i].revmsk & BIT(bus->ci->chiprev)) { - switch (type) { - case BRCMF_FIRMWARE_BIN: - name = brcmf_fwname_data[i].bin; - break; - case BRCMF_FIRMWARE_NVRAM: - name = brcmf_fwname_data[i].nv; - break; - default: - brcmf_err("invalid firmware type (%d)\n", type); - return NULL; - } - goto found; - } - } - brcmf_err("Unknown chipid %d [%d]\n", - bus->ci->chip, bus->ci->chiprev); - return NULL; - -found: - err = request_firmware(&fw, name, &bus->sdiodev->func[2]->dev); - if ((err) || (!fw)) { - brcmf_err("fail to request firmware %s (%d)\n", name, err); - return NULL; - } - - return fw; -} - static void pkt_align(struct sk_buff *p, int len, int align) { uint datalign; @@ -1147,8 +1061,6 @@ static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header, u8 rx_seq, fc, tx_seq_max; u32 swheader; - trace_brcmf_sdpcm_hdr(false, header); - /* hw header */ len = get_unaligned_le16(header); checksum = get_unaligned_le16(header + sizeof(u16)); @@ -1271,7 +1183,6 @@ static void brcmf_sdio_hdpack(struct brcmf_sdio *bus, u8 *header, SDPCM_DOFFSET_MASK; *(((__le32 *)header) + 1) = cpu_to_le32(sw_header); *(((__le32 *)header) + 2) = 0; - trace_brcmf_sdpcm_hdr(true, header); } static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) @@ -1392,7 +1303,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) sdio_claim_host(bus->sdiodev->func[1]); errcode = brcmf_sdcard_recv_chain(bus->sdiodev, bus->sdiodev->sbwad, - SDIO_FUNC_2, F2SYNC, &bus->glom, dlen); + SDIO_FUNC_2, F2SYNC, &bus->glom); sdio_release_host(bus->sdiodev->func[1]); bus->sdcnt.f2rxdata++; @@ -1495,12 +1406,13 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) bus->glom.qlen, pfirst, pfirst->data, pfirst->len, pfirst->next, pfirst->prev); - skb_unlink(pfirst, &bus->glom); - brcmf_rx_frame(bus->sdiodev->dev, pfirst); - bus->sdcnt.rxglompkts++; } + /* sent any remaining packets up */ + if (bus->glom.qlen) + brcmf_rx_frames(bus->sdiodev->dev, &bus->glom); bus->sdcnt.rxglomframes++; + bus->sdcnt.rxglompkts += bus->glom.qlen; } return num; } @@ -1645,6 +1557,7 @@ static void brcmf_pad(struct brcmf_sdio *bus, u16 *pad, u16 *rdlen) static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) { struct sk_buff *pkt; /* Packet for event or data frames */ + struct sk_buff_head pktlist; /* needed for bus interface */ u16 pad; /* Number of pad bytes to read */ uint rxleft = 0; /* Remaining number of frames allowed */ int ret; /* Return code from calls */ @@ -1846,7 +1759,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) continue; } - brcmf_rx_frame(bus->sdiodev->dev, pkt); + skb_queue_head_init(&pktlist); + skb_queue_tail(&pktlist, pkt); + brcmf_rx_frames(bus->sdiodev->dev, &pktlist); } rxcount = maxframes - rxleft; @@ -1871,65 +1786,10 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus) return; } -/** - * struct brcmf_skbuff_cb reserves first two bytes in sk_buff::cb for - * bus layer usage. - */ /* flag marking a dummy skb added for DMA alignment requirement */ -#define ALIGN_SKB_FLAG 0x8000 +#define DUMMY_SKB_FLAG 0x10000 /* bit mask of data length chopped from the previous packet */ -#define ALIGN_SKB_CHOP_LEN_MASK 0x7fff - -static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio_dev *sdiodev, - struct sk_buff_head *pktq, - struct sk_buff *pkt, uint chan) -{ - struct sk_buff *pkt_pad; - u16 tail_pad, tail_chop, sg_align; - unsigned int blksize; - u8 *dat_buf; - int ntail; - - blksize = sdiodev->func[SDIO_FUNC_2]->cur_blksize; - sg_align = 4; - if (sdiodev->pdata && sdiodev->pdata->sd_sgentry_align > 4) - sg_align = sdiodev->pdata->sd_sgentry_align; - /* sg entry alignment should be a divisor of block size */ - WARN_ON(blksize % sg_align); - - /* Check tail padding */ - pkt_pad = NULL; - tail_chop = pkt->len % sg_align; - tail_pad = sg_align - tail_chop; - tail_pad += blksize - (pkt->len + tail_pad) % blksize; - if (skb_tailroom(pkt) < tail_pad && pkt->len > blksize) { - pkt_pad = brcmu_pkt_buf_get_skb(tail_pad + tail_chop); - if (pkt_pad == NULL) - return -ENOMEM; - memcpy(pkt_pad->data, - pkt->data + pkt->len - tail_chop, - tail_chop); - *(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop; - skb_trim(pkt, pkt->len - tail_chop); - __skb_queue_after(pktq, pkt, pkt_pad); - } else { - ntail = pkt->data_len + tail_pad - - (pkt->end - pkt->tail); - if (skb_cloned(pkt) || ntail > 0) - if (pskb_expand_head(pkt, 0, ntail, GFP_ATOMIC)) - return -ENOMEM; - if (skb_linearize(pkt)) - return -ENOMEM; - dat_buf = (u8 *)(pkt->data); - __skb_put(pkt, tail_pad); - } - - if (pkt_pad) - return pkt->len + tail_chop; - else - return pkt->len - tail_pad; -} - +#define DUMMY_SKB_CHOP_LEN_MASK 0xffff /** * brcmf_sdio_txpkt_prep - packet preparation for transmit * @bus: brcmf_sdio structure pointer @@ -1946,16 +1806,24 @@ static int brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq, uint chan) { - u16 head_pad, head_align; - struct sk_buff *pkt_next; + u16 head_pad, tail_pad, tail_chop, head_align, sg_align; + int ntail; + struct sk_buff *pkt_next, *pkt_new; u8 *dat_buf; - int err; + unsigned blksize = bus->sdiodev->func[SDIO_FUNC_2]->cur_blksize; struct brcmf_sdio_hdrinfo hd_info = {0}; /* SDIO ADMA requires at least 32 bit alignment */ head_align = 4; - if (bus->sdiodev->pdata && bus->sdiodev->pdata->sd_head_align > 4) - head_align = bus->sdiodev->pdata->sd_head_align; + sg_align = 4; + if (bus->sdiodev->pdata) { + head_align = bus->sdiodev->pdata->sd_head_align > 4 ? + bus->sdiodev->pdata->sd_head_align : 4; + sg_align = bus->sdiodev->pdata->sd_sgentry_align > 4 ? + bus->sdiodev->pdata->sd_sgentry_align : 4; + } + /* sg entry alignment should be a divisor of block size */ + WARN_ON(blksize % sg_align); pkt_next = pktq->next; dat_buf = (u8 *)(pkt_next->data); @@ -1974,20 +1842,40 @@ brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq, memset(dat_buf, 0, head_pad + bus->tx_hdrlen); } - if (bus->sdiodev->sg_support && pktq->qlen > 1) { - err = brcmf_sdio_txpkt_prep_sg(bus->sdiodev, pktq, - pkt_next, chan); - if (err < 0) - return err; - hd_info.len = (u16)err; + /* Check tail padding */ + pkt_new = NULL; + tail_chop = pkt_next->len % sg_align; + tail_pad = sg_align - tail_chop; + tail_pad += blksize - (pkt_next->len + tail_pad) % blksize; + if (skb_tailroom(pkt_next) < tail_pad && pkt_next->len > blksize) { + pkt_new = brcmu_pkt_buf_get_skb(tail_pad + tail_chop); + if (pkt_new == NULL) + return -ENOMEM; + memcpy(pkt_new->data, + pkt_next->data + pkt_next->len - tail_chop, + tail_chop); + *(u32 *)(pkt_new->cb) = DUMMY_SKB_FLAG + tail_chop; + skb_trim(pkt_next, pkt_next->len - tail_chop); + __skb_queue_after(pktq, pkt_next, pkt_new); } else { - hd_info.len = pkt_next->len; + ntail = pkt_next->data_len + tail_pad - + (pkt_next->end - pkt_next->tail); + if (skb_cloned(pkt_next) || ntail > 0) + if (pskb_expand_head(pkt_next, 0, ntail, GFP_ATOMIC)) + return -ENOMEM; + if (skb_linearize(pkt_next)) + return -ENOMEM; + dat_buf = (u8 *)(pkt_next->data); + __skb_put(pkt_next, tail_pad); } + /* Now prep the header */ + if (pkt_new) + hd_info.len = pkt_next->len + tail_chop; + else + hd_info.len = pkt_next->len - tail_pad; hd_info.channel = chan; hd_info.dat_offset = head_pad + bus->tx_hdrlen; - - /* Now fill the header */ brcmf_sdio_hdpack(bus, dat_buf, &hd_info); if (BRCMF_BYTES_ON() && @@ -2020,8 +1908,8 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq) skb_queue_walk_safe(pktq, pkt_next, tmp) { dummy_flags = *(u32 *)(pkt_next->cb); - if (dummy_flags & ALIGN_SKB_FLAG) { - chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK; + if (dummy_flags & DUMMY_SKB_FLAG) { + chop_len = dummy_flags & DUMMY_SKB_CHOP_LEN_MASK; if (chop_len) { pkt_prev = pkt_next->prev; memcpy(pkt_prev->data + pkt_prev->len, @@ -3149,43 +3037,69 @@ static bool brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter) return true; } +static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_sdio *bus) +{ + if (bus->firmware->size < bus->fw_ptr + len) + len = bus->firmware->size - bus->fw_ptr; + + memcpy(buf, &bus->firmware->data[bus->fw_ptr], len); + bus->fw_ptr += len; + return len; +} + static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) { - const struct firmware *fw; - int err; int offset; - int address; - int len; - - fw = brcmf_sdbrcm_get_fw(bus, BRCMF_FIRMWARE_BIN); - if (fw == NULL) - return -ENOENT; - - if (brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_ARM_CR4) != - BRCMF_MAX_CORENUM) - memcpy(&bus->ci->rst_vec, fw->data, sizeof(bus->ci->rst_vec)); - - err = 0; - offset = 0; - address = bus->ci->rambase; - while (offset < fw->size) { - len = ((offset + MEMBLOCK) < fw->size) ? MEMBLOCK : - fw->size - offset; - err = brcmf_sdio_ramrw(bus->sdiodev, true, address, - (u8 *)&fw->data[offset], len); - if (err) { + uint len; + u8 *memblock = NULL, *memptr; + int ret; + u8 idx; + + brcmf_dbg(INFO, "Enter\n"); + + ret = request_firmware(&bus->firmware, BRCMF_SDIO_FW_NAME, + &bus->sdiodev->func[2]->dev); + if (ret) { + brcmf_err("Fail to request firmware %d\n", ret); + return ret; + } + bus->fw_ptr = 0; + + memptr = memblock = kmalloc(MEMBLOCK + BRCMF_SDALIGN, GFP_ATOMIC); + if (memblock == NULL) { + ret = -ENOMEM; + goto err; + } + if ((u32)(unsigned long)memblock % BRCMF_SDALIGN) + memptr += (BRCMF_SDALIGN - + ((u32)(unsigned long)memblock % BRCMF_SDALIGN)); + + offset = bus->ci->rambase; + + /* Download image */ + len = brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus); + idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_ARM_CR4); + if (BRCMF_MAX_CORENUM != idx) + memcpy(&bus->ci->rst_vec, memptr, sizeof(bus->ci->rst_vec)); + while (len) { + ret = brcmf_sdio_ramrw(bus->sdiodev, true, offset, memptr, len); + if (ret) { brcmf_err("error %d on writing %d membytes at 0x%08x\n", - err, len, address); - goto failure; + ret, MEMBLOCK, offset); + goto err; } - offset += len; - address += len; + + offset += MEMBLOCK; + len = brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus); } -failure: - release_firmware(fw); +err: + kfree(memblock); - return err; + release_firmware(bus->firmware); + bus->fw_ptr = 0; + + return ret; } /* @@ -3197,8 +3111,7 @@ failure: * by two NULs. */ -static int brcmf_process_nvram_vars(struct brcmf_sdio *bus, - const struct firmware *nv) +static int brcmf_process_nvram_vars(struct brcmf_sdio *bus) { char *varbuf; char *dp; @@ -3207,12 +3120,12 @@ static int brcmf_process_nvram_vars(struct brcmf_sdio *bus, int ret = 0; uint buf_len, n, len; - len = nv->size; + len = bus->firmware->size; varbuf = vmalloc(len); if (!varbuf) return -ENOMEM; - memcpy(varbuf, nv->data, len); + memcpy(varbuf, bus->firmware->data, len); dp = varbuf; findNewline = false; @@ -3264,16 +3177,18 @@ err: static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus) { - const struct firmware *nv; int ret; - nv = brcmf_sdbrcm_get_fw(bus, BRCMF_FIRMWARE_NVRAM); - if (nv == NULL) - return -ENOENT; + ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME, + &bus->sdiodev->func[2]->dev); + if (ret) { + brcmf_err("Fail to request nvram %d\n", ret); + return ret; + } - ret = brcmf_process_nvram_vars(bus, nv); + ret = brcmf_process_nvram_vars(bus); - release_firmware(nv); + release_firmware(bus->firmware); return ret; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h index 14bc24d..e679214 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h @@ -102,8 +102,7 @@ struct brcmf_event; BRCMF_ENUM_DEF(DCS_REQUEST, 73) \ BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \ BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \ - BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) \ - BRCMF_ENUM_DEF(PSTA_PRIMARY_INTF_IND, 128) + BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) #define BRCMF_ENUM_DEF(id, val) \ BRCMF_E_##id = (val), @@ -115,8 +114,6 @@ enum brcmf_fweh_event_code { }; #undef BRCMF_ENUM_DEF -#define BRCMF_EVENTING_MASK_LEN DIV_ROUND_UP(BRCMF_E_LAST, 8) - /* flags field values in struct brcmf_event_msg */ #define BRCMF_EVENT_MSG_LINK 0x01 #define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c index d0cd0bf..82f9140 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c @@ -168,7 +168,6 @@ enum brcmf_fws_skb_state { /** * struct brcmf_skbuff_cb - control buffer associated with skbuff. * - * @bus_flags: 2 bytes reserved for bus specific parameters * @if_flags: holds interface index and packet related flags. * @htod: host to device packet identifier (used in PKTTAG tlv). * @state: transmit state of the packet. @@ -178,7 +177,6 @@ enum brcmf_fws_skb_state { * provides 48 bytes of storage so this structure should not exceed that. */ struct brcmf_skbuff_cb { - u16 bus_flags; u16 if_flags; u32 htod; enum brcmf_fws_skb_state state; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c index 4a22930..d7a9745 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c @@ -823,7 +823,6 @@ static s32 brcmf_p2p_run_escan(struct brcmf_cfg80211_info *cfg, } err = brcmf_p2p_escan(p2p, num_nodfs, chanspecs, search_state, action, P2PAPI_BSSCFG_DEVICE); - kfree(chanspecs); } exit: if (err) @@ -1149,7 +1148,7 @@ static s32 brcmf_p2p_af_searching_channel(struct brcmf_p2p_info *p2p) pri_vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; - reinit_completion(&afx_hdl->act_frm_scan); + INIT_COMPLETION(afx_hdl->act_frm_scan); set_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status); afx_hdl->is_active = true; afx_hdl->peer_chan = P2P_INVALID_CHANNEL; @@ -1502,7 +1501,7 @@ static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p, brcmf_dbg(TRACE, "Enter\n"); - reinit_completion(&p2p->send_af_done); + INIT_COMPLETION(p2p->send_af_done); clear_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status); clear_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status); diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index 2096a14..ca72177 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -18,7 +18,6 @@ #include <linux/types.h> #include <linux/netdevice.h> #include <linux/mmc/card.h> -#include <linux/mmc/sdio_func.h> #include <linux/ssb/ssb_regs.h> #include <linux/bcma/bcma.h> @@ -137,8 +136,6 @@ brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev, u8 idx; idx = brcmf_sdio_chip_getinfidx(ci, coreid); - if (idx == BRCMF_MAX_CORENUM) - return false; regdata = brcmf_sdio_regrl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow), @@ -157,8 +154,6 @@ brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev, bool ret; idx = brcmf_sdio_chip_getinfidx(ci, coreid); - if (idx == BRCMF_MAX_CORENUM) - return false; regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, NULL); @@ -266,8 +261,6 @@ brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, u32 regdata; idx = brcmf_sdio_chip_getinfidx(ci, coreid); - if (idx == BRCMF_MAX_CORENUM) - return; /* if core is already in reset, just return */ regdata = brcmf_sdio_regrl(sdiodev, @@ -311,8 +304,6 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, u8 idx; idx = brcmf_sdio_chip_getinfidx(ci, coreid); - if (idx == BRCMF_MAX_CORENUM) - return; /* * Must do the disable sequence first to work for @@ -377,8 +368,6 @@ brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, u32 regdata; idx = brcmf_sdio_chip_getinfidx(ci, coreid); - if (idx == BRCMF_MAX_CORENUM) - return; /* must disable first to work for arbitrary current core state */ brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, core_bits); @@ -455,9 +444,6 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, NULL); ci->chip = regdata & CID_ID_MASK; ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; - if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 && - ci->chiprev >= 2) - ci->chip = BCM4339_CHIP_ID; ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT; brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev); @@ -555,20 +541,6 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, ci->ramsize = 0xc0000; ci->rambase = 0x180000; break; - case BCM4339_CHIP_ID: - ci->c_inf[0].wrapbase = 0x18100000; - ci->c_inf[0].cib = 0x2e084411; - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; - ci->c_inf[1].base = 0x18005000; - ci->c_inf[1].wrapbase = 0x18105000; - ci->c_inf[1].cib = 0x15004211; - ci->c_inf[2].id = BCMA_CORE_ARM_CR4; - ci->c_inf[2].base = 0x18002000; - ci->c_inf[2].wrapbase = 0x18102000; - ci->c_inf[2].cib = 0x04084411; - ci->ramsize = 0xc0000; - ci->rambase = 0x180000; - break; default: brcmf_err("chipid 0x%x is not supported\n", ci->chip); return -ENODEV; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h index 507c61c..83c041f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h @@ -54,14 +54,6 @@ #define BRCMF_MAX_CORENUM 6 -/* SDIO device ID */ -#define SDIO_DEVICE_ID_BROADCOM_43143 43143 -#define SDIO_DEVICE_ID_BROADCOM_43241 0x4324 -#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 -#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 -#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 -#define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335 - struct chip_core_info { u16 id; u16 rev; @@ -223,16 +215,17 @@ struct sdpcmd_regs { u16 PAD[0x80]; }; -int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, - struct chip_info **ci_ptr, u32 regs); -void brcmf_sdio_chip_detach(struct chip_info **ci_ptr); -void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, u32 drivestrength); -u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid); -void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci); -bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, - struct chip_info *ci, char *nvram_dat, - uint nvram_sz); +extern int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, + struct chip_info **ci_ptr, u32 regs); +extern void brcmf_sdio_chip_detach(struct chip_info **ci_ptr); +extern void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, + struct chip_info *ci, + u32 drivestrength); +extern u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid); +extern void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, + struct chip_info *ci); +extern bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, + struct chip_info *ci, char *nvram_dat, + uint nvram_sz); #endif /* _BRCMFMAC_SDIO_CHIP_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h index fc0d4f0..2b5407f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h @@ -178,25 +178,21 @@ struct brcmf_sdio_dev { bool irq_en; /* irq enable flags */ spinlock_t irq_en_lock; bool irq_wake; /* irq wake enable flags */ - bool sg_support; - uint max_request_size; - ushort max_segment_count; - uint max_segment_size; }; /* Register/deregister interrupt handler. */ -int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev); -int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev); +extern int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev); +extern int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev); /* sdio device register access interface */ -u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); -u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); -void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, u8 data, - int *ret); -void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, u32 data, - int *ret); -int brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, - void *data, bool write); +extern u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); +extern u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret); +extern void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, + u8 data, int *ret); +extern void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, + u32 data, int *ret); +extern int brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, + void *data, bool write); /* Buffer transfer to/from device (client) core via cmd53. * fn: function number @@ -210,17 +206,22 @@ int brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, * Returns 0 or error code. * NOTE: Async operation is not currently supported. */ -int brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff_head *pktq); -int brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, u8 *buf, uint nbytes); - -int brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff *pkt); -int brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, u8 *buf, uint nbytes); -int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, - uint flags, struct sk_buff_head *pktq, uint totlen); +extern int +brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, struct sk_buff_head *pktq); +extern int +brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, u8 *buf, uint nbytes); + +extern int +brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, struct sk_buff *pkt); +extern int +brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, u8 *buf, uint nbytes); +extern int +brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, struct sk_buff_head *pktq); /* Flags bits */ @@ -236,43 +237,46 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, * nbytes: number of bytes to transfer to/from buf * Returns 0 or error code. */ -int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr, - u8 *buf, uint nbytes); -int brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address, - u8 *data, uint size); +extern int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, + u32 addr, u8 *buf, uint nbytes); +extern int brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, + u32 address, u8 *data, uint size); /* Issue an abort to the specified function */ -int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn); +extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn); /* platform specific/high level functions */ -int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); -int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev); +extern int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); +extern int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev); /* attach, return handler on success, NULL if failed. * The handler shall be provided by all subsequent calls. No local cache * cfghdl points to the starting address of pci device mapped memory */ -int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev); -void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev); +extern int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev); +extern void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev); /* read or write one byte using cmd52 */ -int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint fnc, - uint addr, u8 *byte); +extern int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, + uint fnc, uint addr, u8 *byte); /* read or write 2/4 bytes using cmd53 */ -int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, uint rw, uint fnc, - uint addr, u32 *word, uint nbyte); +extern int +brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, + uint rw, uint fnc, uint addr, + u32 *word, uint nbyte); /* Watchdog timer interface for pm ops */ -void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable); +extern void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, + bool enable); -void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev); -void brcmf_sdbrcm_disconnect(void *ptr); -void brcmf_sdbrcm_isr(void *arg); +extern void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev); +extern void brcmf_sdbrcm_disconnect(void *ptr); +extern void brcmf_sdbrcm_isr(void *arg); -void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick); +extern void brcmf_sdbrcm_wd_timer(struct brcmf_sdio *bus, uint wdtick); -void brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, - wait_queue_head_t *wq); -bool brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev); +extern void brcmf_pm_resume_wait(struct brcmf_sdio_dev *sdiodev, + wait_queue_head_t *wq); +extern bool brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev); #endif /* _BRCM_SDH_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h index 3c67529..bc29171 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/tracepoint.h @@ -78,15 +78,13 @@ TRACE_EVENT(brcmf_hexdump, TP_ARGS(data, len), TP_STRUCT__entry( __field(unsigned long, len) - __field(unsigned long, addr) __dynamic_array(u8, hdata, len) ), TP_fast_assign( __entry->len = len; - __entry->addr = (unsigned long)data; memcpy(__get_dynamic_array(hdata), data, len); ), - TP_printk("hexdump [addr=%lx, length=%lu]", __entry->addr, __entry->len) + TP_printk("hexdump [length=%lu]", __entry->len) ); TRACE_EVENT(brcmf_bdchdr, @@ -110,23 +108,6 @@ TRACE_EVENT(brcmf_bdchdr, TP_printk("bdc: prio=%d siglen=%d", __entry->prio, __entry->siglen) ); -TRACE_EVENT(brcmf_sdpcm_hdr, - TP_PROTO(bool tx, void *data), - TP_ARGS(tx, data), - TP_STRUCT__entry( - __field(u8, tx) - __field(u16, len) - __array(u8, hdr, 12) - ), - TP_fast_assign( - memcpy(__entry->hdr, data, 12); - __entry->len = __entry->hdr[0] | (__entry->hdr[1] << 8); - __entry->tx = tx ? 1 : 0; - ), - TP_printk("sdpcm: %s len %u, seq %d", __entry->tx ? "TX" : "RX", - __entry->len, __entry->hdr[4]) -); - #ifdef CONFIG_BRCM_TRACING #undef TRACE_INCLUDE_PATH diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 422f44c..f4aea47 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -435,6 +435,7 @@ static void brcmf_usb_rx_complete(struct urb *urb) struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context; struct brcmf_usbdev_info *devinfo = req->devinfo; struct sk_buff *skb; + struct sk_buff_head skbq; brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status); brcmf_usb_del_fromq(devinfo, req); @@ -449,8 +450,10 @@ static void brcmf_usb_rx_complete(struct urb *urb) } if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) { + skb_queue_head_init(&skbq); + skb_queue_tail(&skbq, skb); skb_put(skb, urb->actual_length); - brcmf_rx_frame(devinfo->dev, skb); + brcmf_rx_frames(devinfo->dev, &skbq); brcmf_usb_rx_refill(devinfo, req); } else { brcmu_pkt_buf_free_skb(skb); diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h index 2d08c15..a8a267b 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.h @@ -172,19 +172,19 @@ struct si_info { /* AMBA Interconnect exported externs */ -u32 ai_core_cflags(struct bcma_device *core, u32 mask, u32 val); +extern u32 ai_core_cflags(struct bcma_device *core, u32 mask, u32 val); /* === exported functions === */ -struct si_pub *ai_attach(struct bcma_bus *pbus); -void ai_detach(struct si_pub *sih); -uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val); -void ai_clkctl_init(struct si_pub *sih); -u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih); -bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode); -bool ai_deviceremoved(struct si_pub *sih); +extern struct si_pub *ai_attach(struct bcma_bus *pbus); +extern void ai_detach(struct si_pub *sih); +extern uint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val); +extern void ai_clkctl_init(struct si_pub *sih); +extern u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih); +extern bool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode); +extern bool ai_deviceremoved(struct si_pub *sih); /* Enable Ex-PA for 4313 */ -void ai_epa_4313war(struct si_pub *sih); +extern void ai_epa_4313war(struct si_pub *sih); static inline u32 ai_get_cccaps(struct si_pub *sih) { diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h index 03bdcf2..73d01e5 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h @@ -37,17 +37,17 @@ struct brcms_ampdu_session { u16 dma_len; }; -void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session, - struct brcms_c_info *wlc); -int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session, - struct sk_buff *p); -void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session); +extern void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session, + struct brcms_c_info *wlc); +extern int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session, + struct sk_buff *p); +extern void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session); -struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc); -void brcms_c_ampdu_detach(struct ampdu_info *ampdu); -void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, - struct sk_buff *p, struct tx_status *txs); -void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc); -void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu); +extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc); +extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu); +extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, + struct sk_buff *p, struct tx_status *txs); +extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc); +extern void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu); #endif /* _BRCM_AMPDU_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/antsel.h b/drivers/net/wireless/brcm80211/brcmsmac/antsel.h index a3d487a..97ea388 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/antsel.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/antsel.h @@ -17,11 +17,13 @@ #ifndef _BRCM_ANTSEL_H_ #define _BRCM_ANTSEL_H_ -struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc); -void brcms_c_antsel_detach(struct antsel_info *asi); -void brcms_c_antsel_init(struct antsel_info *asi); -void brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel, - u8 id, u8 fbid, u8 *antcfg, u8 *fbantcfg); -u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel); +extern struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc); +extern void brcms_c_antsel_detach(struct antsel_info *asi); +extern void brcms_c_antsel_init(struct antsel_info *asi); +extern void brcms_c_antsel_antcfg_get(struct antsel_info *asi, bool usedef, + bool sel, + u8 id, u8 fbid, u8 *antcfg, + u8 *fbantcfg); +extern u8 brcms_c_antsel_antsel2id(struct antsel_info *asi, u16 antsel); #endif /* _BRCM_ANTSEL_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.h b/drivers/net/wireless/brcm80211/brcmsmac/channel.h index 39dd3a5..006483a 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.h @@ -32,16 +32,20 @@ #define BRCMS_DFS_EU (BRCMS_DFS_TPC | BRCMS_RADAR_TYPE_EU) /* Flag for DFS EU */ -struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc); +extern struct brcms_cm_info * +brcms_c_channel_mgr_attach(struct brcms_c_info *wlc); -void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm); +extern void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm); -bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec); +extern bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, + u16 chspec); -void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, - struct txpwr_limits *txpwr); -void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, - u8 local_constraint_qdbm); -void brcms_c_regd_init(struct brcms_c_info *wlc); +extern void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, + u16 chanspec, + struct txpwr_limits *txpwr); +extern void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, + u16 chanspec, + u8 local_constraint_qdbm); +extern void brcms_c_regd_init(struct brcms_c_info *wlc); #endif /* _WLC_CHANNEL_H */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h index 198053d..4090032 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h @@ -88,26 +88,26 @@ struct brcms_info { }; /* misc callbacks */ -void brcms_init(struct brcms_info *wl); -uint brcms_reset(struct brcms_info *wl); -void brcms_intrson(struct brcms_info *wl); -u32 brcms_intrsoff(struct brcms_info *wl); -void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask); -int brcms_up(struct brcms_info *wl); -void brcms_down(struct brcms_info *wl); -void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, - bool state, int prio); -bool brcms_rfkill_set_hw_state(struct brcms_info *wl); +extern void brcms_init(struct brcms_info *wl); +extern uint brcms_reset(struct brcms_info *wl); +extern void brcms_intrson(struct brcms_info *wl); +extern u32 brcms_intrsoff(struct brcms_info *wl); +extern void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask); +extern int brcms_up(struct brcms_info *wl); +extern void brcms_down(struct brcms_info *wl); +extern void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, + bool state, int prio); +extern bool brcms_rfkill_set_hw_state(struct brcms_info *wl); /* timer functions */ -struct brcms_timer *brcms_init_timer(struct brcms_info *wl, - void (*fn) (void *arg), void *arg, - const char *name); -void brcms_free_timer(struct brcms_timer *timer); -void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic); -bool brcms_del_timer(struct brcms_timer *timer); -void brcms_dpc(unsigned long data); -void brcms_timer(struct brcms_timer *t); -void brcms_fatal_error(struct brcms_info *wl); +extern struct brcms_timer *brcms_init_timer(struct brcms_info *wl, + void (*fn) (void *arg), void *arg, + const char *name); +extern void brcms_free_timer(struct brcms_timer *timer); +extern void brcms_add_timer(struct brcms_timer *timer, uint ms, int periodic); +extern bool brcms_del_timer(struct brcms_timer *timer); +extern void brcms_dpc(unsigned long data); +extern void brcms_timer(struct brcms_timer *t); +extern void brcms_fatal_error(struct brcms_info *wl); #endif /* _BRCM_MAC80211_IF_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 8138f1c..4608e0e 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -1906,14 +1906,14 @@ static void brcms_c_get_macaddr(struct brcms_hardware *wlc_hw, u8 etheraddr[ETH_ /* If macaddr exists, use it (Sromrev4, CIS, ...). */ if (!is_zero_ether_addr(sprom->il0mac)) { - memcpy(etheraddr, sprom->il0mac, ETH_ALEN); + memcpy(etheraddr, sprom->il0mac, 6); return; } if (wlc_hw->_nbands > 1) - memcpy(etheraddr, sprom->et1mac, ETH_ALEN); + memcpy(etheraddr, sprom->et1mac, 6); else - memcpy(etheraddr, sprom->il0mac, ETH_ALEN); + memcpy(etheraddr, sprom->il0mac, 6); } /* power both the pll and external oscillator on/off */ @@ -5695,7 +5695,7 @@ static bool brcms_c_chipmatch_pci(struct bcma_device *core) return true; if ((device == BCM43224_D11N_ID) || (device == BCM43225_D11N2G_ID)) return true; - if (device == BCM4313_D11N2G_ID || device == BCM4313_CHIP_ID) + if (device == BCM4313_D11N2G_ID) return true; if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID)) return true; diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h index c4d135c..b5d7a38 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h @@ -616,54 +616,66 @@ struct brcms_bss_cfg { struct brcms_bss_info *current_bss; }; -int brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p); -int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, - uint *blocks); - -int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config); -void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags); -u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, uint mac_len); -u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec, - bool use_rspec, u16 mimo_ctlchbw); -u16 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only, - u32 rts_rate, u32 frame_rate, - u8 rts_preamble_type, u8 frame_preamble_type, - uint frame_len, bool ba); -void brcms_c_inval_dma_pkts(struct brcms_hardware *hw, - struct ieee80211_sta *sta, void (*dma_callback_fn)); -void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend); -int brcms_c_set_nmode(struct brcms_c_info *wlc); -void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc, u32 bcn_rate); -void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type); -void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, - bool mute, struct txpwr_limits *txpwr); -void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, u16 v); -u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset); -void brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, u16 val, - int bands); -void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags); -void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val); -void brcms_b_phy_reset(struct brcms_hardware *wlc_hw); -void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw); -void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw); -void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw, - u32 override_bit); -void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw, - u32 override_bit); -void brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, - int len, void *buf); -u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate); -void brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, uint offset, - const void *buf, int len, u32 sel); -void brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, - void *buf, int len, u32 sel); -void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode); -u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw); -void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk); -void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk); -void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on); -void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant); -void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, u8 stf_mode); -void brcms_c_init_scb(struct scb *scb); +extern int brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, + struct sk_buff *p); +extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, + uint *blocks); + +extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config); +extern void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags); +extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, + uint mac_len); +extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, + u32 rspec, + bool use_rspec, u16 mimo_ctlchbw); +extern u16 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only, + u32 rts_rate, + u32 frame_rate, + u8 rts_preamble_type, + u8 frame_preamble_type, uint frame_len, + bool ba); +extern void brcms_c_inval_dma_pkts(struct brcms_hardware *hw, + struct ieee80211_sta *sta, + void (*dma_callback_fn)); +extern void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend); +extern int brcms_c_set_nmode(struct brcms_c_info *wlc); +extern void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc, + u32 bcn_rate); +extern void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, + u8 antsel_type); +extern void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, + u16 chanspec, + bool mute, struct txpwr_limits *txpwr); +extern void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, + u16 v); +extern u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset); +extern void brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, + u16 val, int bands); +extern void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags); +extern void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val); +extern void brcms_b_phy_reset(struct brcms_hardware *wlc_hw); +extern void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw); +extern void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw); +extern void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw, + u32 override_bit); +extern void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw, + u32 override_bit); +extern void brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, + int offset, int len, void *buf); +extern u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate); +extern void brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, + uint offset, const void *buf, int len, + u32 sel); +extern void brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, + void *buf, int len, u32 sel); +extern void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode); +extern u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw); +extern void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk); +extern void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk); +extern void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on); +extern void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant); +extern void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, + u8 stf_mode); +extern void brcms_c_init_scb(struct scb *scb); #endif /* _BRCM_MAIN_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h index 4d3734f..e34a71e 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_hal.h @@ -179,106 +179,121 @@ struct shared_phy_params { }; -struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp); -struct brcms_phy_pub *wlc_phy_attach(struct shared_phy *sh, - struct bcma_device *d11core, int bandtype, - struct wiphy *wiphy); -void wlc_phy_detach(struct brcms_phy_pub *ppi); - -bool wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, - u16 *phyrev, u16 *radioid, u16 *radiover); -bool wlc_phy_get_encore(struct brcms_phy_pub *pih); -u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih); - -void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *ppi, bool newstate); -void wlc_phy_hw_state_upd(struct brcms_phy_pub *ppi, bool newstate); -void wlc_phy_init(struct brcms_phy_pub *ppi, u16 chanspec); -void wlc_phy_watchdog(struct brcms_phy_pub *ppi); -int wlc_phy_down(struct brcms_phy_pub *ppi); -u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih); -void wlc_phy_cal_init(struct brcms_phy_pub *ppi); -void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init); - -void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, u16 chanspec); -u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi); -void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, u16 newch); -u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi); -void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw); - -int wlc_phy_rssi_compute(struct brcms_phy_pub *pih, struct d11rxhdr *rxh); -void wlc_phy_por_inform(struct brcms_phy_pub *ppi); -void wlc_phy_noise_sample_intr(struct brcms_phy_pub *ppi); -bool wlc_phy_bist_check_phy(struct brcms_phy_pub *ppi); - -void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag); - -void wlc_phy_switch_radio(struct brcms_phy_pub *ppi, bool on); -void wlc_phy_anacore(struct brcms_phy_pub *ppi, bool on); - - -void wlc_phy_BSSinit(struct brcms_phy_pub *ppi, bool bonlyap, int rssi); - -void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi, - bool wide_filter); -void wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band, - struct brcms_chanvec *channels); -u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band); - -void wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint chan, u8 *_min_, - u8 *_max_, int rate); -void wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, uint chan, - u8 *_max_, u8 *_min_); -void wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi, uint band, - s32 *, s32 *, u32 *); -void wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, struct txpwr_limits *, - u16 chanspec); -int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, bool *override); -int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, bool override); -void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi, - struct txpwr_limits *); -bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi); -void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, bool hwpwrctrl); -u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi); -u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi); -bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *pih); - -void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain); -void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain); -void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain, u8 *rxchain); -u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih); -s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, u16 chanspec); -void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool val); - -void wlc_phy_cal_perical(struct brcms_phy_pub *ppi, u8 reason); -void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *ppi); -void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock); -void wlc_phy_cal_papd_recal(struct brcms_phy_pub *ppi); - -void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val); -void wlc_phy_clear_tssi(struct brcms_phy_pub *ppi); -void wlc_phy_hold_upd(struct brcms_phy_pub *ppi, u32 id, bool val); -void wlc_phy_mute_upd(struct brcms_phy_pub *ppi, bool val, u32 flags); - -void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type); - -void wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, - struct tx_power *power, uint channel); - -void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal); -bool wlc_phy_test_ison(struct brcms_phy_pub *ppi); -void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi, u8 txpwr_percent); -void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war); -void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, bool bf_preempt); -void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap); - -void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end); - -void wlc_phy_freqtrack_start(struct brcms_phy_pub *ppi); -void wlc_phy_freqtrack_end(struct brcms_phy_pub *ppi); - -const u8 *wlc_phy_get_ofdm_rate_lookup(void); - -s8 wlc_phy_get_tx_power_offset_by_mcs(struct brcms_phy_pub *ppi, - u8 mcs_offset); -s8 wlc_phy_get_tx_power_offset(struct brcms_phy_pub *ppi, u8 tbl_offset); +extern struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp); +extern struct brcms_phy_pub *wlc_phy_attach(struct shared_phy *sh, + struct bcma_device *d11core, + int bandtype, struct wiphy *wiphy); +extern void wlc_phy_detach(struct brcms_phy_pub *ppi); + +extern bool wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, + u16 *phyrev, u16 *radioid, + u16 *radiover); +extern bool wlc_phy_get_encore(struct brcms_phy_pub *pih); +extern u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih); + +extern void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *ppi, bool newstate); +extern void wlc_phy_hw_state_upd(struct brcms_phy_pub *ppi, bool newstate); +extern void wlc_phy_init(struct brcms_phy_pub *ppi, u16 chanspec); +extern void wlc_phy_watchdog(struct brcms_phy_pub *ppi); +extern int wlc_phy_down(struct brcms_phy_pub *ppi); +extern u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih); +extern void wlc_phy_cal_init(struct brcms_phy_pub *ppi); +extern void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init); + +extern void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, + u16 chanspec); +extern u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi); +extern void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, + u16 newch); +extern u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi); +extern void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw); + +extern int wlc_phy_rssi_compute(struct brcms_phy_pub *pih, + struct d11rxhdr *rxh); +extern void wlc_phy_por_inform(struct brcms_phy_pub *ppi); +extern void wlc_phy_noise_sample_intr(struct brcms_phy_pub *ppi); +extern bool wlc_phy_bist_check_phy(struct brcms_phy_pub *ppi); + +extern void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag); + +extern void wlc_phy_switch_radio(struct brcms_phy_pub *ppi, bool on); +extern void wlc_phy_anacore(struct brcms_phy_pub *ppi, bool on); + + +extern void wlc_phy_BSSinit(struct brcms_phy_pub *ppi, bool bonlyap, int rssi); + +extern void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi, + bool wide_filter); +extern void wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band, + struct brcms_chanvec *channels); +extern u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, + uint band); + +extern void wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint chan, + u8 *_min_, u8 *_max_, int rate); +extern void wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, + uint chan, u8 *_max_, u8 *_min_); +extern void wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi, + uint band, s32 *, s32 *, u32 *); +extern void wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, + struct txpwr_limits *, + u16 chanspec); +extern int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, + bool *override); +extern int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, + bool override); +extern void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi, + struct txpwr_limits *); +extern bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi); +extern void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, + bool hwpwrctrl); +extern u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi); +extern u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi); +extern bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *pih); + +extern void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, + u8 rxchain); +extern void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, + u8 rxchain); +extern void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain, + u8 *rxchain); +extern u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih); +extern s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, + u16 chanspec); +extern void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool val); + +extern void wlc_phy_cal_perical(struct brcms_phy_pub *ppi, u8 reason); +extern void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *ppi); +extern void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock); +extern void wlc_phy_cal_papd_recal(struct brcms_phy_pub *ppi); + +extern void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val); +extern void wlc_phy_clear_tssi(struct brcms_phy_pub *ppi); +extern void wlc_phy_hold_upd(struct brcms_phy_pub *ppi, u32 id, bool val); +extern void wlc_phy_mute_upd(struct brcms_phy_pub *ppi, bool val, u32 flags); + +extern void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type); + +extern void wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, + struct tx_power *power, uint channel); + +extern void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal); +extern bool wlc_phy_test_ison(struct brcms_phy_pub *ppi); +extern void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi, + u8 txpwr_percent); +extern void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war); +extern void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, + bool bf_preempt); +extern void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap); + +extern void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end); + +extern void wlc_phy_freqtrack_start(struct brcms_phy_pub *ppi); +extern void wlc_phy_freqtrack_end(struct brcms_phy_pub *ppi); + +extern const u8 *wlc_phy_get_ofdm_rate_lookup(void); + +extern s8 wlc_phy_get_tx_power_offset_by_mcs(struct brcms_phy_pub *ppi, + u8 mcs_offset); +extern s8 wlc_phy_get_tx_power_offset(struct brcms_phy_pub *ppi, u8 tbl_offset); #endif /* _BRCM_PHY_HAL_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h index 4960f7d..1dc767c 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_int.h @@ -910,103 +910,113 @@ struct lcnphy_radio_regs { u8 do_init_g; }; -u16 read_phy_reg(struct brcms_phy *pi, u16 addr); -void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val); -void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val); -void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val); -void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val); - -u16 read_radio_reg(struct brcms_phy *pi, u16 addr); -void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val); -void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val); -void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val); -void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask); - -void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val); - -void wlc_phyreg_enter(struct brcms_phy_pub *pih); -void wlc_phyreg_exit(struct brcms_phy_pub *pih); -void wlc_radioreg_enter(struct brcms_phy_pub *pih); -void wlc_radioreg_exit(struct brcms_phy_pub *pih); - -void wlc_phy_read_table(struct brcms_phy *pi, - const struct phytbl_info *ptbl_info, - u16 tblAddr, u16 tblDataHi, u16 tblDatalo); -void wlc_phy_write_table(struct brcms_phy *pi, - const struct phytbl_info *ptbl_info, - u16 tblAddr, u16 tblDataHi, u16 tblDatalo); -void wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id, uint tbl_offset, - u16 tblAddr, u16 tblDataHi, u16 tblDataLo); -void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val); - -void write_phy_channel_reg(struct brcms_phy *pi, uint val); -void wlc_phy_txpower_update_shm(struct brcms_phy *pi); - -u8 wlc_phy_nbits(s32 value); -void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_dB, u8 core); - -uint wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi, - struct radio_20xx_regs *radioregs); -uint wlc_phy_init_radio_regs(struct brcms_phy *pi, - const struct radio_regs *radioregs, - u16 core_offset); - -void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi); - -void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on); -void wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, s32 *eps_imag); - -void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi); -void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi); - -bool wlc_phy_attach_nphy(struct brcms_phy *pi); -bool wlc_phy_attach_lcnphy(struct brcms_phy *pi); - -void wlc_phy_detach_lcnphy(struct brcms_phy *pi); - -void wlc_phy_init_nphy(struct brcms_phy *pi); -void wlc_phy_init_lcnphy(struct brcms_phy *pi); - -void wlc_phy_cal_init_nphy(struct brcms_phy *pi); -void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi); - -void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, u16 chanspec); -void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec); -void wlc_phy_chanspec_set_fixup_lcnphy(struct brcms_phy *pi, u16 chanspec); -int wlc_phy_channel2freq(uint channel); -int wlc_phy_chanspec_freq2bandrange_lpssn(uint); -int wlc_phy_chanspec_bandrange_get(struct brcms_phy *, u16 chanspec); - -void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode); -s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi); - -void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi); -void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi); -void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi); - -void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index); -void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable); -void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi); -void wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz, u16 max_val, - bool iqcalmode); - -void wlc_phy_txpower_sromlimit_get_nphy(struct brcms_phy *pi, uint chan, - u8 *max_pwr, u8 rate_id); -void wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start, - u8 rate_mcs_end, u8 rate_ofdm_start); -void wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power, u8 rate_ofdm_start, - u8 rate_ofdm_end, u8 rate_mcs_start); - -u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode); -s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode); -s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode); -s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode); -void wlc_phy_carrier_suppress_lcnphy(struct brcms_phy *pi); -void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel); -void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode); -void wlc_2064_vco_cal(struct brcms_phy *pi); - -void wlc_phy_txpower_recalc_target(struct brcms_phy *pi); +extern u16 read_phy_reg(struct brcms_phy *pi, u16 addr); +extern void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val); +extern void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val); +extern void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val); +extern void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val); + +extern u16 read_radio_reg(struct brcms_phy *pi, u16 addr); +extern void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val); +extern void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val); +extern void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask, + u16 val); +extern void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask); + +extern void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val); + +extern void wlc_phyreg_enter(struct brcms_phy_pub *pih); +extern void wlc_phyreg_exit(struct brcms_phy_pub *pih); +extern void wlc_radioreg_enter(struct brcms_phy_pub *pih); +extern void wlc_radioreg_exit(struct brcms_phy_pub *pih); + +extern void wlc_phy_read_table(struct brcms_phy *pi, + const struct phytbl_info *ptbl_info, + u16 tblAddr, u16 tblDataHi, + u16 tblDatalo); +extern void wlc_phy_write_table(struct brcms_phy *pi, + const struct phytbl_info *ptbl_info, + u16 tblAddr, u16 tblDataHi, u16 tblDatalo); +extern void wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id, + uint tbl_offset, u16 tblAddr, u16 tblDataHi, + u16 tblDataLo); +extern void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val); + +extern void write_phy_channel_reg(struct brcms_phy *pi, uint val); +extern void wlc_phy_txpower_update_shm(struct brcms_phy *pi); + +extern u8 wlc_phy_nbits(s32 value); +extern void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_dB, u8 core); + +extern uint wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi, + struct radio_20xx_regs *radioregs); +extern uint wlc_phy_init_radio_regs(struct brcms_phy *pi, + const struct radio_regs *radioregs, + u16 core_offset); + +extern void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi); + +extern void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on); +extern void wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, + s32 *eps_imag); + +extern void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi); +extern void wlc_phy_cal_perical_mphase_restart(struct brcms_phy *pi); + +extern bool wlc_phy_attach_nphy(struct brcms_phy *pi); +extern bool wlc_phy_attach_lcnphy(struct brcms_phy *pi); + +extern void wlc_phy_detach_lcnphy(struct brcms_phy *pi); + +extern void wlc_phy_init_nphy(struct brcms_phy *pi); +extern void wlc_phy_init_lcnphy(struct brcms_phy *pi); + +extern void wlc_phy_cal_init_nphy(struct brcms_phy *pi); +extern void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi); + +extern void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, + u16 chanspec); +extern void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, + u16 chanspec); +extern void wlc_phy_chanspec_set_fixup_lcnphy(struct brcms_phy *pi, + u16 chanspec); +extern int wlc_phy_channel2freq(uint channel); +extern int wlc_phy_chanspec_freq2bandrange_lpssn(uint); +extern int wlc_phy_chanspec_bandrange_get(struct brcms_phy *, u16 chanspec); + +extern void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode); +extern s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi); + +extern void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi); +extern void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi); +extern void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi); + +extern void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index); +extern void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable); +extern void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi); +extern void wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz, + u16 max_val, bool iqcalmode); + +extern void wlc_phy_txpower_sromlimit_get_nphy(struct brcms_phy *pi, uint chan, + u8 *max_pwr, u8 rate_id); +extern void wlc_phy_ofdm_to_mcs_powers_nphy(u8 *power, u8 rate_mcs_start, + u8 rate_mcs_end, + u8 rate_ofdm_start); +extern void wlc_phy_mcs_to_ofdm_powers_nphy(u8 *power, + u8 rate_ofdm_start, + u8 rate_ofdm_end, + u8 rate_mcs_start); + +extern u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode); +extern s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode); +extern s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode); +extern s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode); +extern void wlc_phy_carrier_suppress_lcnphy(struct brcms_phy *pi); +extern void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel); +extern void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode); +extern void wlc_2064_vco_cal(struct brcms_phy *pi); + +extern void wlc_phy_txpower_recalc_target(struct brcms_phy *pi); #define LCNPHY_TBL_ID_PAPDCOMPDELTATBL 0x18 #define LCNPHY_TX_POWER_TABLE_SIZE 128 @@ -1020,24 +1030,26 @@ void wlc_phy_txpower_recalc_target(struct brcms_phy *pi); #define LCNPHY_TX_PWR_CTRL_TEMPBASED 0xE001 -void wlc_lcnphy_write_table(struct brcms_phy *pi, - const struct phytbl_info *pti); -void wlc_lcnphy_read_table(struct brcms_phy *pi, struct phytbl_info *pti); -void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b); -void wlc_lcnphy_set_tx_locc(struct brcms_phy *pi, u16 didq); -void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b); -u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi); -void wlc_lcnphy_get_radio_loft(struct brcms_phy *pi, u8 *ei0, u8 *eq0, u8 *fi0, - u8 *fq0); -void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode); -void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode); -bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi); -void wlc_lcnphy_tx_pwr_update_npt(struct brcms_phy *pi); -s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1); -void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr, s8 *cck_pwr); -void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi); - -s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index); +extern void wlc_lcnphy_write_table(struct brcms_phy *pi, + const struct phytbl_info *pti); +extern void wlc_lcnphy_read_table(struct brcms_phy *pi, + struct phytbl_info *pti); +extern void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b); +extern void wlc_lcnphy_set_tx_locc(struct brcms_phy *pi, u16 didq); +extern void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b); +extern u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi); +extern void wlc_lcnphy_get_radio_loft(struct brcms_phy *pi, u8 *ei0, + u8 *eq0, u8 *fi0, u8 *fq0); +extern void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode); +extern void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode); +extern bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi); +extern void wlc_lcnphy_tx_pwr_update_npt(struct brcms_phy *pi); +extern s32 wlc_lcnphy_tssi2dbm(s32 tssi, s32 a1, s32 b0, s32 b1); +extern void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr, + s8 *cck_pwr); +extern void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi); + +extern s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index); #define NPHY_MAX_HPVGA1_INDEX 10 #define NPHY_DEF_HPVGA1_INDEXLIMIT 7 @@ -1048,8 +1060,9 @@ struct phy_iq_est { u32 q_pwr; }; -void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi, bool enable); -void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode); +extern void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi, + bool enable); +extern void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode); #define wlc_phy_write_table_nphy(pi, pti) \ wlc_phy_write_table(pi, pti, 0x72, 0x74, 0x73) @@ -1063,10 +1076,10 @@ void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode); #define wlc_nphy_table_data_write(pi, w, v) \ wlc_phy_table_data_write((pi), (w), (v)) -void wlc_phy_table_read_nphy(struct brcms_phy *pi, u32, u32 l, u32 o, u32 w, - void *d); -void wlc_phy_table_write_nphy(struct brcms_phy *pi, u32, u32, u32, u32, - const void *); +extern void wlc_phy_table_read_nphy(struct brcms_phy *pi, u32, u32 l, u32 o, + u32 w, void *d); +extern void wlc_phy_table_write_nphy(struct brcms_phy *pi, u32, u32, u32, + u32, const void *); #define PHY_IPA(pi) \ ((pi->ipa2g_on && CHSPEC_IS2G(pi->radio_chanspec)) || \ @@ -1076,67 +1089,73 @@ void wlc_phy_table_write_nphy(struct brcms_phy *pi, u32, u32, u32, u32, if (NREV_LT((pi)->pubpi.phy_rev, 3)) \ (void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) -void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype); -void wlc_phy_aci_reset_nphy(struct brcms_phy *pi); -void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en); - -u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint chan); -void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on); - -void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi); - -void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd); -s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi); - -u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val); - -void wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est, - u16 num_samps, u8 wait_time, u8 wait_for_crs); - -void wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write, - struct nphy_iq_comp *comp); -void wlc_phy_aci_and_noise_reduction_nphy(struct brcms_phy *pi); - -void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, u8 rxcore_bitmask); -u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih); - -void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type); -void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi); -void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi); -void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi); -u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi); - -struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi); -int wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, - struct nphy_txgains target_gain, bool full, bool m); -int wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, - u8 type, bool d); -void wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, - s8 txpwrindex, bool res); -void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core, u8 rssi_type); -int wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type, - s32 *rssi_buf, u8 nsamps); -void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi); -int wlc_phy_aci_scan_nphy(struct brcms_phy *pi); -void wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi, s32 dBm_targetpower, - bool debug); -int wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val, u8 mode, - u8, bool); -void wlc_phy_stopplayback_nphy(struct brcms_phy *pi); -void wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf, - u8 num_samps); -void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi); - -int wlc_phy_rssi_compute_nphy(struct brcms_phy *pi, struct d11rxhdr *rxh); +extern void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype); +extern void wlc_phy_aci_reset_nphy(struct brcms_phy *pi); +extern void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en); + +extern u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint chan); +extern void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on); + +extern void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi); + +extern void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd); +extern s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi); + +extern u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val); + +extern void wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est, + u16 num_samps, u8 wait_time, + u8 wait_for_crs); + +extern void wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write, + struct nphy_iq_comp *comp); +extern void wlc_phy_aci_and_noise_reduction_nphy(struct brcms_phy *pi); + +extern void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, + u8 rxcore_bitmask); +extern u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih); + +extern void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type); +extern void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi); +extern void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi); +extern void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi); +extern u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi); + +extern struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi); +extern int wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, + struct nphy_txgains target_gain, + bool full, bool m); +extern int wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi, + struct nphy_txgains target_gain, + u8 type, bool d); +extern void wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, + s8 txpwrindex, bool res); +extern void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core, u8 rssi_type); +extern int wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type, + s32 *rssi_buf, u8 nsamps); +extern void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi); +extern int wlc_phy_aci_scan_nphy(struct brcms_phy *pi); +extern void wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi, + s32 dBm_targetpower, bool debug); +extern int wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val, + u8 mode, u8, bool); +extern void wlc_phy_stopplayback_nphy(struct brcms_phy *pi); +extern void wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf, + u8 num_samps); +extern void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi); + +extern int wlc_phy_rssi_compute_nphy(struct brcms_phy *pi, + struct d11rxhdr *rxh); #define NPHY_TESTPATTERN_BPHY_EVM 0 #define NPHY_TESTPATTERN_BPHY_RFCS 1 -void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs); +extern void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs); void wlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset, s8 *ofdmoffset); -s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi, u16 chanspec); +extern s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi, + u16 chanspec); -bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pih); +extern bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pih); #endif /* _BRCM_PHY_INT_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h index dd87747..2c5b66b 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy_shim.h @@ -124,49 +124,56 @@ struct brcms_phy; -struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw, - struct brcms_info *wl, - struct brcms_c_info *wlc); -void wlc_phy_shim_detach(struct phy_shim_info *physhim); +extern struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw, + struct brcms_info *wl, + struct brcms_c_info *wlc); +extern void wlc_phy_shim_detach(struct phy_shim_info *physhim); /* PHY to WL utility functions */ -struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim, - void (*fn)(struct brcms_phy *pi), - void *arg, const char *name); -void wlapi_free_timer(struct wlapi_timer *t); -void wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic); -bool wlapi_del_timer(struct wlapi_timer *t); -void wlapi_intrson(struct phy_shim_info *physhim); -u32 wlapi_intrsoff(struct phy_shim_info *physhim); -void wlapi_intrsrestore(struct phy_shim_info *physhim, u32 macintmask); - -void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset, u16 v); -u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset); -void wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx, u16 mask, u16 val, - int bands); -void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags); -void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim); -void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode); -void wlapi_enable_mac(struct phy_shim_info *physhim); -void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask, u32 val); -void wlapi_bmac_phy_reset(struct phy_shim_info *physhim); -void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw); -void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk); -void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk); -void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on); -void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim); -void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info *physhim); -void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info *physhim); -void wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int o, - int len, void *buf); -u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim, u8 rate); -void wlapi_ucode_sample_init(struct phy_shim_info *physhim); -void wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint, void *buf, - int, u32 sel); -void wlapi_copyto_objmem(struct phy_shim_info *physhim, uint, const void *buf, - int, u32); - -void wlapi_high_update_phy_mode(struct phy_shim_info *physhim, u32 phy_mode); -u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim); +extern struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim, + void (*fn) (struct brcms_phy *pi), + void *arg, const char *name); +extern void wlapi_free_timer(struct wlapi_timer *t); +extern void wlapi_add_timer(struct wlapi_timer *t, uint ms, int periodic); +extern bool wlapi_del_timer(struct wlapi_timer *t); +extern void wlapi_intrson(struct phy_shim_info *physhim); +extern u32 wlapi_intrsoff(struct phy_shim_info *physhim); +extern void wlapi_intrsrestore(struct phy_shim_info *physhim, + u32 macintmask); + +extern void wlapi_bmac_write_shm(struct phy_shim_info *physhim, uint offset, + u16 v); +extern u16 wlapi_bmac_read_shm(struct phy_shim_info *physhim, uint offset); +extern void wlapi_bmac_mhf(struct phy_shim_info *physhim, u8 idx, + u16 mask, u16 val, int bands); +extern void wlapi_bmac_corereset(struct phy_shim_info *physhim, u32 flags); +extern void wlapi_suspend_mac_and_wait(struct phy_shim_info *physhim); +extern void wlapi_switch_macfreq(struct phy_shim_info *physhim, u8 spurmode); +extern void wlapi_enable_mac(struct phy_shim_info *physhim); +extern void wlapi_bmac_mctrl(struct phy_shim_info *physhim, u32 mask, + u32 val); +extern void wlapi_bmac_phy_reset(struct phy_shim_info *physhim); +extern void wlapi_bmac_bw_set(struct phy_shim_info *physhim, u16 bw); +extern void wlapi_bmac_phyclk_fgc(struct phy_shim_info *physhim, bool clk); +extern void wlapi_bmac_macphyclk_set(struct phy_shim_info *physhim, bool clk); +extern void wlapi_bmac_core_phypll_ctl(struct phy_shim_info *physhim, bool on); +extern void wlapi_bmac_core_phypll_reset(struct phy_shim_info *physhim); +extern void wlapi_bmac_ucode_wake_override_phyreg_set(struct phy_shim_info * + physhim); +extern void wlapi_bmac_ucode_wake_override_phyreg_clear(struct phy_shim_info * + physhim); +extern void wlapi_bmac_write_template_ram(struct phy_shim_info *physhim, int o, + int len, void *buf); +extern u16 wlapi_bmac_rate_shm_offset(struct phy_shim_info *physhim, + u8 rate); +extern void wlapi_ucode_sample_init(struct phy_shim_info *physhim); +extern void wlapi_copyfrom_objmem(struct phy_shim_info *physhim, uint, + void *buf, int, u32 sel); +extern void wlapi_copyto_objmem(struct phy_shim_info *physhim, uint, + const void *buf, int, u32); + +extern void wlapi_high_update_phy_mode(struct phy_shim_info *physhim, + u32 phy_mode); +extern u16 wlapi_bmac_get_txant(struct phy_shim_info *physhim); #endif /* _BRCM_PHY_SHIM_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pmu.h b/drivers/net/wireless/brcm80211/brcmsmac/pmu.h index a014bbc..20e2012 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/pmu.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/pmu.h @@ -20,7 +20,7 @@ #include "types.h" -u16 si_pmu_fast_pwrup_delay(struct si_pub *sih); -u32 si_pmu_measure_alpclk(struct si_pub *sih); +extern u16 si_pmu_fast_pwrup_delay(struct si_pub *sih); +extern u32 si_pmu_measure_alpclk(struct si_pub *sih); #endif /* _BRCM_PMU_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h index 4da38cb..d36ea5e 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h @@ -266,76 +266,83 @@ struct brcms_antselcfg { }; /* common functions for every port */ -struct brcms_c_info *brcms_c_attach(struct brcms_info *wl, - struct bcma_device *core, uint unit, - bool piomode, uint *perr); -uint brcms_c_detach(struct brcms_c_info *wlc); -int brcms_c_up(struct brcms_c_info *wlc); -uint brcms_c_down(struct brcms_c_info *wlc); - -bool brcms_c_chipmatch(struct bcma_device *core); -void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx); -void brcms_c_reset(struct brcms_c_info *wlc); - -void brcms_c_intrson(struct brcms_c_info *wlc); -u32 brcms_c_intrsoff(struct brcms_c_info *wlc); -void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask); -bool brcms_c_intrsupd(struct brcms_c_info *wlc); -bool brcms_c_isr(struct brcms_c_info *wlc); -bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded); -bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, - struct ieee80211_hw *hw); -bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid); -void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val); -int brcms_c_get_header_len(void); -void brcms_c_set_addrmatch(struct brcms_c_info *wlc, int match_reg_offset, - const u8 *addr); -void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, - const struct ieee80211_tx_queue_params *arg, - bool suspend); -struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc); -void brcms_c_ampdu_flush(struct brcms_c_info *wlc, struct ieee80211_sta *sta, - u16 tid); -void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, - u8 ba_wsize, uint max_rx_ampdu_bytes); -int brcms_c_module_register(struct brcms_pub *pub, const char *name, - struct brcms_info *hdl, - int (*down_fn)(void *handle)); -int brcms_c_module_unregister(struct brcms_pub *pub, const char *name, - struct brcms_info *hdl); -void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc); -void brcms_c_enable_mac(struct brcms_c_info *wlc); -void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state); -void brcms_c_scan_start(struct brcms_c_info *wlc); -void brcms_c_scan_stop(struct brcms_c_info *wlc); -int brcms_c_get_curband(struct brcms_c_info *wlc); -int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel); -int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl); -void brcms_c_get_current_rateset(struct brcms_c_info *wlc, +extern struct brcms_c_info * +brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit, + bool piomode, uint *perr); +extern uint brcms_c_detach(struct brcms_c_info *wlc); +extern int brcms_c_up(struct brcms_c_info *wlc); +extern uint brcms_c_down(struct brcms_c_info *wlc); + +extern bool brcms_c_chipmatch(struct bcma_device *core); +extern void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx); +extern void brcms_c_reset(struct brcms_c_info *wlc); + +extern void brcms_c_intrson(struct brcms_c_info *wlc); +extern u32 brcms_c_intrsoff(struct brcms_c_info *wlc); +extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask); +extern bool brcms_c_intrsupd(struct brcms_c_info *wlc); +extern bool brcms_c_isr(struct brcms_c_info *wlc); +extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded); +extern bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, + struct sk_buff *sdu, + struct ieee80211_hw *hw); +extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid); +extern void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, + int val); +extern int brcms_c_get_header_len(void); +extern void brcms_c_set_addrmatch(struct brcms_c_info *wlc, + int match_reg_offset, + const u8 *addr); +extern void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, + const struct ieee80211_tx_queue_params *arg, + bool suspend); +extern struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc); +extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc, + struct ieee80211_sta *sta, u16 tid); +extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, + u8 ba_wsize, uint max_rx_ampdu_bytes); +extern int brcms_c_module_register(struct brcms_pub *pub, + const char *name, struct brcms_info *hdl, + int (*down_fn)(void *handle)); +extern int brcms_c_module_unregister(struct brcms_pub *pub, const char *name, + struct brcms_info *hdl); +extern void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc); +extern void brcms_c_enable_mac(struct brcms_c_info *wlc); +extern void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state); +extern void brcms_c_scan_start(struct brcms_c_info *wlc); +extern void brcms_c_scan_stop(struct brcms_c_info *wlc); +extern int brcms_c_get_curband(struct brcms_c_info *wlc); +extern int brcms_c_set_channel(struct brcms_c_info *wlc, u16 channel); +extern int brcms_c_set_rate_limit(struct brcms_c_info *wlc, u16 srl, u16 lrl); +extern void brcms_c_get_current_rateset(struct brcms_c_info *wlc, struct brcm_rateset *currs); -int brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcm_rateset *rs); -int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period); -u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx); -void brcms_c_set_shortslot_override(struct brcms_c_info *wlc, +extern int brcms_c_set_rateset(struct brcms_c_info *wlc, + struct brcm_rateset *rs); +extern int brcms_c_set_beacon_period(struct brcms_c_info *wlc, u16 period); +extern u16 brcms_c_get_phy_type(struct brcms_c_info *wlc, int phyidx); +extern void brcms_c_set_shortslot_override(struct brcms_c_info *wlc, s8 sslot_override); -void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, u8 interval); -u64 brcms_c_tsf_get(struct brcms_c_info *wlc); -void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf); -int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr); -int brcms_c_get_tx_power(struct brcms_c_info *wlc); -bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); -void brcms_c_mute(struct brcms_c_info *wlc, bool on); -bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc); -void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr); -void brcms_c_start_ap(struct brcms_c_info *wlc, u8 *addr, const u8 *bssid, - u8 *ssid, size_t ssid_len); -void brcms_c_start_adhoc(struct brcms_c_info *wlc, u8 *addr); -void brcms_c_update_beacon(struct brcms_c_info *wlc); -void brcms_c_set_new_beacon(struct brcms_c_info *wlc, struct sk_buff *beacon, - u16 tim_offset, u16 dtim_period); -void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc, - struct sk_buff *probe_resp); -void brcms_c_enable_probe_resp(struct brcms_c_info *wlc, bool enable); -void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid, size_t ssid_len); +extern void brcms_c_set_beacon_listen_interval(struct brcms_c_info *wlc, + u8 interval); +extern u64 brcms_c_tsf_get(struct brcms_c_info *wlc); +extern void brcms_c_tsf_set(struct brcms_c_info *wlc, u64 tsf); +extern int brcms_c_set_tx_power(struct brcms_c_info *wlc, int txpwr); +extern int brcms_c_get_tx_power(struct brcms_c_info *wlc); +extern bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc); +extern void brcms_c_mute(struct brcms_c_info *wlc, bool on); +extern bool brcms_c_tx_flush_completed(struct brcms_c_info *wlc); +extern void brcms_c_start_station(struct brcms_c_info *wlc, u8 *addr); +extern void brcms_c_start_ap(struct brcms_c_info *wlc, u8 *addr, + const u8 *bssid, u8 *ssid, size_t ssid_len); +extern void brcms_c_start_adhoc(struct brcms_c_info *wlc, u8 *addr); +extern void brcms_c_update_beacon(struct brcms_c_info *wlc); +extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc, + struct sk_buff *beacon, u16 tim_offset, + u16 dtim_period); +extern void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc, + struct sk_buff *probe_resp); +extern void brcms_c_enable_probe_resp(struct brcms_c_info *wlc, bool enable); +extern void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid, + size_t ssid_len); #endif /* _BRCM_PUB_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/rate.h b/drivers/net/wireless/brcm80211/brcmsmac/rate.h index 5bb88b7..980d578 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/rate.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/rate.h @@ -216,30 +216,34 @@ static inline u8 cck_phy2mac_rate(u8 signal) /* sanitize, and sort a rateset with the basic bit(s) preserved, validate * rateset */ -bool brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs, - const struct brcms_c_rateset *hw_rs, - bool check_brate, u8 txstreams); +extern bool +brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs, + const struct brcms_c_rateset *hw_rs, + bool check_brate, u8 txstreams); /* copy rateset src to dst as-is (no masking or sorting) */ -void brcms_c_rateset_copy(const struct brcms_c_rateset *src, - struct brcms_c_rateset *dst); +extern void brcms_c_rateset_copy(const struct brcms_c_rateset *src, + struct brcms_c_rateset *dst); /* would be nice to have these documented ... */ -u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp); - -void brcms_c_rateset_filter(struct brcms_c_rateset *src, - struct brcms_c_rateset *dst, bool basic_only, - u8 rates, uint xmask, bool mcsallow); - -void brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt, - const struct brcms_c_rateset *rs_hw, uint phy_type, - int bandtype, bool cck_only, uint rate_mask, - bool mcsallow, u8 bw, u8 txstreams); - -s16 brcms_c_rate_legacy_phyctl(uint rate); - -void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams); -void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset); -void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset, u8 txstreams); -void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset, u8 bw); +extern u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp); + +extern void brcms_c_rateset_filter(struct brcms_c_rateset *src, + struct brcms_c_rateset *dst, bool basic_only, u8 rates, uint xmask, + bool mcsallow); + +extern void +brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt, + const struct brcms_c_rateset *rs_hw, uint phy_type, + int bandtype, bool cck_only, uint rate_mask, + bool mcsallow, u8 bw, u8 txstreams); + +extern s16 brcms_c_rate_legacy_phyctl(uint rate); + +extern void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams); +extern void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset); +extern void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset, + u8 txstreams); +extern void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset, + u8 bw); #endif /* _BRCM_RATE_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/stf.h b/drivers/net/wireless/brcm80211/brcmsmac/stf.h index ba94930..19f6580 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/stf.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/stf.h @@ -19,19 +19,24 @@ #include "types.h" -int brcms_c_stf_attach(struct brcms_c_info *wlc); -void brcms_c_stf_detach(struct brcms_c_info *wlc); +extern int brcms_c_stf_attach(struct brcms_c_info *wlc); +extern void brcms_c_stf_detach(struct brcms_c_info *wlc); -void brcms_c_tempsense_upd(struct brcms_c_info *wlc); -void brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, - u16 *ss_algo_channel, u16 chanspec); -int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band); -void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc); -int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, bool force); -bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val); -void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc); -void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc); -u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, u32 rspec); -u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, u32 rspec); +extern void brcms_c_tempsense_upd(struct brcms_c_info *wlc); +extern void brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, + u16 *ss_algo_channel, + u16 chanspec); +extern int brcms_c_stf_ss_update(struct brcms_c_info *wlc, + struct brcms_band *band); +extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc); +extern int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, + bool force); +extern bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val); +extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc); +extern void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc); +extern u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, + u32 rspec); +extern u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, + u32 rspec); #endif /* _BRCM_STF_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h index c87dd89..18750a8 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/ucode_loader.h @@ -43,14 +43,16 @@ struct brcms_ucode { u32 *bcm43xx_bomminor; }; -int brcms_ucode_data_init(struct brcms_info *wl, struct brcms_ucode *ucode); +extern int +brcms_ucode_data_init(struct brcms_info *wl, struct brcms_ucode *ucode); -void brcms_ucode_data_free(struct brcms_ucode *ucode); +extern void brcms_ucode_data_free(struct brcms_ucode *ucode); -int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, unsigned int idx); -int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, - unsigned int idx); -void brcms_ucode_free_buf(void *); -int brcms_check_firmwares(struct brcms_info *wl); +extern int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, + unsigned int idx); +extern int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, + unsigned int idx); +extern void brcms_ucode_free_buf(void *); +extern int brcms_check_firmwares(struct brcms_info *wl); #endif /* _BRCM_UCODE_H_ */ diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h index 84113ea..c1fe245 100644 --- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h +++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h @@ -41,6 +41,5 @@ #define BCM4331_CHIP_ID 0x4331 #define BCM4334_CHIP_ID 0x4334 #define BCM4335_CHIP_ID 0x4335 -#define BCM4339_CHIP_ID 0x4339 #endif /* _BRCM_HW_IDS_H_ */ diff --git a/drivers/net/wireless/brcm80211/include/brcmu_d11.h b/drivers/net/wireless/brcm80211/include/brcmu_d11.h index 8660a2c..92623f0 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_d11.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_d11.h @@ -140,6 +140,6 @@ struct brcmu_d11inf { void (*decchspec)(struct brcmu_chan *ch); }; -void brcmu_d11_attach(struct brcmu_d11inf *d11inf); +extern void brcmu_d11_attach(struct brcmu_d11inf *d11inf); #endif /* _BRCMU_CHANNELS_H_ */ diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h index 8ba445b..898cacb 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h @@ -114,29 +114,31 @@ static inline struct sk_buff *pktq_ppeek_tail(struct pktq *pq, int prec) return skb_peek_tail(&pq->q[prec].skblist); } -struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, struct sk_buff *p); -struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec, - struct sk_buff *p); -struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec); -struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec); -struct sk_buff *brcmu_pktq_pdeq_match(struct pktq *pq, int prec, - bool (*match_fn)(struct sk_buff *p, - void *arg), - void *arg); +extern struct sk_buff *brcmu_pktq_penq(struct pktq *pq, int prec, + struct sk_buff *p); +extern struct sk_buff *brcmu_pktq_penq_head(struct pktq *pq, int prec, + struct sk_buff *p); +extern struct sk_buff *brcmu_pktq_pdeq(struct pktq *pq, int prec); +extern struct sk_buff *brcmu_pktq_pdeq_tail(struct pktq *pq, int prec); +extern struct sk_buff *brcmu_pktq_pdeq_match(struct pktq *pq, int prec, + bool (*match_fn)(struct sk_buff *p, + void *arg), + void *arg); /* packet primitives */ -struct sk_buff *brcmu_pkt_buf_get_skb(uint len); -void brcmu_pkt_buf_free_skb(struct sk_buff *skb); +extern struct sk_buff *brcmu_pkt_buf_get_skb(uint len); +extern void brcmu_pkt_buf_free_skb(struct sk_buff *skb); /* Empty the queue at particular precedence level */ /* callback function fn(pkt, arg) returns true if pkt belongs to if */ -void brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir, - bool (*fn)(struct sk_buff *, void *), void *arg); +extern void brcmu_pktq_pflush(struct pktq *pq, int prec, + bool dir, bool (*fn)(struct sk_buff *, void *), void *arg); /* operations on a set of precedences in packet queue */ -int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp); -struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); +extern int brcmu_pktq_mlen(struct pktq *pq, uint prec_bmp); +extern struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp, + int *prec_out); /* operations on packet queue as a whole */ @@ -165,11 +167,11 @@ static inline bool pktq_empty(struct pktq *pq) return pq->len == 0; } -void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len); +extern void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len); /* prec_out may be NULL if caller is not interested in return value */ -struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out); -void brcmu_pktq_flush(struct pktq *pq, bool dir, - bool (*fn)(struct sk_buff *, void *), void *arg); +extern struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out); +extern void brcmu_pktq_flush(struct pktq *pq, bool dir, + bool (*fn)(struct sk_buff *, void *), void *arg); /* externs */ /* ip address */ @@ -202,13 +204,13 @@ static inline u16 brcmu_maskget16(u16 var, u16 mask, u8 shift) /* externs */ /* format/print */ #ifdef DEBUG -void brcmu_prpkt(const char *msg, struct sk_buff *p0); +extern void brcmu_prpkt(const char *msg, struct sk_buff *p0); #else #define brcmu_prpkt(a, b) #endif /* DEBUG */ #ifdef DEBUG -__printf(3, 4) +extern __printf(3, 4) void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...); #else __printf(3, 4) diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c index 40078f5..755a0c8 100644 --- a/drivers/net/wireless/cw1200/cw1200_spi.c +++ b/drivers/net/wireless/cw1200/cw1200_spi.c @@ -365,7 +365,7 @@ static struct hwbus_ops cw1200_spi_hwbus_ops = { static int cw1200_spi_probe(struct spi_device *func) { const struct cw1200_platform_data_spi *plat_data = - dev_get_platdata(&func->dev); + func->dev.platform_data; struct hwbus_priv *self; int status; @@ -443,7 +443,7 @@ static int cw1200_spi_disconnect(struct spi_device *func) } kfree(self); } - cw1200_spi_off(dev_get_platdata(&func->dev)); + cw1200_spi_off(func->dev.platform_data); return 0; } diff --git a/drivers/net/wireless/hostap/hostap_info.c b/drivers/net/wireless/hostap/hostap_info.c index de7c4ff..970a48b 100644 --- a/drivers/net/wireless/hostap/hostap_info.c +++ b/drivers/net/wireless/hostap/hostap_info.c @@ -217,7 +217,7 @@ static void prism2_host_roaming(local_info_t *local) } } - memcpy(req.bssid, selected->bssid, ETH_ALEN); + memcpy(req.bssid, selected->bssid, 6); req.channel = selected->chid; spin_unlock_irqrestore(&local->lock, flags); diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 81903e3..6b823a1 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c @@ -2698,7 +2698,7 @@ static u16 eeprom_read_u16(struct ipw_priv *priv, u8 addr) /* data's copy of the eeprom data */ static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac) { - memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], ETH_ALEN); + memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], 6); } static void ipw_read_eeprom(struct ipw_priv *priv) @@ -11885,6 +11885,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, pci_release_regions(pdev); out_pci_disable_device: pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); out_free_libipw: free_libipw(priv->net_dev, 0); out: @@ -11965,6 +11966,7 @@ static void ipw_pci_remove(struct pci_dev *pdev) iounmap(priv->hw_base); pci_release_regions(pdev); pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); /* wiphy_unregister needs to be here, before free_libipw */ wiphy_unregister(priv->ieee->wdev.wiphy); kfree(priv->ieee->a_band.channels); diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h index 5ce2f59..6eede52 100644 --- a/drivers/net/wireless/ipw2x00/libipw.h +++ b/drivers/net/wireless/ipw2x00/libipw.h @@ -950,55 +950,66 @@ static inline int libipw_is_cck_rate(u8 rate) } /* libipw.c */ -void free_libipw(struct net_device *dev, int monitor); -struct net_device *alloc_libipw(int sizeof_priv, int monitor); -int libipw_change_mtu(struct net_device *dev, int new_mtu); +extern void free_libipw(struct net_device *dev, int monitor); +extern struct net_device *alloc_libipw(int sizeof_priv, int monitor); +extern int libipw_change_mtu(struct net_device *dev, int new_mtu); -void libipw_networks_age(struct libipw_device *ieee, unsigned long age_secs); +extern void libipw_networks_age(struct libipw_device *ieee, + unsigned long age_secs); -int libipw_set_encryption(struct libipw_device *ieee); +extern int libipw_set_encryption(struct libipw_device *ieee); /* libipw_tx.c */ -netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev); -void libipw_txb_free(struct libipw_txb *); +extern netdev_tx_t libipw_xmit(struct sk_buff *skb, + struct net_device *dev); +extern void libipw_txb_free(struct libipw_txb *); /* libipw_rx.c */ -void libipw_rx_any(struct libipw_device *ieee, struct sk_buff *skb, - struct libipw_rx_stats *stats); -int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb, - struct libipw_rx_stats *rx_stats); +extern void libipw_rx_any(struct libipw_device *ieee, + struct sk_buff *skb, struct libipw_rx_stats *stats); +extern int libipw_rx(struct libipw_device *ieee, struct sk_buff *skb, + struct libipw_rx_stats *rx_stats); /* make sure to set stats->len */ -void libipw_rx_mgt(struct libipw_device *ieee, struct libipw_hdr_4addr *header, - struct libipw_rx_stats *stats); -void libipw_network_reset(struct libipw_network *network); +extern void libipw_rx_mgt(struct libipw_device *ieee, + struct libipw_hdr_4addr *header, + struct libipw_rx_stats *stats); +extern void libipw_network_reset(struct libipw_network *network); /* libipw_geo.c */ -const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee); -void libipw_set_geo(struct libipw_device *ieee, const struct libipw_geo *geo); - -int libipw_is_valid_channel(struct libipw_device *ieee, u8 channel); -int libipw_channel_to_index(struct libipw_device *ieee, u8 channel); -u8 libipw_freq_to_channel(struct libipw_device *ieee, u32 freq); -u8 libipw_get_channel_flags(struct libipw_device *ieee, u8 channel); -const struct libipw_channel *libipw_get_channel(struct libipw_device *ieee, - u8 channel); -u32 libipw_channel_to_freq(struct libipw_device *ieee, u8 channel); +extern const struct libipw_geo *libipw_get_geo(struct libipw_device + *ieee); +extern void libipw_set_geo(struct libipw_device *ieee, + const struct libipw_geo *geo); + +extern int libipw_is_valid_channel(struct libipw_device *ieee, + u8 channel); +extern int libipw_channel_to_index(struct libipw_device *ieee, + u8 channel); +extern u8 libipw_freq_to_channel(struct libipw_device *ieee, u32 freq); +extern u8 libipw_get_channel_flags(struct libipw_device *ieee, + u8 channel); +extern const struct libipw_channel *libipw_get_channel(struct + libipw_device + *ieee, u8 channel); +extern u32 libipw_channel_to_freq(struct libipw_device * ieee, + u8 channel); /* libipw_wx.c */ -int libipw_wx_get_scan(struct libipw_device *ieee, struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -int libipw_wx_set_encode(struct libipw_device *ieee, - struct iw_request_info *info, union iwreq_data *wrqu, - char *key); -int libipw_wx_get_encode(struct libipw_device *ieee, - struct iw_request_info *info, union iwreq_data *wrqu, - char *key); -int libipw_wx_set_encodeext(struct libipw_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -int libipw_wx_get_encodeext(struct libipw_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); +extern int libipw_wx_get_scan(struct libipw_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key); +extern int libipw_wx_set_encode(struct libipw_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key); +extern int libipw_wx_get_encode(struct libipw_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key); +extern int libipw_wx_set_encodeext(struct libipw_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +extern int libipw_wx_get_encodeext(struct libipw_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); static inline void libipw_increment_scans(struct libipw_device *ieee) { diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index dea3b50..9581d07 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -3811,6 +3811,7 @@ out_iounmap: out_pci_release_regions: pci_release_regions(pdev); out_pci_disable_device: + pci_set_drvdata(pdev, NULL); pci_disable_device(pdev); out_ieee80211_free_hw: ieee80211_free_hw(il->hw); @@ -3887,6 +3888,7 @@ il3945_pci_remove(struct pci_dev *pdev) iounmap(il->hw_base); pci_release_regions(pdev); pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); il_free_channel_map(il); il_free_geos(il); diff --git a/drivers/net/wireless/iwlegacy/3945.h b/drivers/net/wireless/iwlegacy/3945.h index 00030d4..9a8703d 100644 --- a/drivers/net/wireless/iwlegacy/3945.h +++ b/drivers/net/wireless/iwlegacy/3945.h @@ -189,14 +189,15 @@ struct il3945_ibss_seq { * for use by iwl-*.c * *****************************************************************************/ -int il3945_calc_db_from_ratio(int sig_ratio); -void il3945_rx_replenish(void *data); -void il3945_rx_queue_reset(struct il_priv *il, struct il_rx_queue *rxq); -unsigned int il3945_fill_beacon_frame(struct il_priv *il, - struct ieee80211_hdr *hdr, int left); -int il3945_dump_nic_event_log(struct il_priv *il, bool full_log, char **buf, - bool display); -void il3945_dump_nic_error_log(struct il_priv *il); +extern int il3945_calc_db_from_ratio(int sig_ratio); +extern void il3945_rx_replenish(void *data); +extern void il3945_rx_queue_reset(struct il_priv *il, struct il_rx_queue *rxq); +extern unsigned int il3945_fill_beacon_frame(struct il_priv *il, + struct ieee80211_hdr *hdr, + int left); +extern int il3945_dump_nic_event_log(struct il_priv *il, bool full_log, + char **buf, bool display); +extern void il3945_dump_nic_error_log(struct il_priv *il); /****************************************************************************** * @@ -214,36 +215,39 @@ void il3945_dump_nic_error_log(struct il_priv *il); * il3945_mac_ <-- mac80211 callback * ****************************************************************************/ -void il3945_hw_handler_setup(struct il_priv *il); -void il3945_hw_setup_deferred_work(struct il_priv *il); -void il3945_hw_cancel_deferred_work(struct il_priv *il); -int il3945_hw_rxq_stop(struct il_priv *il); -int il3945_hw_set_hw_params(struct il_priv *il); -int il3945_hw_nic_init(struct il_priv *il); -int il3945_hw_nic_stop_master(struct il_priv *il); -void il3945_hw_txq_ctx_free(struct il_priv *il); -void il3945_hw_txq_ctx_stop(struct il_priv *il); -int il3945_hw_nic_reset(struct il_priv *il); -int il3945_hw_txq_attach_buf_to_tfd(struct il_priv *il, struct il_tx_queue *txq, - dma_addr_t addr, u16 len, u8 reset, u8 pad); -void il3945_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq); -int il3945_hw_get_temperature(struct il_priv *il); -int il3945_hw_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq); -unsigned int il3945_hw_get_beacon_cmd(struct il_priv *il, - struct il3945_frame *frame, u8 rate); +extern void il3945_hw_handler_setup(struct il_priv *il); +extern void il3945_hw_setup_deferred_work(struct il_priv *il); +extern void il3945_hw_cancel_deferred_work(struct il_priv *il); +extern int il3945_hw_rxq_stop(struct il_priv *il); +extern int il3945_hw_set_hw_params(struct il_priv *il); +extern int il3945_hw_nic_init(struct il_priv *il); +extern int il3945_hw_nic_stop_master(struct il_priv *il); +extern void il3945_hw_txq_ctx_free(struct il_priv *il); +extern void il3945_hw_txq_ctx_stop(struct il_priv *il); +extern int il3945_hw_nic_reset(struct il_priv *il); +extern int il3945_hw_txq_attach_buf_to_tfd(struct il_priv *il, + struct il_tx_queue *txq, + dma_addr_t addr, u16 len, u8 reset, + u8 pad); +extern void il3945_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq); +extern int il3945_hw_get_temperature(struct il_priv *il); +extern int il3945_hw_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq); +extern unsigned int il3945_hw_get_beacon_cmd(struct il_priv *il, + struct il3945_frame *frame, + u8 rate); void il3945_hw_build_tx_cmd_rate(struct il_priv *il, struct il_device_cmd *cmd, struct ieee80211_tx_info *info, struct ieee80211_hdr *hdr, int sta_id); -int il3945_hw_reg_send_txpower(struct il_priv *il); -int il3945_hw_reg_set_txpower(struct il_priv *il, s8 power); -void il3945_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb); +extern int il3945_hw_reg_send_txpower(struct il_priv *il); +extern int il3945_hw_reg_set_txpower(struct il_priv *il, s8 power); +extern void il3945_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb); void il3945_hdl_c_stats(struct il_priv *il, struct il_rx_buf *rxb); -void il3945_disable_events(struct il_priv *il); -int il4965_get_temperature(const struct il_priv *il); -void il3945_post_associate(struct il_priv *il); -void il3945_config_ap(struct il_priv *il); +extern void il3945_disable_events(struct il_priv *il); +extern int il4965_get_temperature(const struct il_priv *il); +extern void il3945_post_associate(struct il_priv *il); +extern void il3945_config_ap(struct il_priv *il); -int il3945_commit_rxon(struct il_priv *il); +extern int il3945_commit_rxon(struct il_priv *il); /** * il3945_hw_find_station - Find station id for a given BSSID @@ -253,14 +257,14 @@ int il3945_commit_rxon(struct il_priv *il); * not yet been merged into a single common layer for managing the * station tables. */ -u8 il3945_hw_find_station(struct il_priv *il, const u8 *bssid); +extern u8 il3945_hw_find_station(struct il_priv *il, const u8 * bssid); -__le32 il3945_get_antenna_flags(const struct il_priv *il); -int il3945_init_hw_rate_table(struct il_priv *il); -void il3945_reg_txpower_periodic(struct il_priv *il); -int il3945_txpower_set_from_eeprom(struct il_priv *il); +extern __le32 il3945_get_antenna_flags(const struct il_priv *il); +extern int il3945_init_hw_rate_table(struct il_priv *il); +extern void il3945_reg_txpower_periodic(struct il_priv *il); +extern int il3945_txpower_set_from_eeprom(struct il_priv *il); -int il3945_rs_next_rate(struct il_priv *il, int rate); +extern int il3945_rs_next_rate(struct il_priv *il, int rate); /* scanning */ int il3945_request_scan(struct il_priv *il, struct ieee80211_vif *vif); diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 3982ab7..5ab50a5 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -6706,6 +6706,7 @@ out_free_eeprom: out_iounmap: iounmap(il->hw_base); out_pci_release_regions: + pci_set_drvdata(pdev, NULL); pci_release_regions(pdev); out_pci_disable_device: pci_disable_device(pdev); @@ -6786,6 +6787,7 @@ il4965_pci_remove(struct pci_dev *pdev) iounmap(il->hw_base); pci_release_regions(pdev); pci_disable_device(pdev); + pci_set_drvdata(pdev, NULL); il4965_uninit_drv(il); diff --git a/drivers/net/wireless/iwlegacy/4965.h b/drivers/net/wireless/iwlegacy/4965.h index 337dfcf..1b15b0b 100644 --- a/drivers/net/wireless/iwlegacy/4965.h +++ b/drivers/net/wireless/iwlegacy/4965.h @@ -272,7 +272,7 @@ il4965_hw_valid_rtc_data_addr(u32 addr) ((t) < IL_TX_POWER_TEMPERATURE_MIN || \ (t) > IL_TX_POWER_TEMPERATURE_MAX) -void il4965_temperature_calib(struct il_priv *il); +extern void il4965_temperature_calib(struct il_priv *il); /********************* END TEMPERATURE ***************************************/ /********************* START TXPOWER *****************************************/ diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index ad123d6..83f8ed8 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h @@ -858,9 +858,9 @@ struct il_hw_params { * il4965_mac_ <-- mac80211 callback * ****************************************************************************/ -void il4965_update_chain_flags(struct il_priv *il); +extern void il4965_update_chain_flags(struct il_priv *il); extern const u8 il_bcast_addr[ETH_ALEN]; -int il_queue_space(const struct il_queue *q); +extern int il_queue_space(const struct il_queue *q); static inline int il_queue_used(const struct il_queue *q, int i) { @@ -1727,7 +1727,7 @@ int il_alloc_txq_mem(struct il_priv *il); void il_free_txq_mem(struct il_priv *il); #ifdef CONFIG_IWLEGACY_DEBUGFS -void il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len); +extern void il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len); #else static inline void il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len) @@ -1760,12 +1760,12 @@ void il_chswitch_done(struct il_priv *il, bool is_success); /***************************************************** * TX ******************************************************/ -void il_txq_update_write_ptr(struct il_priv *il, struct il_tx_queue *txq); -int il_tx_queue_init(struct il_priv *il, u32 txq_id); -void il_tx_queue_reset(struct il_priv *il, u32 txq_id); -void il_tx_queue_unmap(struct il_priv *il, int txq_id); -void il_tx_queue_free(struct il_priv *il, int txq_id); -void il_setup_watchdog(struct il_priv *il); +extern void il_txq_update_write_ptr(struct il_priv *il, struct il_tx_queue *txq); +extern int il_tx_queue_init(struct il_priv *il, u32 txq_id); +extern void il_tx_queue_reset(struct il_priv *il, u32 txq_id); +extern void il_tx_queue_unmap(struct il_priv *il, int txq_id); +extern void il_tx_queue_free(struct il_priv *il, int txq_id); +extern void il_setup_watchdog(struct il_priv *il); /***************************************************** * TX power ****************************************************/ @@ -1931,10 +1931,10 @@ il_is_ready_rf(struct il_priv *il) return il_is_ready(il); } -void il_send_bt_config(struct il_priv *il); -int il_send_stats_request(struct il_priv *il, u8 flags, bool clear); -void il_apm_stop(struct il_priv *il); -void _il_apm_stop(struct il_priv *il); +extern void il_send_bt_config(struct il_priv *il); +extern int il_send_stats_request(struct il_priv *il, u8 flags, bool clear); +extern void il_apm_stop(struct il_priv *il); +extern void _il_apm_stop(struct il_priv *il); int il_apm_init(struct il_priv *il); @@ -1968,15 +1968,15 @@ void il_tx_cmd_protection(struct il_priv *il, struct ieee80211_tx_info *info, irqreturn_t il_isr(int irq, void *data); -void il_set_bit(struct il_priv *p, u32 r, u32 m); -void il_clear_bit(struct il_priv *p, u32 r, u32 m); -bool _il_grab_nic_access(struct il_priv *il); -int _il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout); -int il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout); -u32 il_rd_prph(struct il_priv *il, u32 reg); -void il_wr_prph(struct il_priv *il, u32 addr, u32 val); -u32 il_read_targ_mem(struct il_priv *il, u32 addr); -void il_write_targ_mem(struct il_priv *il, u32 addr, u32 val); +extern void il_set_bit(struct il_priv *p, u32 r, u32 m); +extern void il_clear_bit(struct il_priv *p, u32 r, u32 m); +extern bool _il_grab_nic_access(struct il_priv *il); +extern int _il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout); +extern int il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout); +extern u32 il_rd_prph(struct il_priv *il, u32 reg); +extern void il_wr_prph(struct il_priv *il, u32 addr, u32 val); +extern u32 il_read_targ_mem(struct il_priv *il, u32 addr); +extern void il_write_targ_mem(struct il_priv *il, u32 addr, u32 val); static inline void _il_write8(struct il_priv *il, u32 ofs, u8 val) @@ -2868,13 +2868,13 @@ il4965_first_antenna(u8 mask) * The specific throughput table used is based on the type of network * the associated with, including A, B, G, and G w/ TGG protection */ -void il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id); +extern void il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id); /* Initialize station's rate scaling information after adding station */ -void il4965_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, - u8 sta_id); -void il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, - u8 sta_id); +extern void il4965_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, + u8 sta_id); +extern void il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, + u8 sta_id); /** * il_rate_control_register - Register the rate control algorithm callbacks @@ -2886,8 +2886,8 @@ void il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, * ieee80211_register_hw * */ -int il4965_rate_control_register(void); -int il3945_rate_control_register(void); +extern int il4965_rate_control_register(void); +extern int il3945_rate_control_register(void); /** * il_rate_control_unregister - Unregister the rate control callbacks @@ -2895,11 +2895,11 @@ int il3945_rate_control_register(void); * This should be called after calling ieee80211_unregister_hw, but before * the driver is unloaded. */ -void il4965_rate_control_unregister(void); -void il3945_rate_control_unregister(void); +extern void il4965_rate_control_unregister(void); +extern void il3945_rate_control_unregister(void); -int il_power_update_mode(struct il_priv *il, bool force); -void il_power_initialize(struct il_priv *il); +extern int il_power_update_mode(struct il_priv *il, bool force); +extern void il_power_initialize(struct il_priv *il); extern u32 il_debug_level; diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h index 23d5f02..f2a86ff 100644 --- a/drivers/net/wireless/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h @@ -397,7 +397,7 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) return cpu_to_le32(flags|(u32)rate); } -int iwl_alive_start(struct iwl_priv *priv); +extern int iwl_alive_start(struct iwl_priv *priv); #ifdef CONFIG_IWLWIFI_DEBUG void iwl_print_rx_config_cmd(struct iwl_priv *priv, diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h index 7434d9e..a79fdd1 100644 --- a/drivers/net/wireless/iwlwifi/dvm/dev.h +++ b/drivers/net/wireless/iwlwifi/dvm/dev.h @@ -270,7 +270,7 @@ struct iwl_sensitivity_ranges { * iwlXXXX_ <-- Hardware specific (implemented in iwl-XXXX.c for XXXX) * ****************************************************************************/ -void iwl_update_chain_flags(struct iwl_priv *priv); +extern void iwl_update_chain_flags(struct iwl_priv *priv); extern const u8 iwl_bcast_addr[ETH_ALEN]; #define IWL_OPERATION_MODE_AUTO 0 diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.h b/drivers/net/wireless/iwlwifi/dvm/rs.h index 26fc550..5d83cab 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rs.h +++ b/drivers/net/wireless/iwlwifi/dvm/rs.h @@ -407,8 +407,8 @@ static inline u8 first_antenna(u8 mask) /* Initialize station's rate scaling information after adding station */ -void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, - u8 sta_id); +extern void iwl_rs_rate_init(struct iwl_priv *priv, + struct ieee80211_sta *sta, u8 sta_id); /** * iwl_rate_control_register - Register the rate control algorithm callbacks @@ -420,7 +420,7 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, * ieee80211_register_hw * */ -int iwlagn_rate_control_register(void); +extern int iwlagn_rate_control_register(void); /** * iwl_rate_control_unregister - Unregister the rate control callbacks @@ -428,6 +428,6 @@ int iwlagn_rate_control_register(void); * This should be called after calling ieee80211_unregister_hw, but before * the driver is unloaded. */ -void iwlagn_rate_control_unregister(void); +extern void iwlagn_rate_control_unregister(void); #endif /* __iwl_agn__rs__ */ diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index 1fef524..da442b8 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -433,19 +433,27 @@ int iwlagn_tx_skb(struct iwl_priv *priv, /* Copy MAC header from skb into command buffer */ memcpy(tx_cmd->hdr, hdr, hdr_len); - txq_id = info->hw_queue; - if (is_agg) txq_id = priv->tid_data[sta_id][tid].agg.txq_id; else if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) { /* + * Send this frame after DTIM -- there's a special queue + * reserved for this for contexts that support AP mode. + */ + txq_id = ctx->mcast_queue; + + /* * The microcode will clear the more data * bit in the last frame it transmits. */ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); - } + } else if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) + txq_id = IWL_AUX_QUEUE; + else + txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)]; + WARN_ON_ONCE(!is_agg && txq_id != info->hw_queue); WARN_ON_ONCE(is_agg && priv->queue_to_mac80211[txq_id] != info->hw_queue); diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c index 6363794..86270b6 100644 --- a/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c @@ -330,14 +330,15 @@ int iwl_load_ucode_wait_alive(struct iwl_priv *priv, enum iwl_ucode_type old_type; static const u8 alive_cmd[] = { REPLY_ALIVE }; - fw = iwl_get_ucode_image(priv, ucode_type); - if (WARN_ON(!fw)) - return -EINVAL; - old_type = priv->cur_ucode; priv->cur_ucode = ucode_type; + fw = iwl_get_ucode_image(priv, ucode_type); + priv->ucode_loaded = false; + if (!fw) + return -EINVAL; + iwl_init_notification_wait(&priv->notif_wait, &alive_wait, alive_cmd, ARRAY_SIZE(alive_cmd), iwl_alive_fn, &alive_data); diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index 85879db..76e14c0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c @@ -83,8 +83,6 @@ #define IWL7260_TX_POWER_VERSION 0xffff /* meaningless */ #define IWL3160_NVM_VERSION 0x709 #define IWL3160_TX_POWER_VERSION 0xffff /* meaningless */ -#define IWL7265_NVM_VERSION 0x0a1d -#define IWL7265_TX_POWER_VERSION 0xffff /* meaningless */ #define IWL7260_FW_PRE "iwlwifi-7260-" #define IWL7260_MODULE_FIRMWARE(api) IWL7260_FW_PRE __stringify(api) ".ucode" @@ -92,9 +90,6 @@ #define IWL3160_FW_PRE "iwlwifi-3160-" #define IWL3160_MODULE_FIRMWARE(api) IWL3160_FW_PRE __stringify(api) ".ucode" -#define IWL7265_FW_PRE "iwlwifi-7265-" -#define IWL7265_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode" - static const struct iwl_base_params iwl7000_base_params = { .eeprom_size = OTP_LOW_IMAGE_SIZE, .num_of_queues = IWLAGN_NUM_QUEUES, @@ -187,14 +182,5 @@ const struct iwl_cfg iwl3160_n_cfg = { .nvm_calib_ver = IWL3160_TX_POWER_VERSION, }; -const struct iwl_cfg iwl7265_2ac_cfg = { - .name = "Intel(R) Dual Band Wireless AC 7265", - .fw_name_pre = IWL7265_FW_PRE, - IWL_DEVICE_7000, - .ht_params = &iwl7000_ht_params, - .nvm_ver = IWL7265_NVM_VERSION, - .nvm_calib_ver = IWL7265_TX_POWER_VERSION, -}; - MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK)); diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 18f232e..b03c25e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h @@ -293,7 +293,6 @@ extern const struct iwl_cfg iwl7260_n_cfg; extern const struct iwl_cfg iwl3160_2ac_cfg; extern const struct iwl_cfg iwl3160_2n_cfg; extern const struct iwl_cfg iwl3160_n_cfg; -extern const struct iwl_cfg iwl7265_2ac_cfg; #endif /* CONFIG_IWLMVM */ #endif /* __IWL_CONFIG_H__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 54a4fdc..a276af4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -394,38 +394,6 @@ #define CSR_DRAM_INT_TBL_ENABLE (1 << 31) #define CSR_DRAM_INIT_TBL_WRAP_CHECK (1 << 27) -/* SECURE boot registers */ -#define CSR_SECURE_BOOT_CONFIG_ADDR (0x100) -enum secure_boot_config_reg { - CSR_SECURE_BOOT_CONFIG_INSPECTOR_BURNED_IN_OTP = 0x00000001, - CSR_SECURE_BOOT_CONFIG_INSPECTOR_NOT_REQ = 0x00000002, -}; - -#define CSR_SECURE_BOOT_CPU1_STATUS_ADDR (0x100) -#define CSR_SECURE_BOOT_CPU2_STATUS_ADDR (0x100) -enum secure_boot_status_reg { - CSR_SECURE_BOOT_CPU_STATUS_VERF_STATUS = 0x00000003, - CSR_SECURE_BOOT_CPU_STATUS_VERF_COMPLETED = 0x00000002, - CSR_SECURE_BOOT_CPU_STATUS_VERF_SUCCESS = 0x00000004, - CSR_SECURE_BOOT_CPU_STATUS_VERF_FAIL = 0x00000008, - CSR_SECURE_BOOT_CPU_STATUS_SIGN_VERF_FAIL = 0x00000010, -}; - -#define CSR_UCODE_LOAD_STATUS_ADDR (0x100) -enum secure_load_status_reg { - CSR_CPU_STATUS_LOADING_STARTED = 0x00000001, - CSR_CPU_STATUS_LOADING_COMPLETED = 0x00000002, - CSR_CPU_STATUS_NUM_OF_LAST_COMPLETED = 0x000000F8, - CSR_CPU_STATUS_NUM_OF_LAST_LOADED_BLOCK = 0x0000FF00, -}; - -#define CSR_SECURE_INSPECTOR_CODE_ADDR (0x100) -#define CSR_SECURE_INSPECTOR_DATA_ADDR (0x100) - -#define CSR_SECURE_TIME_OUT (100) - -#define FH_TCSR_0_REG0 (0x1D00) - /* * HBUS (Host-side Bus) * diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index ff57002..99e1da3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -483,7 +483,6 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, const u8 *tlv_data; char buildstr[25]; u32 build; - int num_of_cpus; if (len < sizeof(*ucode)) { IWL_ERR(drv, "uCode has invalid length: %zd\n", len); @@ -693,42 +692,6 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, goto invalid_tlv_len; drv->fw.phy_config = le32_to_cpup((__le32 *)tlv_data); break; - case IWL_UCODE_TLV_SECURE_SEC_RT: - iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_REGULAR, - tlv_len); - drv->fw.mvm_fw = true; - drv->fw.img[IWL_UCODE_REGULAR].is_secure = true; - break; - case IWL_UCODE_TLV_SECURE_SEC_INIT: - iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_INIT, - tlv_len); - drv->fw.mvm_fw = true; - drv->fw.img[IWL_UCODE_INIT].is_secure = true; - break; - case IWL_UCODE_TLV_SECURE_SEC_WOWLAN: - iwl_store_ucode_sec(pieces, tlv_data, IWL_UCODE_WOWLAN, - tlv_len); - drv->fw.mvm_fw = true; - drv->fw.img[IWL_UCODE_WOWLAN].is_secure = true; - break; - case IWL_UCODE_TLV_NUM_OF_CPU: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - num_of_cpus = - le32_to_cpup((__le32 *)tlv_data); - - if (num_of_cpus == 2) { - drv->fw.img[IWL_UCODE_REGULAR].is_dual_cpus = - true; - drv->fw.img[IWL_UCODE_INIT].is_dual_cpus = - true; - drv->fw.img[IWL_UCODE_WOWLAN].is_dual_cpus = - true; - } else if ((num_of_cpus > 2) || (num_of_cpus < 1)) { - IWL_ERR(drv, "Driver support upto 2 CPUs\n"); - return -EINVAL; - } - break; default: IWL_DEBUG_INFO(drv, "unknown TLV: %d\n", tlv_type); break; diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h index 6c6c35c..8b6c6fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h @@ -121,10 +121,6 @@ enum iwl_ucode_tlv_type { IWL_UCODE_TLV_SEC_WOWLAN = 21, IWL_UCODE_TLV_DEF_CALIB = 22, IWL_UCODE_TLV_PHY_SKU = 23, - IWL_UCODE_TLV_SECURE_SEC_RT = 24, - IWL_UCODE_TLV_SECURE_SEC_INIT = 25, - IWL_UCODE_TLV_SECURE_SEC_WOWLAN = 26, - IWL_UCODE_TLV_NUM_OF_CPU = 27, }; struct iwl_ucode_tlv { diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index 75db0871..a122368 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h @@ -75,23 +75,11 @@ * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. * @IWL_UCODE_TLV_FLAGS_DW_BC_TABLE: The SCD byte count table is in DWORDS * @IWL_UCODE_TLV_FLAGS_UAPSD: This uCode image supports uAPSD - * @IWL_UCODE_TLV_FLAGS_SHORT_BL: 16 entries of black list instead of 64 in scan - * offload profile config command. * @IWL_UCODE_TLV_FLAGS_RX_ENERGY_API: supports rx signal strength api * @IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2: using the new time event API. * @IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS: D3 image supports up to six * (rather than two) IPv6 addresses * @IWL_UCODE_TLV_FLAGS_BF_UPDATED: new beacon filtering API - * @IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID: not sending a probe with the SSID element - * from the probe request template. - * @IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API: modified D3 API to allow keeping - * connection when going back to D0 - * @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL: new NS offload (small version) - * @IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE: new NS offload (large version) - * @IWL_UCODE_TLV_FLAGS_SCHED_SCAN: this uCode image supports scheduled scan. - * @IWL_UCODE_TLV_FLAGS_STA_KEY_CMD: new ADD_STA and ADD_STA_KEY command API - * @IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD: support device wide power command - * containing CAM (Continuous Active Mode) indication. */ enum iwl_ucode_tlv_flag { IWL_UCODE_TLV_FLAGS_PAN = BIT(0), @@ -99,21 +87,11 @@ enum iwl_ucode_tlv_flag { IWL_UCODE_TLV_FLAGS_MFP = BIT(2), IWL_UCODE_TLV_FLAGS_P2P = BIT(3), IWL_UCODE_TLV_FLAGS_DW_BC_TABLE = BIT(4), - IWL_UCODE_TLV_FLAGS_NEWBT_COEX = BIT(5), - IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT = BIT(6), - IWL_UCODE_TLV_FLAGS_SHORT_BL = BIT(7), + IWL_UCODE_TLV_FLAGS_UAPSD = BIT(6), IWL_UCODE_TLV_FLAGS_RX_ENERGY_API = BIT(8), IWL_UCODE_TLV_FLAGS_TIME_EVENT_API_V2 = BIT(9), IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS = BIT(10), IWL_UCODE_TLV_FLAGS_BF_UPDATED = BIT(11), - IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID = BIT(12), - IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API = BIT(14), - IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL = BIT(15), - IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE = BIT(16), - IWL_UCODE_TLV_FLAGS_SCHED_SCAN = BIT(17), - IWL_UCODE_TLV_FLAGS_STA_KEY_CMD = BIT(19), - IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD = BIT(20), - IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT = BIT(24), }; /* The default calibrate table size if not specified by firmware file */ @@ -155,8 +133,7 @@ enum iwl_ucode_sec { * For 16.0 uCode and above, there is no differentiation between sections, * just an offset to the HW address. */ -#define IWL_UCODE_SECTION_MAX 6 -#define IWL_UCODE_FIRST_SECTION_OF_SECOND_CPU (IWL_UCODE_SECTION_MAX/2) +#define IWL_UCODE_SECTION_MAX 4 struct iwl_ucode_capabilities { u32 max_probe_length; @@ -173,8 +150,6 @@ struct fw_desc { struct fw_img { struct fw_desc sec[IWL_UCODE_SECTION_MAX]; - bool is_secure; - bool is_dual_cpus; }; /* uCode version contains 4 values: Major/Minor/API/Serial */ diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index ad8e19a..dfa4d2e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c @@ -34,6 +34,7 @@ #include "iwl-csr.h" #include "iwl-debug.h" #include "iwl-fh.h" +#include "iwl-csr.h" #define IWL_POLL_INTERVAL 10 /* microseconds */ diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index a70c7b9..ff8cc75 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -97,8 +97,6 @@ #define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800) -#define APMG_RTC_INT_STT_RFKILL (0x10000000) - /* Device system time */ #define DEVICE_SYSTEM_TIME_REG 0xA0206C diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 143292b..80b4750 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -344,7 +344,7 @@ struct iwl_trans_config { u8 cmd_queue; u8 cmd_fifo; const u8 *no_reclaim_cmds; - unsigned int n_no_reclaim_cmds; + int n_no_reclaim_cmds; bool rx_buf_size_8k; bool bc_table_dword; @@ -601,7 +601,7 @@ static inline int iwl_trans_send_cmd(struct iwl_trans *trans, { int ret; - if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) { + if (trans->state != IWL_TRANS_FW_ALIVE) { IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); return -EIO; } @@ -640,8 +640,8 @@ static inline void iwl_trans_free_tx_cmd(struct iwl_trans *trans, static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_device_cmd *dev_cmd, int queue) { - if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); return trans->ops->tx(trans, skb, dev_cmd, queue); } @@ -649,16 +649,16 @@ static inline int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb, static inline void iwl_trans_reclaim(struct iwl_trans *trans, int queue, int ssn, struct sk_buff_head *skbs) { - if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); trans->ops->reclaim(trans, queue, ssn, skbs); } static inline void iwl_trans_txq_disable(struct iwl_trans *trans, int queue) { - if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); trans->ops->txq_disable(trans, queue); } @@ -669,8 +669,8 @@ static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue, { might_sleep(); - if (unlikely((trans->state != IWL_TRANS_FW_ALIVE))) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); trans->ops->txq_enable(trans, queue, fifo, sta_id, tid, frame_limit, ssn); @@ -685,8 +685,8 @@ static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) { - if (unlikely(trans->state != IWL_TRANS_FW_ALIVE)) - IWL_ERR(trans, "%s bad state = %d", __func__, trans->state); + WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, + "%s bad state = %d", __func__, trans->state); return trans->ops->wait_tx_queue_empty(trans); } diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c index 5d066cb..0fad98b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c @@ -98,258 +98,126 @@ static const u8 iwl_bt_prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX] = { #undef EVENT_PRIO_ANT +/* BT Antenna Coupling Threshold (dB) */ +#define IWL_BT_ANTENNA_COUPLING_THRESHOLD (35) +#define IWL_BT_LOAD_FORCE_SISO_THRESHOLD (3) + #define BT_ENABLE_REDUCED_TXPOWER_THRESHOLD (-62) #define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65) -#define BT_ANTENNA_COUPLING_THRESHOLD (30) +#define BT_REDUCED_TX_POWER_BIT BIT(7) -int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm) +static inline bool is_loose_coex(void) { - if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWBT_COEX)) - return 0; + return iwlwifi_mod_params.ant_coupling > + IWL_BT_ANTENNA_COUPLING_THRESHOLD; +} +int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm) +{ return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PRIO_TABLE, CMD_SYNC, sizeof(struct iwl_bt_coex_prio_tbl_cmd), &iwl_bt_prio_tbl); } -const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = { +static int iwl_send_bt_env(struct iwl_mvm *mvm, u8 action, u8 type) +{ + struct iwl_bt_coex_prot_env_cmd env_cmd; + int ret; + + env_cmd.action = action; + env_cmd.type = type; + ret = iwl_mvm_send_cmd_pdu(mvm, BT_COEX_PROT_ENV, CMD_SYNC, + sizeof(env_cmd), &env_cmd); + if (ret) + IWL_ERR(mvm, "failed to send BT env command\n"); + return ret; +} + +enum iwl_bt_kill_msk { + BT_KILL_MSK_DEFAULT, + BT_KILL_MSK_SCO_HID_A2DP, + BT_KILL_MSK_REDUCED_TXPOW, + BT_KILL_MSK_MAX, +}; + +static const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX] = { [BT_KILL_MSK_DEFAULT] = 0xffff0000, [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff, [BT_KILL_MSK_REDUCED_TXPOW] = 0, }; -const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX] = { +static const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX] = { [BT_KILL_MSK_DEFAULT] = 0xffff0000, [BT_KILL_MSK_SCO_HID_A2DP] = 0xffffffff, [BT_KILL_MSK_REDUCED_TXPOW] = 0, }; -static const __le32 iwl_bt_prio_boost[BT_COEX_BOOST_SIZE] = { - cpu_to_le32(0xf0f0f0f0), - cpu_to_le32(0xc0c0c0c0), - cpu_to_le32(0xfcfcfcfc), - cpu_to_le32(0xff00ff00), +#define IWL_BT_DEFAULT_BOOST (0xf0f0f0f0) + +/* Tight Coex */ +static const __le32 iwl_tight_lookup[BT_COEX_LUT_SIZE] = { + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaeaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xcc00ff28), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0xcc00aaaa), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0xc0004000), + cpu_to_le32(0x00000000), + cpu_to_le32(0xf0005000), + cpu_to_le32(0xf0005000), }; -static const __le32 iwl_single_shared_ant[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = { - { - cpu_to_le32(0x40000000), - cpu_to_le32(0x00000000), - cpu_to_le32(0x44000000), - cpu_to_le32(0x00000000), - cpu_to_le32(0x40000000), - cpu_to_le32(0x00000000), - cpu_to_le32(0x44000000), - cpu_to_le32(0x00000000), - cpu_to_le32(0xc0004000), - cpu_to_le32(0xf0005000), - cpu_to_le32(0xc0004000), - cpu_to_le32(0xf0005000), - }, - { - cpu_to_le32(0x40000000), - cpu_to_le32(0x00000000), - cpu_to_le32(0x44000000), - cpu_to_le32(0x00000000), - cpu_to_le32(0x40000000), - cpu_to_le32(0x00000000), - cpu_to_le32(0x44000000), - cpu_to_le32(0x00000000), - cpu_to_le32(0xc0004000), - cpu_to_le32(0xf0005000), - cpu_to_le32(0xc0004000), - cpu_to_le32(0xf0005000), - }, - { - cpu_to_le32(0x40000000), - cpu_to_le32(0x00000000), - cpu_to_le32(0x44000000), - cpu_to_le32(0x00000000), - cpu_to_le32(0x40000000), - cpu_to_le32(0x00000000), - cpu_to_le32(0x44000000), - cpu_to_le32(0x00000000), - cpu_to_le32(0xc0004000), - cpu_to_le32(0xf0005000), - cpu_to_le32(0xc0004000), - cpu_to_le32(0xf0005000), - }, +/* Loose Coex */ +static const __le32 iwl_loose_lookup[BT_COEX_LUT_SIZE] = { + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xcc00ff28), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0xcc00aaaa), + cpu_to_le32(0x0000aaaa), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0xf0005000), + cpu_to_le32(0xf0005000), }; -static const __le32 iwl_combined_lookup[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = { - { - /* Tight */ - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaeaaaaaa), - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xcc00ff28), - cpu_to_le32(0x0000aaaa), - cpu_to_le32(0xcc00aaaa), - cpu_to_le32(0x0000aaaa), - cpu_to_le32(0xc0004000), - cpu_to_le32(0x00000000), - cpu_to_le32(0xf0005000), - cpu_to_le32(0xf0005000), - }, - { - /* Loose */ - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xcc00ff28), - cpu_to_le32(0x0000aaaa), - cpu_to_le32(0xcc00aaaa), - cpu_to_le32(0x0000aaaa), - cpu_to_le32(0x00000000), - cpu_to_le32(0x00000000), - cpu_to_le32(0xf0005000), - cpu_to_le32(0xf0005000), - }, - { - /* Tx Tx disabled */ - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xaaaaaaaa), - cpu_to_le32(0xcc00ff28), - cpu_to_le32(0x0000aaaa), - cpu_to_le32(0xcc00aaaa), - cpu_to_le32(0x0000aaaa), - cpu_to_le32(0xC0004000), - cpu_to_le32(0xC0004000), - cpu_to_le32(0xF0005000), - cpu_to_le32(0xF0005000), - }, +/* Full concurrency */ +static const __le32 iwl_concurrent_lookup[BT_COEX_LUT_SIZE] = { + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0xaaaaaaaa), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0x00000000), }; -/* 20MHz / 40MHz below / 40Mhz above*/ -static const __le64 iwl_ci_mask[][3] = { - /* dummy entry for channel 0 */ - {cpu_to_le64(0), cpu_to_le64(0), cpu_to_le64(0)}, - { - cpu_to_le64(0x0000001FFFULL), - cpu_to_le64(0x0ULL), - cpu_to_le64(0x00007FFFFFULL), - }, - { - cpu_to_le64(0x000000FFFFULL), - cpu_to_le64(0x0ULL), - cpu_to_le64(0x0003FFFFFFULL), - }, - { - cpu_to_le64(0x000003FFFCULL), - cpu_to_le64(0x0ULL), - cpu_to_le64(0x000FFFFFFCULL), - }, - { - cpu_to_le64(0x00001FFFE0ULL), - cpu_to_le64(0x0ULL), - cpu_to_le64(0x007FFFFFE0ULL), - }, - { - cpu_to_le64(0x00007FFF80ULL), - cpu_to_le64(0x00007FFFFFULL), - cpu_to_le64(0x01FFFFFF80ULL), - }, - { - cpu_to_le64(0x0003FFFC00ULL), - cpu_to_le64(0x0003FFFFFFULL), - cpu_to_le64(0x0FFFFFFC00ULL), - }, - { - cpu_to_le64(0x000FFFF000ULL), - cpu_to_le64(0x000FFFFFFCULL), - cpu_to_le64(0x3FFFFFF000ULL), - }, - { - cpu_to_le64(0x007FFF8000ULL), - cpu_to_le64(0x007FFFFFE0ULL), - cpu_to_le64(0xFFFFFF8000ULL), - }, - { - cpu_to_le64(0x01FFFE0000ULL), - cpu_to_le64(0x01FFFFFF80ULL), - cpu_to_le64(0xFFFFFE0000ULL), - }, - { - cpu_to_le64(0x0FFFF00000ULL), - cpu_to_le64(0x0FFFFFFC00ULL), - cpu_to_le64(0x0ULL), - }, - { - cpu_to_le64(0x3FFFC00000ULL), - cpu_to_le64(0x3FFFFFF000ULL), - cpu_to_le64(0x0) - }, - { - cpu_to_le64(0xFFFE000000ULL), - cpu_to_le64(0xFFFFFF8000ULL), - cpu_to_le64(0x0) - }, - { - cpu_to_le64(0xFFF8000000ULL), - cpu_to_le64(0xFFFFFE0000ULL), - cpu_to_le64(0x0) - }, - { - cpu_to_le64(0xFE00000000ULL), - cpu_to_le64(0x0ULL), - cpu_to_le64(0x0) - }, +/* single shared antenna */ +static const __le32 iwl_single_shared_ant_lookup[BT_COEX_LUT_SIZE] = { + cpu_to_le32(0x40000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0x44000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0x40000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0x44000000), + cpu_to_le32(0x00000000), + cpu_to_le32(0xC0004000), + cpu_to_le32(0xF0005000), + cpu_to_le32(0xC0004000), + cpu_to_le32(0xF0005000), }; -static const __le32 iwl_bt_mprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE] = { - cpu_to_le32(0x22002200), - cpu_to_le32(0x33113311), -}; - -static enum iwl_bt_coex_lut_type -iwl_get_coex_type(struct iwl_mvm *mvm, const struct ieee80211_vif *vif) -{ - struct ieee80211_chanctx_conf *chanctx_conf; - enum iwl_bt_coex_lut_type ret; - u16 phy_ctx_id; - - /* - * Checking that we hold mvm->mutex is a good idea, but the rate - * control can't acquire the mutex since it runs in Tx path. - * So this is racy in that case, but in the worst case, the AMPDU - * size limit will be wrong for a short time which is not a big - * issue. - */ - - rcu_read_lock(); - - chanctx_conf = rcu_dereference(vif->chanctx_conf); - - if (!chanctx_conf || - chanctx_conf->def.chan->band != IEEE80211_BAND_2GHZ) { - rcu_read_unlock(); - return BT_COEX_LOOSE_LUT; - } - - ret = BT_COEX_TX_DIS_LUT; - - if (mvm->cfg->bt_shared_single_ant) { - rcu_read_unlock(); - return ret; - } - - phy_ctx_id = *((u16 *)chanctx_conf->drv_priv); - - if (mvm->last_bt_ci_cmd.primary_ch_phy_id == phy_ctx_id) - ret = le32_to_cpu(mvm->last_bt_notif.primary_ch_lut); - else if (mvm->last_bt_ci_cmd.secondary_ch_phy_id == phy_ctx_id) - ret = le32_to_cpu(mvm->last_bt_notif.secondary_ch_lut); - /* else - default = TX TX disallowed */ - - rcu_read_unlock(); - - return ret; -} - int iwl_send_bt_init_conf(struct iwl_mvm *mvm) { struct iwl_bt_coex_cmd *bt_cmd; @@ -360,10 +228,17 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) .flags = CMD_SYNC, }; int ret; - u32 flags; - if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWBT_COEX)) - return 0; + /* go to CALIB state in internal BT-Coex state machine */ + ret = iwl_send_bt_env(mvm, BT_COEX_ENV_OPEN, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); + if (ret) + return ret; + + ret = iwl_send_bt_env(mvm, BT_COEX_ENV_CLOSE, + BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); + if (ret) + return ret; bt_cmd = kzalloc(sizeof(*bt_cmd), GFP_KERNEL); if (!bt_cmd) @@ -371,52 +246,40 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) cmd.data[0] = bt_cmd; bt_cmd->max_kill = 5; - bt_cmd->bt4_antenna_isolation_thr = BT_ANTENNA_COUPLING_THRESHOLD, - bt_cmd->bt4_antenna_isolation = iwlwifi_mod_params.ant_coupling, - bt_cmd->bt4_tx_tx_delta_freq_thr = 15, - bt_cmd->bt4_tx_rx_max_freq0 = 15, + bt_cmd->bt3_time_t7_value = 1; + bt_cmd->bt3_prio_sample_time = 2; + bt_cmd->bt3_timer_t2_value = 0xc; - flags = iwlwifi_mod_params.bt_coex_active ? + bt_cmd->flags = iwlwifi_mod_params.bt_coex_active ? BT_COEX_NW : BT_COEX_DISABLE; - flags |= BT_CH_PRIMARY_EN | BT_CH_SECONDARY_EN | BT_SYNC_2_BT_DISABLE; - bt_cmd->flags = cpu_to_le32(flags); + bt_cmd->flags |= BT_CH_PRIMARY_EN | BT_SYNC_2_BT_DISABLE; - bt_cmd->valid_bit_msk = cpu_to_le32(BT_VALID_ENABLE | + bt_cmd->valid_bit_msk = cpu_to_le16(BT_VALID_ENABLE | BT_VALID_BT_PRIO_BOOST | BT_VALID_MAX_KILL | BT_VALID_3W_TMRS | BT_VALID_KILL_ACK | BT_VALID_KILL_CTS | BT_VALID_REDUCED_TX_POWER | - BT_VALID_LUT | - BT_VALID_WIFI_RX_SW_PRIO_BOOST | - BT_VALID_WIFI_TX_SW_PRIO_BOOST | - BT_VALID_MULTI_PRIO_LUT | - BT_VALID_CORUN_LUT_20 | - BT_VALID_CORUN_LUT_40 | - BT_VALID_ANT_ISOLATION | - BT_VALID_ANT_ISOLATION_THRS | - BT_VALID_TXTX_DELTA_FREQ_THRS | - BT_VALID_TXRX_MAX_FREQ_0); + BT_VALID_LUT); if (mvm->cfg->bt_shared_single_ant) - memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant, - sizeof(iwl_single_shared_ant)); + memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant_lookup, + sizeof(iwl_single_shared_ant_lookup)); + else if (is_loose_coex()) + memcpy(&bt_cmd->decision_lut, iwl_loose_lookup, + sizeof(iwl_tight_lookup)); else - memcpy(&bt_cmd->decision_lut, iwl_combined_lookup, - sizeof(iwl_combined_lookup)); + memcpy(&bt_cmd->decision_lut, iwl_tight_lookup, + sizeof(iwl_tight_lookup)); - memcpy(&bt_cmd->bt_prio_boost, iwl_bt_prio_boost, - sizeof(iwl_bt_prio_boost)); - memcpy(&bt_cmd->bt4_multiprio_lut, iwl_bt_mprio_lut, - sizeof(iwl_bt_mprio_lut)); + bt_cmd->bt_prio_boost = cpu_to_le32(IWL_BT_DEFAULT_BOOST); bt_cmd->kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[BT_KILL_MSK_DEFAULT]); bt_cmd->kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[BT_KILL_MSK_DEFAULT]); memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif)); - memset(&mvm->last_bt_ci_cmd, 0, sizeof(mvm->last_bt_ci_cmd)); ret = iwl_mvm_send_cmd(mvm, &cmd); @@ -471,17 +334,13 @@ static int iwl_mvm_bt_udpate_ctrl_kill_msk(struct iwl_mvm *mvm, if (!bt_cmd) return -ENOMEM; cmd.data[0] = bt_cmd; - bt_cmd->flags = cpu_to_le32(BT_COEX_NW); bt_cmd->kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]); bt_cmd->kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]); - bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_ENABLE | - BT_VALID_KILL_ACK | - BT_VALID_KILL_CTS); + bt_cmd->valid_bit_msk = + cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS); - IWL_DEBUG_COEX(mvm, "ACK Kill msk = 0x%08x, CTS Kill msk = 0x%08x\n", - iwl_bt_ack_kill_msk[bt_kill_msk], - iwl_bt_cts_kill_msk[bt_kill_msk]); + IWL_DEBUG_COEX(mvm, "bt_kill_msk = %d\n", bt_kill_msk); ret = iwl_mvm_send_cmd(mvm, &cmd); @@ -505,16 +364,12 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id, struct iwl_mvm_sta *mvmsta; int ret; + /* This can happen if the station has been removed right now */ if (sta_id == IWL_MVM_STATION_COUNT) return 0; sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[sta_id], lockdep_is_held(&mvm->mutex)); - - /* This can happen if the station has been removed right now */ - if (IS_ERR_OR_NULL(sta)) - return 0; - mvmsta = (void *)sta->drv_priv; /* nothing to do */ @@ -525,10 +380,8 @@ static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id, if (!bt_cmd) return -ENOMEM; cmd.data[0] = bt_cmd; - bt_cmd->flags = cpu_to_le32(BT_COEX_NW); - bt_cmd->valid_bit_msk = - cpu_to_le32(BT_VALID_ENABLE | BT_VALID_REDUCED_TX_POWER); + bt_cmd->valid_bit_msk = cpu_to_le16(BT_VALID_REDUCED_TX_POWER), bt_cmd->bt_reduced_tx_power = sta_id; if (enable) @@ -550,25 +403,8 @@ struct iwl_bt_iterator_data { struct iwl_mvm *mvm; u32 num_bss_ifaces; bool reduced_tx_power; - struct ieee80211_chanctx_conf *primary; - struct ieee80211_chanctx_conf *secondary; }; -static inline -void iwl_mvm_bt_coex_enable_rssi_event(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - bool enable, int rssi) -{ - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - - mvmvif->bf_data.last_bt_coex_event = rssi; - mvmvif->bf_data.bt_coex_max_thold = - enable ? BT_ENABLE_REDUCED_TXPOWER_THRESHOLD : 0; - mvmvif->bf_data.bt_coex_min_thold = - enable ? BT_DISABLE_REDUCED_TXPOWER_THRESHOLD : 0; -} - -/* must be called under rcu_read_lock */ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, struct ieee80211_vif *vif) { @@ -577,94 +413,65 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, struct iwl_mvm *mvm = data->mvm; struct ieee80211_chanctx_conf *chanctx_conf; enum ieee80211_smps_mode smps_mode; + enum ieee80211_band band; int ave_rssi; lockdep_assert_held(&mvm->mutex); - - if (vif->type != NL80211_IFTYPE_STATION && - vif->type != NL80211_IFTYPE_AP) + if (vif->type != NL80211_IFTYPE_STATION) return; - smps_mode = IEEE80211_SMPS_AUTOMATIC; - + rcu_read_lock(); chanctx_conf = rcu_dereference(vif->chanctx_conf); + if (chanctx_conf && chanctx_conf->def.chan) + band = chanctx_conf->def.chan->band; + else + band = -1; + rcu_read_unlock(); - /* If channel context is invalid or not on 2.4GHz .. */ - if ((!chanctx_conf || - chanctx_conf->def.chan->band != IEEE80211_BAND_2GHZ)) { - /* ... and it is an associated STATION, relax constraints */ - if (vif->type == NL80211_IFTYPE_STATION && vif->bss_conf.assoc) - iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX, - smps_mode); - iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0); - return; - } - - /* SoftAP / GO will always be primary */ - if (vif->type == NL80211_IFTYPE_AP) { - if (!mvmvif->ap_ibss_active) - return; - - /* the Ack / Cts kill mask must be default if AP / GO */ - data->reduced_tx_power = false; - - if (chanctx_conf == data->primary) - return; + smps_mode = IEEE80211_SMPS_AUTOMATIC; - /* downgrade the current primary no matter what its type is */ - data->secondary = data->primary; - data->primary = chanctx_conf; + /* non associated BSSes aren't to be considered */ + if (!vif->bss_conf.assoc) return; - } - data->num_bss_ifaces++; - - /* we are now a STA / P2P Client, and take associated ones only */ - if (!vif->bss_conf.assoc) + if (band != IEEE80211_BAND_2GHZ) { + iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX, + smps_mode); return; + } - /* STA / P2P Client, try to be primary if first vif */ - if (!data->primary || data->primary == chanctx_conf) - data->primary = chanctx_conf; - else if (!data->secondary) - /* if secondary is not NULL, it might be a GO */ - data->secondary = chanctx_conf; + if (data->notif->bt_status) + smps_mode = IEEE80211_SMPS_DYNAMIC; - if (le32_to_cpu(data->notif->bt_activity_grading) >= BT_HIGH_TRAFFIC) + if (data->notif->bt_traffic_load >= IWL_BT_LOAD_FORCE_SISO_THRESHOLD) smps_mode = IEEE80211_SMPS_STATIC; - else if (le32_to_cpu(data->notif->bt_activity_grading) >= - BT_LOW_TRAFFIC) - smps_mode = IEEE80211_SMPS_DYNAMIC; IWL_DEBUG_COEX(data->mvm, - "mac %d: bt_status %d bt_activity_grading %d smps_req %d\n", + "mac %d: bt_status %d traffic_load %d smps_req %d\n", mvmvif->id, data->notif->bt_status, - data->notif->bt_activity_grading, smps_mode); + data->notif->bt_traffic_load, smps_mode); iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX, smps_mode); /* don't reduce the Tx power if in loose scheme */ - if (iwl_get_coex_type(mvm, vif) == BT_COEX_LOOSE_LUT || - mvm->cfg->bt_shared_single_ant) { - data->reduced_tx_power = false; - iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0); + if (is_loose_coex()) return; - } - /* reduced Txpower only if BT is on, so ...*/ - if (!data->notif->bt_status) { + data->num_bss_ifaces++; + + /* reduced Txpower only if there are open BT connections, so ...*/ + if (!BT_MBOX_MSG(data->notif, 3, OPEN_CON_2)) { /* ... cancel reduced Tx power ... */ if (iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false)) IWL_ERR(mvm, "Couldn't send BT_CONFIG cmd\n"); data->reduced_tx_power = false; /* ... and there is no need to get reports on RSSI any more. */ - iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, false, 0); + ieee80211_disable_rssi_reports(vif); return; } - /* try to get the avg rssi from fw */ - ave_rssi = mvmvif->bf_data.ave_beacon_signal; + ave_rssi = ieee80211_ave_rssi(vif); /* if the RSSI isn't valid, fake it is very low */ if (!ave_rssi) @@ -692,7 +499,8 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, } /* Begin to monitor the RSSI: it may influence the reduced Tx power */ - iwl_mvm_bt_coex_enable_rssi_event(mvm, vif, true, ave_rssi); + ieee80211_enable_rssi_reports(vif, BT_DISABLE_REDUCED_TXPOWER_THRESHOLD, + BT_ENABLE_REDUCED_TXPOWER_THRESHOLD); } static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm) @@ -702,72 +510,11 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm) .notif = &mvm->last_bt_notif, .reduced_tx_power = true, }; - struct iwl_bt_coex_ci_cmd cmd = {}; - u8 ci_bw_idx; - rcu_read_lock(); ieee80211_iterate_active_interfaces_atomic( mvm->hw, IEEE80211_IFACE_ITER_NORMAL, iwl_mvm_bt_notif_iterator, &data); - if (data.primary) { - struct ieee80211_chanctx_conf *chan = data.primary; - if (WARN_ON(!chan->def.chan)) { - rcu_read_unlock(); - return; - } - - if (chan->def.width < NL80211_CHAN_WIDTH_40) { - ci_bw_idx = 0; - cmd.co_run_bw_primary = 0; - } else { - cmd.co_run_bw_primary = 1; - if (chan->def.center_freq1 > - chan->def.chan->center_freq) - ci_bw_idx = 2; - else - ci_bw_idx = 1; - } - - cmd.bt_primary_ci = - iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx]; - cmd.primary_ch_phy_id = *((u16 *)data.primary->drv_priv); - } - - if (data.secondary) { - struct ieee80211_chanctx_conf *chan = data.secondary; - if (WARN_ON(!data.secondary->def.chan)) { - rcu_read_unlock(); - return; - } - - if (chan->def.width < NL80211_CHAN_WIDTH_40) { - ci_bw_idx = 0; - cmd.co_run_bw_secondary = 0; - } else { - cmd.co_run_bw_secondary = 1; - if (chan->def.center_freq1 > - chan->def.chan->center_freq) - ci_bw_idx = 2; - else - ci_bw_idx = 1; - } - - cmd.bt_secondary_ci = - iwl_ci_mask[chan->def.chan->hw_value][ci_bw_idx]; - cmd.secondary_ch_phy_id = *((u16 *)data.secondary->drv_priv); - } - - rcu_read_unlock(); - - /* Don't spam the fw with the same command over and over */ - if (memcmp(&cmd, &mvm->last_bt_ci_cmd, sizeof(cmd))) { - if (iwl_mvm_send_cmd_pdu(mvm, BT_COEX_CI, CMD_SYNC, - sizeof(cmd), &cmd)) - IWL_ERR(mvm, "Failed to send BT_CI cmd"); - memcpy(&mvm->last_bt_ci_cmd, &cmd, sizeof(cmd)); - } - /* * If there are no BSS / P2P client interfaces, reduced Tx Power is * irrelevant since it is based on the RSSI coming from the beacon. @@ -789,18 +536,12 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n"); - IWL_DEBUG_COEX(mvm, "\tBT status: %s\n", - notif->bt_status ? "ON" : "OFF"); + IWL_DEBUG_COEX(mvm, "\tBT %salive\n", notif->bt_status ? "" : "not "); IWL_DEBUG_COEX(mvm, "\tBT open conn %d\n", notif->bt_open_conn); - IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance); - IWL_DEBUG_COEX(mvm, "\tBT primary_ch_lut %d\n", - le32_to_cpu(notif->primary_ch_lut)); - IWL_DEBUG_COEX(mvm, "\tBT secondary_ch_lut %d\n", - le32_to_cpu(notif->secondary_ch_lut)); - IWL_DEBUG_COEX(mvm, "\tBT activity grading %d\n", - le32_to_cpu(notif->bt_activity_grading)); + IWL_DEBUG_COEX(mvm, "\tBT traffic load %d\n", notif->bt_traffic_load); IWL_DEBUG_COEX(mvm, "\tBT agg traffic load %d\n", notif->bt_agg_traffic_load); + IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance); /* remember this notification for future use: rssi fluctuations */ memcpy(&mvm->last_bt_notif, notif, sizeof(mvm->last_bt_notif)); @@ -824,18 +565,6 @@ static void iwl_mvm_bt_rssi_iterator(void *_data, u8 *mac, struct ieee80211_sta *sta; struct iwl_mvm_sta *mvmsta; - struct ieee80211_chanctx_conf *chanctx_conf; - - rcu_read_lock(); - chanctx_conf = rcu_dereference(vif->chanctx_conf); - /* If channel context is invalid or not on 2.4GHz - don't count it */ - if (!chanctx_conf || - chanctx_conf->def.chan->band != IEEE80211_BAND_2GHZ) { - rcu_read_unlock(); - return; - } - rcu_read_unlock(); - if (vif->type != NL80211_IFTYPE_STATION || mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT) return; @@ -865,15 +594,15 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, }; int ret; - lockdep_assert_held(&mvm->mutex); + mutex_lock(&mvm->mutex); /* Rssi update while not associated ?! */ if (WARN_ON_ONCE(mvmvif->ap_sta_id == IWL_MVM_STATION_COUNT)) - return; + goto out_unlock; - /* No BT - reports should be disabled */ - if (!mvm->last_bt_notif.bt_status) - return; + /* No open connection - reports should be disabled */ + if (!BT_MBOX_MSG(&mvm->last_bt_notif, 3, OPEN_CON_2)) + goto out_unlock; IWL_DEBUG_COEX(mvm, "RSSI for %pM is now %s\n", vif->bss_conf.bssid, rssi_event == RSSI_EVENT_HIGH ? "HIGH" : "LOW"); @@ -882,8 +611,7 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, * Check if rssi is good enough for reduced Tx power, but not in loose * scheme. */ - if (rssi_event == RSSI_EVENT_LOW || mvm->cfg->bt_shared_single_ant || - iwl_get_coex_type(mvm, vif) == BT_COEX_LOOSE_LUT) + if (rssi_event == RSSI_EVENT_LOW || is_loose_coex()) ret = iwl_mvm_bt_coex_reduced_txp(mvm, mvmvif->ap_sta_id, false); else @@ -905,52 +633,12 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, if (iwl_mvm_bt_udpate_ctrl_kill_msk(mvm, data.reduced_tx_power)) IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n"); -} -#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) -#define LINK_QUAL_AGG_TIME_LIMIT_BT_ACT (1200) - -u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm, - struct ieee80211_sta *sta) -{ - struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; - enum iwl_bt_coex_lut_type lut_type; - - if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < - BT_LOW_TRAFFIC) - return LINK_QUAL_AGG_TIME_LIMIT_DEF; - - lut_type = iwl_get_coex_type(mvm, mvmsta->vif); - - if (lut_type == BT_COEX_LOOSE_LUT) - return LINK_QUAL_AGG_TIME_LIMIT_DEF; - - /* tight coex, high bt traffic, reduce AGG time limit */ - return LINK_QUAL_AGG_TIME_LIMIT_BT_ACT; + out_unlock: + mutex_unlock(&mvm->mutex); } -bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm, - struct ieee80211_sta *sta) +void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { - struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; - - if (le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) < - BT_HIGH_TRAFFIC) - return true; - - /* - * In Tight, BT can't Rx while we Tx, so use both antennas since BT is - * already killed. - * In Loose, BT can Rx while we Tx, so forbid MIMO to let BT Rx while we - * Tx. - */ - return iwl_get_coex_type(mvm, mvmsta->vif) == BT_COEX_TIGHT_LUT; -} - -void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm) -{ - if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWBT_COEX)) - return; - iwl_mvm_bt_coex_notif_handle(mvm); } diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h index 4b6d670..2bf29f7 100644 --- a/drivers/net/wireless/iwlwifi/mvm/constants.h +++ b/drivers/net/wireless/iwlwifi/mvm/constants.h @@ -70,9 +70,7 @@ #define IWL_MVM_UAPSD_RX_DATA_TIMEOUT (50 * USEC_PER_MSEC) #define IWL_MVM_UAPSD_TX_DATA_TIMEOUT (50 * USEC_PER_MSEC) #define IWL_MVM_PS_HEAVY_TX_THLD_PACKETS 20 -#define IWL_MVM_PS_HEAVY_RX_THLD_PACKETS 8 -#define IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS 30 -#define IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS 20 +#define IWL_MVM_PS_HEAVY_RX_THLD_PACKETS 20 #define IWL_MVM_PS_HEAVY_TX_THLD_PERCENT 50 #define IWL_MVM_PS_HEAVY_RX_THLD_PERCENT 50 #define IWL_MVM_PS_SNOOZE_INTERVAL 25 diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index 6f45966..417639f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -67,7 +67,6 @@ #include <net/cfg80211.h> #include <net/ipv6.h> #include <net/tcp.h> -#include <net/addrconf.h> #include "iwl-modparams.h" #include "fw-api.h" #include "mvm.h" @@ -382,74 +381,14 @@ static int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm, union { struct iwl_proto_offload_cmd_v1 v1; struct iwl_proto_offload_cmd_v2 v2; - struct iwl_proto_offload_cmd_v3_small v3s; - struct iwl_proto_offload_cmd_v3_large v3l; } cmd = {}; - struct iwl_host_cmd hcmd = { - .id = PROT_OFFLOAD_CONFIG_CMD, - .flags = CMD_SYNC, - .data[0] = &cmd, - .dataflags[0] = IWL_HCMD_DFL_DUP, - }; struct iwl_proto_offload_cmd_common *common; u32 enabled = 0, size; - u32 capa_flags = mvm->fw->ucode_capa.flags; #if IS_ENABLED(CONFIG_IPV6) struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); int i; - if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL || - capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE) { - struct iwl_ns_config *nsc; - struct iwl_targ_addr *addrs; - int n_nsc, n_addrs; - int c; - - if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL) { - nsc = cmd.v3s.ns_config; - n_nsc = IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3S; - addrs = cmd.v3s.targ_addrs; - n_addrs = IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3S; - } else { - nsc = cmd.v3l.ns_config; - n_nsc = IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L; - addrs = cmd.v3l.targ_addrs; - n_addrs = IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L; - } - - if (mvmvif->num_target_ipv6_addrs) - enabled |= IWL_D3_PROTO_OFFLOAD_NS; - - /* - * For each address we have (and that will fit) fill a target - * address struct and combine for NS offload structs with the - * solicited node addresses. - */ - for (i = 0, c = 0; - i < mvmvif->num_target_ipv6_addrs && - i < n_addrs && c < n_nsc; i++) { - struct in6_addr solicited_addr; - int j; - - addrconf_addr_solict_mult(&mvmvif->target_ipv6_addrs[i], - &solicited_addr); - for (j = 0; j < c; j++) - if (ipv6_addr_cmp(&nsc[j].dest_ipv6_addr, - &solicited_addr) == 0) - break; - if (j == c) - c++; - addrs[i].addr = mvmvif->target_ipv6_addrs[i]; - addrs[i].config_num = cpu_to_le32(j); - nsc[j].dest_ipv6_addr = solicited_addr; - memcpy(nsc[j].target_mac_addr, vif->addr, ETH_ALEN); - } - - if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL) - cmd.v3s.num_valid_ipv6_addrs = cpu_to_le32(i); - else - cmd.v3l.num_valid_ipv6_addrs = cpu_to_le32(i); - } else if (capa_flags & IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS) { + if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS) { if (mvmvif->num_target_ipv6_addrs) { enabled |= IWL_D3_PROTO_OFFLOAD_NS; memcpy(cmd.v2.ndp_mac_addr, vif->addr, ETH_ALEN); @@ -480,13 +419,7 @@ static int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm, } #endif - if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_SMALL) { - common = &cmd.v3s.common; - size = sizeof(cmd.v3s); - } else if (capa_flags & IWL_UCODE_TLV_FLAGS_NEW_NSOFFL_LARGE) { - common = &cmd.v3l.common; - size = sizeof(cmd.v3l); - } else if (capa_flags & IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS) { + if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_6_IPV6_ADDRS) { common = &cmd.v2.common; size = sizeof(cmd.v2); } else { @@ -505,8 +438,8 @@ static int iwl_mvm_send_proto_offload(struct iwl_mvm *mvm, common->enabled = cpu_to_le32(enabled); - hcmd.len[0] = size; - return iwl_mvm_send_cmd(mvm, &hcmd); + return iwl_mvm_send_cmd_pdu(mvm, PROT_OFFLOAD_CONFIG_CMD, CMD_SYNC, + size, &cmd); } enum iwl_mvm_tcp_packet_type { @@ -860,74 +793,6 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif, return 0; } -static int iwl_mvm_get_last_nonqos_seq(struct iwl_mvm *mvm, - struct ieee80211_vif *vif) -{ - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - struct iwl_nonqos_seq_query_cmd query_cmd = { - .get_set_flag = cpu_to_le32(IWL_NONQOS_SEQ_GET), - .mac_id_n_color = - cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, - mvmvif->color)), - }; - struct iwl_host_cmd cmd = { - .id = NON_QOS_TX_COUNTER_CMD, - .flags = CMD_SYNC | CMD_WANT_SKB, - }; - int err; - u32 size; - - if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API) { - cmd.data[0] = &query_cmd; - cmd.len[0] = sizeof(query_cmd); - } - - err = iwl_mvm_send_cmd(mvm, &cmd); - if (err) - return err; - - size = le32_to_cpu(cmd.resp_pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; - size -= sizeof(cmd.resp_pkt->hdr); - if (size < sizeof(__le16)) { - err = -EINVAL; - } else { - err = le16_to_cpup((__le16 *)cmd.resp_pkt->data); - /* new API returns next, not last-used seqno */ - if (mvm->fw->ucode_capa.flags & - IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API) - err -= 0x10; - } - - iwl_free_resp(&cmd); - return err; -} - -void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif) -{ - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - struct iwl_nonqos_seq_query_cmd query_cmd = { - .get_set_flag = cpu_to_le32(IWL_NONQOS_SEQ_SET), - .mac_id_n_color = - cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, - mvmvif->color)), - .value = cpu_to_le16(mvmvif->seqno), - }; - - /* return if called during restart, not resume from D3 */ - if (!mvmvif->seqno_valid) - return; - - mvmvif->seqno_valid = false; - - if (!(mvm->fw->ucode_capa.flags & - IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API)) - return; - - if (iwl_mvm_send_cmd_pdu(mvm, NON_QOS_TX_COUNTER_CMD, CMD_SYNC, - sizeof(query_cmd), &query_cmd)) - IWL_ERR(mvm, "failed to set non-QoS seqno\n"); -} - static int __iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan, bool test) @@ -964,6 +829,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, }; int ret, i; int len __maybe_unused; + u16 seq; u8 old_aux_sta_id, old_ap_sta_id = IWL_MVM_STATION_COUNT; if (!wowlan) { @@ -1006,15 +872,26 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv; + /* + * The D3 firmware still hardcodes the AP station ID for the + * BSS we're associated with as 0. Store the real STA ID here + * and assign 0. When we leave this function, we'll restore + * the original value for the resume code. + */ + old_ap_sta_id = mvm_ap_sta->sta_id; + mvm_ap_sta->sta_id = 0; + mvmvif->ap_sta_id = 0; + /* TODO: wowlan_config_cmd.wowlan_ba_teardown_tids */ wowlan_config_cmd.is_11n_connection = ap_sta->ht_cap.ht_supported; - /* Query the last used seqno and set it */ - ret = iwl_mvm_get_last_nonqos_seq(mvm, vif); - if (ret < 0) - goto out_noreset; - wowlan_config_cmd.non_qos_seq = cpu_to_le16(ret); + /* + * We know the last used seqno, and the uCode expects to know that + * one, it will increment before TX. + */ + seq = mvm_ap_sta->last_seq_ctl & IEEE80211_SCTL_SEQ; + wowlan_config_cmd.non_qos_seq = cpu_to_le16(seq); /* * For QoS counters, we store the one to use next, so subtract 0x10 @@ -1022,7 +899,7 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, * increment after using the value (i.e. store the next value to use). */ for (i = 0; i < IWL_MAX_TID_COUNT; i++) { - u16 seq = mvm_ap_sta->tid_data[i].seq_number; + seq = mvm_ap_sta->tid_data[i].seq_number; seq -= 0x10; wowlan_config_cmd.qos_seq[i] = cpu_to_le16(seq); } @@ -1068,16 +945,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, iwl_trans_stop_device(mvm->trans); /* - * The D3 firmware still hardcodes the AP station ID for the - * BSS we're associated with as 0. Store the real STA ID here - * and assign 0. When we leave this function, we'll restore - * the original value for the resume code. - */ - old_ap_sta_id = mvm_ap_sta->sta_id; - mvm_ap_sta->sta_id = 0; - mvmvif->ap_sta_id = 0; - - /* * Set the HW restart bit -- this is mostly true as we're * going to load new firmware and reprogram that, though * the reprogramming is going to be manual to avoid adding @@ -1192,10 +1059,6 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, if (ret) goto out; - ret = iwl_mvm_power_update_device_mode(mvm); - if (ret) - goto out; - ret = iwl_mvm_power_update_mode(mvm, vif); if (ret) goto out; @@ -1246,26 +1109,16 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) return __iwl_mvm_suspend(hw, wowlan, false); } -/* converted data from the different status responses */ -struct iwl_wowlan_status_data { - u16 pattern_number; - u16 qos_seq_ctr[8]; - u32 wakeup_reasons; - u32 wake_packet_length; - u32 wake_packet_bufsize; - const u8 *wake_packet; -}; - static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - struct iwl_wowlan_status_data *status) + struct iwl_wowlan_status *status) { struct sk_buff *pkt = NULL; struct cfg80211_wowlan_wakeup wakeup = { .pattern_idx = -1, }; struct cfg80211_wowlan_wakeup *wakeup_report = &wakeup; - u32 reasons = status->wakeup_reasons; + u32 reasons = le32_to_cpu(status->wakeup_reasons); if (reasons == IWL_WOWLAN_WAKEUP_BY_NON_WIRELESS) { wakeup_report = NULL; @@ -1277,7 +1130,7 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm, if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) wakeup.pattern_idx = - status->pattern_number; + le16_to_cpu(status->pattern_number); if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON | IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH)) @@ -1305,8 +1158,8 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm, wakeup.tcp_match = true; if (status->wake_packet_bufsize) { - int pktsize = status->wake_packet_bufsize; - int pktlen = status->wake_packet_length; + int pktsize = le32_to_cpu(status->wake_packet_bufsize); + int pktlen = le32_to_cpu(status->wake_packet_length); const u8 *pktdata = status->wake_packet; struct ieee80211_hdr *hdr = (void *)pktdata; int truncated = pktlen - pktsize; @@ -1386,229 +1239,8 @@ static void iwl_mvm_report_wakeup_reasons(struct iwl_mvm *mvm, kfree_skb(pkt); } -static void iwl_mvm_aes_sc_to_seq(struct aes_sc *sc, - struct ieee80211_key_seq *seq) -{ - u64 pn; - - pn = le64_to_cpu(sc->pn); - seq->ccmp.pn[0] = pn >> 40; - seq->ccmp.pn[1] = pn >> 32; - seq->ccmp.pn[2] = pn >> 24; - seq->ccmp.pn[3] = pn >> 16; - seq->ccmp.pn[4] = pn >> 8; - seq->ccmp.pn[5] = pn; -} - -static void iwl_mvm_tkip_sc_to_seq(struct tkip_sc *sc, - struct ieee80211_key_seq *seq) -{ - seq->tkip.iv32 = le32_to_cpu(sc->iv32); - seq->tkip.iv16 = le16_to_cpu(sc->iv16); -} - -static void iwl_mvm_set_aes_rx_seq(struct aes_sc *scs, - struct ieee80211_key_conf *key) -{ - int tid; - - BUILD_BUG_ON(IWL_NUM_RSC != IEEE80211_NUM_TIDS); - - for (tid = 0; tid < IWL_NUM_RSC; tid++) { - struct ieee80211_key_seq seq = {}; - - iwl_mvm_aes_sc_to_seq(&scs[tid], &seq); - ieee80211_set_key_rx_seq(key, tid, &seq); - } -} - -static void iwl_mvm_set_tkip_rx_seq(struct tkip_sc *scs, - struct ieee80211_key_conf *key) -{ - int tid; - - BUILD_BUG_ON(IWL_NUM_RSC != IEEE80211_NUM_TIDS); - - for (tid = 0; tid < IWL_NUM_RSC; tid++) { - struct ieee80211_key_seq seq = {}; - - iwl_mvm_tkip_sc_to_seq(&scs[tid], &seq); - ieee80211_set_key_rx_seq(key, tid, &seq); - } -} - -static void iwl_mvm_set_key_rx_seq(struct ieee80211_key_conf *key, - struct iwl_wowlan_status_v6 *status) -{ - union iwl_all_tsc_rsc *rsc = &status->gtk.rsc.all_tsc_rsc; - - switch (key->cipher) { - case WLAN_CIPHER_SUITE_CCMP: - iwl_mvm_set_aes_rx_seq(rsc->aes.multicast_rsc, key); - break; - case WLAN_CIPHER_SUITE_TKIP: - iwl_mvm_set_tkip_rx_seq(rsc->tkip.multicast_rsc, key); - break; - default: - WARN_ON(1); - } -} - -struct iwl_mvm_d3_gtk_iter_data { - struct iwl_wowlan_status_v6 *status; - void *last_gtk; - u32 cipher; - bool find_phase, unhandled_cipher; - int num_keys; -}; - -static void iwl_mvm_d3_update_gtks(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct ieee80211_key_conf *key, - void *_data) -{ - struct iwl_mvm_d3_gtk_iter_data *data = _data; - - if (data->unhandled_cipher) - return; - - switch (key->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - /* ignore WEP completely, nothing to do */ - return; - case WLAN_CIPHER_SUITE_CCMP: - case WLAN_CIPHER_SUITE_TKIP: - /* we support these */ - break; - default: - /* everything else (even CMAC for MFP) - disconnect from AP */ - data->unhandled_cipher = true; - return; - } - - data->num_keys++; - - /* - * pairwise key - update sequence counters only; - * note that this assumes no TDLS sessions are active - */ - if (sta) { - struct ieee80211_key_seq seq = {}; - union iwl_all_tsc_rsc *sc = &data->status->gtk.rsc.all_tsc_rsc; - - if (data->find_phase) - return; - - switch (key->cipher) { - case WLAN_CIPHER_SUITE_CCMP: - iwl_mvm_aes_sc_to_seq(&sc->aes.tsc, &seq); - iwl_mvm_set_aes_rx_seq(sc->aes.unicast_rsc, key); - break; - case WLAN_CIPHER_SUITE_TKIP: - iwl_mvm_tkip_sc_to_seq(&sc->tkip.tsc, &seq); - iwl_mvm_set_tkip_rx_seq(sc->tkip.unicast_rsc, key); - break; - } - ieee80211_set_key_tx_seq(key, &seq); - - /* that's it for this key */ - return; - } - - if (data->find_phase) { - data->last_gtk = key; - data->cipher = key->cipher; - return; - } - - if (data->status->num_of_gtk_rekeys) - ieee80211_remove_key(key); - else if (data->last_gtk == key) - iwl_mvm_set_key_rx_seq(key, data->status); -} - -static bool iwl_mvm_setup_connection_keep(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct iwl_wowlan_status_v6 *status) -{ - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - struct iwl_mvm_d3_gtk_iter_data gtkdata = { - .status = status, - }; - - if (!status || !vif->bss_conf.bssid) - return false; - - /* find last GTK that we used initially, if any */ - gtkdata.find_phase = true; - ieee80211_iter_keys(mvm->hw, vif, - iwl_mvm_d3_update_gtks, >kdata); - /* not trying to keep connections with MFP/unhandled ciphers */ - if (gtkdata.unhandled_cipher) - return false; - if (!gtkdata.num_keys) - return true; - if (!gtkdata.last_gtk) - return false; - - /* - * invalidate all other GTKs that might still exist and update - * the one that we used - */ - gtkdata.find_phase = false; - ieee80211_iter_keys(mvm->hw, vif, - iwl_mvm_d3_update_gtks, >kdata); - - if (status->num_of_gtk_rekeys) { - struct ieee80211_key_conf *key; - struct { - struct ieee80211_key_conf conf; - u8 key[32]; - } conf = { - .conf.cipher = gtkdata.cipher, - .conf.keyidx = status->gtk.key_index, - }; - - switch (gtkdata.cipher) { - case WLAN_CIPHER_SUITE_CCMP: - conf.conf.keylen = WLAN_KEY_LEN_CCMP; - memcpy(conf.conf.key, status->gtk.decrypt_key, - WLAN_KEY_LEN_CCMP); - break; - case WLAN_CIPHER_SUITE_TKIP: - conf.conf.keylen = WLAN_KEY_LEN_TKIP; - memcpy(conf.conf.key, status->gtk.decrypt_key, 16); - /* leave TX MIC key zeroed, we don't use it anyway */ - memcpy(conf.conf.key + - NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY, - status->gtk.tkip_mic_key, 8); - break; - } - - key = ieee80211_gtk_rekey_add(vif, &conf.conf); - if (IS_ERR(key)) - return false; - iwl_mvm_set_key_rx_seq(key, status); - } - - if (status->num_of_gtk_rekeys) { - __be64 replay_ctr = - cpu_to_be64(le64_to_cpu(status->replay_ctr)); - ieee80211_gtk_rekey_notify(vif, vif->bss_conf.bssid, - (void *)&replay_ctr, GFP_KERNEL); - } - - mvmvif->seqno_valid = true; - /* +0x10 because the set API expects next-to-use, not last-used */ - mvmvif->seqno = le16_to_cpu(status->non_qos_seq_ctr) + 0x10; - - return true; -} - /* releases the MVM mutex */ -static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, +static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { u32 base = mvm->error_event_table; @@ -1621,12 +1253,8 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, .id = WOWLAN_GET_STATUSES, .flags = CMD_SYNC | CMD_WANT_SKB, }; - struct iwl_wowlan_status_data status; - struct iwl_wowlan_status_v6 *status_v6; - int ret, len, status_size, i; - bool keep; - struct ieee80211_sta *ap_sta; - struct iwl_mvm_sta *mvm_ap_sta; + struct iwl_wowlan_status *status; + int ret, len; iwl_trans_read_mem_bytes(mvm->trans, base, &err_info, sizeof(err_info)); @@ -1659,83 +1287,32 @@ static bool iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, if (!cmd.resp_pkt) goto out_unlock; - if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API) - status_size = sizeof(struct iwl_wowlan_status_v6); - else - status_size = sizeof(struct iwl_wowlan_status_v4); - len = le32_to_cpu(cmd.resp_pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; - if (len - sizeof(struct iwl_cmd_header) < status_size) { + if (len - sizeof(struct iwl_cmd_header) < sizeof(*status)) { IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); goto out_free_resp; } - if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_D3_CONTINUITY_API) { - status_v6 = (void *)cmd.resp_pkt->data; - - status.pattern_number = le16_to_cpu(status_v6->pattern_number); - for (i = 0; i < 8; i++) - status.qos_seq_ctr[i] = - le16_to_cpu(status_v6->qos_seq_ctr[i]); - status.wakeup_reasons = le32_to_cpu(status_v6->wakeup_reasons); - status.wake_packet_length = - le32_to_cpu(status_v6->wake_packet_length); - status.wake_packet_bufsize = - le32_to_cpu(status_v6->wake_packet_bufsize); - status.wake_packet = status_v6->wake_packet; - } else { - struct iwl_wowlan_status_v4 *status_v4; - status_v6 = NULL; - status_v4 = (void *)cmd.resp_pkt->data; - - status.pattern_number = le16_to_cpu(status_v4->pattern_number); - for (i = 0; i < 8; i++) - status.qos_seq_ctr[i] = - le16_to_cpu(status_v4->qos_seq_ctr[i]); - status.wakeup_reasons = le32_to_cpu(status_v4->wakeup_reasons); - status.wake_packet_length = - le32_to_cpu(status_v4->wake_packet_length); - status.wake_packet_bufsize = - le32_to_cpu(status_v4->wake_packet_bufsize); - status.wake_packet = status_v4->wake_packet; - } + status = (void *)cmd.resp_pkt->data; if (len - sizeof(struct iwl_cmd_header) != - status_size + ALIGN(status.wake_packet_bufsize, 4)) { + sizeof(*status) + + ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4)) { IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); goto out_free_resp; } - /* still at hard-coded place 0 for D3 image */ - ap_sta = rcu_dereference_protected( - mvm->fw_id_to_mac_id[0], - lockdep_is_held(&mvm->mutex)); - if (IS_ERR_OR_NULL(ap_sta)) - goto out_free_resp; - - mvm_ap_sta = (struct iwl_mvm_sta *)ap_sta->drv_priv; - for (i = 0; i < IWL_MAX_TID_COUNT; i++) { - u16 seq = status.qos_seq_ctr[i]; - /* firmware stores last-used value, we store next value */ - seq += 0x10; - mvm_ap_sta->tid_data[i].seq_number = seq; - } - /* now we have all the data we need, unlock to avoid mac80211 issues */ mutex_unlock(&mvm->mutex); - iwl_mvm_report_wakeup_reasons(mvm, vif, &status); - - keep = iwl_mvm_setup_connection_keep(mvm, vif, status_v6); - + iwl_mvm_report_wakeup_reasons(mvm, vif, status); iwl_free_resp(&cmd); - return keep; + return; out_free_resp: iwl_free_resp(&cmd); out_unlock: mutex_unlock(&mvm->mutex); - return false; } static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm) @@ -1758,17 +1335,6 @@ static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm) #endif } -static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac, - struct ieee80211_vif *vif) -{ - /* skip the one we keep connection on */ - if (data == vif) - return; - - if (vif->type == NL80211_IFTYPE_STATION) - ieee80211_resume_disconnect(vif); -} - static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) { struct iwl_d3_iter_data resume_iter_data = { @@ -1777,7 +1343,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) struct ieee80211_vif *vif = NULL; int ret; enum iwl_d3_status d3_status; - bool keep = false; mutex_lock(&mvm->mutex); @@ -1803,7 +1368,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) /* query SRAM first in case we want event logging */ iwl_mvm_read_d3_sram(mvm); - keep = iwl_mvm_query_wakeup_reasons(mvm, vif); + iwl_mvm_query_wakeup_reasons(mvm, vif); /* has unlocked the mutex, so skip that */ goto out; @@ -1811,10 +1376,8 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) mutex_unlock(&mvm->mutex); out: - if (!test) - ieee80211_iterate_active_interfaces_rtnl(mvm->hw, - IEEE80211_IFACE_ITER_NORMAL, - iwl_mvm_d3_disconnect_iter, keep ? vif : NULL); + if (!test && vif) + ieee80211_resume_disconnect(vif); /* return 1 to reconfigure the device */ set_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index 9864d71..aac81b8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c @@ -246,56 +246,58 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, return simple_read_from_buffer(user_buf, count, ppos, buf, pos); } -static ssize_t iwl_dbgfs_disable_power_off_read(struct file *file, - char __user *user_buf, +static ssize_t iwl_dbgfs_power_down_allow_write(struct file *file, + const char __user *user_buf, size_t count, loff_t *ppos) { struct iwl_mvm *mvm = file->private_data; - char buf[64]; - int bufsz = sizeof(buf); - int pos = 0; + char buf[8] = {}; + int allow; + + if (!mvm->ucode_loaded) + return -EIO; - pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off_d0=%d\n", - mvm->disable_power_off); - pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off_d3=%d\n", - mvm->disable_power_off_d3); + if (copy_from_user(buf, user_buf, sizeof(buf))) + return -EFAULT; - return simple_read_from_buffer(user_buf, count, ppos, buf, pos); + if (sscanf(buf, "%d", &allow) != 1) + return -EINVAL; + + IWL_DEBUG_POWER(mvm, "%s device power down\n", + allow ? "allow" : "prevent"); + + /* + * TODO: Send REPLY_DEBUG_CMD (0xf0) when FW support it + */ + + return count; } -static ssize_t iwl_dbgfs_disable_power_off_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) +static ssize_t iwl_dbgfs_power_down_d3_allow_write(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) { struct iwl_mvm *mvm = file->private_data; - char buf[64] = {}; - int ret; - int val; - - if (!mvm->ucode_loaded) - return -EIO; + char buf[8] = {}; + int allow; - count = min_t(size_t, count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, count)) + if (copy_from_user(buf, user_buf, sizeof(buf))) return -EFAULT; - if (!strncmp("disable_power_off_d0=", buf, 21)) { - if (sscanf(buf + 21, "%d", &val) != 1) - return -EINVAL; - mvm->disable_power_off = val; - } else if (!strncmp("disable_power_off_d3=", buf, 21)) { - if (sscanf(buf + 21, "%d", &val) != 1) - return -EINVAL; - mvm->disable_power_off_d3 = val; - } else { + if (sscanf(buf, "%d", &allow) != 1) return -EINVAL; - } - mutex_lock(&mvm->mutex); - ret = iwl_mvm_power_update_device_mode(mvm); - mutex_unlock(&mvm->mutex); + IWL_DEBUG_POWER(mvm, "%s device power down in d3\n", + allow ? "allow" : "prevent"); - return ret ?: count; + /* + * TODO: When WoWLAN FW alive notification happens, driver will send + * REPLY_DEBUG_CMD setting power_down_allow flag according to + * mvm->prevent_power_down_d3 + */ + mvm->prevent_power_down_d3 = !allow; + + return count; } static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm, @@ -342,7 +344,6 @@ static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm, case MVM_DEBUGFS_PM_DISABLE_POWER_OFF: IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val); dbgfs_pm->disable_power_off = val; - break; case MVM_DEBUGFS_PM_LPRX_ENA: IWL_DEBUG_POWER(mvm, "lprx %s\n", val ? "enabled" : "disabled"); dbgfs_pm->lprx_ena = val; @@ -370,8 +371,7 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file, int val; int ret; - count = min_t(size_t, count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, count)) + if (copy_from_user(buf, user_buf, sizeof(buf))) return -EFAULT; if (!strncmp("keep_alive=", buf, 11)) { @@ -394,9 +394,7 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file, if (sscanf(buf + 16, "%d", &val) != 1) return -EINVAL; param = MVM_DEBUGFS_PM_TX_DATA_TIMEOUT; - } else if (!strncmp("disable_power_off=", buf, 18) && - !(mvm->fw->ucode_capa.flags & - IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) { + } else if (!strncmp("disable_power_off=", buf, 18)) { if (sscanf(buf + 18, "%d", &val) != 1) return -EINVAL; param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF; @@ -583,21 +581,15 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf, BT_MBOX_PRINT(3, UPDATE_REQUEST, true); pos += scnprintf(buf+pos, bufsz-pos, "bt_status = %d\n", - notif->bt_status); + notif->bt_status); pos += scnprintf(buf+pos, bufsz-pos, "bt_open_conn = %d\n", - notif->bt_open_conn); + notif->bt_open_conn); pos += scnprintf(buf+pos, bufsz-pos, "bt_traffic_load = %d\n", - notif->bt_traffic_load); + notif->bt_traffic_load); pos += scnprintf(buf+pos, bufsz-pos, "bt_agg_traffic_load = %d\n", - notif->bt_agg_traffic_load); + notif->bt_agg_traffic_load); pos += scnprintf(buf+pos, bufsz-pos, "bt_ci_compliance = %d\n", - notif->bt_ci_compliance); - pos += scnprintf(buf+pos, bufsz-pos, "primary_ch_lut = %d\n", - le32_to_cpu(notif->primary_ch_lut)); - pos += scnprintf(buf+pos, bufsz-pos, "secondary_ch_lut = %d\n", - le32_to_cpu(notif->secondary_ch_lut)); - pos += scnprintf(buf+pos, bufsz-pos, "bt_activity_grading = %d\n", - le32_to_cpu(notif->bt_activity_grading)); + notif->bt_ci_compliance); mutex_unlock(&mvm->mutex); @@ -608,38 +600,6 @@ static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf, } #undef BT_MBOX_PRINT -static ssize_t iwl_dbgfs_bt_cmd_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_mvm *mvm = file->private_data; - struct iwl_bt_coex_ci_cmd *cmd = &mvm->last_bt_ci_cmd; - char buf[256]; - int bufsz = sizeof(buf); - int pos = 0; - - mutex_lock(&mvm->mutex); - - pos += scnprintf(buf+pos, bufsz-pos, "Channel inhibition CMD\n"); - pos += scnprintf(buf+pos, bufsz-pos, - "\tPrimary Channel Bitmap 0x%016llx Fat: %d\n", - le64_to_cpu(cmd->bt_primary_ci), - !!cmd->co_run_bw_primary); - pos += scnprintf(buf+pos, bufsz-pos, - "\tSecondary Channel Bitmap 0x%016llx Fat: %d\n", - le64_to_cpu(cmd->bt_secondary_ci), - !!cmd->co_run_bw_secondary); - - pos += scnprintf(buf+pos, bufsz-pos, "BT Configuration CMD\n"); - pos += scnprintf(buf+pos, bufsz-pos, "\tACK Kill Mask 0x%08x\n", - iwl_bt_ack_kill_msk[mvm->bt_kill_msk]); - pos += scnprintf(buf+pos, bufsz-pos, "\tCTS Kill Mask 0x%08x\n", - iwl_bt_cts_kill_msk[mvm->bt_kill_msk]); - - mutex_unlock(&mvm->mutex); - - return simple_read_from_buffer(user_buf, count, ppos, buf, pos); -} - #define PRINT_STATS_LE32(_str, _val) \ pos += scnprintf(buf + pos, bufsz - pos, \ fmt_table, _str, \ @@ -655,11 +615,9 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file, int pos = 0; char *buf; int ret; - /* 43 is the size of each data line, 33 is the size of each header */ - size_t bufsz = - ((sizeof(struct mvm_statistics_rx) / sizeof(__le32)) * 43) + - (4 * 33) + 1; - + int bufsz = sizeof(struct mvm_statistics_rx_phy) * 20 + + sizeof(struct mvm_statistics_rx_non_phy) * 10 + + sizeof(struct mvm_statistics_rx_ht_phy) * 10 + 200; struct mvm_statistics_rx_phy *ofdm; struct mvm_statistics_rx_phy *cck; struct mvm_statistics_rx_non_phy *general; @@ -754,7 +712,6 @@ static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file, PRINT_STATS_LE32("beacon_energy_b", general->beacon_energy_b); PRINT_STATS_LE32("beacon_energy_c", general->beacon_energy_c); PRINT_STATS_LE32("num_bt_kills", general->num_bt_kills); - PRINT_STATS_LE32("mac_id", general->mac_id); PRINT_STATS_LE32("directed_data_mpdu", general->directed_data_mpdu); pos += scnprintf(buf + pos, bufsz - pos, fmt_header, @@ -800,59 +757,6 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, return count; } -static ssize_t -iwl_dbgfs_scan_ant_rxchain_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_mvm *mvm = file->private_data; - int pos = 0; - char buf[32]; - const size_t bufsz = sizeof(buf); - - /* print which antennas were set for the scan command by the user */ - pos += scnprintf(buf + pos, bufsz - pos, "Antennas for scan: "); - if (mvm->scan_rx_ant & ANT_A) - pos += scnprintf(buf + pos, bufsz - pos, "A"); - if (mvm->scan_rx_ant & ANT_B) - pos += scnprintf(buf + pos, bufsz - pos, "B"); - if (mvm->scan_rx_ant & ANT_C) - pos += scnprintf(buf + pos, bufsz - pos, "C"); - pos += scnprintf(buf + pos, bufsz - pos, " (%hhx)\n", mvm->scan_rx_ant); - - return simple_read_from_buffer(user_buf, count, ppos, buf, pos); -} - -static ssize_t -iwl_dbgfs_scan_ant_rxchain_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct iwl_mvm *mvm = file->private_data; - char buf[8]; - int buf_size; - u8 scan_rx_ant; - - memset(buf, 0, sizeof(buf)); - buf_size = min(count, sizeof(buf) - 1); - - /* get the argument from the user and check if it is valid */ - if (copy_from_user(buf, user_buf, buf_size)) - return -EFAULT; - if (sscanf(buf, "%hhx", &scan_rx_ant) != 1) - return -EINVAL; - if (scan_rx_ant > ANT_ABC) - return -EINVAL; - if (scan_rx_ant & ~iwl_fw_valid_rx_ant(mvm->fw)) - return -EINVAL; - - /* change the rx antennas for scan command */ - mvm->scan_rx_ant = scan_rx_ant; - - return count; -} - - static void iwl_dbgfs_update_bf(struct ieee80211_vif *vif, enum iwl_dbgfs_bf_mask param, int value) { @@ -1064,8 +968,7 @@ static ssize_t iwl_dbgfs_d3_sram_write(struct file *file, char buf[8] = {}; int store; - count = min_t(size_t, count, sizeof(buf) - 1); - if (copy_from_user(buf, user_buf, count)) + if (copy_from_user(buf, user_buf, sizeof(buf))) return -EFAULT; if (sscanf(buf, "%d", &store) != 1) @@ -1160,12 +1063,10 @@ MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain); MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram); MVM_DEBUGFS_READ_FILE_OPS(stations); MVM_DEBUGFS_READ_FILE_OPS(bt_notif); -MVM_DEBUGFS_READ_FILE_OPS(bt_cmd); -MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off); +MVM_DEBUGFS_WRITE_FILE_OPS(power_down_allow); +MVM_DEBUGFS_WRITE_FILE_OPS(power_down_d3_allow); MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats); MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart); -MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain); - #ifdef CONFIG_PM_SLEEP MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram); #endif @@ -1186,14 +1087,10 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, S_IWUSR | S_IRUSR); MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, S_IRUSR); - MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, S_IRUSR); - if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD) - MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir, - S_IRUSR | S_IWUSR); + MVM_DEBUGFS_ADD_FILE(power_down_allow, mvm->debugfs_dir, S_IWUSR); + MVM_DEBUGFS_ADD_FILE(power_down_d3_allow, mvm->debugfs_dir, S_IWUSR); MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, S_IRUSR); MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, S_IWUSR); - MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, - S_IWUSR | S_IRUSR); #ifdef CONFIG_PM_SLEEP MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, S_IRUSR | S_IWUSR); MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, S_IRUSR); diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h index 4ea5e24..05c61d6 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-bt-coex.h @@ -82,8 +82,6 @@ * @BT_USE_DEFAULTS: * @BT_SYNC_2_BT_DISABLE: * @BT_COEX_CORUNNING_TBL_EN: - * - * The COEX_MODE must be set for each command. Even if it is not changed. */ enum iwl_bt_coex_flags { BT_CH_PRIMARY_EN = BIT(0), @@ -97,16 +95,14 @@ enum iwl_bt_coex_flags { BT_COEX_NW = 0x3 << BT_COEX_MODE_POS, BT_USE_DEFAULTS = BIT(6), BT_SYNC_2_BT_DISABLE = BIT(7), - BT_COEX_CORUNNING_TBL_EN = BIT(8), - BT_COEX_MPLUT_TBL_EN = BIT(9), - /* Bit 10 is reserved */ - BT_COEX_WF_PRIO_BOOST_CHECK_EN = BIT(11), + /* + * For future use - when the flags will be enlarged + * BT_COEX_CORUNNING_TBL_EN = BIT(8), + */ }; /* * indicates what has changed in the BT_COEX command. - * BT_VALID_ENABLE must be set for each command. Commands without this bit will - * discarded by the firmware */ enum iwl_bt_coex_valid_bit_msk { BT_VALID_ENABLE = BIT(0), @@ -125,8 +121,11 @@ enum iwl_bt_coex_valid_bit_msk { BT_VALID_CORUN_LUT_40 = BIT(13), BT_VALID_ANT_ISOLATION = BIT(14), BT_VALID_ANT_ISOLATION_THRS = BIT(15), - BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16), - BT_VALID_TXRX_MAX_FREQ_0 = BIT(17), + /* + * For future use - when the valid flags will be enlarged + * BT_VALID_TXTX_DELTA_FREQ_THRS = BIT(16), + * BT_VALID_TXRX_MAX_FREQ_0 = BIT(17), + */ }; /** @@ -143,88 +142,48 @@ enum iwl_bt_reduced_tx_power { BT_REDUCED_TX_POWER_DATA = BIT(1), }; -enum iwl_bt_coex_lut_type { - BT_COEX_TIGHT_LUT = 0, - BT_COEX_LOOSE_LUT, - BT_COEX_TX_DIS_LUT, - - BT_COEX_MAX_LUT, -}; - #define BT_COEX_LUT_SIZE (12) -#define BT_COEX_CORUN_LUT_SIZE (32) -#define BT_COEX_MULTI_PRIO_LUT_SIZE (2) -#define BT_COEX_BOOST_SIZE (4) -#define BT_REDUCED_TX_POWER_BIT BIT(7) /** * struct iwl_bt_coex_cmd - bt coex configuration command * @flags:&enum iwl_bt_coex_flags + * @lead_time: * @max_kill: - * @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power - * @bt4_antenna_isolation: - * @bt4_antenna_isolation_thr: - * @bt4_tx_tx_delta_freq_thr: - * @bt4_tx_rx_max_freq0: - * @bt_prio_boost: - * @wifi_tx_prio_boost: SW boost of wifi tx priority - * @wifi_rx_prio_boost: SW boost of wifi rx priority + * @bt3_time_t7_value: * @kill_ack_msk: * @kill_cts_msk: - * @decision_lut: - * @bt4_multiprio_lut: - * @bt4_corun_lut20: - * @bt4_corun_lut40: + * @bt3_prio_sample_time: + * @bt3_timer_t2_value: + * @bt4_reaction_time: + * @decision_lut[12]: + * @bt_reduced_tx_power: enum %iwl_bt_reduced_tx_power * @valid_bit_msk: enum %iwl_bt_coex_valid_bit_msk + * @bt_prio_boost: values for PTA boost register + * @wifi_tx_prio_boost: SW boost of wifi tx priority + * @wifi_rx_prio_boost: SW boost of wifi rx priority * * The structure is used for the BT_COEX command. */ struct iwl_bt_coex_cmd { - __le32 flags; + u8 flags; + u8 lead_time; u8 max_kill; - u8 bt_reduced_tx_power; - u8 reserved[2]; - - u8 bt4_antenna_isolation; - u8 bt4_antenna_isolation_thr; - u8 bt4_tx_tx_delta_freq_thr; - u8 bt4_tx_rx_max_freq0; - - __le32 bt_prio_boost[BT_COEX_BOOST_SIZE]; - __le32 wifi_tx_prio_boost; - __le32 wifi_rx_prio_boost; + u8 bt3_time_t7_value; __le32 kill_ack_msk; __le32 kill_cts_msk; - - __le32 decision_lut[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE]; - __le32 bt4_multiprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE]; - __le32 bt4_corun_lut20[BT_COEX_CORUN_LUT_SIZE]; - __le32 bt4_corun_lut40[BT_COEX_CORUN_LUT_SIZE]; - - __le32 valid_bit_msk; + u8 bt3_prio_sample_time; + u8 bt3_timer_t2_value; + __le16 bt4_reaction_time; + __le32 decision_lut[BT_COEX_LUT_SIZE]; + u8 bt_reduced_tx_power; + u8 reserved; + __le16 valid_bit_msk; + __le32 bt_prio_boost; + u8 reserved2; + u8 wifi_tx_prio_boost; + __le16 wifi_rx_prio_boost; } __packed; /* BT_COEX_CMD_API_S_VER_3 */ -/** - * struct iwl_bt_coex_ci_cmd - bt coex channel inhibition command - * @bt_primary_ci: - * @bt_secondary_ci: - * @co_run_bw_primary: - * @co_run_bw_secondary: - * @primary_ch_phy_id: - * @secondary_ch_phy_id: - * - * Used for BT_COEX_CI command - */ -struct iwl_bt_coex_ci_cmd { - __le64 bt_primary_ci; - __le64 bt_secondary_ci; - - u8 co_run_bw_primary; - u8 co_run_bw_secondary; - u8 primary_ch_phy_id; - u8 secondary_ch_phy_id; -} __packed; /* BT_CI_MSG_API_S_VER_1 */ - #define BT_MBOX(n_dw, _msg, _pos, _nbits) \ BT_MBOX##n_dw##_##_msg##_POS = (_pos), \ BT_MBOX##n_dw##_##_msg = BITS(_nbits) << BT_MBOX##n_dw##_##_msg##_POS @@ -285,39 +244,23 @@ enum iwl_bt_mxbox_dw3 { ((le32_to_cpu((_notif)->mbox_msg[(_num)]) & BT_MBOX##_num##_##_field)\ >> BT_MBOX##_num##_##_field##_POS) -enum iwl_bt_activity_grading { - BT_OFF = 0, - BT_ON_NO_CONNECTION = 1, - BT_LOW_TRAFFIC = 2, - BT_HIGH_TRAFFIC = 3, -}; - /** * struct iwl_bt_coex_profile_notif - notification about BT coex * @mbox_msg: message from BT to WiFi - * @msg_idx: the index of the message - * @bt_status: 0 - off, 1 - on - * @bt_open_conn: number of BT connections open - * @bt_traffic_load: load of BT traffic - * @bt_agg_traffic_load: aggregated load of BT traffic - * @bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant - * @primary_ch_lut: LUT used for primary channel - * @secondary_ch_lut: LUT used for secondary channel - * @bt_activity_grading: the activity of BT enum %iwl_bt_activity_grading + * @:bt_status: 0 - off, 1 - on + * @:bt_open_conn: number of BT connections open + * @:bt_traffic_load: load of BT traffic + * @:bt_agg_traffic_load: aggregated load of BT traffic + * @:bt_ci_compliance: 0 - no CI compliance, 1 - CI compliant */ struct iwl_bt_coex_profile_notif { __le32 mbox_msg[4]; - __le32 msg_idx; u8 bt_status; u8 bt_open_conn; u8 bt_traffic_load; u8 bt_agg_traffic_load; u8 bt_ci_compliance; u8 reserved[3]; - - __le32 primary_ch_lut; - __le32 secondary_ch_lut; - __le32 bt_activity_grading; } __packed; /* BT_COEX_PROFILE_NTFY_API_S_VER_2 */ enum iwl_bt_coex_prio_table_event { @@ -357,4 +300,20 @@ struct iwl_bt_coex_prio_tbl_cmd { u8 prio_tbl[BT_COEX_PRIO_TBL_EVT_MAX]; } __packed; +enum iwl_bt_coex_env_action { + BT_COEX_ENV_CLOSE = 0, + BT_COEX_ENV_OPEN = 1, +}; /* BT_COEX_PROT_ENV_ACTION_API_E_VER_1 */ + +/** + * struct iwl_bt_coex_prot_env_cmd - BT Protection Envelope + * @action: enum %iwl_bt_coex_env_action + * @type: enum %iwl_bt_coex_prio_table_event + */ +struct iwl_bt_coex_prot_env_cmd { + u8 action; /* 0 = closed, 1 = open */ + u8 type; /* 0 .. 15 */ + u8 reserved[2]; +} __packed; + #endif /* __fw_api_bt_coex_h__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h index 4e7dd8c..df72fcdf 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-d3.h @@ -100,12 +100,7 @@ enum iwl_proto_offloads { #define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V1 2 #define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V2 6 -#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L 12 -#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3S 4 -#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX 12 - -#define IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L 4 -#define IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3S 2 +#define IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX 6 /** * struct iwl_proto_offload_cmd_common - ARP/NS offload common part @@ -160,43 +155,6 @@ struct iwl_proto_offload_cmd_v2 { u8 reserved2[3]; } __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_2 */ -struct iwl_ns_config { - struct in6_addr source_ipv6_addr; - struct in6_addr dest_ipv6_addr; - u8 target_mac_addr[ETH_ALEN]; - __le16 reserved; -} __packed; /* NS_OFFLOAD_CONFIG */ - -struct iwl_targ_addr { - struct in6_addr addr; - __le32 config_num; -} __packed; /* TARGET_IPV6_ADDRESS */ - -/** - * struct iwl_proto_offload_cmd_v3_small - ARP/NS offload configuration - * @common: common/IPv4 configuration - * @target_ipv6_addr: target IPv6 addresses - * @ns_config: NS offload configurations - */ -struct iwl_proto_offload_cmd_v3_small { - struct iwl_proto_offload_cmd_common common; - __le32 num_valid_ipv6_addrs; - struct iwl_targ_addr targ_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3S]; - struct iwl_ns_config ns_config[IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3S]; -} __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_3 */ - -/** - * struct iwl_proto_offload_cmd_v3_large - ARP/NS offload configuration - * @common: common/IPv4 configuration - * @target_ipv6_addr: target IPv6 addresses - * @ns_config: NS offload configurations - */ -struct iwl_proto_offload_cmd_v3_large { - struct iwl_proto_offload_cmd_common common; - __le32 num_valid_ipv6_addrs; - struct iwl_targ_addr targ_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_V3L]; - struct iwl_ns_config ns_config[IWL_PROTO_OFFLOAD_NUM_NS_CONFIG_V3L]; -} __packed; /* PROT_OFFLOAD_CONFIG_CMD_DB_S_VER_3 */ /* * WOWLAN_PATTERNS @@ -335,7 +293,7 @@ enum iwl_wowlan_wakeup_reason { IWL_WOWLAN_WAKEUP_BY_REM_WAKE_WAKEUP_PACKET = BIT(12), }; /* WOWLAN_WAKE_UP_REASON_API_E_VER_2 */ -struct iwl_wowlan_status_v4 { +struct iwl_wowlan_status { __le64 replay_ctr; __le16 pattern_number; __le16 non_qos_seq_ctr; @@ -350,29 +308,6 @@ struct iwl_wowlan_status_v4 { u8 wake_packet[]; /* can be truncated from _length to _bufsize */ } __packed; /* WOWLAN_STATUSES_API_S_VER_4 */ -struct iwl_wowlan_gtk_status { - u8 key_index; - u8 reserved[3]; - u8 decrypt_key[16]; - u8 tkip_mic_key[8]; - struct iwl_wowlan_rsc_tsc_params_cmd rsc; -} __packed; - -struct iwl_wowlan_status_v6 { - struct iwl_wowlan_gtk_status gtk; - __le64 replay_ctr; - __le16 pattern_number; - __le16 non_qos_seq_ctr; - __le16 qos_seq_ctr[8]; - __le32 wakeup_reasons; - __le32 num_of_gtk_rekeys; - __le32 transmitted_ndps; - __le32 received_beacons; - __le32 wake_packet_length; - __le32 wake_packet_bufsize; - u8 wake_packet[]; /* can be truncated from _length to _bufsize */ -} __packed; /* WOWLAN_STATUSES_API_S_VER_6 */ - #define IWL_WOWLAN_TCP_MAX_PACKET_LEN 64 #define IWL_WOWLAN_REMOTE_WAKE_MAX_PACKET_LEN 128 #define IWL_WOWLAN_REMOTE_WAKE_MAX_TOKENS 2048 diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h index 39c3148..98b1feb 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-mac.h @@ -170,14 +170,12 @@ struct iwl_mac_data_ap { * @beacon_tsf: beacon transmit time in TSF * @bi: beacon interval in TU * @bi_reciprocal: 2^32 / bi - * @beacon_template: beacon template ID */ struct iwl_mac_data_ibss { __le32 beacon_time; __le64 beacon_tsf; __le32 bi; __le32 bi_reciprocal; - __le32 beacon_template; } __packed; /* IBSS_MAC_DATA_API_S_VER_1 */ /** @@ -374,13 +372,4 @@ static inline u32 iwl_mvm_reciprocal(u32 v) return 0xFFFFFFFF / v; } -#define IWL_NONQOS_SEQ_GET 0x1 -#define IWL_NONQOS_SEQ_SET 0x2 -struct iwl_nonqos_seq_query_cmd { - __le32 get_set_flag; - __le32 mac_id_n_color; - __le16 value; - __le16 reserved; -} __packed; /* NON_QOS_TX_COUNTER_GET_SET_API_S_VER_1 */ - #endif /* __fw_api_mac_h__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h index 5cb93ae..8e7ab41 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h @@ -132,33 +132,6 @@ struct iwl_powertable_cmd { } __packed; /** - * enum iwl_device_power_flags - masks for device power command flags - * @DEVIC_POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off - * receiver and transmitter. '0' - does not allow. This flag should be - * always set to '1' unless one need to disable actual power down for debug - * purposes. - * @DEVICE_POWER_FLAGS_CAM_MSK: '1' CAM (Continuous Active Mode) is set, meaning - * that power management is disabled. '0' Power management is enabled, one - * of power schemes is applied. -*/ -enum iwl_device_power_flags { - DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK = BIT(0), - DEVICE_POWER_FLAGS_CAM_MSK = BIT(13), -}; - -/** - * struct iwl_device_power_cmd - device wide power command. - * DEVICE_POWER_CMD = 0x77 (command, has simple generic response) - * - * @flags: Power table command flags from DEVICE_POWER_FLAGS_* - */ -struct iwl_device_power_cmd { - /* PM_POWER_TABLE_CMD_API_S_VER_6 */ - __le16 flags; - __le16 reserved; -} __packed; - -/** * struct iwl_mac_power_cmd - New power command containing uAPSD support * MAC_PM_POWER_TABLE = 0xA9 (command, has simple generic response) * @id_and_color: MAC contex identifier @@ -317,7 +290,7 @@ struct iwl_beacon_filter_cmd { #define IWL_BF_ESCAPE_TIMER_MIN 0 #define IWL_BA_ESCAPE_TIMER_DEFAULT 6 -#define IWL_BA_ESCAPE_TIMER_D3 9 +#define IWL_BA_ESCAPE_TIMER_D3 6 #define IWL_BA_ESCAPE_TIMER_MAX 1024 #define IWL_BA_ESCAPE_TIMER_MIN 0 diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h index 538f1c7..fdd33bc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-rs.h @@ -68,7 +68,6 @@ /* * These serve as indexes into * struct iwl_rate_info fw_rate_idx_to_plcp[IWL_RATE_COUNT]; - * TODO: avoid overlap between legacy and HT rates */ enum { IWL_RATE_1M_INDEX = 0, @@ -79,31 +78,18 @@ enum { IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX, IWL_RATE_6M_INDEX, IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX, - IWL_RATE_MCS_0_INDEX = IWL_RATE_6M_INDEX, - IWL_FIRST_HT_RATE = IWL_RATE_MCS_0_INDEX, - IWL_FIRST_VHT_RATE = IWL_RATE_MCS_0_INDEX, IWL_RATE_9M_INDEX, IWL_RATE_12M_INDEX, - IWL_RATE_MCS_1_INDEX = IWL_RATE_12M_INDEX, IWL_RATE_18M_INDEX, - IWL_RATE_MCS_2_INDEX = IWL_RATE_18M_INDEX, IWL_RATE_24M_INDEX, - IWL_RATE_MCS_3_INDEX = IWL_RATE_24M_INDEX, IWL_RATE_36M_INDEX, - IWL_RATE_MCS_4_INDEX = IWL_RATE_36M_INDEX, IWL_RATE_48M_INDEX, - IWL_RATE_MCS_5_INDEX = IWL_RATE_48M_INDEX, IWL_RATE_54M_INDEX, - IWL_RATE_MCS_6_INDEX = IWL_RATE_54M_INDEX, IWL_LAST_NON_HT_RATE = IWL_RATE_54M_INDEX, IWL_RATE_60M_INDEX, - IWL_RATE_MCS_7_INDEX = IWL_RATE_60M_INDEX, - IWL_LAST_HT_RATE = IWL_RATE_MCS_7_INDEX, - IWL_RATE_MCS_8_INDEX, - IWL_RATE_MCS_9_INDEX, - IWL_LAST_VHT_RATE = IWL_RATE_MCS_9_INDEX, + IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX, IWL_RATE_COUNT_LEGACY = IWL_LAST_NON_HT_RATE + 1, - IWL_RATE_COUNT = IWL_LAST_VHT_RATE + 1, + IWL_RATE_COUNT, }; #define IWL_RATE_BIT_MSK(r) BIT(IWL_RATE_##r##M_INDEX) @@ -122,7 +108,6 @@ enum { IWL_RATE_2M_PLCP = 20, IWL_RATE_5M_PLCP = 55, IWL_RATE_11M_PLCP = 110, - IWL_RATE_INVM_PLCP = -1, }; /* @@ -179,8 +164,6 @@ enum { * which is the duplicate 20 MHz MCS (bit 5 set, all others zero.) */ #define RATE_HT_MCS_RATE_CODE_MSK 0x7 -#define RATE_HT_MCS_NSS_POS 3 -#define RATE_HT_MCS_NSS_MSK (3 << RATE_HT_MCS_NSS_POS) /* Bit 10: (1) Use Green Field preamble */ #define RATE_HT_MCS_GF_POS 10 diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h index c3782b4..83cb9b9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h @@ -356,7 +356,6 @@ struct iwl_scan_complete_notif { /* scan offload */ #define IWL_MAX_SCAN_CHANNELS 40 #define IWL_SCAN_MAX_BLACKLIST_LEN 64 -#define IWL_SCAN_SHORT_BLACKLIST_LEN 16 #define IWL_SCAN_MAX_PROFILES 11 #define SCAN_OFFLOAD_PROBE_REQ_SIZE 512 @@ -369,12 +368,6 @@ struct iwl_scan_complete_notif { #define IWL_FULL_SCAN_MULTIPLIER 5 #define IWL_FAST_SCHED_SCAN_ITERATIONS 3 -enum scan_framework_client { - SCAN_CLIENT_SCHED_SCAN = BIT(0), - SCAN_CLIENT_NETDETECT = BIT(1), - SCAN_CLIENT_ASSET_TRACKING = BIT(2), -}; - /** * struct iwl_scan_offload_cmd - SCAN_REQUEST_FIXED_PART_API_S_VER_6 * @scan_flags: see enum iwl_scan_flags @@ -456,12 +449,11 @@ struct iwl_scan_offload_cfg { * iwl_scan_offload_blacklist - SCAN_OFFLOAD_BLACKLIST_S * @ssid: MAC address to filter out * @reported_rssi: AP rssi reported to the host - * @client_bitmap: clients ignore this entry - enum scan_framework_client */ struct iwl_scan_offload_blacklist { u8 ssid[ETH_ALEN]; u8 reported_rssi; - u8 client_bitmap; + u8 reserved; } __packed; enum iwl_scan_offload_network_type { @@ -483,7 +475,6 @@ enum iwl_scan_offload_band_selection { * @aut_alg: authentication olgorithm to match - bitmap * @network_type: enum iwl_scan_offload_network_type * @band_selection: enum iwl_scan_offload_band_selection - * @client_bitmap: clients waiting for match - enum scan_framework_client */ struct iwl_scan_offload_profile { u8 ssid_index; @@ -491,8 +482,7 @@ struct iwl_scan_offload_profile { u8 auth_alg; u8 network_type; u8 band_selection; - u8 client_bitmap; - u8 reserved[2]; + u8 reserved[3]; } __packed; /** @@ -501,18 +491,13 @@ struct iwl_scan_offload_profile { * @profiles: profiles to search for match * @blacklist_len: length of blacklist * @num_profiles: num of profiles in the list - * @match_notify: clients waiting for match found notification - * @pass_match: clients waiting for the results - * @active_clients: active clients bitmap - enum scan_framework_client */ struct iwl_scan_offload_profile_cfg { + struct iwl_scan_offload_blacklist blacklist[IWL_SCAN_MAX_BLACKLIST_LEN]; struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES]; u8 blacklist_len; u8 num_profiles; - u8 match_notify; - u8 pass_match; - u8 active_clients; - u8 reserved[3]; + u8 reserved[2]; } __packed; /** @@ -575,15 +560,4 @@ struct iwl_scan_offload_complete { u8 reserved; } __packed; -/** - * iwl_sched_scan_results - SCAN_OFFLOAD_MATCH_FOUND_NTF_API_S_VER_1 - * @ssid_bitmap: SSIDs indexes found in this iteration - * @client_bitmap: clients that are active and wait for this notification - */ -struct iwl_sched_scan_results { - __le16 ssid_bitmap; - u8 client_bitmap; - u8 reserved; -}; - #endif diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h index 4aca593..a30691a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-sta.h @@ -247,7 +247,7 @@ struct iwl_mvm_keyinfo { } __packed; /** - * struct iwl_mvm_add_sta_cmd_v5 - Add/modify a station in the fw's sta table. + * struct iwl_mvm_add_sta_cmd - Add / modify a station in the fw's station table * ( REPLY_ADD_STA = 0x18 ) * @add_modify: 1: modify existing, 0: add new station * @unicast_tx_key_id: unicast tx key id. Relevant only when unicast key sent @@ -286,7 +286,7 @@ struct iwl_mvm_keyinfo { * ADD_STA sets up the table entry for one station, either creating a new * entry, or modifying a pre-existing one. */ -struct iwl_mvm_add_sta_cmd_v5 { +struct iwl_mvm_add_sta_cmd { u8 add_modify; u8 unicast_tx_key_id; u8 multicast_tx_key_id; @@ -313,57 +313,6 @@ struct iwl_mvm_add_sta_cmd_v5 { } __packed; /* ADD_STA_CMD_API_S_VER_5 */ /** - * struct iwl_mvm_add_sta_cmd_v6 - Add / modify a station - * VER_6 of this command is quite similar to VER_5 except - * exclusion of all fields related to the security key installation. - */ -struct iwl_mvm_add_sta_cmd_v6 { - u8 add_modify; - u8 reserved1; - __le16 tid_disable_tx; - __le32 mac_id_n_color; - u8 addr[ETH_ALEN]; /* _STA_ID_MODIFY_INFO_API_S_VER_1 */ - __le16 reserved2; - u8 sta_id; - u8 modify_mask; - __le16 reserved3; - __le32 station_flags; - __le32 station_flags_msk; - u8 add_immediate_ba_tid; - u8 remove_immediate_ba_tid; - __le16 add_immediate_ba_ssn; - __le16 sleep_tx_count; - __le16 sleep_state_flags; - __le16 assoc_id; - __le16 beamform_flags; - __le32 tfd_queue_msk; -} __packed; /* ADD_STA_CMD_API_S_VER_6 */ - -/** - * struct iwl_mvm_add_sta_key_cmd - add/modify sta key - * ( REPLY_ADD_STA_KEY = 0x17 ) - * @sta_id: index of station in uCode's station table - * @key_offset: key offset in key storage - * @key_flags: type %iwl_sta_key_flag - * @key: key material data - * @key2: key material data - * @rx_secur_seq_cnt: RX security sequence counter for the key - * @tkip_rx_tsc_byte2: TSC[2] for key mix ph1 detection - * @tkip_rx_ttak: 10-byte unicast TKIP TTAK for Rx - */ -struct iwl_mvm_add_sta_key_cmd { - u8 sta_id; - u8 key_offset; - __le16 key_flags; - u8 key[16]; - u8 key2[16]; - u8 rx_secur_seq_cnt[16]; - u8 tkip_rx_tsc_byte2; - u8 reserved; - __le16 tkip_rx_ttak[5]; -} __packed; /* ADD_MODIFY_STA_KEY_API_S_VER_1 */ - -/** * enum iwl_mvm_add_sta_rsp_status - status in the response to ADD_STA command * @ADD_STA_SUCCESS: operation was executed successfully * @ADD_STA_STATIONS_OVERLOAD: no room left in the fw's station table diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index bad5a55..66264cc 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -72,17 +72,17 @@ #include "fw-api-d3.h" #include "fw-api-bt-coex.h" -/* maximal number of Tx queues in any platform */ -#define IWL_MVM_MAX_QUEUES 20 - -/* Tx queue numbers */ +/* queue and FIFO numbers by usage */ enum { IWL_MVM_OFFCHANNEL_QUEUE = 8, IWL_MVM_CMD_QUEUE = 9, + IWL_MVM_AUX_QUEUE = 15, + IWL_MVM_FIRST_AGG_QUEUE = 16, + IWL_MVM_NUM_QUEUES = 20, + IWL_MVM_LAST_AGG_QUEUE = IWL_MVM_NUM_QUEUES - 1, + IWL_MVM_CMD_FIFO = 7 }; -#define IWL_MVM_CMD_FIFO 7 - #define IWL_MVM_STATION_COUNT 16 /* commands */ @@ -97,7 +97,6 @@ enum { DBG_CFG = 0x9, /* station table */ - ADD_STA_KEY = 0x17, ADD_STA = 0x18, REMOVE_STA = 0x19, @@ -115,7 +114,6 @@ enum { TIME_EVENT_NOTIFICATION = 0x2a, BINDING_CONTEXT_CMD = 0x2b, TIME_QUOTA_CMD = 0x2c, - NON_QOS_TX_COUNTER_CMD = 0x2d, LQ_CMD = 0x4e, @@ -132,7 +130,6 @@ enum { SCAN_OFFLOAD_COMPLETE = 0x6D, SCAN_OFFLOAD_UPDATE_PROFILES_CMD = 0x6E, SCAN_OFFLOAD_CONFIG_CMD = 0x6f, - MATCH_FOUND_NOTIFICATION = 0xd9, /* Phy */ PHY_CONFIGURATION_CMD = 0x6a, @@ -181,7 +178,6 @@ enum { BT_COEX_PRIO_TABLE = 0xcc, BT_COEX_PROT_ENV = 0xcd, BT_PROFILE_NOTIFICATION = 0xce, - BT_COEX_CI = 0x5d, REPLY_BEACON_FILTERING_CMD = 0xd2, diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index 70e5297..c76299a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -151,12 +151,14 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, enum iwl_ucode_type old_type = mvm->cur_ucode; static const u8 alive_cmd[] = { MVM_ALIVE }; - fw = iwl_get_ucode_image(mvm, ucode_type); - if (WARN_ON(!fw)) - return -EINVAL; mvm->cur_ucode = ucode_type; + fw = iwl_get_ucode_image(mvm, ucode_type); + mvm->ucode_loaded = false; + if (!fw) + return -EINVAL; + iwl_init_notification_wait(&mvm->notif_wait, &alive_wait, alive_cmd, ARRAY_SIZE(alive_cmd), iwl_alive_fn, &alive_data); @@ -197,7 +199,7 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, */ for (i = 0; i < IWL_MAX_HW_QUEUES; i++) { - if (i < mvm->first_agg_queue && i != IWL_MVM_CMD_QUEUE) + if (i < IWL_MVM_FIRST_AGG_QUEUE && i != IWL_MVM_CMD_QUEUE) mvm->queue_to_mac80211[i] = i; else mvm->queue_to_mac80211[i] = IWL_INVALID_MAC80211_QUEUE; @@ -241,7 +243,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) lockdep_assert_held(&mvm->mutex); - if (mvm->init_ucode_complete) + if (mvm->init_ucode_run) return 0; iwl_init_notification_wait(&mvm->notif_wait, @@ -262,7 +264,6 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) if (ret) goto error; - /* Read the NVM only at driver load time, no need to do this twice */ if (read_nvm) { /* Read nvm */ ret = iwl_nvm_init(mvm); @@ -272,10 +273,6 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) } } - /* In case we read the NVM from external file, load it to the NIC */ - if (iwlwifi_mod_params.nvm_file) - iwl_mvm_load_nvm_to_nic(mvm); - ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans); WARN_ON(ret); @@ -313,7 +310,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait, MVM_UCODE_CALIB_TIMEOUT); if (!ret) - mvm->init_ucode_complete = true; + mvm->init_ucode_run = true; goto out; error: @@ -356,12 +353,8 @@ int iwl_mvm_up(struct iwl_mvm *mvm) if (ret) return ret; - /* - * If we haven't completed the run of the init ucode during - * module loading, load init ucode now - * (for example, if we were in RFKILL) - */ - if (!mvm->init_ucode_complete) { + /* If we were in RFKILL during module loading, load init ucode now */ + if (!mvm->init_ucode_run) { ret = iwl_run_init_mvm_ucode(mvm, false); if (ret && !iwlmvm_mod_params.init_dbg) { IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret); @@ -431,10 +424,6 @@ int iwl_mvm_up(struct iwl_mvm *mvm) goto error; } - ret = iwl_mvm_power_update_device_mode(mvm); - if (ret) - goto error; - IWL_DEBUG_INFO(mvm, "RT uCode started.\n"); return 0; error: diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index f41f9b0..5fe23a5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c @@ -80,7 +80,7 @@ struct iwl_mvm_mac_iface_iterator_data { struct ieee80211_vif *vif; unsigned long available_mac_ids[BITS_TO_LONGS(NUM_MAC_INDEX_DRIVER)]; unsigned long available_tsf_ids[BITS_TO_LONGS(NUM_TSF_IDS)]; - unsigned long used_hw_queues[BITS_TO_LONGS(IWL_MVM_MAX_QUEUES)]; + unsigned long used_hw_queues[BITS_TO_LONGS(IWL_MVM_FIRST_AGG_QUEUE)]; enum iwl_tsf_id preferred_tsf; bool found_vif; }; @@ -218,7 +218,7 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, .preferred_tsf = NUM_TSF_IDS, .used_hw_queues = { BIT(IWL_MVM_OFFCHANNEL_QUEUE) | - BIT(mvm->aux_queue) | + BIT(IWL_MVM_AUX_QUEUE) | BIT(IWL_MVM_CMD_QUEUE) }, .found_vif = false, @@ -242,17 +242,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, * that we should share it with another interface. */ - /* Currently, MAC ID 0 should be used only for the managed/IBSS vif */ - switch (vif->type) { - case NL80211_IFTYPE_ADHOC: - break; - case NL80211_IFTYPE_STATION: - if (!vif->p2p) - break; - /* fall through */ - default: + /* Currently, MAC ID 0 should be used only for the managed vif */ + if (vif->type != NL80211_IFTYPE_STATION || vif->p2p) __clear_bit(0, data.available_mac_ids); - } ieee80211_iterate_active_interfaces_atomic( mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL, @@ -310,9 +302,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, /* Find available queues, and allocate them to the ACs */ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { u8 queue = find_first_zero_bit(data.used_hw_queues, - mvm->first_agg_queue); + IWL_MVM_FIRST_AGG_QUEUE); - if (queue >= mvm->first_agg_queue) { + if (queue >= IWL_MVM_FIRST_AGG_QUEUE) { IWL_ERR(mvm, "Failed to allocate queue\n"); ret = -EIO; goto exit_fail; @@ -325,9 +317,9 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm, /* Allocate the CAB queue for softAP and GO interfaces */ if (vif->type == NL80211_IFTYPE_AP) { u8 queue = find_first_zero_bit(data.used_hw_queues, - mvm->first_agg_queue); + IWL_MVM_FIRST_AGG_QUEUE); - if (queue >= mvm->first_agg_queue) { + if (queue >= IWL_MVM_FIRST_AGG_QUEUE) { IWL_ERR(mvm, "Failed to allocate cab queue\n"); ret = -EIO; goto exit_fail; @@ -567,12 +559,8 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm, cmd->qos_flags |= cpu_to_le32(MAC_QOS_FLG_UPDATE_EDCA); /* Don't use cts to self as the fw doesn't support it currently. */ - if (vif->bss_conf.use_cts_prot) { + if (vif->bss_conf.use_cts_prot) cmd->protection_flags |= cpu_to_le32(MAC_PROT_FLG_TGG_PROTECT); - if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 8) - cmd->protection_flags |= - cpu_to_le32(MAC_PROT_FLG_SELF_CTS_EN); - } /* * I think that we should enable these 2 flags regardless the HT PROT @@ -719,35 +707,8 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm, cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_PROMISC | MAC_FILTER_IN_CONTROL_AND_MGMT | MAC_FILTER_IN_BEACON | - MAC_FILTER_IN_PROBE_REQUEST | - MAC_FILTER_IN_CRC32); - mvm->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS; - - return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); -} - -static int iwl_mvm_mac_ctxt_cmd_ibss(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - u32 action) -{ - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - struct iwl_mac_ctx_cmd cmd = {}; - - WARN_ON(vif->type != NL80211_IFTYPE_ADHOC); - - iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action); - - cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_BEACON | MAC_FILTER_IN_PROBE_REQUEST); - /* cmd.ibss.beacon_time/cmd.ibss.beacon_tsf are curently ignored */ - cmd.ibss.bi = cpu_to_le32(vif->bss_conf.beacon_int); - cmd.ibss.bi_reciprocal = - cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int)); - - /* TODO: Assumes that the beacon id == mac context id */ - cmd.ibss.beacon_template = cpu_to_le32(mvmvif->id); - return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd); } @@ -760,8 +721,7 @@ static void iwl_mvm_go_iterator(void *_data, u8 *mac, struct ieee80211_vif *vif) struct iwl_mvm_go_iterator_data *data = _data; struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - if (vif->type == NL80211_IFTYPE_AP && vif->p2p && - mvmvif->ap_ibss_active) + if (vif->type == NL80211_IFTYPE_AP && vif->p2p && mvmvif->ap_active) data->go_active = true; } @@ -873,10 +833,9 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm, cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(rate)); /* Set up TX beacon command fields */ - if (vif->type == NL80211_IFTYPE_AP) - iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd, - beacon->data, - beacon_skb_len); + iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd, + beacon->data, + beacon_skb_len); /* Submit command */ cmd.len[0] = sizeof(beacon_cmd); @@ -889,15 +848,14 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm, return iwl_mvm_send_cmd(mvm, &cmd); } -/* The beacon template for the AP/GO/IBSS has changed and needs update */ +/* The beacon template for the AP/GO context has changed and needs update */ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { struct sk_buff *beacon; int ret; - WARN_ON(vif->type != NL80211_IFTYPE_AP && - vif->type != NL80211_IFTYPE_ADHOC); + WARN_ON(vif->type != NL80211_IFTYPE_AP); beacon = ieee80211_beacon_get(mvm->hw, vif); if (!beacon) @@ -1060,8 +1018,6 @@ static int iwl_mvm_mac_ctx_send(struct iwl_mvm *mvm, struct ieee80211_vif *vif, return iwl_mvm_mac_ctxt_cmd_listener(mvm, vif, action); case NL80211_IFTYPE_P2P_DEVICE: return iwl_mvm_mac_ctxt_cmd_p2p_device(mvm, vif, action); - case NL80211_IFTYPE_ADHOC: - return iwl_mvm_mac_ctxt_cmd_ibss(mvm, vif, action); default: break; } @@ -1082,9 +1038,6 @@ int iwl_mvm_mac_ctxt_add(struct iwl_mvm *mvm, struct ieee80211_vif *vif) if (ret) return ret; - /* will only do anything at resume from D3 time */ - iwl_mvm_set_last_nonqos_seq(mvm, vif); - mvmvif->uploaded = true; return 0; } @@ -1124,10 +1077,6 @@ int iwl_mvm_mac_ctxt_remove(struct iwl_mvm *mvm, struct ieee80211_vif *vif) } mvmvif->uploaded = false; - - if (vif->type == NL80211_IFTYPE_MONITOR) - mvm->hw->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS; - return 0; } diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 74bc2c8..9833cdf 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -77,7 +77,6 @@ #include "iwl-eeprom-parse.h" #include "fw-api-scan.h" #include "iwl-phy-db.h" -#include "testmode.h" static const struct ieee80211_iface_limit iwl_mvm_limits[] = { { @@ -139,14 +138,6 @@ static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm) } } -static int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm) -{ - /* we create the 802.11 header and SSID element */ - if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID) - return mvm->fw->ucode_capa.max_probe_length - 24 - 2; - return mvm->fw->ucode_capa.max_probe_length - 24 - 34; -} - int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) { struct ieee80211_hw *hw = mvm->hw; @@ -164,9 +155,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) IEEE80211_HW_TIMING_BEACON_ONLY | IEEE80211_HW_CONNECTION_MONITOR | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | - IEEE80211_HW_SUPPORTS_STATIC_SMPS; + IEEE80211_HW_SUPPORTS_STATIC_SMPS | + IEEE80211_HW_SUPPORTS_UAPSD; - hw->queues = mvm->first_agg_queue; + hw->queues = IWL_MVM_FIRST_AGG_QUEUE; hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; hw->rate_control_algorithm = "iwl-mvm-rs"; @@ -179,12 +171,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) !iwlwifi_mod_params.sw_crypto) hw->flags |= IEEE80211_HW_MFP_CAPABLE; - if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD_SUPPORT) { - hw->flags |= IEEE80211_HW_SUPPORTS_UAPSD; - hw->uapsd_queues = IWL_UAPSD_AC_INFO; - hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP; - } - hw->sta_data_size = sizeof(struct iwl_mvm_sta); hw->vif_data_size = sizeof(struct iwl_mvm_vif); hw->chanctx_data_size = sizeof(u16); @@ -195,10 +181,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_DEVICE); - /* IBSS has bugs in older versions */ - if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 8) - hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); - hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS | WIPHY_FLAG_IBSS_RSN; @@ -209,6 +191,8 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->wiphy->max_remain_on_channel_duration = 10000; hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL; + hw->uapsd_queues = IWL_UAPSD_AC_INFO; + hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP; /* Extract MAC address */ memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN); @@ -228,8 +212,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) iwl_mvm_reset_phy_ctxts(mvm); - hw->wiphy->max_scan_ie_len = iwl_mvm_max_scan_ie_len(mvm); - + /* we create the 802.11 header and a max-length SSID element */ + hw->wiphy->max_scan_ie_len = + mvm->fw->ucode_capa.max_probe_length - 24 - 34; hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX; if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels) @@ -246,15 +231,6 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) else hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; - if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SCHED_SCAN) { - hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; - hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX; - hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES; - /* we create the 802.11 header and zero length SSID IE. */ - hw->wiphy->max_sched_scan_ie_len = - SCAN_OFFLOAD_PROBE_REQ_SIZE - 24 - 2; - } - hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN | NL80211_FEATURE_P2P_GO_OPPPS; @@ -572,8 +548,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, * In short: there's not much we can do at this point, other than * allocating resources :) */ - if (vif->type == NL80211_IFTYPE_AP || - vif->type == NL80211_IFTYPE_ADHOC) { + if (vif->type == NL80211_IFTYPE_AP) { u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif); ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta, qmask); @@ -723,14 +698,7 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, * For AP/GO interface, the tear down of the resources allocated to the * interface is be handled as part of the stop_ap flow. */ - if (vif->type == NL80211_IFTYPE_AP || - vif->type == NL80211_IFTYPE_ADHOC) { -#ifdef CONFIG_NL80211_TESTMODE - if (vif == mvm->noa_vif) { - mvm->noa_vif = NULL; - mvm->noa_duration = 0; - } -#endif + if (vif->type == NL80211_IFTYPE_AP) { iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); goto out_release; } @@ -828,27 +796,6 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, return; } iwl_mvm_configure_mcast_filter(mvm, vif); - - if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, - &mvm->status)) { - /* - * If we're restarting then the firmware will - * obviously have lost synchronisation with - * the AP. It will attempt to synchronise by - * itself, but we can make it more reliable by - * scheduling a session protection time event. - * - * The firmware needs to receive a beacon to - * catch up with synchronisation, use 110% of - * the beacon interval. - * - * Set a large maximum delay to allow for more - * than a single interface. - */ - u32 dur = (11 * vif->bss_conf.beacon_int) / 10; - iwl_mvm_protect_session(mvm, vif, dur, dur, - 5 * dur); - } } else if (mvmvif->ap_sta_id != IWL_MVM_STATION_COUNT) { /* remove AP station now that the MAC is unassoc */ ret = iwl_mvm_rm_sta_id(mvm, vif, mvmvif->ap_sta_id); @@ -864,8 +811,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, /* reset rssi values */ mvmvif->bf_data.ave_beacon_signal = 0; - if (!(mvm->fw->ucode_capa.flags & - IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT)) { + if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD)) { /* Workaround for FW bug, otherwise FW disables device * power save upon disassociation */ @@ -873,7 +819,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, if (ret) IWL_ERR(mvm, "failed to update power mode\n"); } - iwl_mvm_bt_coex_vif_change(mvm); + iwl_mvm_bt_coex_vif_assoc(mvm, vif); } else if (changes & BSS_CHANGED_BEACON_INFO) { /* * We received a beacon _after_ association so @@ -902,8 +848,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, } } -static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); @@ -926,7 +871,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, if (ret) goto out_remove; - mvmvif->ap_ibss_active = true; + mvmvif->ap_active = true; /* Send the bcast station. At this stage the TBTT and DTIM time events * are added and applied to the scheduler */ @@ -938,12 +883,10 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, if (ret) goto out_rm_bcast; - /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ + /* Need to update the P2P Device MAC */ if (vif->p2p && mvm->p2p_device_vif) iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif); - iwl_mvm_bt_coex_vif_change(mvm); - mutex_unlock(&mvm->mutex); return 0; @@ -958,8 +901,7 @@ out_unlock: return ret; } -static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); @@ -968,11 +910,9 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw, mutex_lock(&mvm->mutex); - mvmvif->ap_ibss_active = false; - - iwl_mvm_bt_coex_vif_change(mvm); + mvmvif->ap_active = false; - /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */ + /* Need to update the P2P Device MAC */ if (vif->p2p && mvm->p2p_device_vif) iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif); @@ -984,11 +924,10 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw, mutex_unlock(&mvm->mutex); } -static void -iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct ieee80211_bss_conf *bss_conf, - u32 changes) +static void iwl_mvm_bss_info_changed_ap(struct iwl_mvm *mvm, + struct ieee80211_vif *vif, + struct ieee80211_bss_conf *bss_conf, + u32 changes) { /* Need to send a new beacon template to the FW */ if (changes & BSS_CHANGED_BEACON) { @@ -1011,8 +950,7 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw, iwl_mvm_bss_info_changed_station(mvm, vif, bss_conf, changes); break; case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_ADHOC: - iwl_mvm_bss_info_changed_ap_ibss(mvm, vif, bss_conf, changes); + iwl_mvm_bss_info_changed_ap(mvm, vif, bss_conf, changes); break; default: /* shouldn't happen */ @@ -1225,54 +1163,7 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw, mutex_lock(&mvm->mutex); /* Try really hard to protect the session and hear a beacon */ - iwl_mvm_protect_session(mvm, vif, duration, min_duration, 500); - mutex_unlock(&mvm->mutex); -} - -static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct cfg80211_sched_scan_request *req, - struct ieee80211_sched_scan_ies *ies) -{ - struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); - int ret; - - mutex_lock(&mvm->mutex); - - if (mvm->scan_status != IWL_MVM_SCAN_NONE) { - IWL_DEBUG_SCAN(mvm, - "SCHED SCAN request during internal scan - abort\n"); - ret = -EBUSY; - goto out; - } - - mvm->scan_status = IWL_MVM_SCAN_SCHED; - - ret = iwl_mvm_config_sched_scan(mvm, vif, req, ies); - if (ret) - goto err; - - ret = iwl_mvm_config_sched_scan_profiles(mvm, req); - if (ret) - goto err; - - ret = iwl_mvm_sched_scan_start(mvm, req); - if (!ret) - goto out; -err: - mvm->scan_status = IWL_MVM_SCAN_NONE; -out: - mutex_unlock(&mvm->mutex); - return ret; -} - -static void iwl_mvm_mac_sched_scan_stop(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) -{ - struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); - - mutex_lock(&mvm->mutex); - iwl_mvm_sched_scan_stop(mvm); + iwl_mvm_protect_session(mvm, vif, duration, min_duration); mutex_unlock(&mvm->mutex); } @@ -1316,13 +1207,8 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw, switch (cmd) { case SET_KEY: - if ((vif->type == NL80211_IFTYPE_ADHOC || - vif->type == NL80211_IFTYPE_AP) && !sta) { - /* - * GTK on AP interface is a TX-only key, return 0; - * on IBSS they're per-station and because we're lazy - * we don't support them for RX, so do the same. - */ + if (vif->type == NL80211_IFTYPE_AP && !sta) { + /* GTK on AP interface is a TX-only key, return 0 */ ret = 0; key->hw_key_idx = STA_KEY_IDX_INVALID; break; @@ -1366,9 +1252,6 @@ static void iwl_mvm_mac_update_tkip_key(struct ieee80211_hw *hw, { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); - if (keyconf->hw_key_idx == STA_KEY_IDX_INVALID) - return; - iwl_mvm_update_tkip_key(mvm, vif, keyconf, sta, iv32, phase1key); } @@ -1562,7 +1445,6 @@ static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw, iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def, ctx->rx_chains_static, ctx->rx_chains_dynamic); - iwl_mvm_bt_coex_vif_change(mvm); mutex_unlock(&mvm->mutex); } @@ -1582,14 +1464,14 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw, switch (vif->type) { case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_ADHOC: /* * The AP binding flow is handled as part of the start_ap flow - * (in bss_info_changed), similarly for IBSS. + * (in bss_info_changed). */ ret = 0; goto out_unlock; case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_MONITOR: break; default: @@ -1635,10 +1517,10 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw, iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data); - switch (vif->type) { - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_ADHOC: + if (vif->type == NL80211_IFTYPE_AP) goto out_unlock; + + switch (vif->type) { case NL80211_IFTYPE_MONITOR: mvmvif->monitor_active = false; iwl_mvm_update_quotas(mvm, NULL); @@ -1668,72 +1550,14 @@ static int iwl_mvm_set_tim(struct ieee80211_hw *hw, return iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm_sta->vif); } -#ifdef CONFIG_NL80211_TESTMODE -static const struct nla_policy iwl_mvm_tm_policy[IWL_MVM_TM_ATTR_MAX + 1] = { - [IWL_MVM_TM_ATTR_CMD] = { .type = NLA_U32 }, - [IWL_MVM_TM_ATTR_NOA_DURATION] = { .type = NLA_U32 }, - [IWL_MVM_TM_ATTR_BEACON_FILTER_STATE] = { .type = NLA_U32 }, -}; - -static int __iwl_mvm_mac_testmode_cmd(struct iwl_mvm *mvm, +static void iwl_mvm_mac_rssi_callback(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - void *data, int len) -{ - struct nlattr *tb[IWL_MVM_TM_ATTR_MAX + 1]; - int err; - u32 noa_duration; - - err = nla_parse(tb, IWL_MVM_TM_ATTR_MAX, data, len, iwl_mvm_tm_policy); - if (err) - return err; - - if (!tb[IWL_MVM_TM_ATTR_CMD]) - return -EINVAL; - - switch (nla_get_u32(tb[IWL_MVM_TM_ATTR_CMD])) { - case IWL_MVM_TM_CMD_SET_NOA: - if (!vif || vif->type != NL80211_IFTYPE_AP || !vif->p2p || - !vif->bss_conf.enable_beacon || - !tb[IWL_MVM_TM_ATTR_NOA_DURATION]) - return -EINVAL; - - noa_duration = nla_get_u32(tb[IWL_MVM_TM_ATTR_NOA_DURATION]); - if (noa_duration >= vif->bss_conf.beacon_int) - return -EINVAL; - - mvm->noa_duration = noa_duration; - mvm->noa_vif = vif; - - return iwl_mvm_update_quotas(mvm, NULL); - case IWL_MVM_TM_CMD_SET_BEACON_FILTER: - /* must be associated client vif - ignore authorized */ - if (!vif || vif->type != NL80211_IFTYPE_STATION || - !vif->bss_conf.assoc || !vif->bss_conf.dtim_period || - !tb[IWL_MVM_TM_ATTR_BEACON_FILTER_STATE]) - return -EINVAL; - - if (nla_get_u32(tb[IWL_MVM_TM_ATTR_BEACON_FILTER_STATE])) - return iwl_mvm_enable_beacon_filter(mvm, vif); - return iwl_mvm_disable_beacon_filter(mvm, vif); - } - - return -EOPNOTSUPP; -} - -static int iwl_mvm_mac_testmode_cmd(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - void *data, int len) + enum ieee80211_rssi_event rssi_event) { struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); - int err; - mutex_lock(&mvm->mutex); - err = __iwl_mvm_mac_testmode_cmd(mvm, vif, data, len); - mutex_unlock(&mvm->mutex); - - return err; + iwl_mvm_bt_rssi_event(mvm, vif, rssi_event); } -#endif struct ieee80211_ops iwl_mvm_hw_ops = { .tx = iwl_mvm_mac_tx, @@ -1754,27 +1578,23 @@ struct ieee80211_ops iwl_mvm_hw_ops = { .set_rts_threshold = iwl_mvm_mac_set_rts_threshold, .conf_tx = iwl_mvm_mac_conf_tx, .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx, - .sched_scan_start = iwl_mvm_mac_sched_scan_start, - .sched_scan_stop = iwl_mvm_mac_sched_scan_stop, .set_key = iwl_mvm_mac_set_key, .update_tkip_key = iwl_mvm_mac_update_tkip_key, .remain_on_channel = iwl_mvm_roc, .cancel_remain_on_channel = iwl_mvm_cancel_roc, + .rssi_callback = iwl_mvm_mac_rssi_callback, + .add_chanctx = iwl_mvm_add_chanctx, .remove_chanctx = iwl_mvm_remove_chanctx, .change_chanctx = iwl_mvm_change_chanctx, .assign_vif_chanctx = iwl_mvm_assign_vif_chanctx, .unassign_vif_chanctx = iwl_mvm_unassign_vif_chanctx, - .start_ap = iwl_mvm_start_ap_ibss, - .stop_ap = iwl_mvm_stop_ap_ibss, - .join_ibss = iwl_mvm_start_ap_ibss, - .leave_ibss = iwl_mvm_stop_ap_ibss, + .start_ap = iwl_mvm_start_ap, + .stop_ap = iwl_mvm_stop_ap, .set_tim = iwl_mvm_set_tim, - CFG80211_TESTMODE_CMD(iwl_mvm_mac_testmode_cmd) - #ifdef CONFIG_PM_SLEEP /* look at d3.c */ .suspend = iwl_mvm_suspend, diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index fed21ef..b038927 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -73,6 +73,7 @@ #include "iwl-trans.h" #include "iwl-notif-wait.h" #include "iwl-eeprom-parse.h" +#include "iwl-trans.h" #include "sta.h" #include "fw-api.h" #include "constants.h" @@ -161,7 +162,6 @@ enum iwl_power_scheme { struct iwl_mvm_power_ops { int (*power_update_mode)(struct iwl_mvm *mvm, struct ieee80211_vif *vif); - int (*power_update_device_mode)(struct iwl_mvm *mvm); int (*power_disable)(struct iwl_mvm *mvm, struct ieee80211_vif *vif); #ifdef CONFIG_IWLWIFI_DEBUGFS int (*power_dbgfs_read)(struct iwl_mvm *mvm, struct ieee80211_vif *vif, @@ -241,18 +241,12 @@ enum iwl_mvm_smps_type_request { * @last_beacon_signal: last beacon rssi signal in dbm * @ave_beacon_signal: average beacon signal * @last_cqm_event: rssi of the last cqm event -* @bt_coex_min_thold: minimum threshold for BT coex -* @bt_coex_max_thold: maximum threshold for BT coex -* @last_bt_coex_event: rssi of the last BT coex event */ struct iwl_mvm_vif_bf_data { bool bf_enabled; bool ba_enabled; s8 ave_beacon_signal; s8 last_cqm_event; - s8 bt_coex_min_thold; - s8 bt_coex_max_thold; - s8 last_bt_coex_event; }; /** @@ -261,8 +255,8 @@ struct iwl_mvm_vif_bf_data { * @color: to solve races upon MAC addition and removal * @ap_sta_id: the sta_id of the AP - valid only if VIF type is STA * @uploaded: indicates the MAC context has been added to the device - * @ap_ibss_active: indicates that AP/IBSS is configured and that the interface - * should get quota etc. + * @ap_active: indicates that ap context is configured, and that the interface + * should get quota etc. * @monitor_active: indicates that monitor context is configured, and that the * interface should get quota etc. * @queue_params: QoS params for this MAC @@ -278,7 +272,7 @@ struct iwl_mvm_vif { u8 ap_sta_id; bool uploaded; - bool ap_ibss_active; + bool ap_active; bool monitor_active; struct iwl_mvm_vif_bf_data bf_data; @@ -312,9 +306,6 @@ struct iwl_mvm_vif { int tx_key_idx; - bool seqno_valid; - u16 seqno; - #if IS_ENABLED(CONFIG_IPV6) /* IPv6 addresses for WoWLAN */ struct in6_addr target_ipv6_addrs[IWL_PROTO_OFFLOAD_NUM_IPV6_ADDRS_MAX]; @@ -342,7 +333,6 @@ iwl_mvm_vif_from_mac80211(struct ieee80211_vif *vif) enum iwl_scan_status { IWL_MVM_SCAN_NONE, IWL_MVM_SCAN_OS, - IWL_MVM_SCAN_SCHED, }; /** @@ -444,7 +434,7 @@ struct iwl_mvm { enum iwl_ucode_type cur_ucode; bool ucode_loaded; - bool init_ucode_complete; + bool init_ucode_run; u32 error_event_table; u32 log_event_table; @@ -480,9 +470,6 @@ struct iwl_mvm { enum iwl_scan_status scan_status; struct iwl_scan_cmd *scan_cmd; - /* rx chain antennas set through debugfs for the scan command */ - u8 scan_rx_ant; - /* Internal station */ struct iwl_mvm_int_sta aux_sta; @@ -492,8 +479,7 @@ struct iwl_mvm { #ifdef CONFIG_IWLWIFI_DEBUGFS struct dentry *debugfs_dir; u32 dbgfs_sram_offset, dbgfs_sram_len; - bool disable_power_off; - bool disable_power_off_d3; + bool prevent_power_down_d3; #endif struct iwl_mvm_phy_ctxt phy_ctxts[NUM_PHY_CTX]; @@ -537,23 +523,12 @@ struct iwl_mvm { /* BT-Coex */ u8 bt_kill_msk; struct iwl_bt_coex_profile_notif last_bt_notif; - struct iwl_bt_coex_ci_cmd last_bt_ci_cmd; /* Thermal Throttling and CTkill */ struct iwl_mvm_tt_mgmt thermal_throttle; s32 temperature; /* Celsius */ const struct iwl_mvm_power_ops *pm_ops; - -#ifdef CONFIG_NL80211_TESTMODE - u32 noa_duration; - struct ieee80211_vif *noa_vif; -#endif - - /* Tx queues */ - u8 aux_queue; - u8 first_agg_queue; - u8 last_agg_queue; }; /* Extract MVM priv from op_mode and _hw */ @@ -595,9 +570,6 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm); /* Utils */ int iwl_mvm_legacy_rate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band); -void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags, - enum ieee80211_band band, - struct ieee80211_tx_rate *r); u8 iwl_mvm_mac80211_idx_to_hwrate(int rate_idx); void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm); void iwl_mvm_dump_sram(struct iwl_mvm *mvm); @@ -636,7 +608,6 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm, /* NVM */ int iwl_nvm_init(struct iwl_mvm *mvm); -int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm); int iwl_mvm_up(struct iwl_mvm *mvm); int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm); @@ -711,23 +682,6 @@ int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, struct iwl_device_cmd *cmd); void iwl_mvm_cancel_scan(struct iwl_mvm *mvm); -/* Scheduled scan */ -int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, - struct iwl_rx_cmd_buffer *rxb, - struct iwl_device_cmd *cmd); -int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct cfg80211_sched_scan_request *req, - struct ieee80211_sched_scan_ies *ies); -int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, - struct cfg80211_sched_scan_request *req); -int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm, - struct cfg80211_sched_scan_request *req); -void iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm); -int iwl_mvm_rx_sched_scan_results(struct iwl_mvm *mvm, - struct iwl_rx_cmd_buffer *rxb, - struct iwl_device_cmd *cmd); - /* MVM debugfs */ #ifdef CONFIG_IWLWIFI_DEBUGFS int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir); @@ -766,13 +720,6 @@ static inline int iwl_mvm_power_disable(struct iwl_mvm *mvm, return mvm->pm_ops->power_disable(mvm, vif); } -static inline int iwl_mvm_power_update_device_mode(struct iwl_mvm *mvm) -{ - if (mvm->pm_ops->power_update_device_mode) - return mvm->pm_ops->power_update_device_mode(mvm); - return 0; -} - #ifdef CONFIG_IWLWIFI_DEBUGFS static inline int iwl_mvm_power_dbgfs_read(struct iwl_mvm *mvm, struct ieee80211_vif *vif, @@ -798,15 +745,6 @@ void iwl_mvm_ipv6_addr_change(struct ieee80211_hw *hw, void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int idx); extern const struct file_operations iwl_dbgfs_d3_test_ops; -#ifdef CONFIG_PM_SLEEP -void iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, - struct ieee80211_vif *vif); -#else -static inline void -iwl_mvm_set_last_nonqos_seq(struct iwl_mvm *mvm, struct ieee80211_vif *vif) -{ -} -#endif /* BT Coex */ int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm); @@ -816,20 +754,7 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, struct iwl_device_cmd *cmd); void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif, enum ieee80211_rssi_event rssi_event); -void iwl_mvm_bt_coex_vif_change(struct iwl_mvm *mvm); -u16 iwl_mvm_bt_coex_agg_time_limit(struct iwl_mvm *mvm, - struct ieee80211_sta *sta); -bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm, - struct ieee80211_sta *sta); - -enum iwl_bt_kill_msk { - BT_KILL_MSK_DEFAULT, - BT_KILL_MSK_SCO_HID_A2DP, - BT_KILL_MSK_REDUCED_TXPOW, - BT_KILL_MSK_MAX, -}; -extern const u32 iwl_bt_ack_kill_msk[BT_KILL_MSK_MAX]; -extern const u32 iwl_bt_cts_kill_msk[BT_KILL_MSK_MAX]; +void iwl_mvm_bt_coex_vif_assoc(struct iwl_mvm *mvm, struct ieee80211_vif *vif); /* beacon filtering */ #ifdef CONFIG_IWLWIFI_DEBUGFS diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index 2beffd0..edb94ea 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c @@ -77,7 +77,7 @@ static const int nvm_to_read[] = { /* Default NVM size to read */ #define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024) -#define IWL_MAX_NVM_SECTION_SIZE 7000 +#define IWL_MAX_NVM_SECTION_SIZE 6000 #define NVM_WRITE_OPCODE 1 #define NVM_READ_OPCODE 0 @@ -259,8 +259,6 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) #define MAX_NVM_FILE_LEN 16384 /* - * Reads external NVM from a file into mvm->nvm_sections - * * HOW TO CREATE THE NVM FILE FORMAT: * ------------------------------ * 1. create hex file, format: @@ -279,23 +277,20 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm) * * 4. save as "iNVM_xxx.bin" under /lib/firmware */ -static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm) +static int iwl_mvm_load_external_nvm(struct iwl_mvm *mvm) { - int ret, section_size; - u16 section_id; + int ret, section_id, section_size; const struct firmware *fw_entry; const struct { __le16 word1; __le16 word2; u8 data[]; } *file_sec; - const u8 *eof, *temp; + const u8 *eof; #define NVM_WORD1_LEN(x) (8 * (x & 0x03FF)) #define NVM_WORD2_ID(x) (x >> 12) - IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n"); - /* * Obtain NVM image via request_firmware. Since we already used * request_firmware_nowait() for the firmware binary load and only @@ -367,18 +362,12 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm) break; } - temp = kmemdup(file_sec->data, section_size, GFP_KERNEL); - if (!temp) { - ret = -ENOMEM; - break; - } - if (WARN_ON(section_id >= NVM_NUM_OF_SECTIONS)) { - IWL_ERR(mvm, "Invalid NVM section ID\n"); - ret = -EINVAL; + ret = iwl_nvm_write_section(mvm, section_id, file_sec->data, + section_size); + if (ret < 0) { + IWL_ERR(mvm, "iwl_mvm_send_cmd failed: %d\n", ret); break; } - mvm->nvm_sections[section_id].data = temp; - mvm->nvm_sections[section_id].length = section_size; /* advance to the next section */ file_sec = (void *)(file_sec->data + section_size); @@ -388,28 +377,6 @@ out: return ret; } -/* Loads the NVM data stored in mvm->nvm_sections into the NIC */ -int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm) -{ - int i, ret; - u16 section_id; - struct iwl_nvm_section *sections = mvm->nvm_sections; - - IWL_DEBUG_EEPROM(mvm->trans->dev, "'Write to NVM\n"); - - for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) { - section_id = nvm_to_read[i]; - ret = iwl_nvm_write_section(mvm, section_id, - sections[section_id].data, - sections[section_id].length); - if (ret < 0) { - IWL_ERR(mvm, "iwl_mvm_send_cmd failed: %d\n", ret); - break; - } - } - return ret; -} - int iwl_nvm_init(struct iwl_mvm *mvm) { int ret, i, section; @@ -418,36 +385,36 @@ int iwl_nvm_init(struct iwl_mvm *mvm) /* load external NVM if configured */ if (iwlwifi_mod_params.nvm_file) { /* move to External NVM flow */ - ret = iwl_mvm_read_external_nvm(mvm); + ret = iwl_mvm_load_external_nvm(mvm); if (ret) return ret; - } else { - /* Read From FW NVM */ - IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n"); - - /* TODO: find correct NVM max size for a section */ - nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size, - GFP_KERNEL); - if (!nvm_buffer) - return -ENOMEM; - for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) { - section = nvm_to_read[i]; - /* we override the constness for initial read */ - ret = iwl_nvm_read_section(mvm, section, nvm_buffer); - if (ret < 0) - break; - temp = kmemdup(nvm_buffer, ret, GFP_KERNEL); - if (!temp) { - ret = -ENOMEM; - break; - } - mvm->nvm_sections[section].data = temp; - mvm->nvm_sections[section].length = ret; - } - kfree(nvm_buffer); + } + + /* Read From FW NVM */ + IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n"); + + /* TODO: find correct NVM max size for a section */ + nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size, + GFP_KERNEL); + if (!nvm_buffer) + return -ENOMEM; + for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) { + section = nvm_to_read[i]; + /* we override the constness for initial read */ + ret = iwl_nvm_read_section(mvm, section, nvm_buffer); if (ret < 0) - return ret; + break; + temp = kmemdup(nvm_buffer, ret, GFP_KERNEL); + if (!temp) { + ret = -ENOMEM; + break; + } + mvm->nvm_sections[section].data = temp; + mvm->nvm_sections[section].length = ret; } + kfree(nvm_buffer); + if (ret < 0) + return ret; mvm->nvm_data = iwl_parse_nvm_sections(mvm); if (!mvm->nvm_data) diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index d86083c..2fcc8ef 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -224,10 +224,6 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = { RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false), - RX_HANDLER(SCAN_OFFLOAD_COMPLETE, - iwl_mvm_rx_scan_offload_complete_notif, false), - RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_sched_scan_results, - false), RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), @@ -253,7 +249,6 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { CMD(TIME_EVENT_NOTIFICATION), CMD(BINDING_CONTEXT_CMD), CMD(TIME_QUOTA_CMD), - CMD(NON_QOS_TX_COUNTER_CMD), CMD(RADIO_VERSION_NOTIFICATION), CMD(SCAN_REQUEST_CMD), CMD(SCAN_ABORT_CMD), @@ -265,12 +260,10 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { CMD(CALIB_RES_NOTIF_PHY_DB), CMD(SET_CALIB_DEFAULT_CMD), CMD(CALIBRATION_COMPLETE_NOTIFICATION), - CMD(ADD_STA_KEY), CMD(ADD_STA), CMD(REMOVE_STA), CMD(LQ_CMD), CMD(SCAN_OFFLOAD_CONFIG_CMD), - CMD(MATCH_FOUND_NOTIFICATION), CMD(SCAN_OFFLOAD_REQUEST_CMD), CMD(SCAN_OFFLOAD_ABORT_CMD), CMD(SCAN_OFFLOAD_COMPLETE), @@ -310,7 +303,6 @@ static const char *iwl_mvm_cmd_strings[REPLY_MAX] = { CMD(REPLY_BEACON_FILTERING_CMD), CMD(REPLY_THERMAL_MNG_BACKOFF), CMD(MAC_PM_POWER_TABLE), - CMD(BT_COEX_CI), }; #undef CMD @@ -352,14 +344,6 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, mvm->restart_fw = iwlwifi_mod_params.restart_fw ? -1 : 0; - mvm->aux_queue = 15; - mvm->first_agg_queue = 16; - mvm->last_agg_queue = mvm->cfg->base_params->num_of_queues - 1; - if (mvm->cfg->base_params->num_of_queues == 16) { - mvm->aux_queue = 11; - mvm->first_agg_queue = 12; - } - mutex_init(&mvm->mutex); spin_lock_init(&mvm->async_handlers_lock); INIT_LIST_HEAD(&mvm->time_event_list); @@ -417,33 +401,25 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, IWL_INFO(mvm, "Detected %s, REV=0x%X\n", mvm->cfg->name, mvm->trans->hw_rev); - iwl_mvm_tt_initialize(mvm); + err = iwl_trans_start_hw(mvm->trans); + if (err) + goto out_free; - /* - * If the NVM exists in an external file, - * there is no need to unnecessarily power up the NIC at driver load - */ - if (iwlwifi_mod_params.nvm_file) { - iwl_nvm_init(mvm); - } else { - err = iwl_trans_start_hw(mvm->trans); - if (err) - goto out_free; - - mutex_lock(&mvm->mutex); - err = iwl_run_init_mvm_ucode(mvm, true); - mutex_unlock(&mvm->mutex); - /* returns 0 if successful, 1 if success but in rfkill */ - if (err < 0 && !iwlmvm_mod_params.init_dbg) { - IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err); - goto out_free; - } + iwl_mvm_tt_initialize(mvm); - /* Stop the hw after the ALIVE and NVM has been read */ - if (!iwlmvm_mod_params.init_dbg) - iwl_trans_stop_hw(mvm->trans, false); + mutex_lock(&mvm->mutex); + err = iwl_run_init_mvm_ucode(mvm, true); + mutex_unlock(&mvm->mutex); + /* returns 0 if successful, 1 if success but in rfkill */ + if (err < 0 && !iwlmvm_mod_params.init_dbg) { + IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err); + goto out_free; } + /* Stop the hw after the ALIVE and NVM has been read */ + if (!iwlmvm_mod_params.init_dbg) + iwl_trans_stop_hw(mvm->trans, false); + scan_size = sizeof(struct iwl_scan_cmd) + mvm->fw->ucode_capa.max_probe_length + (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel)); @@ -459,7 +435,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, if (err) goto out_unregister; - if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PM_CMD_SUPPORT) + if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_UAPSD) mvm->pm_ops = &pm_mac_ops; else mvm->pm_ops = &pm_legacy_ops; @@ -473,8 +449,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, out_free: iwl_phy_db_free(mvm->phy_db); kfree(mvm->scan_cmd); - if (!iwlwifi_mod_params.nvm_file) - iwl_trans_stop_hw(trans, true); + iwl_trans_stop_hw(trans, true); ieee80211_free_hw(mvm->hw); return NULL; } @@ -740,9 +715,6 @@ static void iwl_mvm_nic_restart(struct iwl_mvm *mvm) case IWL_MVM_SCAN_OS: ieee80211_scan_completed(mvm->hw, true); break; - case IWL_MVM_SCAN_SCHED: - ieee80211_sched_scan_stopped(mvm->hw); - break; } if (mvm->restart_fw > 0) diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index 550824a..d58e393 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c @@ -300,6 +300,11 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, } if (cmd->flags & cpu_to_le16(POWER_FLAGS_ADVANCE_PM_ENA_MSK)) { + cmd->rx_data_timeout_uapsd = + cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT); + cmd->tx_data_timeout_uapsd = + cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT); + if (cmd->uapsd_ac_flags == (BIT(IEEE80211_AC_VO) | BIT(IEEE80211_AC_VI) | BIT(IEEE80211_AC_BE) | @@ -314,31 +319,10 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, } cmd->uapsd_max_sp = IWL_UAPSD_MAX_SP; - - if (mvm->cur_ucode == IWL_UCODE_WOWLAN || cmd->flags & - cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) { - cmd->rx_data_timeout_uapsd = - cpu_to_le32(IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT); - cmd->tx_data_timeout_uapsd = - cpu_to_le32(IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT); - } else { - cmd->rx_data_timeout_uapsd = - cpu_to_le32(IWL_MVM_UAPSD_RX_DATA_TIMEOUT); - cmd->tx_data_timeout_uapsd = - cpu_to_le32(IWL_MVM_UAPSD_TX_DATA_TIMEOUT); - } - - if (cmd->flags & cpu_to_le16(POWER_FLAGS_SNOOZE_ENA_MSK)) { - cmd->heavy_tx_thld_packets = - IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS; - cmd->heavy_rx_thld_packets = - IWL_MVM_PS_SNOOZE_HEAVY_RX_THLD_PACKETS; - } else { - cmd->heavy_tx_thld_packets = - IWL_MVM_PS_HEAVY_TX_THLD_PACKETS; - cmd->heavy_rx_thld_packets = - IWL_MVM_PS_HEAVY_RX_THLD_PACKETS; - } + cmd->heavy_tx_thld_packets = + IWL_MVM_PS_HEAVY_TX_THLD_PACKETS; + cmd->heavy_rx_thld_packets = + IWL_MVM_PS_HEAVY_RX_THLD_PACKETS; cmd->heavy_tx_thld_percentage = IWL_MVM_PS_HEAVY_TX_THLD_PERCENT; cmd->heavy_rx_thld_percentage = @@ -446,32 +430,6 @@ static int iwl_mvm_power_mac_disable(struct iwl_mvm *mvm, sizeof(cmd), &cmd); } -static int iwl_mvm_power_update_device(struct iwl_mvm *mvm) -{ - struct iwl_device_power_cmd cmd = { - .flags = cpu_to_le16(DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK), - }; - - if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) - return 0; - - if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM) - cmd.flags |= cpu_to_le16(DEVICE_POWER_FLAGS_CAM_MSK); - -#ifdef CONFIG_IWLWIFI_DEBUGFS - if ((mvm->cur_ucode == IWL_UCODE_WOWLAN) ? mvm->disable_power_off_d3 : - mvm->disable_power_off) - cmd.flags &= - cpu_to_le16(~DEVICE_POWER_FLAGS_POWER_SAVE_ENA_MSK); -#endif - IWL_DEBUG_POWER(mvm, - "Sending device power command with flags = 0x%X\n", - cmd.flags); - - return iwl_mvm_send_cmd_pdu(mvm, POWER_TABLE_CMD, CMD_SYNC, sizeof(cmd), - &cmd); -} - #ifdef CONFIG_IWLWIFI_DEBUGFS static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, struct ieee80211_vif *vif, char *buf, @@ -482,11 +440,10 @@ static int iwl_mvm_power_mac_dbgfs_read(struct iwl_mvm *mvm, iwl_mvm_power_build_cmd(mvm, vif, &cmd); - if (!(mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DEVICE_PS_CMD)) - pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n", - (cmd.flags & - cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ? - 0 : 1); + pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off = %d\n", + (cmd.flags & + cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK)) ? + 0 : 1); pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n", iwlmvm_mod_params.power_scheme); pos += scnprintf(buf+pos, bufsz-pos, "flags = 0x%x\n", @@ -652,7 +609,6 @@ int iwl_mvm_update_beacon_filter(struct iwl_mvm *mvm, const struct iwl_mvm_power_ops pm_mac_ops = { .power_update_mode = iwl_mvm_power_mac_update_mode, - .power_update_device_mode = iwl_mvm_power_update_device, .power_disable = iwl_mvm_power_mac_disable, #ifdef CONFIG_IWLWIFI_DEBUGFS .power_dbgfs_read = iwl_mvm_power_mac_dbgfs_read, diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c index 17e2bc8..5c6ae16 100644 --- a/drivers/net/wireless/iwlwifi/mvm/quota.c +++ b/drivers/net/wireless/iwlwifi/mvm/quota.c @@ -110,8 +110,7 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac, data->n_interfaces[id]++; break; case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_ADHOC: - if (mvmvif->ap_ibss_active) + if (mvmvif->ap_active) data->n_interfaces[id]++; break; case NL80211_IFTYPE_MONITOR: @@ -120,45 +119,16 @@ static void iwl_mvm_quota_iterator(void *_data, u8 *mac, break; case NL80211_IFTYPE_P2P_DEVICE: break; + case NL80211_IFTYPE_ADHOC: + if (vif->bss_conf.ibss_joined) + data->n_interfaces[id]++; + break; default: WARN_ON_ONCE(1); break; } } -static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm, - struct iwl_time_quota_cmd *cmd) -{ -#ifdef CONFIG_NL80211_TESTMODE - struct iwl_mvm_vif *mvmvif; - int i, phy_id = -1, beacon_int = 0; - - if (!mvm->noa_duration || !mvm->noa_vif) - return; - - mvmvif = iwl_mvm_vif_from_mac80211(mvm->noa_vif); - if (!mvmvif->ap_ibss_active) - return; - - phy_id = mvmvif->phy_ctxt->id; - 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); - u32 id = (id_n_c & FW_CTXT_ID_MSK) >> FW_CTXT_ID_POS; - u32 quota = le32_to_cpu(cmd->quotas[i].quota); - - if (id != phy_id) - continue; - - quota *= (beacon_int - mvm->noa_duration); - quota /= beacon_int; - - cmd->quotas[i].quota = cpu_to_le32(quota); - } -#endif -} - int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif) { struct iwl_time_quota_cmd cmd = {}; @@ -226,8 +196,6 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, struct ieee80211_vif *newvif) /* Give the remainder of the session to the first binding */ le32_add_cpu(&cmd.quotas[0].quota, quota_rem); - iwl_mvm_adjust_quota_for_noa(mvm, &cmd); - ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, CMD_SYNC, sizeof(cmd), &cmd); if (ret) diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index a0b4cc8..4ffaa3f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c @@ -82,24 +82,13 @@ static const u8 ant_toggle_lookup[] = { [ANT_ABC] = ANT_ABC, }; -#define IWL_DECLARE_RATE_INFO(r, s, rp, rn) \ - [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ - IWL_RATE_HT_SISO_MCS_##s##_PLCP, \ - IWL_RATE_HT_MIMO2_MCS_##s##_PLCP, \ - IWL_RATE_VHT_SISO_MCS_##s##_PLCP, \ - IWL_RATE_VHT_MIMO2_MCS_##s##_PLCP,\ - IWL_RATE_##rp##M_INDEX, \ +#define IWL_DECLARE_RATE_INFO(r, s, rp, rn) \ + [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ + IWL_RATE_SISO_##s##M_PLCP, \ + IWL_RATE_MIMO2_##s##M_PLCP,\ + IWL_RATE_##rp##M_INDEX, \ IWL_RATE_##rn##M_INDEX } -#define IWL_DECLARE_MCS_RATE(s) \ - [IWL_RATE_MCS_##s##_INDEX] = { IWL_RATE_INVM_PLCP, \ - IWL_RATE_HT_SISO_MCS_##s##_PLCP, \ - IWL_RATE_HT_MIMO2_MCS_##s##_PLCP, \ - IWL_RATE_VHT_SISO_MCS_##s##_PLCP, \ - IWL_RATE_VHT_MIMO2_MCS_##s##_PLCP, \ - IWL_RATE_INVM_INDEX, \ - IWL_RATE_INVM_INDEX } - /* * Parameter order: * rate, ht rate, prev rate, next rate @@ -113,17 +102,16 @@ static const struct iwl_rs_rate_info iwl_rates[IWL_RATE_COUNT] = { IWL_DECLARE_RATE_INFO(2, INV, 1, 5), /* 2mbps */ IWL_DECLARE_RATE_INFO(5, INV, 2, 11), /*5.5mbps */ IWL_DECLARE_RATE_INFO(11, INV, 9, 12), /* 11mbps */ - IWL_DECLARE_RATE_INFO(6, 0, 5, 11), /* 6mbps ; MCS 0 */ - IWL_DECLARE_RATE_INFO(9, INV, 6, 11), /* 9mbps */ - IWL_DECLARE_RATE_INFO(12, 1, 11, 18), /* 12mbps ; MCS 1 */ - IWL_DECLARE_RATE_INFO(18, 2, 12, 24), /* 18mbps ; MCS 2 */ - IWL_DECLARE_RATE_INFO(24, 3, 18, 36), /* 24mbps ; MCS 3 */ - IWL_DECLARE_RATE_INFO(36, 4, 24, 48), /* 36mbps ; MCS 4 */ - IWL_DECLARE_RATE_INFO(48, 5, 36, 54), /* 48mbps ; MCS 5 */ - IWL_DECLARE_RATE_INFO(54, 6, 48, INV), /* 54mbps ; MCS 6 */ - IWL_DECLARE_MCS_RATE(7), /* MCS 7 */ - IWL_DECLARE_MCS_RATE(8), /* MCS 8 */ - IWL_DECLARE_MCS_RATE(9), /* MCS 9 */ + IWL_DECLARE_RATE_INFO(6, 6, 5, 11), /* 6mbps */ + IWL_DECLARE_RATE_INFO(9, 6, 6, 11), /* 9mbps */ + IWL_DECLARE_RATE_INFO(12, 12, 11, 18), /* 12mbps */ + IWL_DECLARE_RATE_INFO(18, 18, 12, 24), /* 18mbps */ + IWL_DECLARE_RATE_INFO(24, 24, 18, 36), /* 24mbps */ + IWL_DECLARE_RATE_INFO(36, 36, 24, 48), /* 36mbps */ + IWL_DECLARE_RATE_INFO(48, 48, 36, 54), /* 48mbps */ + IWL_DECLARE_RATE_INFO(54, 54, 48, INV), /* 54mbps */ + IWL_DECLARE_RATE_INFO(60, 60, 48, INV), /* 60mbps */ + /* FIXME:RS: ^^ should be INV (legacy) */ }; static inline u8 rs_extract_rate(u32 rate_n_flags) @@ -136,30 +124,26 @@ static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) { int idx = 0; + /* HT rate format */ if (rate_n_flags & RATE_MCS_HT_MSK) { - idx = rate_n_flags & RATE_HT_MCS_RATE_CODE_MSK; - idx += IWL_RATE_MCS_0_INDEX; + idx = rs_extract_rate(rate_n_flags); + + WARN_ON_ONCE(idx >= IWL_RATE_MIMO3_6M_PLCP); + if (idx >= IWL_RATE_MIMO2_6M_PLCP) + idx = idx - IWL_RATE_MIMO2_6M_PLCP; - /* skip 9M not supported in HT*/ + idx += IWL_FIRST_OFDM_RATE; + /* skip 9M not supported in ht*/ if (idx >= IWL_RATE_9M_INDEX) idx += 1; - if ((idx >= IWL_FIRST_HT_RATE) && (idx <= IWL_LAST_HT_RATE)) + if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE)) return idx; - } else if (rate_n_flags & RATE_MCS_VHT_MSK) { - idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK; - idx += IWL_RATE_MCS_0_INDEX; - /* skip 9M not supported in VHT*/ - if (idx >= IWL_RATE_9M_INDEX) - idx++; - if ((idx >= IWL_FIRST_VHT_RATE) && (idx <= IWL_LAST_VHT_RATE)) - return idx; + /* legacy rate format, search for match in table */ } else { - /* legacy rate format, search for match in table */ - - u8 legacy_rate = rs_extract_rate(rate_n_flags); for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++) - if (iwl_rates[idx].plcp == legacy_rate) + if (iwl_rates[idx].plcp == + rs_extract_rate(rate_n_flags)) return idx; } @@ -171,7 +155,6 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, struct ieee80211_sta *sta, struct iwl_lq_sta *lq_sta); static void rs_fill_link_cmd(struct iwl_mvm *mvm, - struct ieee80211_sta *sta, struct iwl_lq_sta *lq_sta, u32 rate_n_flags); static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search); @@ -197,52 +180,35 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta, */ static s32 expected_tpt_legacy[IWL_RATE_COUNT] = { - 7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 0, 0, 0 + 7, 13, 35, 58, 40, 57, 72, 98, 121, 154, 177, 186, 0 }; -/* Expected TpT tables. 4 indexes: - * 0 - NGI, 1 - SGI, 2 - AGG+NGI, 3 - AGG+SGI - */ -static s32 expected_tpt_siso_20MHz[4][IWL_RATE_COUNT] = { - {0, 0, 0, 0, 42, 0, 76, 102, 124, 159, 183, 193, 202, 216, 0}, - {0, 0, 0, 0, 46, 0, 82, 110, 132, 168, 192, 202, 210, 225, 0}, - {0, 0, 0, 0, 49, 0, 97, 145, 192, 285, 375, 420, 464, 551, 0}, - {0, 0, 0, 0, 54, 0, 108, 160, 213, 315, 415, 465, 513, 608, 0}, +static s32 expected_tpt_siso20MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 42, 0, 76, 102, 124, 159, 183, 193, 202}, /* Norm */ + {0, 0, 0, 0, 46, 0, 82, 110, 132, 168, 192, 202, 210}, /* SGI */ + {0, 0, 0, 0, 47, 0, 91, 133, 171, 242, 305, 334, 362}, /* AGG */ + {0, 0, 0, 0, 52, 0, 101, 145, 187, 264, 330, 361, 390}, /* AGG+SGI */ }; -static s32 expected_tpt_siso_40MHz[4][IWL_RATE_COUNT] = { - {0, 0, 0, 0, 77, 0, 127, 160, 184, 220, 242, 250, 257, 269, 275}, - {0, 0, 0, 0, 83, 0, 135, 169, 193, 229, 250, 257, 264, 275, 280}, - {0, 0, 0, 0, 101, 0, 199, 295, 389, 570, 744, 828, 911, 1070, 1173}, - {0, 0, 0, 0, 112, 0, 220, 326, 429, 629, 819, 912, 1000, 1173, 1284}, -}; - -static s32 expected_tpt_siso_80MHz[4][IWL_RATE_COUNT] = { - {0, 0, 0, 0, 130, 0, 191, 223, 244, 273, 288, 294, 298, 305, 308}, - {0, 0, 0, 0, 138, 0, 200, 231, 251, 279, 293, 298, 302, 308, 312}, - {0, 0, 0, 0, 217, 0, 429, 634, 834, 1220, 1585, 1760, 1931, 2258, 2466}, - {0, 0, 0, 0, 241, 0, 475, 701, 921, 1343, 1741, 1931, 2117, 2468, 2691}, +static s32 expected_tpt_siso40MHz[4][IWL_RATE_COUNT] = { + {0, 0, 0, 0, 77, 0, 127, 160, 184, 220, 242, 250, 257}, /* Norm */ + {0, 0, 0, 0, 83, 0, 135, 169, 193, 229, 250, 257, 264}, /* SGI */ + {0, 0, 0, 0, 94, 0, 177, 249, 313, 423, 512, 550, 586}, /* AGG */ + {0, 0, 0, 0, 104, 0, 193, 270, 338, 454, 545, 584, 620}, /* AGG+SGI */ }; static s32 expected_tpt_mimo2_20MHz[4][IWL_RATE_COUNT] = { - {0, 0, 0, 0, 74, 0, 123, 155, 179, 213, 235, 243, 250, 261, 0}, - {0, 0, 0, 0, 81, 0, 131, 164, 187, 221, 242, 250, 256, 267, 0}, - {0, 0, 0, 0, 98, 0, 193, 286, 375, 550, 718, 799, 878, 1032, 0}, - {0, 0, 0, 0, 109, 0, 214, 316, 414, 607, 790, 879, 965, 1132, 0}, + {0, 0, 0, 0, 74, 0, 123, 155, 179, 214, 236, 244, 251}, /* Norm */ + {0, 0, 0, 0, 81, 0, 131, 164, 188, 223, 243, 251, 257}, /* SGI */ + {0, 0, 0, 0, 89, 0, 167, 235, 296, 402, 488, 526, 560}, /* AGG */ + {0, 0, 0, 0, 97, 0, 182, 255, 320, 431, 520, 558, 593}, /* AGG+SGI*/ }; static s32 expected_tpt_mimo2_40MHz[4][IWL_RATE_COUNT] = { - {0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289, 296, 300}, - {0, 0, 0, 0, 131, 0, 191, 222, 242, 270, 284, 289, 293, 300, 303}, - {0, 0, 0, 0, 200, 0, 390, 571, 741, 1067, 1365, 1505, 1640, 1894, 2053}, - {0, 0, 0, 0, 221, 0, 430, 630, 816, 1169, 1490, 1641, 1784, 2053, 2221}, -}; - -static s32 expected_tpt_mimo2_80MHz[4][IWL_RATE_COUNT] = { - {0, 0, 0, 0, 182, 0, 240, 264, 278, 299, 308, 311, 313, 317, 319}, - {0, 0, 0, 0, 190, 0, 247, 269, 282, 302, 310, 313, 315, 319, 320}, - {0, 0, 0, 0, 428, 0, 833, 1215, 1577, 2254, 2863, 3147, 3418, 3913, 4219}, - {0, 0, 0, 0, 474, 0, 920, 1338, 1732, 2464, 3116, 3418, 3705, 4225, 4545}, + {0, 0, 0, 0, 123, 0, 182, 214, 235, 264, 279, 285, 289}, /* Norm */ + {0, 0, 0, 0, 131, 0, 191, 222, 242, 270, 284, 289, 293}, /* SGI */ + {0, 0, 0, 0, 171, 0, 305, 410, 496, 634, 731, 771, 805}, /* AGG */ + {0, 0, 0, 0, 186, 0, 329, 439, 527, 667, 764, 803, 838}, /* AGG+SGI */ }; /* mbps, mcs */ @@ -297,7 +263,7 @@ static void rs_program_fix_rate(struct iwl_mvm *mvm, lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate); if (lq_sta->dbg_fixed_rate) { - rs_fill_link_cmd(NULL, NULL, lq_sta, lq_sta->dbg_fixed_rate); + rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate); iwl_mvm_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false); } } @@ -309,6 +275,17 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm, { int ret = -EAGAIN; + /* + * Don't create TX aggregation sessions when in high + * BT traffic, as they would just be disrupted by BT. + */ + if (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >= 2) { + IWL_DEBUG_COEX(mvm, "BT traffic (%d), no aggregation allowed\n", + BT_MBOX_MSG(&mvm->last_bt_notif, + 3, TRAFFIC_LOAD)); + return ret; + } + IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n", sta->addr, tid); ret = ieee80211_start_tx_ba_session(sta, tid, 5000); @@ -439,54 +416,49 @@ static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl, */ /* FIXME:RS:remove this function and put the flags statically in the table */ static u32 rate_n_flags_from_tbl(struct iwl_mvm *mvm, - struct iwl_scale_tbl_info *tbl, int index) + struct iwl_scale_tbl_info *tbl, + int index, u8 use_green) { u32 rate_n_flags = 0; - rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) & - RATE_MCS_ANT_ABC_MSK); - if (is_legacy(tbl->lq_type)) { - rate_n_flags |= iwl_rates[index].plcp; + rate_n_flags = iwl_rates[index].plcp; if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE) rate_n_flags |= RATE_MCS_CCK_MSK; - return rate_n_flags; - } - - if (is_ht(tbl->lq_type)) { - if (index < IWL_FIRST_HT_RATE || index > IWL_LAST_HT_RATE) { + } else if (is_Ht(tbl->lq_type)) { + if (index > IWL_LAST_OFDM_RATE) { IWL_ERR(mvm, "Invalid HT rate index %d\n", index); - index = IWL_LAST_HT_RATE; + index = IWL_LAST_OFDM_RATE; } - rate_n_flags |= RATE_MCS_HT_MSK; + rate_n_flags = RATE_MCS_HT_MSK; - if (is_ht_siso(tbl->lq_type)) - rate_n_flags |= iwl_rates[index].plcp_ht_siso; - else if (is_ht_mimo2(tbl->lq_type)) - rate_n_flags |= iwl_rates[index].plcp_ht_mimo2; - else - WARN_ON_ONCE(1); - } else if (is_vht(tbl->lq_type)) { - if (index < IWL_FIRST_VHT_RATE || index > IWL_LAST_VHT_RATE) { - IWL_ERR(mvm, "Invalid VHT rate index %d\n", index); - index = IWL_LAST_VHT_RATE; - } - rate_n_flags |= RATE_MCS_VHT_MSK; - if (is_vht_siso(tbl->lq_type)) - rate_n_flags |= iwl_rates[index].plcp_vht_siso; - else if (is_vht_mimo2(tbl->lq_type)) - rate_n_flags |= iwl_rates[index].plcp_vht_mimo2; + if (is_siso(tbl->lq_type)) + rate_n_flags |= iwl_rates[index].plcp_siso; + else if (is_mimo2(tbl->lq_type)) + rate_n_flags |= iwl_rates[index].plcp_mimo2; else WARN_ON_ONCE(1); - } else { IWL_ERR(mvm, "Invalid tbl->lq_type %d\n", tbl->lq_type); } - rate_n_flags |= tbl->bw; - if (tbl->is_SGI) - rate_n_flags |= RATE_MCS_SGI_MSK; - + rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) & + RATE_MCS_ANT_ABC_MSK); + + if (is_Ht(tbl->lq_type)) { + if (tbl->is_ht40) + rate_n_flags |= RATE_MCS_CHAN_WIDTH_40; + if (tbl->is_SGI) + rate_n_flags |= RATE_MCS_SGI_MSK; + + if (use_green) { + rate_n_flags |= RATE_HT_MCS_GF_MSK; + if (is_siso(tbl->lq_type) && tbl->is_SGI) { + rate_n_flags &= ~RATE_MCS_SGI_MSK; + IWL_ERR(mvm, "GF was set with SGI:SISO\n"); + } + } + } return rate_n_flags; } @@ -501,7 +473,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags, { u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK); u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags); - u8 nss; + u8 mcs; memset(tbl, 0, offsetof(struct iwl_scale_tbl_info, win)); *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags); @@ -511,62 +483,41 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags, return -EINVAL; } tbl->is_SGI = 0; /* default legacy setup */ - tbl->bw = 0; + tbl->is_ht40 = 0; tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS); tbl->lq_type = LQ_NONE; tbl->max_search = IWL_MAX_SEARCH; - /* Legacy */ - if (!(rate_n_flags & RATE_MCS_HT_MSK) && - !(rate_n_flags & RATE_MCS_VHT_MSK)) { + /* legacy rate format */ + if (!(rate_n_flags & RATE_MCS_HT_MSK)) { if (num_of_ant == 1) { if (band == IEEE80211_BAND_5GHZ) - tbl->lq_type = LQ_LEGACY_A; + tbl->lq_type = LQ_A; else - tbl->lq_type = LQ_LEGACY_G; - } - - return 0; - } - - /* HT or VHT */ - if (rate_n_flags & RATE_MCS_SGI_MSK) - tbl->is_SGI = 1; - - tbl->bw = rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK; - - if (rate_n_flags & RATE_MCS_HT_MSK) { - nss = ((rate_n_flags & RATE_HT_MCS_NSS_MSK) >> - RATE_HT_MCS_NSS_POS) + 1; - - if (nss == 1) { - tbl->lq_type = LQ_HT_SISO; - WARN_ON_ONCE(num_of_ant != 1); - } else if (nss == 2) { - tbl->lq_type = LQ_HT_MIMO2; - WARN_ON_ONCE(num_of_ant != 2); - } else { - WARN_ON_ONCE(1); + tbl->lq_type = LQ_G; } - } else if (rate_n_flags & RATE_MCS_VHT_MSK) { - nss = ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >> - RATE_VHT_MCS_NSS_POS) + 1; - - if (nss == 1) { - tbl->lq_type = LQ_VHT_SISO; - WARN_ON_ONCE(num_of_ant != 1); - } else if (nss == 2) { - tbl->lq_type = LQ_VHT_MIMO2; - WARN_ON_ONCE(num_of_ant != 2); + /* HT rate format */ + } else { + if (rate_n_flags & RATE_MCS_SGI_MSK) + tbl->is_SGI = 1; + + if (rate_n_flags & RATE_MCS_CHAN_WIDTH_40) /* TODO */ + tbl->is_ht40 = 1; + + mcs = rs_extract_rate(rate_n_flags); + + /* SISO */ + if (mcs <= IWL_RATE_SISO_60M_PLCP) { + if (num_of_ant == 1) + tbl->lq_type = LQ_SISO; /*else NONE*/ + /* MIMO2 */ + } else if (mcs <= IWL_RATE_MIMO2_60M_PLCP) { + if (num_of_ant == 2) + tbl->lq_type = LQ_MIMO2; } else { - WARN_ON_ONCE(1); + WARN_ON_ONCE(num_of_ant == 3); } } - - WARN_ON_ONCE(tbl->bw == RATE_MCS_CHAN_WIDTH_160); - WARN_ON_ONCE(tbl->bw == RATE_MCS_CHAN_WIDTH_80 && - !is_vht(tbl->lq_type)); - return 0; } @@ -599,6 +550,22 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, } /** + * Green-field mode is valid if the station supports it and + * there are no non-GF stations present in the BSS. + */ +static bool rs_use_green(struct ieee80211_sta *sta) +{ + /* + * There's a bug somewhere in this code that causes the + * scaling to get stuck because GF+SGI can't be combined + * in SISO rates. Until we find that bug, disable GF, it + * has only limited benefit and we still interoperate with + * GF APs since we can always receive GF transmissions. + */ + return false; +} + +/** * rs_get_supported_rates - get the available rates * * if management frame or broadcast frame only return @@ -609,15 +576,16 @@ static u16 rs_get_supported_rates(struct iwl_lq_sta *lq_sta, struct ieee80211_hdr *hdr, enum iwl_table_type rate_type) { - if (is_legacy(rate_type)) + if (is_legacy(rate_type)) { return lq_sta->active_legacy_rate; - else if (is_siso(rate_type)) - return lq_sta->active_siso_rate; - else if (is_mimo2(rate_type)) - return lq_sta->active_mimo2_rate; - - WARN_ON_ONCE(1); - return 0; + } else { + if (is_siso(rate_type)) + return lq_sta->active_siso_rate; + else { + WARN_ON_ONCE(!is_mimo2(rate_type)); + return lq_sta->active_mimo2_rate; + } + } } static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask, @@ -684,6 +652,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, u16 rate_mask; u16 high_low; u8 switch_to_legacy = 0; + u8 is_green = lq_sta->is_green; struct iwl_mvm *mvm = lq_sta->drv; /* check if we need to switch from HT to legacy rates. @@ -693,15 +662,15 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, switch_to_legacy = 1; scale_index = rs_ht_to_legacy[scale_index]; if (lq_sta->band == IEEE80211_BAND_5GHZ) - tbl->lq_type = LQ_LEGACY_A; + tbl->lq_type = LQ_A; else - tbl->lq_type = LQ_LEGACY_G; + tbl->lq_type = LQ_G; if (num_of_ant(tbl->ant_type) > 1) tbl->ant_type = first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); - tbl->bw = 0; + tbl->is_ht40 = 0; tbl->is_SGI = 0; tbl->max_search = IWL_MAX_SEARCH; } @@ -732,7 +701,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, low = scale_index; out: - return rate_n_flags_from_tbl(lq_sta->drv, tbl, low); + return rate_n_flags_from_tbl(lq_sta->drv, tbl, low, is_green); } /* @@ -745,18 +714,6 @@ static bool table_type_matches(struct iwl_scale_tbl_info *a, (a->is_SGI == b->is_SGI); } -static u32 rs_ch_width_from_mac_flags(enum mac80211_rate_control_flags flags) -{ - if (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) - return RATE_MCS_CHAN_WIDTH_40; - else if (flags & IEEE80211_TX_RC_80_MHZ_WIDTH) - return RATE_MCS_CHAN_WIDTH_80; - else if (flags & IEEE80211_TX_RC_160_MHZ_WIDTH) - return RATE_MCS_CHAN_WIDTH_160; - - return RATE_MCS_CHAN_WIDTH_20; -} - /* * mac80211 sends us Tx status */ @@ -826,23 +783,16 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband, */ if (info->band == IEEE80211_BAND_2GHZ) mac_index += IWL_FIRST_OFDM_RATE; - } else if (mac_flags & IEEE80211_TX_RC_VHT_MCS) { - mac_index &= RATE_VHT_MCS_RATE_CODE_MSK; - if (mac_index >= (IWL_RATE_9M_INDEX - IWL_FIRST_OFDM_RATE)) - mac_index++; } - /* Here we actually compare this rate to the latest LQ command */ if ((mac_index < 0) || (tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI)) || - (tbl_type.bw != rs_ch_width_from_mac_flags(mac_flags)) || + (tbl_type.is_ht40 != !!(mac_flags & IEEE80211_TX_RC_40_MHZ_WIDTH)) || (tbl_type.ant_type != info->status.antenna) || (!!(tx_rate & RATE_MCS_HT_MSK) != - !!(mac_flags & IEEE80211_TX_RC_MCS)) || - (!!(tx_rate & RATE_MCS_VHT_MSK) != - !!(mac_flags & IEEE80211_TX_RC_VHT_MCS)) || + !!(mac_flags & IEEE80211_TX_RC_MCS)) || (!!(tx_rate & RATE_HT_MCS_GF_MSK) != - !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) || + !!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD)) || (rs_index != mac_index)) { IWL_DEBUG_RATE(mvm, "initial rate %d does not match %d (0x%x)\n", @@ -997,8 +947,7 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta, s32 (*ht_tbl_pointer)[IWL_RATE_COUNT]; /* Check for invalid LQ type */ - if (WARN_ON_ONCE(!is_legacy(tbl->lq_type) && !is_ht(tbl->lq_type) && - !(is_vht(tbl->lq_type)))) { + if (WARN_ON_ONCE(!is_legacy(tbl->lq_type) && !is_Ht(tbl->lq_type))) { tbl->expected_tpt = expected_tpt_legacy; return; } @@ -1009,40 +958,18 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta, return; } - ht_tbl_pointer = expected_tpt_mimo2_20MHz; /* Choose among many HT tables depending on number of streams - * (SISO/MIMO2), channel width (20/40/80), SGI, and aggregation + * (SISO/MIMO2), channel width (20/40), SGI, and aggregation * status */ - if (is_siso(tbl->lq_type)) { - switch (tbl->bw) { - case RATE_MCS_CHAN_WIDTH_20: - ht_tbl_pointer = expected_tpt_siso_20MHz; - break; - case RATE_MCS_CHAN_WIDTH_40: - ht_tbl_pointer = expected_tpt_siso_40MHz; - break; - case RATE_MCS_CHAN_WIDTH_80: - ht_tbl_pointer = expected_tpt_siso_80MHz; - break; - default: - WARN_ON_ONCE(1); - } - } else if (is_mimo2(tbl->lq_type)) { - switch (tbl->bw) { - case RATE_MCS_CHAN_WIDTH_20: - ht_tbl_pointer = expected_tpt_mimo2_20MHz; - break; - case RATE_MCS_CHAN_WIDTH_40: - ht_tbl_pointer = expected_tpt_mimo2_40MHz; - break; - case RATE_MCS_CHAN_WIDTH_80: - ht_tbl_pointer = expected_tpt_mimo2_80MHz; - break; - default: - WARN_ON_ONCE(1); - } - } else { - WARN_ON_ONCE(1); + if (is_siso(tbl->lq_type) && !tbl->is_ht40) + ht_tbl_pointer = expected_tpt_siso20MHz; + else if (is_siso(tbl->lq_type)) + ht_tbl_pointer = expected_tpt_siso40MHz; + else if (is_mimo2(tbl->lq_type) && !tbl->is_ht40) + ht_tbl_pointer = expected_tpt_mimo2_20MHz; + else { + WARN_ON_ONCE(!is_mimo2(tbl->lq_type)); + ht_tbl_pointer = expected_tpt_mimo2_40MHz; } if (!tbl->is_SGI && !lq_sta->is_agg) /* Normal */ @@ -1157,47 +1084,9 @@ static s32 rs_get_best_rate(struct iwl_mvm *mvm, return new_rate; } -/* Move to the next action and wrap around to the first action in case - * we're at the last action. Assumes actions start at 0. - */ -static inline void rs_move_next_action(struct iwl_scale_tbl_info *tbl, - u8 last_action) -{ - BUILD_BUG_ON(IWL_LEGACY_FIRST_ACTION != 0); - BUILD_BUG_ON(IWL_SISO_FIRST_ACTION != 0); - BUILD_BUG_ON(IWL_MIMO2_FIRST_ACTION != 0); - - tbl->action = (tbl->action + 1) % (last_action + 1); -} - -static void rs_set_bw_from_sta(struct iwl_scale_tbl_info *tbl, - struct ieee80211_sta *sta) -{ - if (sta->bandwidth >= IEEE80211_STA_RX_BW_80) - tbl->bw = RATE_MCS_CHAN_WIDTH_80; - else if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) - tbl->bw = RATE_MCS_CHAN_WIDTH_40; - else - tbl->bw = RATE_MCS_CHAN_WIDTH_20; -} - -static bool rs_sgi_allowed(struct iwl_scale_tbl_info *tbl, - struct ieee80211_sta *sta) +static bool iwl_is_ht40_tx_allowed(struct ieee80211_sta *sta) { - struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; - struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; - - if (is_ht20(tbl) && (ht_cap->cap & - IEEE80211_HT_CAP_SGI_20)) - return true; - if (is_ht40(tbl) && (ht_cap->cap & - IEEE80211_HT_CAP_SGI_40)) - return true; - if (is_ht80(tbl) && (vht_cap->cap & - IEEE80211_VHT_CAP_SHORT_GI_80)) - return true; - - return false; + return sta->bandwidth >= IEEE80211_STA_RX_BW_40; } /* @@ -1210,6 +1099,7 @@ static int rs_switch_to_mimo2(struct iwl_mvm *mvm, { u16 rate_mask; s32 rate; + s8 is_green = lq_sta->is_green; if (!sta->ht_cap.ht_supported) return -1; @@ -1223,12 +1113,16 @@ static int rs_switch_to_mimo2(struct iwl_mvm *mvm, IWL_DEBUG_RATE(mvm, "LQ: try to switch to MIMO2\n"); - tbl->lq_type = lq_sta->is_vht ? LQ_VHT_MIMO2 : LQ_HT_MIMO2; + tbl->lq_type = LQ_MIMO2; tbl->action = 0; tbl->max_search = IWL_MAX_SEARCH; rate_mask = lq_sta->active_mimo2_rate; - rs_set_bw_from_sta(tbl, sta); + if (iwl_is_ht40_tx_allowed(sta)) + tbl->is_ht40 = 1; + else + tbl->is_ht40 = 0; + rs_set_expected_tpt_table(lq_sta, tbl); rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index); @@ -1240,10 +1134,10 @@ static int rs_switch_to_mimo2(struct iwl_mvm *mvm, rate, rate_mask); return -1; } - tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate); + tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate, is_green); - IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index\n", - tbl->current_rate); + IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index is green %X\n", + tbl->current_rate, is_green); return 0; } @@ -1256,6 +1150,7 @@ static int rs_switch_to_siso(struct iwl_mvm *mvm, struct iwl_scale_tbl_info *tbl, int index) { u16 rate_mask; + u8 is_green = lq_sta->is_green; s32 rate; if (!sta->ht_cap.ht_supported) @@ -1263,12 +1158,19 @@ static int rs_switch_to_siso(struct iwl_mvm *mvm, IWL_DEBUG_RATE(mvm, "LQ: try to switch to SISO\n"); - tbl->lq_type = lq_sta->is_vht ? LQ_VHT_SISO : LQ_HT_SISO; + tbl->lq_type = LQ_SISO; tbl->action = 0; tbl->max_search = IWL_MAX_SEARCH; rate_mask = lq_sta->active_siso_rate; - rs_set_bw_from_sta(tbl, sta); + if (iwl_is_ht40_tx_allowed(sta)) + tbl->is_ht40 = 1; + else + tbl->is_ht40 = 0; + + if (is_green) + tbl->is_SGI = 0; /*11n spec: no SGI in SISO+Greenfield*/ + rs_set_expected_tpt_table(lq_sta, tbl); rate = rs_get_best_rate(mvm, lq_sta, tbl, rate_mask, index); @@ -1279,9 +1181,9 @@ static int rs_switch_to_siso(struct iwl_mvm *mvm, rate, rate_mask); return -1; } - tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate); - IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index\n", - tbl->current_rate); + tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, rate, is_green); + IWL_DEBUG_RATE(mvm, "LQ: Switch to new mcs %X index is green %X\n", + tbl->current_rate, is_green); return 0; } @@ -1309,10 +1211,14 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm, while (1) { lq_sta->action_counter++; switch (tbl->action) { - case IWL_LEGACY_SWITCH_ANTENNA: + case IWL_LEGACY_SWITCH_ANTENNA1: + case IWL_LEGACY_SWITCH_ANTENNA2: IWL_DEBUG_RATE(mvm, "LQ: Legacy toggle Antenna\n"); - if (tx_chains_num <= 1) + if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 && + tx_chains_num <= 1) || + (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 && + tx_chains_num <= 2)) break; /* Don't change antenna if success has been great */ @@ -1367,7 +1273,9 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm, default: WARN_ON_ONCE(1); } - rs_move_next_action(tbl, IWL_LEGACY_LAST_ACTION); + tbl->action++; + if (tbl->action > IWL_LEGACY_SWITCH_MIMO2) + tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; if (tbl->action == start_action) break; @@ -1377,7 +1285,9 @@ static int rs_move_legacy_other(struct iwl_mvm *mvm, out: lq_sta->search_better_tbl = 1; - rs_move_next_action(tbl, IWL_LEGACY_LAST_ACTION); + tbl->action++; + if (tbl->action > IWL_LEGACY_SWITCH_MIMO2) + tbl->action = IWL_LEGACY_SWITCH_ANTENNA1; if (update_search_tbl_counter) search_tbl->action = tbl->action; return 0; @@ -1390,10 +1300,12 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm, struct iwl_lq_sta *lq_sta, struct ieee80211_sta *sta, int index) { + u8 is_green = lq_sta->is_green; struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); struct iwl_scale_tbl_info *search_tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); struct iwl_rate_scale_data *window = &(tbl->win[index]); + struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); u8 start_action; @@ -1402,17 +1314,40 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm, u8 update_search_tbl_counter = 0; int ret; - if (tbl->action == IWL_SISO_SWITCH_MIMO2 && - !iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) - tbl->action = IWL_SISO_SWITCH_ANTENNA; + switch (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) { + case IWL_BT_COEX_TRAFFIC_LOAD_NONE: + /* nothing */ + break; + case IWL_BT_COEX_TRAFFIC_LOAD_LOW: + /* avoid antenna B unless MIMO */ + if (tbl->action == IWL_SISO_SWITCH_ANTENNA2) + tbl->action = IWL_SISO_SWITCH_MIMO2; + break; + case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: + case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: + /* avoid antenna B and MIMO */ + valid_tx_ant = + first_antenna(iwl_fw_valid_tx_ant(mvm->fw)); + if (tbl->action != IWL_SISO_SWITCH_ANTENNA1) + tbl->action = IWL_SISO_SWITCH_ANTENNA1; + break; + default: + IWL_ERR(mvm, "Invalid BT load %d", + BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)); + break; + } start_action = tbl->action; while (1) { lq_sta->action_counter++; switch (tbl->action) { - case IWL_SISO_SWITCH_ANTENNA: + case IWL_SISO_SWITCH_ANTENNA1: + case IWL_SISO_SWITCH_ANTENNA2: IWL_DEBUG_RATE(mvm, "LQ: SISO toggle Antenna\n"); - if (tx_chains_num <= 1) + if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 && + tx_chains_num <= 1) || + (tbl->action == IWL_SISO_SWITCH_ANTENNA2 && + tx_chains_num <= 2)) break; if (window->success_ratio >= IWL_RS_GOOD_RATIO && @@ -1445,12 +1380,23 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm, goto out; break; case IWL_SISO_SWITCH_GI: - if (!rs_sgi_allowed(tbl, sta)) + if (!tbl->is_ht40 && !(ht_cap->cap & + IEEE80211_HT_CAP_SGI_20)) + break; + if (tbl->is_ht40 && !(ht_cap->cap & + IEEE80211_HT_CAP_SGI_40)) break; IWL_DEBUG_RATE(mvm, "LQ: SISO toggle SGI/NGI\n"); memcpy(search_tbl, tbl, sz); + if (is_green) { + if (!tbl->is_SGI) + break; + else + IWL_ERR(mvm, + "SGI was set in GF+SISO\n"); + } search_tbl->is_SGI = !tbl->is_SGI; rs_set_expected_tpt_table(lq_sta, search_tbl); if (tbl->is_SGI) { @@ -1459,13 +1405,16 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm, break; } search_tbl->current_rate = - rate_n_flags_from_tbl(mvm, search_tbl, index); + rate_n_flags_from_tbl(mvm, search_tbl, + index, is_green); update_search_tbl_counter = 1; goto out; default: WARN_ON_ONCE(1); } - rs_move_next_action(tbl, IWL_SISO_LAST_ACTION); + tbl->action++; + if (tbl->action > IWL_SISO_SWITCH_GI) + tbl->action = IWL_SISO_SWITCH_ANTENNA1; if (tbl->action == start_action) break; @@ -1475,7 +1424,9 @@ static int rs_move_siso_to_other(struct iwl_mvm *mvm, out: lq_sta->search_better_tbl = 1; - rs_move_next_action(tbl, IWL_SISO_LAST_ACTION); + tbl->action++; + if (tbl->action > IWL_SISO_SWITCH_GI) + tbl->action = IWL_SISO_SWITCH_ANTENNA1; if (update_search_tbl_counter) search_tbl->action = tbl->action; @@ -1489,20 +1440,63 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm, struct iwl_lq_sta *lq_sta, struct ieee80211_sta *sta, int index) { + s8 is_green = lq_sta->is_green; struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); struct iwl_scale_tbl_info *search_tbl = &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); + struct iwl_rate_scale_data *window = &(tbl->win[index]); + struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; u32 sz = (sizeof(struct iwl_scale_tbl_info) - (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); u8 start_action; u8 valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw); + u8 tx_chains_num = num_of_ant(valid_tx_ant); u8 update_search_tbl_counter = 0; int ret; + switch (BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) { + case IWL_BT_COEX_TRAFFIC_LOAD_NONE: + /* nothing */ + break; + case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: + case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: + /* avoid antenna B and MIMO */ + if (tbl->action != IWL_MIMO2_SWITCH_SISO_A) + tbl->action = IWL_MIMO2_SWITCH_SISO_A; + break; + case IWL_BT_COEX_TRAFFIC_LOAD_LOW: + /* avoid antenna B unless MIMO */ + if (tbl->action == IWL_MIMO2_SWITCH_SISO_B) + tbl->action = IWL_MIMO2_SWITCH_SISO_A; + break; + default: + IWL_ERR(mvm, "Invalid BT load %d", + BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)); + break; + } + start_action = tbl->action; while (1) { lq_sta->action_counter++; switch (tbl->action) { + case IWL_MIMO2_SWITCH_ANTENNA1: + case IWL_MIMO2_SWITCH_ANTENNA2: + IWL_DEBUG_RATE(mvm, "LQ: MIMO2 toggle Antennas\n"); + + if (tx_chains_num <= 2) + break; + + if (window->success_ratio >= IWL_RS_GOOD_RATIO) + break; + + memcpy(search_tbl, tbl, sz); + if (rs_toggle_antenna(valid_tx_ant, + &search_tbl->current_rate, + search_tbl)) { + update_search_tbl_counter = 1; + goto out; + } + break; case IWL_MIMO2_SWITCH_SISO_A: case IWL_MIMO2_SWITCH_SISO_B: IWL_DEBUG_RATE(mvm, "LQ: MIMO2 switch to SISO\n"); @@ -1527,7 +1521,11 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm, break; case IWL_MIMO2_SWITCH_GI: - if (!rs_sgi_allowed(tbl, sta)) + if (!tbl->is_ht40 && !(ht_cap->cap & + IEEE80211_HT_CAP_SGI_20)) + break; + if (tbl->is_ht40 && !(ht_cap->cap & + IEEE80211_HT_CAP_SGI_40)) break; IWL_DEBUG_RATE(mvm, "LQ: MIMO2 toggle SGI/NGI\n"); @@ -1548,13 +1546,16 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm, break; } search_tbl->current_rate = - rate_n_flags_from_tbl(mvm, search_tbl, index); + rate_n_flags_from_tbl(mvm, search_tbl, + index, is_green); update_search_tbl_counter = 1; goto out; default: WARN_ON_ONCE(1); } - rs_move_next_action(tbl, IWL_MIMO2_LAST_ACTION); + tbl->action++; + if (tbl->action > IWL_MIMO2_SWITCH_GI) + tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; if (tbl->action == start_action) break; @@ -1563,7 +1564,9 @@ static int rs_move_mimo2_to_other(struct iwl_mvm *mvm, return 0; out: lq_sta->search_better_tbl = 1; - rs_move_next_action(tbl, IWL_MIMO2_LAST_ACTION); + tbl->action++; + if (tbl->action > IWL_MIMO2_SWITCH_GI) + tbl->action = IWL_MIMO2_SWITCH_ANTENNA1; if (update_search_tbl_counter) search_tbl->action = tbl->action; @@ -1657,16 +1660,15 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search) * setup rate table in uCode */ static void rs_update_rate_tbl(struct iwl_mvm *mvm, - struct ieee80211_sta *sta, struct iwl_lq_sta *lq_sta, struct iwl_scale_tbl_info *tbl, - int index) + int index, u8 is_green) { u32 rate; /* Update uCode's rate table. */ - rate = rate_n_flags_from_tbl(mvm, tbl, index); - rs_fill_link_cmd(mvm, sta, lq_sta, rate); + rate = rate_n_flags_from_tbl(mvm, tbl, index, is_green); + rs_fill_link_cmd(mvm, lq_sta, rate); iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false); } @@ -1710,6 +1712,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, u8 update_lq = 0; struct iwl_scale_tbl_info *tbl, *tbl1; u16 rate_scale_index_msk = 0; + u8 is_green = 0; u8 active_tbl = 0; u8 done_search = 0; u16 high_low; @@ -1751,6 +1754,11 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, active_tbl = 1 - lq_sta->active_tbl; tbl = &(lq_sta->lq_info[active_tbl]); + if (is_legacy(tbl->lq_type)) + lq_sta->is_green = 0; + else + lq_sta->is_green = rs_use_green(sta); + is_green = lq_sta->is_green; /* current tx rate */ index = lq_sta->last_txrate_idx; @@ -1789,7 +1797,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); /* get "active" rate info */ index = iwl_hwrate_to_plcp_idx(tbl->current_rate); - rs_update_rate_tbl(mvm, sta, lq_sta, tbl, index); + rs_update_rate_tbl(mvm, lq_sta, tbl, index, is_green); } return; } @@ -1970,24 +1978,24 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, (current_tpt > (100 * tbl->expected_tpt[low])))) scale_action = 0; - if ((le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) >= + if ((BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && (is_mimo(tbl->lq_type))) { if (lq_sta->last_bt_traffic > - le32_to_cpu(mvm->last_bt_notif.bt_activity_grading)) { + BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) { /* * don't set scale_action, don't want to scale up if * the rate scale doesn't otherwise think that is a * good idea. */ } else if (lq_sta->last_bt_traffic <= - le32_to_cpu(mvm->last_bt_notif.bt_activity_grading)) { + BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD)) { scale_action = -1; } } lq_sta->last_bt_traffic = - le32_to_cpu(mvm->last_bt_notif.bt_activity_grading); + BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD); - if ((le32_to_cpu(mvm->last_bt_notif.bt_activity_grading) >= + if ((BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH) && is_mimo(tbl->lq_type)) { /* search for a new modulation */ rs_stay_in_table(lq_sta, true); @@ -2024,7 +2032,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, lq_update: /* Replace uCode's rate table for the destination station. */ if (update_lq) - rs_update_rate_tbl(mvm, sta, lq_sta, tbl, index); + rs_update_rate_tbl(mvm, lq_sta, tbl, index, is_green); rs_stay_in_table(lq_sta, false); @@ -2063,7 +2071,7 @@ lq_update: IWL_DEBUG_RATE(mvm, "Switch current mcs: %X index: %d\n", tbl->current_rate, index); - rs_fill_link_cmd(mvm, sta, lq_sta, tbl->current_rate); + rs_fill_link_cmd(mvm, lq_sta, tbl->current_rate); iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_ASYNC, false); } else { done_search = 1; @@ -2105,7 +2113,7 @@ lq_update: } out: - tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, index); + tbl->current_rate = rate_n_flags_from_tbl(mvm, tbl, index, is_green); lq_sta->last_txrate_idx = index; } @@ -2132,6 +2140,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm, int rate_idx; int i; u32 rate; + u8 use_green = rs_use_green(sta); u8 active_tbl = 0; u8 valid_tx_ant; @@ -2163,10 +2172,10 @@ static void rs_initialize_lq(struct iwl_mvm *mvm, if (!rs_is_valid_ant(valid_tx_ant, tbl->ant_type)) rs_toggle_antenna(valid_tx_ant, &rate, tbl); - rate = rate_n_flags_from_tbl(mvm, tbl, rate_idx); + rate = rate_n_flags_from_tbl(mvm, tbl, rate_idx, use_green); tbl->current_rate = rate; rs_set_expected_tpt_table(lq_sta, tbl); - rs_fill_link_cmd(NULL, NULL, lq_sta, rate); + rs_fill_link_cmd(NULL, lq_sta, rate); /* TODO restore station should remember the lq cmd */ iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, CMD_SYNC, true); } @@ -2181,6 +2190,7 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta, struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct iwl_lq_sta *lq_sta = mvm_sta; + int rate_idx; IWL_DEBUG_RATE_LIMIT(mvm, "rate scale calculate new rate for skb\n"); @@ -2205,9 +2215,36 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta, if (rate_control_send_low(sta, mvm_sta, txrc)) return; - iwl_mvm_hwrate_to_tx_rate(lq_sta->last_rate_n_flags, - info->band, &info->control.rates[0]); - + rate_idx = lq_sta->last_txrate_idx; + + if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) { + rate_idx -= IWL_FIRST_OFDM_RATE; + /* 6M and 9M shared same MCS index */ + rate_idx = (rate_idx > 0) ? (rate_idx - 1) : 0; + WARN_ON_ONCE(rs_extract_rate(lq_sta->last_rate_n_flags) >= + IWL_RATE_MIMO3_6M_PLCP); + if (rs_extract_rate(lq_sta->last_rate_n_flags) >= + IWL_RATE_MIMO2_6M_PLCP) + rate_idx = rate_idx + MCS_INDEX_PER_STREAM; + info->control.rates[0].flags = IEEE80211_TX_RC_MCS; + if (lq_sta->last_rate_n_flags & RATE_MCS_SGI_MSK) + info->control.rates[0].flags |= IEEE80211_TX_RC_SHORT_GI; + if (lq_sta->last_rate_n_flags & RATE_MCS_CHAN_WIDTH_40) /* TODO */ + info->control.rates[0].flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; + if (lq_sta->last_rate_n_flags & RATE_HT_MCS_GF_MSK) + info->control.rates[0].flags |= IEEE80211_TX_RC_GREEN_FIELD; + } else { + /* Check for invalid rates */ + if ((rate_idx < 0) || (rate_idx >= IWL_RATE_COUNT_LEGACY) || + ((sband->band == IEEE80211_BAND_5GHZ) && + (rate_idx < IWL_FIRST_OFDM_RATE))) + rate_idx = rate_lowest_index(sband, sta); + /* On valid 5 GHz rate, adjust index */ + else if (sband->band == IEEE80211_BAND_5GHZ) + rate_idx -= IWL_FIRST_OFDM_RATE; + info->control.rates[0].flags = 0; + } + info->control.rates[0].idx = rate_idx; info->control.rates[0].count = 1; } @@ -2224,24 +2261,6 @@ static void *rs_alloc_sta(void *mvm_rate, struct ieee80211_sta *sta, return &sta_priv->lq_sta; } -static int rs_vht_highest_rx_mcs_index(struct ieee80211_sta_vht_cap *vht_cap, - int nss) -{ - u16 rx_mcs = le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map) & - (0x3 << (2 * (nss - 1))); - rx_mcs >>= (2 * (nss - 1)); - - if (rx_mcs == IEEE80211_VHT_MCS_SUPPORT_0_7) - return IWL_RATE_MCS_7_INDEX; - else if (rx_mcs == IEEE80211_VHT_MCS_SUPPORT_0_8) - return IWL_RATE_MCS_8_INDEX; - else if (rx_mcs == IEEE80211_VHT_MCS_SUPPORT_0_9) - return IWL_RATE_MCS_9_INDEX; - - WARN_ON_ONCE(rx_mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED); - return -1; -} - /* * Called after adding a new station to initialize rate scaling */ @@ -2251,7 +2270,6 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, int i, j; struct ieee80211_hw *hw = mvm->hw; struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; - struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; struct iwl_mvm_sta *sta_priv; struct iwl_lq_sta *lq_sta; struct ieee80211_supported_band *sband; @@ -2280,6 +2298,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, lq_sta->max_rate_idx = -1; lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; + lq_sta->is_green = rs_use_green(sta); lq_sta->band = sband->band; /* * active legacy rates as per supported rates bitmap @@ -2289,54 +2308,25 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, for_each_set_bit(i, &supp, BITS_PER_LONG) lq_sta->active_legacy_rate |= BIT(sband->bitrates[i].hw_value); - /* TODO: should probably account for rx_highest for both HT/VHT */ - if (!vht_cap || !vht_cap->vht_supported) { - /* active_siso_rate mask includes 9 MBits (bit 5), - * and CCK (bits 0-3), supp_rates[] does not; - * shift to convert format, force 9 MBits off. - */ - lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1; - lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1; - lq_sta->active_siso_rate &= ~((u16)0x2); - lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; - - /* Same here */ - lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1; - lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1; - lq_sta->active_mimo2_rate &= ~((u16)0x2); - lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; - - lq_sta->is_vht = false; - } else { - int highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 1); - if (highest_mcs >= IWL_RATE_MCS_0_INDEX) { - for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) { - if (i == IWL_RATE_9M_INDEX) - continue; - - lq_sta->active_siso_rate |= BIT(i); - } - } - - highest_mcs = rs_vht_highest_rx_mcs_index(vht_cap, 2); - if (highest_mcs >= IWL_RATE_MCS_0_INDEX) { - for (i = IWL_RATE_MCS_0_INDEX; i <= highest_mcs; i++) { - if (i == IWL_RATE_9M_INDEX) - continue; - - lq_sta->active_mimo2_rate |= BIT(i); - } - } + /* + * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), + * supp_rates[] does not; shift to convert format, force 9 MBits off. + */ + lq_sta->active_siso_rate = ht_cap->mcs.rx_mask[0] << 1; + lq_sta->active_siso_rate |= ht_cap->mcs.rx_mask[0] & 0x1; + lq_sta->active_siso_rate &= ~((u16)0x2); + lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; - /* TODO: avoid MCS9 in 20Mhz which isn't valid for 11ac */ - lq_sta->is_vht = true; - } + /* Same here */ + lq_sta->active_mimo2_rate = ht_cap->mcs.rx_mask[1] << 1; + lq_sta->active_mimo2_rate |= ht_cap->mcs.rx_mask[1] & 0x1; + lq_sta->active_mimo2_rate &= ~((u16)0x2); + lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; IWL_DEBUG_RATE(mvm, - "SISO-RATE=%X MIMO2-RATE=%X VHT=%d\n", + "SISO-RATE=%X MIMO2-RATE=%X\n", lq_sta->active_siso_rate, - lq_sta->active_mimo2_rate, - lq_sta->is_vht); + lq_sta->active_mimo2_rate); /* These values will be overridden later */ lq_sta->lq.single_stream_ant_msk = @@ -2368,7 +2358,6 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, } static void rs_fill_link_cmd(struct iwl_mvm *mvm, - struct ieee80211_sta *sta, struct iwl_lq_sta *lq_sta, u32 new_rate) { struct iwl_scale_tbl_info tbl_type; @@ -2440,6 +2429,7 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm, rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type, &rate_idx); + /* Indicate to uCode which entries might be MIMO. * If initial rate was MIMO, this will finally end up * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */ @@ -2465,9 +2455,7 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm, } /* Don't allow HT rates after next pass. - * rs_get_lower_rate() will change type to LQ_LEGACY_A - * or LQ_LEGACY_G. - */ + * rs_get_lower_rate() will change type to LQ_A or LQ_G. */ use_ht_possible = 0; /* Override next rate if needed for debug purposes */ @@ -2486,9 +2474,12 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm, lq_cmd->agg_time_limit = cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF); - if (sta) - lq_cmd->agg_time_limit = - cpu_to_le16(iwl_mvm_bt_coex_agg_time_limit(mvm, sta)); + /* + * overwrite if needed, pass aggregation time limit + * to uCode in uSec - This is racy - but heh, at least it helps... + */ + if (mvm && BT_MBOX_MSG(&mvm->last_bt_notif, 3, TRAFFIC_LOAD) >= 2) + lq_cmd->agg_time_limit = cpu_to_le16(1200); } static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) @@ -2595,18 +2586,16 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, (iwl_fw_valid_tx_ant(mvm->fw) & ANT_B) ? "ANT_B," : "", (iwl_fw_valid_tx_ant(mvm->fw) & ANT_C) ? "ANT_C" : ""); desc += sprintf(buff+desc, "lq type %s\n", - (is_legacy(tbl->lq_type)) ? "legacy" : - is_vht(tbl->lq_type) ? "VHT" : "HT"); - if (is_ht(tbl->lq_type)) { + (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); + if (is_Ht(tbl->lq_type)) { desc += sprintf(buff+desc, " %s", (is_siso(tbl->lq_type)) ? "SISO" : "MIMO2"); desc += sprintf(buff+desc, " %s", - (is_ht20(tbl)) ? "20MHz" : - (is_ht40(tbl)) ? "40MHz" : - (is_ht80(tbl)) ? "80Mhz" : "BAD BW"); - desc += sprintf(buff+desc, " %s %s\n", + (tbl->is_ht40) ? "40MHz" : "20MHz"); + desc += sprintf(buff+desc, " %s %s %s\n", (tbl->is_SGI) ? "SGI" : "", - (lq_sta->is_agg) ? "AGG on" : ""); + (lq_sta->is_green) ? "GF enabled" : "", + (lq_sta->is_agg) ? "AGG on" : ""); } desc += sprintf(buff+desc, "last tx rate=0x%X\n", lq_sta->last_rate_n_flags); @@ -2664,7 +2653,7 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file, int desc = 0; int i, j; ssize_t ret; - struct iwl_scale_tbl_info *tbl; + struct iwl_lq_sta *lq_sta = file->private_data; buff = kmalloc(1024, GFP_KERNEL); @@ -2672,23 +2661,21 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file, return -ENOMEM; for (i = 0; i < LQ_SIZE; i++) { - tbl = &(lq_sta->lq_info[i]); desc += sprintf(buff+desc, - "%s type=%d SGI=%d BW=%s DUP=0\n" + "%s type=%d SGI=%d HT40=%d DUP=0 GF=%d\n" "rate=0x%X\n", lq_sta->active_tbl == i ? "*" : "x", - tbl->lq_type, - tbl->is_SGI, - is_ht20(tbl) ? "20Mhz" : - is_ht40(tbl) ? "40Mhz" : - is_ht80(tbl) ? "80Mhz" : "ERR", - tbl->current_rate); + lq_sta->lq_info[i].lq_type, + lq_sta->lq_info[i].is_SGI, + lq_sta->lq_info[i].is_ht40, + lq_sta->is_green, + lq_sta->lq_info[i].current_rate); for (j = 0; j < IWL_RATE_COUNT; j++) { desc += sprintf(buff+desc, "counter=%d success=%d %%=%d\n", - tbl->win[j].counter, - tbl->win[j].success_counter, - tbl->win[j].success_ratio); + lq_sta->lq_info[i].win[j].counter, + lq_sta->lq_info[i].win[j].success_counter, + lq_sta->lq_info[i].win[j].success_ratio); } } ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h index 5d5344f..335cf16 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/rs.h @@ -35,11 +35,9 @@ #include "iwl-trans.h" struct iwl_rs_rate_info { - u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ - u8 plcp_ht_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ - u8 plcp_ht_mimo2; /* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */ - u8 plcp_vht_siso; - u8 plcp_vht_mimo2; + u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ + u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ + u8 plcp_mimo2; /* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */ u8 prev_rs; /* previous rate used in rs algo */ u8 next_rs; /* next rate used in rs algo */ }; @@ -85,52 +83,35 @@ enum { #define IWL_RATE_11M_MASK (1 << IWL_RATE_11M_INDEX) -/* uCode API values for HT/VHT bit rates */ +/* uCode API values for OFDM high-throughput (HT) bit rates */ enum { - IWL_RATE_HT_SISO_MCS_0_PLCP = 0, - IWL_RATE_HT_SISO_MCS_1_PLCP = 1, - IWL_RATE_HT_SISO_MCS_2_PLCP = 2, - IWL_RATE_HT_SISO_MCS_3_PLCP = 3, - IWL_RATE_HT_SISO_MCS_4_PLCP = 4, - IWL_RATE_HT_SISO_MCS_5_PLCP = 5, - IWL_RATE_HT_SISO_MCS_6_PLCP = 6, - IWL_RATE_HT_SISO_MCS_7_PLCP = 7, - IWL_RATE_HT_MIMO2_MCS_0_PLCP = 0x8, - IWL_RATE_HT_MIMO2_MCS_1_PLCP = 0x9, - IWL_RATE_HT_MIMO2_MCS_2_PLCP = 0xA, - IWL_RATE_HT_MIMO2_MCS_3_PLCP = 0xB, - IWL_RATE_HT_MIMO2_MCS_4_PLCP = 0xC, - IWL_RATE_HT_MIMO2_MCS_5_PLCP = 0xD, - IWL_RATE_HT_MIMO2_MCS_6_PLCP = 0xE, - IWL_RATE_HT_MIMO2_MCS_7_PLCP = 0xF, - IWL_RATE_VHT_SISO_MCS_0_PLCP = 0, - IWL_RATE_VHT_SISO_MCS_1_PLCP = 1, - IWL_RATE_VHT_SISO_MCS_2_PLCP = 2, - IWL_RATE_VHT_SISO_MCS_3_PLCP = 3, - IWL_RATE_VHT_SISO_MCS_4_PLCP = 4, - IWL_RATE_VHT_SISO_MCS_5_PLCP = 5, - IWL_RATE_VHT_SISO_MCS_6_PLCP = 6, - IWL_RATE_VHT_SISO_MCS_7_PLCP = 7, - IWL_RATE_VHT_SISO_MCS_8_PLCP = 8, - IWL_RATE_VHT_SISO_MCS_9_PLCP = 9, - IWL_RATE_VHT_MIMO2_MCS_0_PLCP = 0x10, - IWL_RATE_VHT_MIMO2_MCS_1_PLCP = 0x11, - IWL_RATE_VHT_MIMO2_MCS_2_PLCP = 0x12, - IWL_RATE_VHT_MIMO2_MCS_3_PLCP = 0x13, - IWL_RATE_VHT_MIMO2_MCS_4_PLCP = 0x14, - IWL_RATE_VHT_MIMO2_MCS_5_PLCP = 0x15, - IWL_RATE_VHT_MIMO2_MCS_6_PLCP = 0x16, - IWL_RATE_VHT_MIMO2_MCS_7_PLCP = 0x17, - IWL_RATE_VHT_MIMO2_MCS_8_PLCP = 0x18, - IWL_RATE_VHT_MIMO2_MCS_9_PLCP = 0x19, - IWL_RATE_HT_SISO_MCS_INV_PLCP, - IWL_RATE_HT_MIMO2_MCS_INV_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, - IWL_RATE_VHT_SISO_MCS_INV_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, - IWL_RATE_VHT_MIMO2_MCS_INV_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, - IWL_RATE_HT_SISO_MCS_8_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, - IWL_RATE_HT_SISO_MCS_9_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, - IWL_RATE_HT_MIMO2_MCS_8_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, - IWL_RATE_HT_MIMO2_MCS_9_PLCP = IWL_RATE_HT_SISO_MCS_INV_PLCP, + IWL_RATE_SISO_6M_PLCP = 0, + IWL_RATE_SISO_12M_PLCP = 1, + IWL_RATE_SISO_18M_PLCP = 2, + IWL_RATE_SISO_24M_PLCP = 3, + IWL_RATE_SISO_36M_PLCP = 4, + IWL_RATE_SISO_48M_PLCP = 5, + IWL_RATE_SISO_54M_PLCP = 6, + IWL_RATE_SISO_60M_PLCP = 7, + IWL_RATE_MIMO2_6M_PLCP = 0x8, + IWL_RATE_MIMO2_12M_PLCP = 0x9, + IWL_RATE_MIMO2_18M_PLCP = 0xa, + IWL_RATE_MIMO2_24M_PLCP = 0xb, + IWL_RATE_MIMO2_36M_PLCP = 0xc, + IWL_RATE_MIMO2_48M_PLCP = 0xd, + IWL_RATE_MIMO2_54M_PLCP = 0xe, + IWL_RATE_MIMO2_60M_PLCP = 0xf, + IWL_RATE_MIMO3_6M_PLCP = 0x10, + IWL_RATE_MIMO3_12M_PLCP = 0x11, + IWL_RATE_MIMO3_18M_PLCP = 0x12, + IWL_RATE_MIMO3_24M_PLCP = 0x13, + IWL_RATE_MIMO3_36M_PLCP = 0x14, + IWL_RATE_MIMO3_48M_PLCP = 0x15, + IWL_RATE_MIMO3_54M_PLCP = 0x16, + IWL_RATE_MIMO3_60M_PLCP = 0x17, + IWL_RATE_SISO_INVM_PLCP, + IWL_RATE_MIMO2_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP, + IWL_RATE_MIMO3_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP, }; #define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1) @@ -158,33 +139,25 @@ enum { #define IWL_RATE_DECREASE_TH 1920 /* 15% */ /* possible actions when in legacy mode */ -enum { - IWL_LEGACY_SWITCH_ANTENNA, - IWL_LEGACY_SWITCH_SISO, - IWL_LEGACY_SWITCH_MIMO2, - IWL_LEGACY_FIRST_ACTION = IWL_LEGACY_SWITCH_ANTENNA, - IWL_LEGACY_LAST_ACTION = IWL_LEGACY_SWITCH_MIMO2, -}; +#define IWL_LEGACY_SWITCH_ANTENNA1 0 +#define IWL_LEGACY_SWITCH_ANTENNA2 1 +#define IWL_LEGACY_SWITCH_SISO 2 +#define IWL_LEGACY_SWITCH_MIMO2 3 /* possible actions when in siso mode */ -enum { - IWL_SISO_SWITCH_ANTENNA, - IWL_SISO_SWITCH_MIMO2, - IWL_SISO_SWITCH_GI, - IWL_SISO_FIRST_ACTION = IWL_SISO_SWITCH_ANTENNA, - IWL_SISO_LAST_ACTION = IWL_SISO_SWITCH_GI, -}; +#define IWL_SISO_SWITCH_ANTENNA1 0 +#define IWL_SISO_SWITCH_ANTENNA2 1 +#define IWL_SISO_SWITCH_MIMO2 2 +#define IWL_SISO_SWITCH_GI 3 /* possible actions when in mimo mode */ -enum { - IWL_MIMO2_SWITCH_SISO_A, - IWL_MIMO2_SWITCH_SISO_B, - IWL_MIMO2_SWITCH_GI, - IWL_MIMO2_FIRST_ACTION = IWL_MIMO2_SWITCH_SISO_A, - IWL_MIMO2_LAST_ACTION = IWL_MIMO2_SWITCH_GI, -}; +#define IWL_MIMO2_SWITCH_ANTENNA1 0 +#define IWL_MIMO2_SWITCH_ANTENNA2 1 +#define IWL_MIMO2_SWITCH_SISO_A 2 +#define IWL_MIMO2_SWITCH_SISO_B 3 +#define IWL_MIMO2_SWITCH_GI 4 -#define IWL_MAX_SEARCH IWL_MIMO2_LAST_ACTION +#define IWL_MAX_SEARCH IWL_MIMO2_SWITCH_GI #define IWL_ACTION_LIMIT 3 /* # possible actions */ @@ -215,31 +188,20 @@ enum { enum iwl_table_type { LQ_NONE, - LQ_LEGACY_G, /* legacy types */ - LQ_LEGACY_A, - LQ_HT_SISO, /* HT types */ - LQ_HT_MIMO2, - LQ_VHT_SISO, /* VHT types */ - LQ_VHT_MIMO2, + LQ_G, /* legacy types */ + LQ_A, + LQ_SISO, /* high-throughput types */ + LQ_MIMO2, LQ_MAX, }; -#define is_legacy(tbl) (((tbl) == LQ_LEGACY_G) || ((tbl) == LQ_LEGACY_A)) -#define is_ht_siso(tbl) ((tbl) == LQ_HT_SISO) -#define is_ht_mimo2(tbl) ((tbl) == LQ_HT_MIMO2) -#define is_vht_siso(tbl) ((tbl) == LQ_VHT_SISO) -#define is_vht_mimo2(tbl) ((tbl) == LQ_VHT_MIMO2) -#define is_siso(tbl) (is_ht_siso(tbl) || is_vht_siso(tbl)) -#define is_mimo2(tbl) (is_ht_mimo2(tbl) || is_vht_mimo2(tbl)) -#define is_mimo(tbl) (is_mimo2(tbl)) -#define is_ht(tbl) (is_ht_siso(tbl) || is_ht_mimo2(tbl)) -#define is_vht(tbl) (is_vht_siso(tbl) || is_vht_mimo2(tbl)) -#define is_a_band(tbl) ((tbl) == LQ_LEGACY_A) -#define is_g_band(tbl) ((tbl) == LQ_LEGACY_G) - -#define is_ht20(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_20) -#define is_ht40(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_40) -#define is_ht80(tbl) (tbl->bw == RATE_MCS_CHAN_WIDTH_80) +#define is_legacy(tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A)) +#define is_siso(tbl) ((tbl) == LQ_SISO) +#define is_mimo2(tbl) ((tbl) == LQ_MIMO2) +#define is_mimo(tbl) is_mimo2(tbl) +#define is_Ht(tbl) (is_siso(tbl) || is_mimo(tbl)) +#define is_a_band(tbl) ((tbl) == LQ_A) +#define is_g_and(tbl) ((tbl) == LQ_G) #define IWL_MAX_MCS_DISPLAY_SIZE 12 @@ -270,7 +232,7 @@ struct iwl_scale_tbl_info { enum iwl_table_type lq_type; u8 ant_type; u8 is_SGI; /* 1 = short guard interval */ - u32 bw; /* channel bandwidth; RATE_MCS_CHAN_WIDTH_XX */ + u8 is_ht40; /* 1 = 40 MHz channel width */ u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ u8 max_search; /* maximun number of tables we can search */ s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ @@ -300,7 +262,7 @@ struct iwl_lq_sta { u64 flush_timer; /* time staying in mode before new search */ u8 action_counter; /* # mode-switch actions tried */ - bool is_vht; + u8 is_green; enum ieee80211_band band; /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ @@ -352,8 +314,9 @@ static inline u8 num_of_ant(u8 mask) } /* Initialize station's rate scaling information after adding station */ -void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, - enum ieee80211_band band); +extern void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, + struct ieee80211_sta *sta, + enum ieee80211_band band); /** * iwl_rate_control_register - Register the rate control algorithm callbacks @@ -365,7 +328,7 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, * ieee80211_register_hw * */ -int iwl_mvm_rate_control_register(void); +extern int iwl_mvm_rate_control_register(void); /** * iwl_rate_control_unregister - Unregister the rate control callbacks @@ -373,7 +336,7 @@ int iwl_mvm_rate_control_register(void); * This should be called after calling ieee80211_unregister_hw, but before * the driver is unloaded. */ -void iwl_mvm_rate_control_unregister(void); +extern void iwl_mvm_rate_control_unregister(void); struct iwl_mvm_sta; diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index 3a1f398..2a8cb5a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c @@ -300,14 +300,10 @@ int iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, return 0; } - /* - * Keep packets with CRC errors (and with overrun) for monitor mode - * (otherwise the firmware discards them) but mark them as bad. - */ if (!(rx_pkt_status & RX_MPDU_RES_STATUS_CRC_OK) || !(rx_pkt_status & RX_MPDU_RES_STATUS_OVERRUN_OK)) { IWL_DEBUG_RX(mvm, "Bad CRC or FIFO: 0x%08X.\n", rx_pkt_status); - rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; + return 0; } /* This will be used in several places later */ @@ -426,27 +422,6 @@ static void iwl_mvm_stat_iterator(void *_data, u8 *mac, mvmvif->bf_data.ave_beacon_signal = sig; - /* BT Coex */ - if (mvmvif->bf_data.bt_coex_min_thold != - mvmvif->bf_data.bt_coex_max_thold) { - last_event = mvmvif->bf_data.last_bt_coex_event; - if (sig > mvmvif->bf_data.bt_coex_max_thold && - (last_event <= mvmvif->bf_data.bt_coex_min_thold || - last_event == 0)) { - mvmvif->bf_data.last_bt_coex_event = sig; - IWL_DEBUG_RX(mvm, "cqm_iterator bt coex high %d\n", - sig); - iwl_mvm_bt_rssi_event(mvm, vif, RSSI_EVENT_HIGH); - } else if (sig < mvmvif->bf_data.bt_coex_min_thold && - (last_event >= mvmvif->bf_data.bt_coex_max_thold || - last_event == 0)) { - mvmvif->bf_data.last_bt_coex_event = sig; - IWL_DEBUG_RX(mvm, "cqm_iterator bt coex low %d\n", - sig); - iwl_mvm_bt_rssi_event(mvm, vif, RSSI_EVENT_LOW); - } - } - if (!(vif->driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)) return; diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index dff7592..621fb71 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c @@ -74,12 +74,8 @@ static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm) { u16 rx_chain; - u8 rx_ant; + u8 rx_ant = iwl_fw_valid_rx_ant(mvm->fw); - if (mvm->scan_rx_ant != ANT_NONE) - rx_ant = mvm->scan_rx_ant; - else - rx_ant = iwl_fw_valid_rx_ant(mvm->fw); rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS; rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS; rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_SEL_POS; @@ -97,10 +93,10 @@ static inline __le32 iwl_mvm_scan_max_out_time(struct ieee80211_vif *vif) static inline __le32 iwl_mvm_scan_suspend_time(struct ieee80211_vif *vif) { - if (!vif->bss_conf.assoc) + if (vif->bss_conf.assoc) + return cpu_to_le32(vif->bss_conf.beacon_int); + else return 0; - - return cpu_to_le32(ieee80211_tu_to_usec(vif->bss_conf.beacon_int)); } static inline __le32 @@ -137,12 +133,11 @@ iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum ieee80211_band band, * request. */ static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd, - struct cfg80211_scan_request *req, - int first) + struct cfg80211_scan_request *req) { int fw_idx, req_idx; - for (req_idx = req->n_ssids - 1, fw_idx = 0; req_idx >= first; + for (req_idx = req->n_ssids - 1, fw_idx = 0; req_idx > 0; req_idx--, fw_idx++) { cmd->direct_scan[fw_idx].id = WLAN_EID_SSID; cmd->direct_scan[fw_idx].len = req->ssids[req_idx].ssid_len; @@ -158,9 +153,9 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_scan_cmd *cmd, * just to notify that this scan is active and not passive. * In order to notify the FW of the number of SSIDs we wish to scan (including * the zero-length one), we need to set the corresponding bits in chan->type, - * one for each SSID, and set the active bit (first). If the first SSID is - * already included in the probe template, so we need to set only - * req->n_ssids - 1 bits in addition to the first bit. + * one for each SSID, and set the active bit (first). The first SSID is already + * included in the probe template, so we need to set only req->n_ssids - 1 bits + * in addition to the first bit. */ static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) { @@ -175,8 +170,7 @@ static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band) } static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd, - struct cfg80211_scan_request *req, - bool basic_ssid) + struct cfg80211_scan_request *req) { u16 passive_dwell = iwl_mvm_get_passive_dwell(req->channels[0]->band); u16 active_dwell = iwl_mvm_get_active_dwell(req->channels[0]->band, @@ -184,14 +178,10 @@ static void iwl_mvm_scan_fill_channels(struct iwl_scan_cmd *cmd, struct iwl_scan_channel *chan = (struct iwl_scan_channel *) (cmd->data + le16_to_cpu(cmd->tx_cmd.len)); int i; - int type = BIT(req->n_ssids) - 1; - - if (!basic_ssid) - type |= BIT(req->n_ssids); for (i = 0; i < cmd->channel_count; i++) { chan->channel = cpu_to_le16(req->channels[i]->hw_value); - chan->type = cpu_to_le32(type); + chan->type = cpu_to_le32(BIT(req->n_ssids) - 1); if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE); chan->active_dwell = cpu_to_le16(active_dwell); @@ -278,8 +268,6 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm, u32 status; int ssid_len = 0; u8 *ssid = NULL; - bool basic_ssid = !(mvm->fw->ucode_capa.flags & - IWL_UCODE_TLV_FLAGS_NO_BASIC_SSID); lockdep_assert_held(&mvm->mutex); BUG_ON(mvm->scan_cmd == NULL); @@ -314,16 +302,14 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm, if (req->n_ssids > 0) { cmd->passive2active = cpu_to_le16(1); cmd->scan_flags |= SCAN_FLAGS_PASSIVE2ACTIVE; - if (basic_ssid) { - ssid = req->ssids[0].ssid; - ssid_len = req->ssids[0].ssid_len; - } + ssid = req->ssids[0].ssid; + ssid_len = req->ssids[0].ssid_len; } else { cmd->passive2active = 0; cmd->scan_flags &= ~SCAN_FLAGS_PASSIVE2ACTIVE; } - iwl_mvm_scan_fill_ssids(cmd, req, basic_ssid ? 1 : 0); + iwl_mvm_scan_fill_ssids(cmd, req); cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL); cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id; @@ -340,7 +326,7 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm, req->ie, req->ie_len, mvm->fw->ucode_capa.max_probe_length)); - iwl_mvm_scan_fill_channels(cmd, req, basic_ssid); + iwl_mvm_scan_fill_channels(cmd, req); cmd->len = cpu_to_le16(sizeof(struct iwl_scan_cmd) + le16_to_cpu(cmd->tx_cmd.len) + @@ -391,21 +377,6 @@ int iwl_mvm_rx_scan_complete(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, return 0; } -int iwl_mvm_rx_sched_scan_results(struct iwl_mvm *mvm, - struct iwl_rx_cmd_buffer *rxb, - struct iwl_device_cmd *cmd) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_sched_scan_results *notif = (void *)pkt->data; - - if (notif->client_bitmap & SCAN_CLIENT_SCHED_SCAN) { - IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n"); - ieee80211_sched_scan_results(mvm->hw); - } - - return 0; -} - static bool iwl_mvm_scan_abort_notif(struct iwl_notif_wait_data *notif_wait, struct iwl_rx_packet *pkt, void *data) { @@ -476,406 +447,3 @@ void iwl_mvm_cancel_scan(struct iwl_mvm *mvm) out_remove_notif: iwl_remove_notification(&mvm->notif_wait, &wait_scan_abort); } - -int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm, - struct iwl_rx_cmd_buffer *rxb, - struct iwl_device_cmd *cmd) -{ - struct iwl_rx_packet *pkt = rxb_addr(rxb); - struct iwl_scan_offload_complete *scan_notif = (void *)pkt->data; - - IWL_DEBUG_SCAN(mvm, "Scheduled scan completed, status %s\n", - scan_notif->status == IWL_SCAN_OFFLOAD_COMPLETED ? - "completed" : "aborted"); - - mvm->scan_status = IWL_MVM_SCAN_NONE; - ieee80211_sched_scan_stopped(mvm->hw); - - return 0; -} - -static void iwl_scan_offload_build_tx_cmd(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct ieee80211_sched_scan_ies *ies, - enum ieee80211_band band, - struct iwl_tx_cmd *cmd, - u8 *data) -{ - u16 cmd_len; - - cmd->tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL); - cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); - cmd->sta_id = mvm->aux_sta.sta_id; - - cmd->rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm, band, false); - - cmd_len = iwl_mvm_fill_probe_req((struct ieee80211_mgmt *)data, - vif->addr, - 1, NULL, 0, - ies->ie[band], ies->len[band], - SCAN_OFFLOAD_PROBE_REQ_SIZE); - cmd->len = cpu_to_le16(cmd_len); -} - -static void iwl_build_scan_cmd(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct cfg80211_sched_scan_request *req, - struct iwl_scan_offload_cmd *scan) -{ - scan->channel_count = - mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels + - mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels; - scan->quiet_time = cpu_to_le16(IWL_ACTIVE_QUIET_TIME); - scan->quiet_plcp_th = cpu_to_le16(IWL_PLCP_QUIET_THRESH); - scan->good_CRC_th = IWL_GOOD_CRC_TH_DEFAULT; - scan->rx_chain = iwl_mvm_scan_rx_chain(mvm); - scan->max_out_time = cpu_to_le32(200 * 1024); - scan->suspend_time = iwl_mvm_scan_suspend_time(vif); - scan->filter_flags |= cpu_to_le32(MAC_FILTER_ACCEPT_GRP | - MAC_FILTER_IN_BEACON); - scan->scan_type = cpu_to_le32(SCAN_TYPE_BACKGROUND); - scan->rep_count = cpu_to_le32(1); -} - -static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list) -{ - int i; - - for (i = 0; i < PROBE_OPTION_MAX; i++) { - if (!ssid_list[i].len) - break; - if (ssid_list[i].len == ssid_len && - !memcmp(ssid_list->ssid, ssid, ssid_len)) - return i; - } - return -1; -} - -static void iwl_scan_offload_build_ssid(struct cfg80211_sched_scan_request *req, - struct iwl_scan_offload_cmd *scan, - u32 *ssid_bitmap) -{ - int i, j; - int index; - - /* - * copy SSIDs from match list. - * iwl_config_sched_scan_profiles() uses the order of these ssids to - * config match list. - */ - for (i = 0; i < req->n_match_sets && i < PROBE_OPTION_MAX; i++) { - scan->direct_scan[i].id = WLAN_EID_SSID; - scan->direct_scan[i].len = req->match_sets[i].ssid.ssid_len; - memcpy(scan->direct_scan[i].ssid, req->match_sets[i].ssid.ssid, - scan->direct_scan[i].len); - } - - /* add SSIDs from scan SSID list */ - *ssid_bitmap = 0; - for (j = 0; j < req->n_ssids && i < PROBE_OPTION_MAX; j++) { - index = iwl_ssid_exist(req->ssids[j].ssid, - req->ssids[j].ssid_len, - scan->direct_scan); - if (index < 0) { - if (!req->ssids[j].ssid_len) - continue; - scan->direct_scan[i].id = WLAN_EID_SSID; - scan->direct_scan[i].len = req->ssids[j].ssid_len; - memcpy(scan->direct_scan[i].ssid, req->ssids[j].ssid, - scan->direct_scan[i].len); - *ssid_bitmap |= BIT(i + 1); - i++; - } else { - *ssid_bitmap |= BIT(index + 1); - } - } -} - -static void iwl_build_channel_cfg(struct iwl_mvm *mvm, - struct cfg80211_sched_scan_request *req, - struct iwl_scan_channel_cfg *channels, - enum ieee80211_band band, - int *head, int *tail, - u32 ssid_bitmap) -{ - struct ieee80211_supported_band *s_band; - int n_probes = req->n_ssids; - int n_channels = req->n_channels; - u8 active_dwell, passive_dwell; - int i, j, index = 0; - bool partial; - - /* - * We have to configure all supported channels, even if we don't want to - * scan on them, but we have to send channels in the order that we want - * to scan. So add requested channels to head of the list and others to - * the end. - */ - active_dwell = iwl_mvm_get_active_dwell(band, n_probes); - passive_dwell = iwl_mvm_get_passive_dwell(band); - s_band = &mvm->nvm_data->bands[band]; - - for (i = 0; i < s_band->n_channels && *head <= *tail; i++) { - partial = false; - for (j = 0; j < n_channels; j++) - if (s_band->channels[i].center_freq == - req->channels[j]->center_freq) { - index = *head; - (*head)++; - /* - * Channels that came with the request will be - * in partial scan . - */ - partial = true; - break; - } - if (!partial) { - index = *tail; - (*tail)--; - } - channels->channel_number[index] = - cpu_to_le16(ieee80211_frequency_to_channel( - s_band->channels[i].center_freq)); - channels->dwell_time[index][0] = active_dwell; - channels->dwell_time[index][1] = passive_dwell; - - channels->iter_count[index] = cpu_to_le16(1); - channels->iter_interval[index] = 0; - - if (!(s_band->channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) - channels->type[index] |= - cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE); - - channels->type[index] |= - cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_FULL); - if (partial) - channels->type[index] |= - cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_PARTIAL); - - if (s_band->channels[i].flags & IEEE80211_CHAN_NO_HT40) - channels->type[index] |= - cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_NARROW); - - /* scan for all SSIDs from req->ssids */ - channels->type[index] |= cpu_to_le32(ssid_bitmap); - } -} - -int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm, - struct ieee80211_vif *vif, - struct cfg80211_sched_scan_request *req, - struct ieee80211_sched_scan_ies *ies) -{ - int supported_bands = 0; - int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels; - int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels; - int head = 0; - int tail = band_2ghz + band_5ghz; - u32 ssid_bitmap; - int cmd_len; - int ret; - - struct iwl_scan_offload_cfg *scan_cfg; - struct iwl_host_cmd cmd = { - .id = SCAN_OFFLOAD_CONFIG_CMD, - .flags = CMD_SYNC, - }; - - lockdep_assert_held(&mvm->mutex); - - if (band_2ghz) - supported_bands++; - if (band_5ghz) - supported_bands++; - - cmd_len = sizeof(struct iwl_scan_offload_cfg) + - supported_bands * SCAN_OFFLOAD_PROBE_REQ_SIZE; - - scan_cfg = kzalloc(cmd_len, GFP_KERNEL); - if (!scan_cfg) - return -ENOMEM; - - iwl_build_scan_cmd(mvm, vif, req, &scan_cfg->scan_cmd); - scan_cfg->scan_cmd.len = cpu_to_le16(cmd_len); - - iwl_scan_offload_build_ssid(req, &scan_cfg->scan_cmd, &ssid_bitmap); - /* build tx frames for supported bands */ - if (band_2ghz) { - iwl_scan_offload_build_tx_cmd(mvm, vif, ies, - IEEE80211_BAND_2GHZ, - &scan_cfg->scan_cmd.tx_cmd[0], - scan_cfg->data); - iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg, - IEEE80211_BAND_2GHZ, &head, &tail, - ssid_bitmap); - } - if (band_5ghz) { - iwl_scan_offload_build_tx_cmd(mvm, vif, ies, - IEEE80211_BAND_5GHZ, - &scan_cfg->scan_cmd.tx_cmd[1], - scan_cfg->data + - SCAN_OFFLOAD_PROBE_REQ_SIZE); - iwl_build_channel_cfg(mvm, req, &scan_cfg->channel_cfg, - IEEE80211_BAND_5GHZ, &head, &tail, - ssid_bitmap); - } - - cmd.data[0] = scan_cfg; - cmd.len[0] = cmd_len; - cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY; - - IWL_DEBUG_SCAN(mvm, "Sending scheduled scan config\n"); - - ret = iwl_mvm_send_cmd(mvm, &cmd); - kfree(scan_cfg); - return ret; -} - -int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, - struct cfg80211_sched_scan_request *req) -{ - struct iwl_scan_offload_profile *profile; - struct iwl_scan_offload_profile_cfg *profile_cfg; - struct iwl_scan_offload_blacklist *blacklist; - struct iwl_host_cmd cmd = { - .id = SCAN_OFFLOAD_UPDATE_PROFILES_CMD, - .flags = CMD_SYNC, - .len[1] = sizeof(*profile_cfg), - .dataflags[0] = IWL_HCMD_DFL_NOCOPY, - .dataflags[1] = IWL_HCMD_DFL_NOCOPY, - }; - int blacklist_len; - int i; - int ret; - - if (WARN_ON(req->n_match_sets > IWL_SCAN_MAX_PROFILES)) - return -EIO; - - if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SHORT_BL) - blacklist_len = IWL_SCAN_SHORT_BLACKLIST_LEN; - else - blacklist_len = IWL_SCAN_MAX_BLACKLIST_LEN; - - blacklist = kzalloc(sizeof(*blacklist) * blacklist_len, GFP_KERNEL); - if (!blacklist) - return -ENOMEM; - - profile_cfg = kzalloc(sizeof(*profile_cfg), GFP_KERNEL); - if (!profile_cfg) { - ret = -ENOMEM; - goto free_blacklist; - } - - cmd.data[0] = blacklist; - cmd.len[0] = sizeof(*blacklist) * blacklist_len; - cmd.data[1] = profile_cfg; - - /* No blacklist configuration */ - - profile_cfg->num_profiles = req->n_match_sets; - profile_cfg->active_clients = SCAN_CLIENT_SCHED_SCAN; - profile_cfg->pass_match = SCAN_CLIENT_SCHED_SCAN; - profile_cfg->match_notify = SCAN_CLIENT_SCHED_SCAN; - - for (i = 0; i < req->n_match_sets; i++) { - profile = &profile_cfg->profiles[i]; - profile->ssid_index = i; - /* Support any cipher and auth algorithm */ - profile->unicast_cipher = 0xff; - profile->auth_alg = 0xff; - profile->network_type = IWL_NETWORK_TYPE_ANY; - profile->band_selection = IWL_SCAN_OFFLOAD_SELECT_ANY; - profile->client_bitmap = SCAN_CLIENT_SCHED_SCAN; - } - - IWL_DEBUG_SCAN(mvm, "Sending scheduled scan profile config\n"); - - ret = iwl_mvm_send_cmd(mvm, &cmd); - kfree(profile_cfg); -free_blacklist: - kfree(blacklist); - - return ret; -} - -int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm, - struct cfg80211_sched_scan_request *req) -{ - struct iwl_scan_offload_req scan_req = { - .watchdog = IWL_SCHED_SCAN_WATCHDOG, - - .schedule_line[0].iterations = IWL_FAST_SCHED_SCAN_ITERATIONS, - .schedule_line[0].delay = req->interval / 1000, - .schedule_line[0].full_scan_mul = 1, - - .schedule_line[1].iterations = 0xff, - .schedule_line[1].delay = req->interval / 1000, - .schedule_line[1].full_scan_mul = IWL_FULL_SCAN_MULTIPLIER, - }; - - if (req->n_match_sets && req->match_sets[0].ssid.ssid_len) { - IWL_DEBUG_SCAN(mvm, - "Sending scheduled scan with filtering, filter len %d\n", - req->n_match_sets); - scan_req.flags |= - cpu_to_le16(IWL_SCAN_OFFLOAD_FLAG_FILTER_SSID); - } else { - IWL_DEBUG_SCAN(mvm, - "Sending Scheduled scan without filtering\n"); - } - - return iwl_mvm_send_cmd_pdu(mvm, SCAN_OFFLOAD_REQUEST_CMD, CMD_SYNC, - sizeof(scan_req), &scan_req); -} - -static int iwl_mvm_send_sched_scan_abort(struct iwl_mvm *mvm) -{ - int ret; - struct iwl_host_cmd cmd = { - .id = SCAN_OFFLOAD_ABORT_CMD, - .flags = CMD_SYNC, - }; - u32 status; - - /* Exit instantly with error when device is not ready - * to receive scan abort command or it does not perform - * scheduled scan currently */ - if (mvm->scan_status != IWL_MVM_SCAN_SCHED) - return -EIO; - - ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status); - if (ret) - return ret; - - if (status != CAN_ABORT_STATUS) { - /* - * The scan abort will return 1 for success or - * 2 for "failure". A failure condition can be - * due to simply not being in an active scan which - * can occur if we send the scan abort before the - * microcode has notified us that a scan is completed. - */ - IWL_DEBUG_SCAN(mvm, "SCAN OFFLOAD ABORT ret %d.\n", status); - ret = -EIO; - } - - return ret; -} - -void iwl_mvm_sched_scan_stop(struct iwl_mvm *mvm) -{ - int ret; - - lockdep_assert_held(&mvm->mutex); - - if (mvm->scan_status != IWL_MVM_SCAN_SCHED) { - IWL_DEBUG_SCAN(mvm, "No offloaded scan to stop\n"); - return; - } - - ret = iwl_mvm_send_sched_scan_abort(mvm); - if (ret) - IWL_DEBUG_SCAN(mvm, "Send stop offload scan failed %d\n", ret); - else - IWL_DEBUG_SCAN(mvm, "Successfully sent stop offload scan\n"); -} diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 3299523..44add29 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -66,115 +66,6 @@ #include "sta.h" #include "rs.h" -static void iwl_mvm_add_sta_cmd_v6_to_v5(struct iwl_mvm_add_sta_cmd_v6 *cmd_v6, - struct iwl_mvm_add_sta_cmd_v5 *cmd_v5) -{ - memset(cmd_v5, 0, sizeof(*cmd_v5)); - - cmd_v5->add_modify = cmd_v6->add_modify; - cmd_v5->tid_disable_tx = cmd_v6->tid_disable_tx; - cmd_v5->mac_id_n_color = cmd_v6->mac_id_n_color; - memcpy(cmd_v5->addr, cmd_v6->addr, ETH_ALEN); - cmd_v5->sta_id = cmd_v6->sta_id; - cmd_v5->modify_mask = cmd_v6->modify_mask; - cmd_v5->station_flags = cmd_v6->station_flags; - cmd_v5->station_flags_msk = cmd_v6->station_flags_msk; - cmd_v5->add_immediate_ba_tid = cmd_v6->add_immediate_ba_tid; - cmd_v5->remove_immediate_ba_tid = cmd_v6->remove_immediate_ba_tid; - cmd_v5->add_immediate_ba_ssn = cmd_v6->add_immediate_ba_ssn; - cmd_v5->sleep_tx_count = cmd_v6->sleep_tx_count; - cmd_v5->sleep_state_flags = cmd_v6->sleep_state_flags; - cmd_v5->assoc_id = cmd_v6->assoc_id; - cmd_v5->beamform_flags = cmd_v6->beamform_flags; - cmd_v5->tfd_queue_msk = cmd_v6->tfd_queue_msk; -} - -static void -iwl_mvm_add_sta_key_to_add_sta_cmd_v5(struct iwl_mvm_add_sta_key_cmd *key_cmd, - struct iwl_mvm_add_sta_cmd_v5 *sta_cmd, - u32 mac_id_n_color) -{ - memset(sta_cmd, 0, sizeof(*sta_cmd)); - - sta_cmd->sta_id = key_cmd->sta_id; - sta_cmd->add_modify = STA_MODE_MODIFY; - sta_cmd->modify_mask = STA_MODIFY_KEY; - sta_cmd->mac_id_n_color = cpu_to_le32(mac_id_n_color); - - sta_cmd->key.key_offset = key_cmd->key_offset; - sta_cmd->key.key_flags = key_cmd->key_flags; - memcpy(sta_cmd->key.key, key_cmd->key, sizeof(sta_cmd->key.key)); - sta_cmd->key.tkip_rx_tsc_byte2 = key_cmd->tkip_rx_tsc_byte2; - memcpy(sta_cmd->key.tkip_rx_ttak, key_cmd->tkip_rx_ttak, - sizeof(sta_cmd->key.tkip_rx_ttak)); -} - -static int iwl_mvm_send_add_sta_cmd_status(struct iwl_mvm *mvm, - struct iwl_mvm_add_sta_cmd_v6 *cmd, - int *status) -{ - struct iwl_mvm_add_sta_cmd_v5 cmd_v5; - - if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD) - return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(*cmd), - cmd, status); - - iwl_mvm_add_sta_cmd_v6_to_v5(cmd, &cmd_v5); - - return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd_v5), - &cmd_v5, status); -} - -static int iwl_mvm_send_add_sta_cmd(struct iwl_mvm *mvm, u32 flags, - struct iwl_mvm_add_sta_cmd_v6 *cmd) -{ - struct iwl_mvm_add_sta_cmd_v5 cmd_v5; - - if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD) - return iwl_mvm_send_cmd_pdu(mvm, ADD_STA, flags, - sizeof(*cmd), cmd); - - iwl_mvm_add_sta_cmd_v6_to_v5(cmd, &cmd_v5); - - return iwl_mvm_send_cmd_pdu(mvm, ADD_STA, flags, sizeof(cmd_v5), - &cmd_v5); -} - -static int -iwl_mvm_send_add_sta_key_cmd_status(struct iwl_mvm *mvm, - struct iwl_mvm_add_sta_key_cmd *cmd, - u32 mac_id_n_color, - int *status) -{ - struct iwl_mvm_add_sta_cmd_v5 sta_cmd; - - if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD) - return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA_KEY, - sizeof(*cmd), cmd, status); - - iwl_mvm_add_sta_key_to_add_sta_cmd_v5(cmd, &sta_cmd, mac_id_n_color); - - return iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(sta_cmd), - &sta_cmd, status); -} - -static int iwl_mvm_send_add_sta_key_cmd(struct iwl_mvm *mvm, - u32 flags, - struct iwl_mvm_add_sta_key_cmd *cmd, - u32 mac_id_n_color) -{ - struct iwl_mvm_add_sta_cmd_v5 sta_cmd; - - if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_STA_KEY_CMD) - return iwl_mvm_send_cmd_pdu(mvm, ADD_STA_KEY, flags, - sizeof(*cmd), cmd); - - iwl_mvm_add_sta_key_to_add_sta_cmd_v5(cmd, &sta_cmd, mac_id_n_color); - - return iwl_mvm_send_cmd_pdu(mvm, ADD_STA, flags, sizeof(sta_cmd), - &sta_cmd); -} - static int iwl_mvm_find_free_sta_id(struct iwl_mvm *mvm) { int sta_id; @@ -196,7 +87,7 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, bool update) { struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; - struct iwl_mvm_add_sta_cmd_v6 add_sta_cmd; + struct iwl_mvm_add_sta_cmd add_sta_cmd; int ret; u32 status; u32 agg_size = 0, mpdu_dens = 0; @@ -284,7 +175,8 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct ieee80211_sta *sta, cpu_to_le32(mpdu_dens << STA_FLG_AGG_MPDU_DENS_SHIFT); status = ADD_STA_SUCCESS; - ret = iwl_mvm_send_add_sta_cmd_status(mvm, &add_sta_cmd, &status); + ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(add_sta_cmd), + &add_sta_cmd, &status); if (ret) return ret; @@ -337,12 +229,8 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm, if (vif->hw_queue[i] != IEEE80211_INVAL_HW_QUEUE) mvm_sta->tfd_queue_msk |= BIT(vif->hw_queue[i]); - /* for HW restart - reset everything but the sequence number */ - for (i = 0; i < IWL_MAX_TID_COUNT; i++) { - u16 seq = mvm_sta->tid_data[i].seq_number; - memset(&mvm_sta->tid_data[i], 0, sizeof(mvm_sta->tid_data[i])); - mvm_sta->tid_data[i].seq_number = seq; - } + /* for HW restart - need to reset the seq_number etc... */ + memset(mvm_sta->tid_data, 0, sizeof(mvm_sta->tid_data)); ret = iwl_mvm_sta_send_to_fw(mvm, sta, false); if (ret) @@ -368,7 +256,7 @@ int iwl_mvm_update_sta(struct iwl_mvm *mvm, int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, bool drain) { - struct iwl_mvm_add_sta_cmd_v6 cmd = {}; + struct iwl_mvm_add_sta_cmd cmd = {}; int ret; u32 status; @@ -381,7 +269,8 @@ int iwl_mvm_drain_sta(struct iwl_mvm *mvm, struct iwl_mvm_sta *mvmsta, cmd.station_flags_msk = cpu_to_le32(STA_FLG_DRAIN_FLOW); status = ADD_STA_SUCCESS; - ret = iwl_mvm_send_add_sta_cmd_status(mvm, &cmd, &status); + ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), + &cmd, &status); if (ret) return ret; @@ -580,13 +469,13 @@ static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm, const u8 *addr, u16 mac_id, u16 color) { - struct iwl_mvm_add_sta_cmd_v6 cmd; + struct iwl_mvm_add_sta_cmd cmd; int ret; u32 status; lockdep_assert_held(&mvm->mutex); - memset(&cmd, 0, sizeof(struct iwl_mvm_add_sta_cmd_v6)); + memset(&cmd, 0, sizeof(struct iwl_mvm_add_sta_cmd)); cmd.sta_id = sta->sta_id; cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id, color)); @@ -596,7 +485,8 @@ static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm, if (addr) memcpy(cmd.addr, addr, ETH_ALEN); - ret = iwl_mvm_send_add_sta_cmd_status(mvm, &cmd, &status); + ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), + &cmd, &status); if (ret) return ret; @@ -644,14 +534,10 @@ int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct iwl_mvm_int_sta *bsta) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; - static const u8 *baddr = _baddr; + static const u8 baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; lockdep_assert_held(&mvm->mutex); - if (vif->type == NL80211_IFTYPE_ADHOC) - baddr = vif->bss_conf.bssid; - if (WARN_ON_ONCE(bsta->sta_id == IWL_MVM_STATION_COUNT)) return -ENOSPC; @@ -728,7 +614,7 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, int tid, u16 ssn, bool start) { struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; - struct iwl_mvm_add_sta_cmd_v6 cmd = {}; + struct iwl_mvm_add_sta_cmd cmd = {}; int ret; u32 status; @@ -752,7 +638,8 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, STA_MODIFY_REMOVE_BA_TID; status = ADD_STA_SUCCESS; - ret = iwl_mvm_send_add_sta_cmd_status(mvm, &cmd, &status); + ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), + &cmd, &status); if (ret) return ret; @@ -787,7 +674,7 @@ static int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, int tid, u8 queue, bool start) { struct iwl_mvm_sta *mvm_sta = (void *)sta->drv_priv; - struct iwl_mvm_add_sta_cmd_v6 cmd = {}; + struct iwl_mvm_add_sta_cmd cmd = {}; int ret; u32 status; @@ -809,7 +696,8 @@ static int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta, cmd.tid_disable_tx = cpu_to_le16(mvm_sta->tid_disable_agg); status = ADD_STA_SUCCESS; - ret = iwl_mvm_send_add_sta_cmd_status(mvm, &cmd, &status); + ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), + &cmd, &status); if (ret) return ret; @@ -855,13 +743,13 @@ int iwl_mvm_sta_tx_agg_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif, lockdep_assert_held(&mvm->mutex); - for (txq_id = mvm->first_agg_queue; - txq_id <= mvm->last_agg_queue; txq_id++) + for (txq_id = IWL_MVM_FIRST_AGG_QUEUE; + txq_id <= IWL_MVM_LAST_AGG_QUEUE; txq_id++) if (mvm->queue_to_mac80211[txq_id] == IWL_INVALID_MAC80211_QUEUE) break; - if (txq_id > mvm->last_agg_queue) { + if (txq_id > IWL_MVM_LAST_AGG_QUEUE) { IWL_ERR(mvm, "Failed to allocate agg queue\n"); return -EIO; } @@ -1099,11 +987,10 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, u32 cmd_flags) { __le16 key_flags; - struct iwl_mvm_add_sta_key_cmd cmd = {}; + struct iwl_mvm_add_sta_cmd cmd = {}; int ret, status; u16 keyidx; int i; - u32 mac_id_n_color = mvm_sta->mac_id_n_color; keyidx = (keyconf->keyidx << STA_KEY_FLG_KEYID_POS) & STA_KEY_FLG_KEYID_MSK; @@ -1113,14 +1000,14 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, switch (keyconf->cipher) { case WLAN_CIPHER_SUITE_TKIP: key_flags |= cpu_to_le16(STA_KEY_FLG_TKIP); - cmd.tkip_rx_tsc_byte2 = tkip_iv32; + cmd.key.tkip_rx_tsc_byte2 = tkip_iv32; for (i = 0; i < 5; i++) - cmd.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]); - memcpy(cmd.key, keyconf->key, keyconf->keylen); + cmd.key.tkip_rx_ttak[i] = cpu_to_le16(tkip_p1k[i]); + memcpy(cmd.key.key, keyconf->key, keyconf->keylen); break; case WLAN_CIPHER_SUITE_CCMP: key_flags |= cpu_to_le16(STA_KEY_FLG_CCM); - memcpy(cmd.key, keyconf->key, keyconf->keylen); + memcpy(cmd.key.key, keyconf->key, keyconf->keylen); break; default: WARN_ON(1); @@ -1130,18 +1017,20 @@ static int iwl_mvm_send_sta_key(struct iwl_mvm *mvm, if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) key_flags |= cpu_to_le16(STA_KEY_MULTICAST); - cmd.key_offset = keyconf->hw_key_idx; - cmd.key_flags = key_flags; + cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color); + cmd.key.key_offset = keyconf->hw_key_idx; + cmd.key.key_flags = key_flags; + cmd.add_modify = STA_MODE_MODIFY; + cmd.modify_mask = STA_MODIFY_KEY; cmd.sta_id = sta_id; status = ADD_STA_SUCCESS; if (cmd_flags == CMD_SYNC) - ret = iwl_mvm_send_add_sta_key_cmd_status(mvm, &cmd, - mac_id_n_color, - &status); + ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), + &cmd, &status); else - ret = iwl_mvm_send_add_sta_key_cmd(mvm, CMD_ASYNC, &cmd, - mac_id_n_color); + ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, + sizeof(cmd), &cmd); switch (status) { case ADD_STA_SUCCESS: @@ -1308,7 +1197,7 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, struct ieee80211_key_conf *keyconf) { struct iwl_mvm_sta *mvm_sta; - struct iwl_mvm_add_sta_key_cmd cmd = {}; + struct iwl_mvm_add_sta_cmd cmd = {}; __le16 key_flags; int ret, status; u8 sta_id; @@ -1363,14 +1252,17 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm, if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) key_flags |= cpu_to_le16(STA_KEY_MULTICAST); - cmd.key_flags = key_flags; - cmd.key_offset = keyconf->hw_key_idx; + cmd.mac_id_n_color = cpu_to_le32(mvm_sta->mac_id_n_color); + cmd.key.key_flags = key_flags; + cmd.key.key_offset = keyconf->hw_key_idx; cmd.sta_id = sta_id; + cmd.modify_mask = STA_MODIFY_KEY; + cmd.add_modify = STA_MODE_MODIFY; + status = ADD_STA_SUCCESS; - ret = iwl_mvm_send_add_sta_key_cmd_status(mvm, &cmd, - mvm_sta->mac_id_n_color, - &status); + ret = iwl_mvm_send_cmd_pdu_status(mvm, ADD_STA, sizeof(cmd), + &cmd, &status); switch (status) { case ADD_STA_SUCCESS: @@ -1417,7 +1309,7 @@ void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, struct ieee80211_sta *sta) { struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; - struct iwl_mvm_add_sta_cmd_v6 cmd = { + struct iwl_mvm_add_sta_cmd cmd = { .add_modify = STA_MODE_MODIFY, .sta_id = mvmsta->sta_id, .station_flags_msk = cpu_to_le32(STA_FLG_PS), @@ -1425,7 +1317,7 @@ void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, }; int ret; - ret = iwl_mvm_send_add_sta_cmd(mvm, CMD_ASYNC, &cmd); + ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd); if (ret) IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret); } @@ -1439,7 +1331,7 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm, (reason == IEEE80211_FRAME_RELEASE_UAPSD) ? STA_SLEEP_STATE_UAPSD : STA_SLEEP_STATE_PS_POLL; struct iwl_mvm_sta *mvmsta = (void *)sta->drv_priv; - struct iwl_mvm_add_sta_cmd_v6 cmd = { + struct iwl_mvm_add_sta_cmd cmd = { .add_modify = STA_MODE_MODIFY, .sta_id = mvmsta->sta_id, .modify_mask = STA_MODIFY_SLEEPING_STA_TX_COUNT, @@ -1454,7 +1346,7 @@ void iwl_mvm_sta_modify_sleep_tx_count(struct iwl_mvm *mvm, int ret; /* TODO: somehow the fw doesn't seem to take PS_POLL into account */ - ret = iwl_mvm_send_add_sta_cmd(mvm, CMD_ASYNC, &cmd); + ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd); if (ret) IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret); } diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index 4dfc359..94b265e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h @@ -293,6 +293,10 @@ struct iwl_mvm_sta { struct iwl_lq_sta lq_sta; struct ieee80211_vif *vif; +#ifdef CONFIG_PM_SLEEP + u16 last_seq_ctl; +#endif + /* Temporary, until the new TLC will control the Tx protection */ s8 tx_protection; bool tt_tx_protection; diff --git a/drivers/net/wireless/iwlwifi/mvm/testmode.h b/drivers/net/wireless/iwlwifi/mvm/testmode.h deleted file mode 100644 index eb74391..0000000 --- a/drivers/net/wireless/iwlwifi/mvm/testmode.h +++ /dev/null @@ -1,95 +0,0 @@ -/****************************************************************************** - * - * 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) 2013 Intel Corporation. All rights reserved. - * - * 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; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called COPYING. - * - * Contact Information: - * Intel Linux Wireless <ilw@linux.intel.com> - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - * - * BSD LICENSE - * - * Copyright(c) 2013 Intel Corporation. All rights reserved. - * 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_MVM_TESTMODE_H__ -#define __IWL_MVM_TESTMODE_H__ - -/** - * enum iwl_mvm_testmode_attrs - testmode attributes inside NL80211_ATTR_TESTDATA - * @IWL_MVM_TM_ATTR_UNSPEC: (invalid attribute) - * @IWL_MVM_TM_ATTR_CMD: sub command, see &enum iwl_mvm_testmode_commands (u32) - * @IWL_MVM_TM_ATTR_NOA_DURATION: requested NoA duration (u32) - * @IWL_MVM_TM_ATTR_BEACON_FILTER_STATE: beacon filter state (0 or 1, u32) - */ -enum iwl_mvm_testmode_attrs { - IWL_MVM_TM_ATTR_UNSPEC, - IWL_MVM_TM_ATTR_CMD, - IWL_MVM_TM_ATTR_NOA_DURATION, - IWL_MVM_TM_ATTR_BEACON_FILTER_STATE, - - /* keep last */ - NUM_IWL_MVM_TM_ATTRS, - IWL_MVM_TM_ATTR_MAX = NUM_IWL_MVM_TM_ATTRS - 1, -}; - -/** - * enum iwl_mvm_testmode_commands - MVM testmode commands - * @IWL_MVM_TM_CMD_SET_NOA: set NoA on GO vif for testing - * @IWL_MVM_TM_CMD_SET_BEACON_FILTER: turn beacon filtering off/on - */ -enum iwl_mvm_testmode_commands { - IWL_MVM_TM_CMD_SET_NOA, - IWL_MVM_TM_CMD_SET_BEACON_FILTER, -}; - -#endif /* __IWL_MVM_TESTMODE_H__ */ diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index 33cf56f..76a3c17 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c @@ -387,8 +387,7 @@ static int iwl_mvm_time_event_send_add(struct iwl_mvm *mvm, void iwl_mvm_protect_session(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - u32 duration, u32 min_duration, - u32 max_delay) + u32 duration, u32 min_duration) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; @@ -427,7 +426,7 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm, cpu_to_le32(iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG)); time_cmd.max_frags = TE_V2_FRAG_NONE; - time_cmd.max_delay = cpu_to_le32(max_delay); + time_cmd.max_delay = cpu_to_le32(500); /* TODO: why do we need to interval = bi if it is not periodic? */ time_cmd.interval = cpu_to_le32(1); time_cmd.duration = cpu_to_le32(duration); diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h index d9c8d6c..f86c510 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.h +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h @@ -123,7 +123,6 @@ * @duration: the duration of the session in TU. * @min_duration: will start a new session if the current session will end * in less than min_duration. - * @max_delay: maximum delay before starting the time event (in TU) * * This function can be used to start a session protection which means that the * fw will stay on the channel for %duration_ms milliseconds. This function @@ -134,8 +133,7 @@ */ void iwl_mvm_protect_session(struct iwl_mvm *mvm, struct ieee80211_vif *vif, - u32 duration, u32 min_duration, - u32 max_delay); + u32 duration, u32 min_duration); /** * iwl_mvm_stop_session_protection - cancel the session protection. diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 43d97c3..e05440d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -417,7 +417,7 @@ int iwl_mvm_tx_skb(struct iwl_mvm *mvm, struct sk_buff *skb, spin_unlock(&mvmsta->lock); - if (txq_id < mvm->first_agg_queue) + if (txq_id < IWL_MVM_FIRST_AGG_QUEUE) atomic_inc(&mvm->pending_frames[mvmsta->sta_id]); return 0; @@ -511,10 +511,16 @@ const char *iwl_mvm_get_tx_fail_reason(u32 status) } #endif /* CONFIG_IWLWIFI_DEBUG */ -void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags, - enum ieee80211_band band, - struct ieee80211_tx_rate *r) +/** + * translate ucode response to mac80211 tx status control values + */ +static void iwl_mvm_hwrate_to_tx_control(u32 rate_n_flags, + struct ieee80211_tx_info *info) { + struct ieee80211_tx_rate *r = &info->status.rates[0]; + + info->status.antenna = + ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS); if (rate_n_flags & RATE_HT_MCS_GF_MSK) r->flags |= IEEE80211_TX_RC_GREEN_FIELD; switch (rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK) { @@ -543,23 +549,10 @@ void iwl_mvm_hwrate_to_tx_rate(u32 rate_n_flags, r->flags |= IEEE80211_TX_RC_VHT_MCS; } else { r->idx = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags, - band); + info->band); } } -/** - * translate ucode response to mac80211 tx status control values - */ -static void iwl_mvm_hwrate_to_tx_status(u32 rate_n_flags, - struct ieee80211_tx_info *info) -{ - struct ieee80211_tx_rate *r = &info->status.rates[0]; - - info->status.antenna = - ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS); - iwl_mvm_hwrate_to_tx_rate(rate_n_flags, info->band, r); -} - static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, struct iwl_rx_packet *pkt) { @@ -609,11 +602,11 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, } info->status.rates[0].count = tx_resp->failure_frame + 1; - iwl_mvm_hwrate_to_tx_status(le32_to_cpu(tx_resp->initial_rate), - info); + iwl_mvm_hwrate_to_tx_control(le32_to_cpu(tx_resp->initial_rate), + info); /* Single frame failure in an AMPDU queue => send BAR */ - if (txq_id >= mvm->first_agg_queue && + if (txq_id >= IWL_MVM_FIRST_AGG_QUEUE && !(info->flags & IEEE80211_TX_STAT_ACK)) info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; @@ -626,7 +619,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, ieee80211_tx_status_ni(mvm->hw, skb); } - if (txq_id >= mvm->first_agg_queue) { + if (txq_id >= IWL_MVM_FIRST_AGG_QUEUE) { /* If this is an aggregation queue, we use the ssn since: * ssn = wifi seq_num % 256. * The seq_ctl is the sequence control of the packet to which @@ -675,6 +668,10 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, iwl_mvm_check_ratid_empty(mvm, sta, tid); spin_unlock_bh(&mvmsta->lock); } + +#ifdef CONFIG_PM_SLEEP + mvmsta->last_seq_ctl = seq_ctl; +#endif } else { sta = NULL; mvmsta = NULL; @@ -684,7 +681,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, * If the txq is not an AMPDU queue, there is no chance we freed * several skbs. Check that out... */ - if (txq_id < mvm->first_agg_queue && !WARN_ON(skb_freed > 1) && + if (txq_id < IWL_MVM_FIRST_AGG_QUEUE && !WARN_ON(skb_freed > 1) && atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) { if (mvmsta) { /* @@ -780,7 +777,7 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm, u16 sequence = le16_to_cpu(pkt->hdr.sequence); struct ieee80211_sta *sta; - if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < mvm->first_agg_queue)) + if (WARN_ON_ONCE(SEQ_TO_QUEUE(sequence) < IWL_MVM_FIRST_AGG_QUEUE)) return; if (WARN_ON_ONCE(tid == IWL_TID_NON_QOS)) @@ -907,8 +904,8 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb, info->flags |= IEEE80211_TX_STAT_AMPDU; info->status.ampdu_ack_len = ba_notif->txed_2_done; info->status.ampdu_len = ba_notif->txed; - iwl_mvm_hwrate_to_tx_status(tid_data->rate_n_flags, - info); + iwl_mvm_hwrate_to_tx_control(tid_data->rate_n_flags, + info); } } diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c index ed69e9b..a9c3574 100644 --- a/drivers/net/wireless/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/iwlwifi/mvm/utils.c @@ -466,7 +466,7 @@ void iwl_mvm_dump_sram(struct iwl_mvm *mvm) ofs = img->sec[IWL_UCODE_SECTION_DATA].offset; len = img->sec[IWL_UCODE_SECTION_DATA].len; - buf = kzalloc(len, GFP_ATOMIC); + buf = kzalloc(len, GFP_KERNEL); if (!buf) return; diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 941c0c8..26108a1 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c @@ -268,7 +268,7 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { #endif /* CONFIG_IWLDVM */ #if IS_ENABLED(CONFIG_IWLMVM) -/* 7260 Series */ +/* 7000 Series */ {IWL_PCI_DEVICE(0x08B1, 0x4070, iwl7260_2ac_cfg)}, {IWL_PCI_DEVICE(0x08B1, 0x4072, iwl7260_2ac_cfg)}, {IWL_PCI_DEVICE(0x08B1, 0x4170, iwl7260_2ac_cfg)}, @@ -350,9 +350,6 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { {IWL_PCI_DEVICE(0x08B4, 0x8270, iwl3160_2ac_cfg)}, {IWL_PCI_DEVICE(0x08B3, 0x8470, iwl3160_2ac_cfg)}, {IWL_PCI_DEVICE(0x08B3, 0x8570, iwl3160_2ac_cfg)}, - -/* 7265 Series */ - {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)}, #endif /* CONFIG_IWLMVM */ {0} @@ -394,6 +391,7 @@ out_free_drv: iwl_drv_stop(trans_pcie->drv); out_free_trans: iwl_trans_pcie_free(iwl_trans); + pci_set_drvdata(pdev, NULL); return ret; } @@ -404,6 +402,8 @@ static void iwl_pci_remove(struct pci_dev *pdev) iwl_drv_stop(trans_pcie->drv); iwl_trans_pcie_free(trans); + + pci_set_drvdata(pdev, NULL); } #ifdef CONFIG_PM_SLEEP diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 5d9337b..c3f904d 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -220,9 +220,6 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans) iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_L1_ACT_DIS); - /* Clear the interrupt in APMG if the NIC is in RFKILL */ - iwl_write_prph(trans, APMG_RTC_INT_STT_REG, APMG_RTC_INT_STT_RFKILL); - set_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); out: @@ -446,138 +443,22 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num, return ret; } -static int iwl_pcie_secure_set(struct iwl_trans *trans, int cpu) -{ - int shift_param; - u32 address; - int ret = 0; - - if (cpu == 1) { - shift_param = 0; - address = CSR_SECURE_BOOT_CPU1_STATUS_ADDR; - } else { - shift_param = 16; - address = CSR_SECURE_BOOT_CPU2_STATUS_ADDR; - } - - /* set CPU to started */ - iwl_trans_set_bits_mask(trans, - CSR_UCODE_LOAD_STATUS_ADDR, - CSR_CPU_STATUS_LOADING_STARTED << shift_param, - 1); - - /* set last complete descriptor number */ - iwl_trans_set_bits_mask(trans, - CSR_UCODE_LOAD_STATUS_ADDR, - CSR_CPU_STATUS_NUM_OF_LAST_COMPLETED - << shift_param, - 1); - - /* set last loaded block */ - iwl_trans_set_bits_mask(trans, - CSR_UCODE_LOAD_STATUS_ADDR, - CSR_CPU_STATUS_NUM_OF_LAST_LOADED_BLOCK - << shift_param, - 1); - - /* image loading complete */ - iwl_trans_set_bits_mask(trans, - CSR_UCODE_LOAD_STATUS_ADDR, - CSR_CPU_STATUS_LOADING_COMPLETED - << shift_param, - 1); - - /* set FH_TCSR_0_REG */ - iwl_trans_set_bits_mask(trans, FH_TCSR_0_REG0, 0x00400000, 1); - - /* verify image verification started */ - ret = iwl_poll_bit(trans, address, - CSR_SECURE_BOOT_CPU_STATUS_VERF_STATUS, - CSR_SECURE_BOOT_CPU_STATUS_VERF_STATUS, - CSR_SECURE_TIME_OUT); - if (ret < 0) { - IWL_ERR(trans, "secure boot process didn't start\n"); - return ret; - } - - /* wait for image verification to complete */ - ret = iwl_poll_bit(trans, address, - CSR_SECURE_BOOT_CPU_STATUS_VERF_COMPLETED, - CSR_SECURE_BOOT_CPU_STATUS_VERF_COMPLETED, - CSR_SECURE_TIME_OUT); - - if (ret < 0) { - IWL_ERR(trans, "Time out on secure boot process\n"); - return ret; - } - - return 0; -} - static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, const struct fw_img *image) { int i, ret = 0; - IWL_DEBUG_FW(trans, - "working with %s image\n", - image->is_secure ? "Secured" : "Non Secured"); - IWL_DEBUG_FW(trans, - "working with %s CPU\n", - image->is_dual_cpus ? "Dual" : "Single"); - - /* configure the ucode to be ready to get the secured image */ - if (image->is_secure) { - /* set secure boot inspector addresses */ - iwl_write32(trans, CSR_SECURE_INSPECTOR_CODE_ADDR, 0); - iwl_write32(trans, CSR_SECURE_INSPECTOR_DATA_ADDR, 0); - - /* release CPU1 reset if secure inspector image burned in OTP */ - iwl_write32(trans, CSR_RESET, 0); - } - - /* load to FW the binary sections of CPU1 */ - IWL_DEBUG_INFO(trans, "Loading CPU1\n"); - for (i = 0; - i < IWL_UCODE_FIRST_SECTION_OF_SECOND_CPU; - i++) { + for (i = 0; i < IWL_UCODE_SECTION_MAX; i++) { if (!image->sec[i].data) break; - ret = iwl_pcie_load_section(trans, i, &image->sec[i]); - if (ret) - return ret; - } - /* configure the ucode to start secure process on CPU1 */ - if (image->is_secure) { - /* config CPU1 to start secure protocol */ - ret = iwl_pcie_secure_set(trans, 1); + ret = iwl_pcie_load_section(trans, i, &image->sec[i]); if (ret) return ret; - } else { - /* Remove all resets to allow NIC to operate */ - iwl_write32(trans, CSR_RESET, 0); } - if (image->is_dual_cpus) { - /* load to FW the binary sections of CPU2 */ - IWL_DEBUG_INFO(trans, "working w/ DUAL CPUs - Loading CPU2\n"); - for (i = IWL_UCODE_FIRST_SECTION_OF_SECOND_CPU; - i < IWL_UCODE_SECTION_MAX; i++) { - if (!image->sec[i].data) - break; - ret = iwl_pcie_load_section(trans, i, &image->sec[i]); - if (ret) - return ret; - } - - if (image->is_secure) { - /* set CPU2 for secure protocol */ - ret = iwl_pcie_secure_set(trans, 2); - if (ret) - return ret; - } - } + /* Remove all resets to allow NIC to operate */ + iwl_write32(trans, CSR_RESET, 0); return 0; } diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 059c5ac..1424335 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1465,8 +1465,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, spin_unlock_bh(&txq->lock); } -#define HOST_COMPLETE_TIMEOUT (2 * HZ) -#define COMMAND_POKE_TIMEOUT (HZ / 10) +#define HOST_COMPLETE_TIMEOUT (2 * HZ) static int iwl_pcie_send_hcmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) @@ -1494,16 +1493,16 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int cmd_idx; int ret; - int timeout = HOST_COMPLETE_TIMEOUT; IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", get_cmd_string(trans_pcie, cmd->id)); - if (WARN(test_and_set_bit(STATUS_HCMD_ACTIVE, - &trans_pcie->status), - "Command %s: a command is already active!\n", - get_cmd_string(trans_pcie, cmd->id))) + if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE, + &trans_pcie->status))) { + IWL_ERR(trans, "Command %s: a command is already active!\n", + get_cmd_string(trans_pcie, cmd->id)); return -EIO; + } IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", get_cmd_string(trans_pcie, cmd->id)); @@ -1518,29 +1517,10 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, return ret; } - while (timeout > 0) { - unsigned long flags; - - timeout -= COMMAND_POKE_TIMEOUT; - ret = wait_event_timeout(trans_pcie->wait_command_queue, - !test_bit(STATUS_HCMD_ACTIVE, - &trans_pcie->status), - COMMAND_POKE_TIMEOUT); - if (ret) - break; - /* poke the device - it may have lost the command */ - if (iwl_trans_grab_nic_access(trans, true, &flags)) { - iwl_trans_release_nic_access(trans, &flags); - IWL_DEBUG_INFO(trans, - "Tried to wake NIC for command %s\n", - get_cmd_string(trans_pcie, cmd->id)); - } else { - IWL_ERR(trans, "Failed to poke NIC for command %s\n", - get_cmd_string(trans_pcie, cmd->id)); - break; - } - } - + ret = wait_event_timeout(trans_pcie->wait_command_queue, + !test_bit(STATUS_HCMD_ACTIVE, + &trans_pcie->status), + HOST_COMPLETE_TIMEOUT); if (!ret) { if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { struct iwl_txq *txq = @@ -1561,9 +1541,6 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, "Clearing HCMD_ACTIVE for command %s\n", get_cmd_string(trans_pcie, cmd->id)); ret = -ETIMEDOUT; - - iwl_op_mode_nic_error(trans->op_mode); - goto cancel; } } diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index cc6a0a5..668dd27 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c @@ -913,10 +913,7 @@ static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf, char *p2; struct debug_data *d = f->private_data; - if (cnt == 0) - return 0; - - pdata = kmalloc(cnt + 1, GFP_KERNEL); + pdata = kmalloc(cnt, GFP_KERNEL); if (pdata == NULL) return 0; @@ -925,7 +922,6 @@ static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf, kfree(pdata); return 0; } - pdata[cnt] = '\0'; p0 = pdata; for (i = 0; i < num_of_items; i++) { diff --git a/drivers/net/wireless/libertas/firmware.c b/drivers/net/wireless/libertas/firmware.c index 51b92b5..c0f9e7e 100644 --- a/drivers/net/wireless/libertas/firmware.c +++ b/drivers/net/wireless/libertas/firmware.c @@ -53,11 +53,6 @@ static void main_firmware_cb(const struct firmware *firmware, void *context) /* Firmware found! */ lbs_fw_loaded(priv, 0, priv->helper_fw, firmware); - if (priv->helper_fw) { - release_firmware (priv->helper_fw); - priv->helper_fw = NULL; - } - release_firmware (firmware); } static void helper_firmware_cb(const struct firmware *firmware, void *context) diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index f499efc..c94dd68 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -754,14 +754,14 @@ static void if_cs_prog_firmware(struct lbs_private *priv, int ret, if (ret == 0 && (card->model != MODEL_8305)) ret = if_cs_prog_real(card, mainfw); if (ret) - return; + goto out; /* Now actually get the IRQ */ ret = request_irq(card->p_dev->irq, if_cs_interrupt, IRQF_SHARED, DRV_NAME, card); if (ret) { pr_err("error in request_irq\n"); - return; + goto out; } /* @@ -777,6 +777,10 @@ static void if_cs_prog_firmware(struct lbs_private *priv, int ret, pr_err("could not activate card\n"); free_irq(card->p_dev->irq, card); } + +out: + release_firmware(helper); + release_firmware(mainfw); } @@ -902,7 +906,6 @@ static int if_cs_probe(struct pcmcia_device *p_dev) if (card->model == MODEL_UNKNOWN) { pr_err("unsupported manf_id 0x%04x / card_id 0x%04x\n", p_dev->manf_id, p_dev->card_id); - ret = -ENODEV; goto out2; } diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 991238a..4557833 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -708,16 +708,20 @@ static void if_sdio_do_prog_firmware(struct lbs_private *priv, int ret, ret = if_sdio_prog_helper(card, helper); if (ret) - return; + goto out; lbs_deb_sdio("Helper firmware loaded\n"); ret = if_sdio_prog_real(card, mainfw); if (ret) - return; + goto out; lbs_deb_sdio("Firmware loaded\n"); if_sdio_finish_power_on(card); + +out: + release_firmware(helper); + release_firmware(mainfw); } static int if_sdio_prog_firmware(struct if_sdio_card *card) diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 8366915..4bb6574 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c @@ -1094,7 +1094,11 @@ static int if_spi_init_card(struct if_spi_card *card) goto out; out: + release_firmware(helper); + release_firmware(mainfw); + lbs_deb_leave_args(LBS_DEB_SPI, "err %d\n", err); + return err; } @@ -1124,7 +1128,7 @@ static int if_spi_probe(struct spi_device *spi) { struct if_spi_card *card; struct lbs_private *priv = NULL; - struct libertas_spi_platform_data *pdata = dev_get_platdata(&spi->dev); + struct libertas_spi_platform_data *pdata = spi->dev.platform_data; int err = 0; lbs_deb_enter(LBS_DEB_SPI); diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index dff08a2..2798077 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -844,7 +844,7 @@ static void if_usb_prog_firmware(struct lbs_private *priv, int ret, cardp->fw = fw; if (check_fwfile_format(cardp->fw->data, cardp->fw->size)) { ret = -EINVAL; - goto done; + goto release_fw; } /* Cancel any pending usb business */ @@ -861,7 +861,7 @@ restart: if (if_usb_submit_rx_urb_fwload(cardp) < 0) { lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n"); ret = -EIO; - goto done; + goto release_fw; } cardp->bootcmdresp = 0; @@ -883,14 +883,14 @@ restart: usb_kill_urb(cardp->tx_urb); if (if_usb_submit_rx_urb(cardp) < 0) ret = -EIO; - goto done; + goto release_fw; } else if (cardp->bootcmdresp <= 0) { if (--reset_count >= 0) { if_usb_reset_device(cardp); goto restart; } ret = -EIO; - goto done; + goto release_fw; } i = 0; @@ -921,14 +921,14 @@ restart: pr_info("FW download failure, time = %d ms\n", i * 100); ret = -EIO; - goto done; + goto release_fw; } cardp->priv->fw_ready = 1; if_usb_submit_rx_urb(cardp); if (lbs_start_card(priv)) - goto done; + goto release_fw; if_usb_setup_firmware(priv); @@ -939,8 +939,11 @@ restart: if (lbs_host_sleep_cfg(priv, priv->wol_criteria, NULL)) priv->ehs_remove_supported = false; - done: + release_fw: + release_firmware(cardp->fw); cardp->fw = NULL; + + done: lbs_deb_leave(LBS_DEB_USB); } diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 9df7bc9..2cd3f54 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -167,7 +167,6 @@ struct hwsim_vif_priv { u32 magic; u8 bssid[ETH_ALEN]; bool assoc; - bool bcn_en; u16 aid; }; @@ -1171,16 +1170,6 @@ static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw, *total_flags = data->rx_filter; } -static void mac80211_hwsim_bcn_en_iter(void *data, u8 *mac, - struct ieee80211_vif *vif) -{ - unsigned int *count = data; - struct hwsim_vif_priv *vp = (void *)vif->drv_priv; - - if (vp->bcn_en) - (*count)++; -} - static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, @@ -1191,8 +1180,7 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, hwsim_check_magic(vif); - wiphy_debug(hw->wiphy, "%s(changed=0x%x vif->addr=%pM)\n", - __func__, changed, vif->addr); + wiphy_debug(hw->wiphy, "%s(changed=0x%x)\n", __func__, changed); if (changed & BSS_CHANGED_BSSID) { wiphy_debug(hw->wiphy, "%s: BSSID changed: %pM\n", @@ -1214,7 +1202,6 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_BEACON_ENABLED) { wiphy_debug(hw->wiphy, " BCN EN: %d\n", info->enable_beacon); - vp->bcn_en = info->enable_beacon; if (data->started && !hrtimer_is_queued(&data->beacon_timer.timer) && info->enable_beacon) { @@ -1228,16 +1215,8 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, tasklet_hrtimer_start(&data->beacon_timer, ns_to_ktime(until_tbtt * 1000), HRTIMER_MODE_REL); - } else if (!info->enable_beacon) { - unsigned int count = 0; - ieee80211_iterate_active_interfaces( - data->hw, IEEE80211_IFACE_ITER_NORMAL, - mac80211_hwsim_bcn_en_iter, &count); - wiphy_debug(hw->wiphy, " beaconing vifs remaining: %u", - count); - if (count == 0) - tasklet_hrtimer_cancel(&data->beacon_timer); - } + } else if (!info->enable_beacon) + tasklet_hrtimer_cancel(&data->beacon_timer); } if (changed & BSS_CHANGED_ERP_CTS_PROT) { @@ -2097,7 +2076,7 @@ out: } /* Generic Netlink operations array */ -static const struct genl_ops hwsim_ops[] = { +static struct genl_ops hwsim_ops[] = { { .cmd = HWSIM_CMD_REGISTER, .policy = hwsim_genl_policy, @@ -2148,7 +2127,8 @@ static int hwsim_init_netlink(void) printk(KERN_INFO "mac80211_hwsim: initializing netlink\n"); - rc = genl_register_family_with_ops(&hwsim_genl_family, hwsim_ops); + rc = genl_register_family_with_ops(&hwsim_genl_family, + hwsim_ops, ARRAY_SIZE(hwsim_ops)); if (rc) goto failure; diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index aeaea0e..fbad00a 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -2210,10 +2210,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->bss_started = 0; priv->bss_num = 0; - if (mwifiex_cfg80211_init_p2p_client(priv)) { - wdev = ERR_PTR(-EFAULT); - goto done; - } + if (mwifiex_cfg80211_init_p2p_client(priv)) + return ERR_PTR(-EFAULT); break; default: @@ -2226,8 +2224,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, if (!dev) { wiphy_err(wiphy, "no memory available for netdevice\n"); priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; - wdev = ERR_PTR(-ENOMEM); - goto done; + return ERR_PTR(-ENOMEM); } mwifiex_init_priv_params(priv, dev); @@ -2267,9 +2264,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, wiphy_err(wiphy, "cannot register virtual network device\n"); free_netdev(dev); priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; - priv->netdev = NULL; - wdev = ERR_PTR(-EFAULT); - goto done; + return ERR_PTR(-EFAULT); } sema_init(&priv->async_sem, 1); @@ -2279,13 +2274,6 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, #ifdef CONFIG_DEBUG_FS mwifiex_dev_debugfs_init(priv); #endif - -done: - if (IS_ERR(wdev)) { - kfree(priv->wdev); - priv->wdev = NULL; - } - return wdev; } EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); @@ -2310,10 +2298,7 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) unregister_netdevice(wdev->netdev); /* Clear the priv in adapter */ - priv->netdev->ieee80211_ptr = NULL; priv->netdev = NULL; - kfree(wdev); - priv->wdev = NULL; priv->media_connected = false; diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index e47f4e3..a6c46f3 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -1048,7 +1048,7 @@ mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter) struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL; unsigned long cmd_flags; unsigned long scan_pending_q_flags; - bool cancel_scan_cmd = false; + uint16_t cancel_scan_cmd = false; if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) { diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index c8385ec..f80f30b 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h @@ -1020,8 +1020,8 @@ struct mwifiex_power_group { } __packed; struct mwifiex_types_power_group { - __le16 type; - __le16 length; + u16 type; + u16 length; } __packed; struct host_cmd_ds_txpwr_cfg { diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c index 81ac001..220af4f 100644 --- a/drivers/net/wireless/mwifiex/ie.c +++ b/drivers/net/wireless/mwifiex/ie.c @@ -82,7 +82,7 @@ mwifiex_update_autoindex_ies(struct mwifiex_private *priv, struct mwifiex_ie_list *ie_list) { u16 travel_len, index, mask; - s16 input_len, tlv_len; + s16 input_len; struct mwifiex_ie *ie; u8 *tmp; @@ -91,13 +91,11 @@ mwifiex_update_autoindex_ies(struct mwifiex_private *priv, ie_list->len = 0; - while (input_len >= sizeof(struct mwifiex_ie_types_header)) { + while (input_len > 0) { ie = (struct mwifiex_ie *)(((u8 *)ie_list) + travel_len); - tlv_len = le16_to_cpu(ie->ie_length); - travel_len += tlv_len + MWIFIEX_IE_HDR_SIZE; + input_len -= le16_to_cpu(ie->ie_length) + MWIFIEX_IE_HDR_SIZE; + travel_len += le16_to_cpu(ie->ie_length) + MWIFIEX_IE_HDR_SIZE; - if (input_len < tlv_len + MWIFIEX_IE_HDR_SIZE) - return -1; index = le16_to_cpu(ie->ie_index); mask = le16_to_cpu(ie->mgmt_subtype_mask); @@ -134,7 +132,6 @@ mwifiex_update_autoindex_ies(struct mwifiex_private *priv, le16_add_cpu(&ie_list->len, le16_to_cpu(priv->mgmt_ie[index].ie_length) + MWIFIEX_IE_HDR_SIZE); - input_len -= tlv_len + MWIFIEX_IE_HDR_SIZE; } if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 4e4686e..37f873b 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -621,7 +621,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, int ret = 0; struct ieee_types_assoc_rsp *assoc_rsp; struct mwifiex_bssdescriptor *bss_desc; - bool enable_data = true; + u8 enable_data = true; u16 cap_info, status_code; assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params; diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 78e8a66..c2b91f5 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -411,14 +411,13 @@ static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter) */ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) { - int ret; + int ret, i; char fmt[64]; struct mwifiex_private *priv; struct mwifiex_adapter *adapter = context; struct mwifiex_fw_image fw; struct semaphore *sem = adapter->card_sem; bool init_failed = false; - struct wireless_dev *wdev; if (!firmware) { dev_err(adapter->dev, @@ -470,16 +469,14 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) priv = adapter->priv[MWIFIEX_BSS_ROLE_STA]; if (mwifiex_register_cfg80211(adapter)) { dev_err(adapter->dev, "cannot register with cfg80211\n"); - goto err_init_fw; + goto err_register_cfg80211; } rtnl_lock(); /* Create station interface by default */ - wdev = mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d", - NL80211_IFTYPE_STATION, NULL, NULL); - if (IS_ERR(wdev)) { + if (!mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d", + NL80211_IFTYPE_STATION, NULL, NULL)) { dev_err(adapter->dev, "cannot create default STA interface\n"); - rtnl_unlock(); goto err_add_intf; } rtnl_unlock(); @@ -489,6 +486,17 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) goto done; err_add_intf: + for (i = 0; i < adapter->priv_num; i++) { + priv = adapter->priv[i]; + + if (!priv) + continue; + + if (priv->wdev && priv->netdev) + mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev); + } + rtnl_unlock(); +err_register_cfg80211: wiphy_unregister(adapter->wiphy); wiphy_free(adapter->wiphy); err_init_fw: @@ -874,9 +882,7 @@ mwifiex_add_card(void *card, struct semaphore *sem, adapter->cmd_wait_q.status = 0; adapter->scan_wait_q_woken = false; - adapter->workqueue = - alloc_workqueue("MWIFIEX_WORK_QUEUE", - WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND, 1); + adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE"); if (!adapter->workqueue) goto err_kmalloc; @@ -998,6 +1004,12 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) wiphy_unregister(priv->wdev->wiphy); wiphy_free(priv->wdev->wiphy); + for (i = 0; i < adapter->priv_num; i++) { + priv = adapter->priv[i]; + if (priv) + kfree(priv->wdev); + } + mwifiex_terminate_workqueue(adapter); /* Unregister device */ diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 03688aa..52da8ee 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -93,7 +93,7 @@ static int mwifiex_pcie_suspend(struct device *dev) struct pci_dev *pdev = to_pci_dev(dev); if (pdev) { - card = pci_get_drvdata(pdev); + card = (struct pcie_service_card *) pci_get_drvdata(pdev); if (!card || !card->adapter) { pr_err("Card or adapter structure is not valid\n"); return 0; @@ -128,7 +128,7 @@ static int mwifiex_pcie_resume(struct device *dev) struct pci_dev *pdev = to_pci_dev(dev); if (pdev) { - card = pci_get_drvdata(pdev); + card = (struct pcie_service_card *) pci_get_drvdata(pdev); if (!card || !card->adapter) { pr_err("Card or adapter structure is not valid\n"); return 0; @@ -232,6 +232,7 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev) } mwifiex_remove_card(card->adapter, &add_remove_card_sem); + kfree(card); } static void mwifiex_pcie_shutdown(struct pci_dev *pdev) @@ -2036,7 +2037,7 @@ static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context) goto exit; } - card = pci_get_drvdata(pdev); + card = (struct pcie_service_card *) pci_get_drvdata(pdev); if (!card || !card->adapter) { pr_debug("info: %s: card=%p adapter=%p\n", __func__, card, card ? card->adapter : NULL); @@ -2312,7 +2313,6 @@ static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter) pci_release_region(pdev, 0); pci_set_drvdata(pdev, NULL); } - kfree(card); } /* diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index b44a315..1576104 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -196,6 +196,7 @@ mwifiex_sdio_remove(struct sdio_func *func) } mwifiex_remove_card(card->adapter, &add_remove_card_sem); + kfree(card); } /* @@ -1028,10 +1029,7 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb, u32 upld_typ) { u8 *cmd_buf; - __le16 *curr_ptr = (__le16 *)skb->data; - u16 pkt_len = le16_to_cpu(*curr_ptr); - skb_trim(skb, pkt_len); skb_pull(skb, INTF_HEADER_LEN); switch (upld_typ) { @@ -1744,6 +1742,7 @@ mwifiex_unregister_dev(struct mwifiex_adapter *adapter) sdio_claim_host(card->func); sdio_disable_func(card->func); sdio_release_host(card->func); + sdio_set_drvdata(card->func, NULL); } } @@ -1771,6 +1770,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) return ret; } + sdio_set_drvdata(func, card); adapter->dev = &func->dev; @@ -1798,8 +1798,6 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter) int ret; u8 sdio_ireg; - sdio_set_drvdata(card->func, card); - /* * Read the HOST_INT_STATUS_REG for ACK the first interrupt got * from the bootloader. If we don't do this we get a interrupt @@ -1882,8 +1880,6 @@ static void mwifiex_cleanup_sdio(struct mwifiex_adapter *adapter) kfree(card->mpa_rx.len_arr); kfree(card->mpa_tx.buf); kfree(card->mpa_rx.buf); - sdio_set_drvdata(card->func, NULL); - kfree(card); } /* diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 2181ee2..c0268b5 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c @@ -239,14 +239,14 @@ static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, memmove(cmd_txp_cfg, txp, sizeof(struct host_cmd_ds_txpwr_cfg) + sizeof(struct mwifiex_types_power_group) + - le16_to_cpu(pg_tlv->length)); + pg_tlv->length); pg_tlv = (struct mwifiex_types_power_group *) ((u8 *) cmd_txp_cfg + sizeof(struct host_cmd_ds_txpwr_cfg)); cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) + sizeof(struct mwifiex_types_power_group) + - le16_to_cpu(pg_tlv->length)); + pg_tlv->length); } else { memmove(cmd_txp_cfg, txp, sizeof(*txp)); } @@ -327,7 +327,7 @@ mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, { struct mwifiex_adapter *adapter = priv->adapter; struct host_cmd_ds_802_11_hs_cfg_enh *hs_cfg = &cmd->params.opt_hs_cfg; - bool hs_activate = false; + u16 hs_activate = false; if (!hscfg_param) /* New Activate command */ diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 2675ca7..58a6013 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -274,20 +274,17 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg; struct mwifiex_rate_scope *rate_scope; struct mwifiex_ie_types_header *head; - u16 tlv, tlv_buf_len, tlv_buf_left; + u16 tlv, tlv_buf_len; u8 *tlv_buf; u32 i; - tlv_buf = ((u8 *)rate_cfg) + sizeof(struct host_cmd_ds_tx_rate_cfg); - tlv_buf_left = le16_to_cpu(resp->size) - S_DS_GEN - sizeof(*rate_cfg); + tlv_buf = ((u8 *)rate_cfg) + + sizeof(struct host_cmd_ds_tx_rate_cfg); + tlv_buf_len = le16_to_cpu(*(__le16 *) (tlv_buf + sizeof(u16))); - while (tlv_buf_left >= sizeof(*head)) { - head = (struct mwifiex_ie_types_header *)tlv_buf; - tlv = le16_to_cpu(head->type); - tlv_buf_len = le16_to_cpu(head->len); - - if (tlv_buf_left < (sizeof(*head) + tlv_buf_len)) - break; + while (tlv_buf && tlv_buf_len > 0) { + tlv = (*tlv_buf); + tlv = tlv | (*(tlv_buf + 1) << 8); switch (tlv) { case TLV_TYPE_RATE_SCOPE: @@ -307,8 +304,9 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, /* Add RATE_DROP tlv here */ } - tlv_buf += (sizeof(*head) + tlv_buf_len); - tlv_buf_left -= (sizeof(*head) + tlv_buf_len); + head = (struct mwifiex_ie_types_header *) tlv_buf; + tlv_buf += le16_to_cpu(head->len) + sizeof(*head); + tlv_buf_len -= le16_to_cpu(head->len); } priv->is_data_rate_auto = mwifiex_is_rate_auto(priv); @@ -342,17 +340,13 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf) ((u8 *) data_buf + sizeof(struct host_cmd_ds_txpwr_cfg)); pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr + sizeof(struct mwifiex_types_power_group)); - length = le16_to_cpu(pg_tlv_hdr->length); - - /* At least one structure required to update power */ - if (length < sizeof(struct mwifiex_power_group)) - return 0; - - max_power = pg->power_max; - min_power = pg->power_min; - length -= sizeof(struct mwifiex_power_group); - - while (length >= sizeof(struct mwifiex_power_group)) { + length = pg_tlv_hdr->length; + if (length > 0) { + max_power = pg->power_max; + min_power = pg->power_min; + length -= sizeof(struct mwifiex_power_group); + } + while (length) { pg++; if (max_power < pg->power_max) max_power = pg->power_max; @@ -362,8 +356,10 @@ static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf) length -= sizeof(struct mwifiex_power_group); } - priv->min_tx_power_level = (u8) min_power; - priv->max_tx_power_level = (u8) max_power; + if (pg_tlv_hdr->length > 0) { + priv->min_tx_power_level = (u8) min_power; + priv->max_tx_power_level = (u8) max_power; + } return 0; } diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index c8e029d..f084412 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -638,9 +638,8 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv, txp_cfg->mode = cpu_to_le32(1); pg_tlv = (struct mwifiex_types_power_group *) (buf + sizeof(struct host_cmd_ds_txpwr_cfg)); - pg_tlv->type = cpu_to_le16(TLV_TYPE_POWER_GROUP); - pg_tlv->length = - cpu_to_le16(4 * sizeof(struct mwifiex_power_group)); + pg_tlv->type = TLV_TYPE_POWER_GROUP; + pg_tlv->length = 4 * sizeof(struct mwifiex_power_group); pg = (struct mwifiex_power_group *) (buf + sizeof(struct host_cmd_ds_txpwr_cfg) + sizeof(struct mwifiex_types_power_group)); diff --git a/drivers/net/wireless/mwifiex/uap_txrx.c b/drivers/net/wireless/mwifiex/uap_txrx.c index 92f76d6..1cfe5a7 100644 --- a/drivers/net/wireless/mwifiex/uap_txrx.c +++ b/drivers/net/wireless/mwifiex/uap_txrx.c @@ -97,7 +97,6 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv, struct mwifiex_txinfo *tx_info; int hdr_chop; struct timeval tv; - struct ethhdr *p_ethhdr; u8 rfc1042_eth_hdr[ETH_ALEN] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; uap_rx_pd = (struct uap_rxpd *)(skb->data); @@ -113,36 +112,14 @@ static void mwifiex_uap_queue_bridged_pkt(struct mwifiex_private *priv, } if (!memcmp(&rx_pkt_hdr->rfc1042_hdr, - rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr))) { - /* Replace the 803 header and rfc1042 header (llc/snap) with - * an Ethernet II header, keep the src/dst and snap_type - * (ethertype). - * - * The firmware only passes up SNAP frames converting all RX - * data from 802.11 to 802.2/LLC/SNAP frames. - * - * To create the Ethernet II, just move the src, dst address - * right before the snap_type. - */ - p_ethhdr = (struct ethhdr *) - ((u8 *)(&rx_pkt_hdr->eth803_hdr) - + sizeof(rx_pkt_hdr->eth803_hdr) - + sizeof(rx_pkt_hdr->rfc1042_hdr) - - sizeof(rx_pkt_hdr->eth803_hdr.h_dest) - - sizeof(rx_pkt_hdr->eth803_hdr.h_source) - - sizeof(rx_pkt_hdr->rfc1042_hdr.snap_type)); - memcpy(p_ethhdr->h_source, rx_pkt_hdr->eth803_hdr.h_source, - sizeof(p_ethhdr->h_source)); - memcpy(p_ethhdr->h_dest, rx_pkt_hdr->eth803_hdr.h_dest, - sizeof(p_ethhdr->h_dest)); + rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr))) /* Chop off the rxpd + the excess memory from * 802.2/llc/snap header that was removed. */ - hdr_chop = (u8 *)p_ethhdr - (u8 *)uap_rx_pd; - } else { + hdr_chop = (u8 *)eth_hdr - (u8 *)uap_rx_pd; + else /* Chop off the rxpd */ hdr_chop = (u8 *)&rx_pkt_hdr->eth803_hdr - (u8 *)uap_rx_pd; - } /* Chop off the leading header bytes so the it points * to the start of either the reconstructed EthII frame diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index edf5b7a..1c70b8d 100644 --- a/drivers/net/wireless/mwifiex/usb.c +++ b/drivers/net/wireless/mwifiex/usb.c @@ -350,6 +350,7 @@ static int mwifiex_usb_probe(struct usb_interface *intf, card->udev = udev; card->intf = intf; + usb_card = card; pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocol=%#x\n", udev->descriptor.bcdUSB, udev->descriptor.bDeviceClass, @@ -524,28 +525,25 @@ static int mwifiex_usb_resume(struct usb_interface *intf) static void mwifiex_usb_disconnect(struct usb_interface *intf) { struct usb_card_rec *card = usb_get_intfdata(intf); + struct mwifiex_adapter *adapter; - if (!card) { - pr_err("%s: card is NULL\n", __func__); + if (!card || !card->adapter) { + pr_err("%s: card or card->adapter is NULL\n", __func__); return; } - mwifiex_usb_free(card); - - if (card->adapter) { - struct mwifiex_adapter *adapter = card->adapter; + adapter = card->adapter; + if (!adapter->priv_num) + return; - if (!adapter->priv_num) - return; + mwifiex_usb_free(card); - dev_dbg(adapter->dev, "%s: removing card\n", __func__); - mwifiex_remove_card(adapter, &add_remove_card_sem); - } + dev_dbg(adapter->dev, "%s: removing card\n", __func__); + mwifiex_remove_card(adapter, &add_remove_card_sem); usb_set_intfdata(intf, NULL); usb_put_dev(interface_to_usbdev(intf)); kfree(card); - usb_card = NULL; return; } @@ -756,7 +754,6 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) card->adapter = adapter; adapter->dev = &card->udev->dev; strcpy(adapter->fw_name, USB8797_DEFAULT_FW_NAME); - usb_card = card; return 0; } @@ -765,7 +762,7 @@ static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter) { struct usb_card_rec *card = (struct usb_card_rec *)adapter->card; - card->adapter = NULL; + usb_set_intfdata(card->intf, NULL); } static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, @@ -1007,7 +1004,7 @@ static void mwifiex_usb_cleanup_module(void) if (!down_interruptible(&add_remove_card_sem)) up(&add_remove_card_sem); - if (usb_card && usb_card->adapter) { + if (usb_card) { struct mwifiex_adapter *adapter = usb_card->adapter; int i; diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 13eaeed..95fa359 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -708,7 +708,7 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, { u8 *curr = (u8 *) &resp->params.get_wmm_status; uint16_t resp_len = le16_to_cpu(resp->size), tlv_len; - bool valid = true; + int valid = true; struct mwifiex_ie_types_data *tlv_hdr; struct mwifiex_ie_types_wmm_queue_status *tlv_wmm_qstatus; @@ -722,9 +722,6 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, tlv_hdr = (struct mwifiex_ie_types_data *) curr; tlv_len = le16_to_cpu(tlv_hdr->header.len); - if (resp_len < tlv_len + sizeof(tlv_hdr->header)) - break; - switch (le16_to_cpu(tlv_hdr->header.type)) { case TLV_TYPE_WMMQSTATUS: tlv_wmm_qstatus = diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h index 0f129d4..644d6e0 100644 --- a/drivers/net/wireless/mwifiex/wmm.h +++ b/drivers/net/wireless/mwifiex/wmm.h @@ -83,10 +83,11 @@ mwifiex_wmm_is_ra_list_empty(struct list_head *ra_list_hhead) } void mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, - struct sk_buff *skb); + struct sk_buff *skb); void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra); void mwifiex_rotate_priolists(struct mwifiex_private *priv, - struct mwifiex_ra_list_tbl *ra, int tid); + struct mwifiex_ra_list_tbl *ra, + int tid); int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter); void mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter); @@ -94,18 +95,21 @@ int mwifiex_is_ralist_valid(struct mwifiex_private *priv, struct mwifiex_ra_list_tbl *ra_list, int tid); u8 mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv, - const struct sk_buff *skb); + const struct sk_buff *skb); void mwifiex_wmm_init(struct mwifiex_adapter *adapter); -u32 mwifiex_wmm_process_association_req(struct mwifiex_private *priv, - u8 **assoc_buf, - struct ieee_types_wmm_parameter *wmmie, - struct ieee80211_ht_cap *htcap); +extern u32 mwifiex_wmm_process_association_req(struct mwifiex_private *priv, + u8 **assoc_buf, + struct ieee_types_wmm_parameter + *wmmie, + struct ieee80211_ht_cap + *htcap); void mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv, - struct ieee_types_wmm_parameter *wmm_ie); + struct ieee_types_wmm_parameter + *wmm_ie); void mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv); -int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, - const struct host_cmd_ds_command *resp); +extern int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv, + const struct host_cmd_ds_command *resp); #endif /* !_MWIFIEX_WMM_H_ */ diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index b953ad6..a3707fd 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -6093,6 +6093,7 @@ err_iounmap: if (priv->sram != NULL) pci_iounmap(pdev, priv->sram); + pci_set_drvdata(pdev, NULL); ieee80211_free_hw(hw); err_free_reg: @@ -6146,6 +6147,7 @@ static void mwl8k_remove(struct pci_dev *pdev) unmap: pci_iounmap(pdev, priv->regs); pci_iounmap(pdev, priv->sram); + pci_set_drvdata(pdev, NULL); ieee80211_free_hw(hw); pci_release_regions(pdev); pci_disable_device(pdev); diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h index eebd2be..3bb936b 100644 --- a/drivers/net/wireless/orinoco/orinoco.h +++ b/drivers/net/wireless/orinoco/orinoco.h @@ -182,20 +182,23 @@ extern int orinoco_debug; /* Exported prototypes */ /********************************************************************/ -struct orinoco_private *alloc_orinocodev(int sizeof_card, struct device *device, - int (*hard_reset)(struct orinoco_private *), - int (*stop_fw)(struct orinoco_private *, int)); -void free_orinocodev(struct orinoco_private *priv); -int orinoco_init(struct orinoco_private *priv); -int orinoco_if_add(struct orinoco_private *priv, unsigned long base_addr, - unsigned int irq, const struct net_device_ops *ops); -void orinoco_if_del(struct orinoco_private *priv); -int orinoco_up(struct orinoco_private *priv); -void orinoco_down(struct orinoco_private *priv); -irqreturn_t orinoco_interrupt(int irq, void *dev_id); - -void __orinoco_ev_info(struct net_device *dev, struct hermes *hw); -void __orinoco_ev_rx(struct net_device *dev, struct hermes *hw); +extern struct orinoco_private *alloc_orinocodev( + int sizeof_card, struct device *device, + int (*hard_reset)(struct orinoco_private *), + int (*stop_fw)(struct orinoco_private *, int)); +extern void free_orinocodev(struct orinoco_private *priv); +extern int orinoco_init(struct orinoco_private *priv); +extern int orinoco_if_add(struct orinoco_private *priv, + unsigned long base_addr, + unsigned int irq, + const struct net_device_ops *ops); +extern void orinoco_if_del(struct orinoco_private *priv); +extern int orinoco_up(struct orinoco_private *priv); +extern void orinoco_down(struct orinoco_private *priv); +extern irqreturn_t orinoco_interrupt(int irq, void *dev_id); + +extern void __orinoco_ev_info(struct net_device *dev, struct hermes *hw); +extern void __orinoco_ev_rx(struct net_device *dev, struct hermes *hw); int orinoco_process_xmit_skb(struct sk_buff *skb, struct net_device *dev, diff --git a/drivers/net/wireless/orinoco/orinoco_nortel.c b/drivers/net/wireless/orinoco/orinoco_nortel.c index ffb2469..d73fdf6 100644 --- a/drivers/net/wireless/orinoco/orinoco_nortel.c +++ b/drivers/net/wireless/orinoco/orinoco_nortel.c @@ -234,6 +234,7 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev, free_irq(pdev->irq, priv); fail_irq: + pci_set_drvdata(pdev, NULL); free_orinocodev(priv); fail_alloc: @@ -264,6 +265,7 @@ static void orinoco_nortel_remove_one(struct pci_dev *pdev) orinoco_if_del(priv); free_irq(pdev->irq, priv); + pci_set_drvdata(pdev, NULL); free_orinocodev(priv); pci_iounmap(pdev, priv->hw.iobase); pci_iounmap(pdev, card->attr_io); diff --git a/drivers/net/wireless/orinoco/orinoco_pci.c b/drivers/net/wireless/orinoco/orinoco_pci.c index 5ae1191..677bf14 100644 --- a/drivers/net/wireless/orinoco/orinoco_pci.c +++ b/drivers/net/wireless/orinoco/orinoco_pci.c @@ -184,6 +184,7 @@ static int orinoco_pci_init_one(struct pci_dev *pdev, free_irq(pdev->irq, priv); fail_irq: + pci_set_drvdata(pdev, NULL); free_orinocodev(priv); fail_alloc: @@ -204,6 +205,7 @@ static void orinoco_pci_remove_one(struct pci_dev *pdev) orinoco_if_del(priv); free_irq(pdev->irq, priv); + pci_set_drvdata(pdev, NULL); free_orinocodev(priv); pci_iounmap(pdev, priv->hw.iobase); pci_release_regions(pdev); diff --git a/drivers/net/wireless/orinoco/orinoco_plx.c b/drivers/net/wireless/orinoco/orinoco_plx.c index bbd36d1..2559dbd 100644 --- a/drivers/net/wireless/orinoco/orinoco_plx.c +++ b/drivers/net/wireless/orinoco/orinoco_plx.c @@ -273,6 +273,7 @@ static int orinoco_plx_init_one(struct pci_dev *pdev, free_irq(pdev->irq, priv); fail_irq: + pci_set_drvdata(pdev, NULL); free_orinocodev(priv); fail_alloc: @@ -300,6 +301,7 @@ static void orinoco_plx_remove_one(struct pci_dev *pdev) orinoco_if_del(priv); free_irq(pdev->irq, priv); + pci_set_drvdata(pdev, NULL); free_orinocodev(priv); pci_iounmap(pdev, priv->hw.iobase); pci_iounmap(pdev, card->attr_io); diff --git a/drivers/net/wireless/orinoco/orinoco_tmd.c b/drivers/net/wireless/orinoco/orinoco_tmd.c index 04b08de..42afeee 100644 --- a/drivers/net/wireless/orinoco/orinoco_tmd.c +++ b/drivers/net/wireless/orinoco/orinoco_tmd.c @@ -170,6 +170,7 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev, free_irq(pdev->irq, priv); fail_irq: + pci_set_drvdata(pdev, NULL); free_orinocodev(priv); fail_alloc: @@ -194,6 +195,7 @@ static void orinoco_tmd_remove_one(struct pci_dev *pdev) orinoco_if_del(priv); free_irq(pdev->irq, priv); + pci_set_drvdata(pdev, NULL); free_orinocodev(priv); pci_iounmap(pdev, priv->hw.iobase); pci_iounmap(pdev, card->bridge_io); diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index f9a07b0..57e3af8 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c @@ -631,6 +631,7 @@ static int p54p_probe(struct pci_dev *pdev, iounmap(priv->map); err_free_dev: + pci_set_drvdata(pdev, NULL); p54_free_common(dev); err_free_reg: diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index de15171..7fc46f2 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c @@ -636,7 +636,7 @@ static int p54spi_probe(struct spi_device *spi) gpio_direction_input(p54spi_gpio_irq); ret = request_irq(gpio_to_irq(p54spi_gpio_irq), - p54spi_interrupt, 0, "p54spi", + p54spi_interrupt, IRQF_DISABLED, "p54spi", priv->spi); if (ret < 0) { dev_err(&priv->spi->dev, "request_irq() failed"); diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index 8863a6c..1c22b81 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c @@ -183,7 +183,7 @@ prism54_update_stats(struct work_struct *work) data = r.ptr; /* copy this MAC to the bss */ - memcpy(bss.address, data, ETH_ALEN); + memcpy(bss.address, data, 6); kfree(data); /* now ask for the corresponding bss */ @@ -531,7 +531,7 @@ prism54_set_wap(struct net_device *ndev, struct iw_request_info *info, return -EINVAL; /* prepare the structure for the set object */ - memcpy(&bssid[0], awrq->sa_data, ETH_ALEN); + memcpy(&bssid[0], awrq->sa_data, 6); /* set the bssid -- does this make sense when in AP mode? */ rvalue = mgt_set_request(priv, DOT11_OID_BSSID, 0, &bssid); @@ -550,7 +550,7 @@ prism54_get_wap(struct net_device *ndev, struct iw_request_info *info, int rvalue; rvalue = mgt_get_request(priv, DOT11_OID_BSSID, 0, NULL, &r); - memcpy(awrq->sa_data, r.ptr, ETH_ALEN); + memcpy(awrq->sa_data, r.ptr, 6); awrq->sa_family = ARPHRD_ETHER; kfree(r.ptr); @@ -582,7 +582,7 @@ prism54_translate_bss(struct net_device *ndev, struct iw_request_info *info, size_t wpa_ie_len; /* The first entry must be the MAC address */ - memcpy(iwe.u.ap_addr.sa_data, bss->address, ETH_ALEN); + memcpy(iwe.u.ap_addr.sa_data, bss->address, 6); iwe.u.ap_addr.sa_family = ARPHRD_ETHER; iwe.cmd = SIOCGIWAP; current_ev = iwe_stream_add_event(info, current_ev, end_buf, @@ -2489,7 +2489,7 @@ prism54_set_mac_address(struct net_device *ndev, void *addr) &((struct sockaddr *) addr)->sa_data); if (!ret) memcpy(priv->ndev->dev_addr, - &((struct sockaddr *) addr)->sa_data, ETH_ALEN); + &((struct sockaddr *) addr)->sa_data, 6); return ret; } diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index e05d9b4..5970ff6 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c @@ -811,10 +811,6 @@ static const struct net_device_ops islpci_netdev_ops = { .ndo_validate_addr = eth_validate_addr, }; -static struct device_type wlan_type = { - .name = "wlan", -}; - struct net_device * islpci_setup(struct pci_dev *pdev) { @@ -825,8 +821,9 @@ islpci_setup(struct pci_dev *pdev) return ndev; pci_set_drvdata(pdev, ndev); +#if defined(SET_NETDEV_DEV) SET_NETDEV_DEV(ndev, &pdev->dev); - SET_NETDEV_DEVTYPE(ndev, &wlan_type); +#endif /* setup the structure members */ ndev->base_addr = pci_resource_start(pdev, 0); @@ -840,7 +837,7 @@ islpci_setup(struct pci_dev *pdev) /* ndev->set_multicast_list = &islpci_set_multicast_list; */ ndev->addr_len = ETH_ALEN; /* Get a non-zero dummy MAC address for nameif. Jean II */ - memcpy(ndev->dev_addr, dummy_mac, ETH_ALEN); + memcpy(ndev->dev_addr, dummy_mac, 6); ndev->watchdog_timeo = ISLPCI_TX_TIMEOUT; diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c index 056af38..a01606b 100644 --- a/drivers/net/wireless/prism54/oid_mgt.c +++ b/drivers/net/wireless/prism54/oid_mgt.c @@ -682,7 +682,7 @@ mgt_update_addr(islpci_private *priv) isl_oid[GEN_OID_MACADDRESS].size, &res); if ((ret == 0) && res && (res->header->operation != PIMFOR_OP_ERROR)) - memcpy(priv->ndev->dev_addr, res->data, ETH_ALEN); + memcpy(priv->ndev->dev_addr, res->data, 6); else ret = -EIO; if (res) diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 006b8bc..68dbbb9 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -58,11 +58,11 @@ config RT61PCI config RT2800PCI tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support" - depends on PCI + depends on PCI || SOC_RT288X || SOC_RT305X select RT2800_LIB - select RT2800_LIB_MMIO select RT2X00_LIB_MMIO - select RT2X00_LIB_PCI + select RT2X00_LIB_PCI if PCI + select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X select RT2X00_LIB_FIRMWARE select RT2X00_LIB_CRYPTO select CRC_CCITT @@ -199,30 +199,9 @@ config RT2800USB_UNKNOWN endif -config RT2800SOC - tristate "Ralink WiSoC support" - depends on SOC_RT288X || SOC_RT305X - select RT2X00_LIB_SOC - select RT2X00_LIB_MMIO - select RT2X00_LIB_CRYPTO - select RT2X00_LIB_FIRMWARE - select RT2800_LIB - select RT2800_LIB_MMIO - ---help--- - This adds support for Ralink WiSoC devices. - Supported chips: RT2880, RT3050, RT3052, RT3350, RT3352. - - When compiled as a module, this driver will be called rt2800soc. - - config RT2800_LIB tristate -config RT2800_LIB_MMIO - tristate - select RT2X00_LIB_MMIO - select RT2800_LIB - config RT2X00_LIB_MMIO tristate @@ -240,7 +219,6 @@ config RT2X00_LIB_USB config RT2X00_LIB tristate - select AVERAGE config RT2X00_LIB_FIRMWARE boolean diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile index 24a6601..f069d8b 100644 --- a/drivers/net/wireless/rt2x00/Makefile +++ b/drivers/net/wireless/rt2x00/Makefile @@ -14,7 +14,6 @@ obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o obj-$(CONFIG_RT2X00_LIB_SOC) += rt2x00soc.o obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o obj-$(CONFIG_RT2800_LIB) += rt2800lib.o -obj-$(CONFIG_RT2800_LIB_MMIO) += rt2800mmio.o obj-$(CONFIG_RT2400PCI) += rt2400pci.o obj-$(CONFIG_RT2500PCI) += rt2500pci.o obj-$(CONFIG_RT61PCI) += rt61pci.o @@ -22,4 +21,3 @@ obj-$(CONFIG_RT2800PCI) += rt2800pci.o obj-$(CONFIG_RT2500USB) += rt2500usb.o obj-$(CONFIG_RT73USB) += rt73usb.o obj-$(CONFIG_RT2800USB) += rt2800usb.o -obj-$(CONFIG_RT2800SOC) += rt2800soc.o diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 38ed9a3..3d53a09 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c @@ -1261,7 +1261,7 @@ static void rt2400pci_fill_rxdone(struct queue_entry *entry, */ rxdesc->timestamp = ((u64)rx_high << 32) | rx_low; rxdesc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL) & ~0x08; - rxdesc->rssi = rt2x00_get_field32(word3, RXD_W3_RSSI) - + rxdesc->rssi = rt2x00_get_field32(word2, RXD_W3_RSSI) - entry->queue->rt2x00dev->rssi_offset; rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index aab6b5e..fa33b5e 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h @@ -52,7 +52,6 @@ * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) * RF5592 2.4G/5G 2T2R - * RF3070 2.4G 1T1R * RF5360 2.4G 1T1R * RF5370 2.4G 1T1R * RF5390 2.4G 1T1R @@ -71,7 +70,6 @@ #define RF3322 0x000c #define RF3053 0x000d #define RF5592 0x000f -#define RF3070 0x3070 #define RF3290 0x3290 #define RF5360 0x5360 #define RF5370 0x5370 @@ -124,7 +122,7 @@ /* * MAC_CSR0_3290: MAC_CSR0 for RT3290 to identity MAC version number. */ -#define MAC_CSR0_3290 0x0000 +#define MAC_CSR0_3290 0x0000 /* * E2PROM_CSR: PCI EEPROM control register. @@ -213,17 +211,17 @@ /* * COEX_CFG_0 */ -#define COEX_CFG0 0x0040 +#define COEX_CFG0 0x0040 #define COEX_CFG_ANT FIELD32(0xff000000) /* * COEX_CFG_1 */ -#define COEX_CFG1 0x0044 +#define COEX_CFG1 0x0044 /* * COEX_CFG_2 */ -#define COEX_CFG2 0x0048 +#define COEX_CFG2 0x0048 #define BT_COEX_CFG1 FIELD32(0xff000000) #define BT_COEX_CFG0 FIELD32(0x00ff0000) #define WL_COEX_CFG1 FIELD32(0x0000ff00) @@ -237,8 +235,8 @@ #define PLL_RESERVED_INPUT2 FIELD32(0x0000ff00) #define PLL_CONTROL FIELD32(0x00070000) #define PLL_LPF_R1 FIELD32(0x00080000) -#define PLL_LPF_C1_CTRL FIELD32(0x00300000) -#define PLL_LPF_C2_CTRL FIELD32(0x00c00000) +#define PLL_LPF_C1_CTRL FIELD32(0x00300000) +#define PLL_LPF_C2_CTRL FIELD32(0x00c00000) #define PLL_CP_CURRENT_CTRL FIELD32(0x03000000) #define PLL_PFD_DELAY_CTRL FIELD32(0x0c000000) #define PLL_LOCK_CTRL FIELD32(0x70000000) @@ -2166,7 +2164,7 @@ struct mac_iveiv_entry { */ #define RFCSR6_R1 FIELD8(0x03) #define RFCSR6_R2 FIELD8(0x40) -#define RFCSR6_TXDIV FIELD8(0x0c) +#define RFCSR6_TXDIV FIELD8(0x0c) /* bits for RF3053 */ #define RFCSR6_VCO_IC FIELD8(0xc0) @@ -2204,13 +2202,13 @@ struct mac_iveiv_entry { * RFCSR 12: */ #define RFCSR12_TX_POWER FIELD8(0x1f) -#define RFCSR12_DR0 FIELD8(0xe0) +#define RFCSR12_DR0 FIELD8(0xe0) /* * RFCSR 13: */ #define RFCSR13_TX_POWER FIELD8(0x1f) -#define RFCSR13_DR0 FIELD8(0xe0) +#define RFCSR13_DR0 FIELD8(0xe0) /* * RFCSR 15: @@ -2228,7 +2226,7 @@ struct mac_iveiv_entry { #define RFCSR17_TXMIXER_GAIN FIELD8(0x07) #define RFCSR17_TX_LO1_EN FIELD8(0x08) #define RFCSR17_R FIELD8(0x20) -#define RFCSR17_CODE FIELD8(0x7f) +#define RFCSR17_CODE FIELD8(0x7f) /* RFCSR 18 */ #define RFCSR18_XO_TUNE_BYPASS FIELD8(0x40) @@ -2451,7 +2449,7 @@ enum rt2800_eeprom_word { */ #define EEPROM_NIC_CONF0_RXPATH FIELD16(0x000f) #define EEPROM_NIC_CONF0_TXPATH FIELD16(0x00f0) -#define EEPROM_NIC_CONF0_RF_TYPE FIELD16(0x0f00) +#define EEPROM_NIC_CONF0_RF_TYPE FIELD16(0x0f00) /* * EEPROM NIC Configuration 1 @@ -2473,18 +2471,18 @@ enum rt2800_eeprom_word { * DAC_TEST: 0: disable, 1: enable */ #define EEPROM_NIC_CONF1_HW_RADIO FIELD16(0x0001) -#define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC FIELD16(0x0002) -#define EEPROM_NIC_CONF1_EXTERNAL_LNA_2G FIELD16(0x0004) -#define EEPROM_NIC_CONF1_EXTERNAL_LNA_5G FIELD16(0x0008) +#define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC FIELD16(0x0002) +#define EEPROM_NIC_CONF1_EXTERNAL_LNA_2G FIELD16(0x0004) +#define EEPROM_NIC_CONF1_EXTERNAL_LNA_5G FIELD16(0x0008) #define EEPROM_NIC_CONF1_CARDBUS_ACCEL FIELD16(0x0010) #define EEPROM_NIC_CONF1_BW40M_SB_2G FIELD16(0x0020) #define EEPROM_NIC_CONF1_BW40M_SB_5G FIELD16(0x0040) #define EEPROM_NIC_CONF1_WPS_PBC FIELD16(0x0080) #define EEPROM_NIC_CONF1_BW40M_2G FIELD16(0x0100) #define EEPROM_NIC_CONF1_BW40M_5G FIELD16(0x0200) -#define EEPROM_NIC_CONF1_BROADBAND_EXT_LNA FIELD16(0x400) +#define EEPROM_NIC_CONF1_BROADBAND_EXT_LNA FIELD16(0x400) #define EEPROM_NIC_CONF1_ANT_DIVERSITY FIELD16(0x1800) -#define EEPROM_NIC_CONF1_INTERNAL_TX_ALC FIELD16(0x2000) +#define EEPROM_NIC_CONF1_INTERNAL_TX_ALC FIELD16(0x2000) #define EEPROM_NIC_CONF1_BT_COEXIST FIELD16(0x4000) #define EEPROM_NIC_CONF1_DAC_TEST FIELD16(0x8000) @@ -2523,9 +2521,9 @@ enum rt2800_eeprom_word { * TX_STREAM: 0: Reserved, 1: 1 Stream, 2: 2 Stream * CRYSTAL: 00: Reserved, 01: One crystal, 10: Two crystal, 11: Reserved */ -#define EEPROM_NIC_CONF2_RX_STREAM FIELD16(0x000f) -#define EEPROM_NIC_CONF2_TX_STREAM FIELD16(0x00f0) -#define EEPROM_NIC_CONF2_CRYSTAL FIELD16(0x0600) +#define EEPROM_NIC_CONF2_RX_STREAM FIELD16(0x000f) +#define EEPROM_NIC_CONF2_TX_STREAM FIELD16(0x00f0) +#define EEPROM_NIC_CONF2_CRYSTAL FIELD16(0x0600) /* * EEPROM LNA @@ -2792,7 +2790,7 @@ enum rt2800_eeprom_word { #define MCU_CURRENT 0x36 #define MCU_LED 0x50 #define MCU_LED_STRENGTH 0x51 -#define MCU_LED_AG_CONF 0x52 +#define MCU_LED_AG_CONF 0x52 #define MCU_LED_ACT_CONF 0x53 #define MCU_LED_LED_POLARITY 0x54 #define MCU_RADAR 0x60 @@ -2801,7 +2799,7 @@ enum rt2800_eeprom_word { #define MCU_FREQ_OFFSET 0x74 #define MCU_BBP_SIGNAL 0x80 #define MCU_POWER_SAVE 0x83 -#define MCU_BAND_SELECT 0x91 +#define MCU_BAND_SELECT 0x91 /* * MCU mailbox tokens diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 776aff3..88ce656 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -278,9 +278,12 @@ static const unsigned int rt2800_eeprom_map_ext[EEPROM_WORD_COUNT] = { [EEPROM_LNA] = 0x0026, [EEPROM_EXT_LNA2] = 0x0027, [EEPROM_RSSI_BG] = 0x0028, + [EEPROM_TXPOWER_DELTA] = 0x0028, /* Overlaps with RSSI_BG */ [EEPROM_RSSI_BG2] = 0x0029, + [EEPROM_TXMIXER_GAIN_BG] = 0x0029, /* Overlaps with RSSI_BG2 */ [EEPROM_RSSI_A] = 0x002a, [EEPROM_RSSI_A2] = 0x002b, + [EEPROM_TXMIXER_GAIN_A] = 0x002b, /* Overlaps with RSSI_A2 */ [EEPROM_TXPOWER_BG1] = 0x0030, [EEPROM_TXPOWER_BG2] = 0x0037, [EEPROM_EXT_TXPOWER_BG3] = 0x003e, @@ -1780,7 +1783,7 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) rt2800_bbp_read(rt2x00dev, 3, &r3); if (rt2x00_rt(rt2x00dev, RT3572) && - rt2x00_has_cap_bt_coexist(rt2x00dev)) + test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) rt2800_config_3572bt_ant(rt2x00dev); /* @@ -1792,7 +1795,7 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) break; case 2: if (rt2x00_rt(rt2x00dev, RT3572) && - rt2x00_has_cap_bt_coexist(rt2x00dev)) + test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 1); else rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2); @@ -1822,7 +1825,7 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) break; case 2: if (rt2x00_rt(rt2x00dev, RT3572) && - rt2x00_has_cap_bt_coexist(rt2x00dev)) { + test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) { rt2x00_set_field8(&r3, BBP3_RX_ADC, 1); rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); @@ -2026,6 +2029,13 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, rt2x00dev->default_ant.tx_chain_num <= 2); rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); + rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + msleep(1); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset); rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); @@ -2131,7 +2141,7 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0); rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0); rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0); - if (rt2x00_has_cap_bt_coexist(rt2x00dev)) { + if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) { if (rf->channel <= 14) { rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); @@ -2640,7 +2650,7 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, if (rt2x00_rt(rt2x00dev, RT5392)) { rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr); - if (info->default_power2 > POWER_BOUND) + if (info->default_power1 > POWER_BOUND) rt2x00_set_field8(&rfcsr, RFCSR50_TX, POWER_BOUND); else rt2x00_set_field8(&rfcsr, RFCSR50_TX, @@ -2664,7 +2674,7 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, if (rf->channel <= 14) { int idx = rf->channel-1; - if (rt2x00_has_cap_bt_coexist(rt2x00dev)) { + if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) { if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { /* r55/r59 value array of channel 1~14 */ static const char r55_bt_rev[] = {0x83, 0x83, @@ -3142,7 +3152,6 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, case RF3322: rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info); break; - case RF3070: case RF5360: case RF5370: case RF5372: @@ -3157,8 +3166,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); } - if (rt2x00_rf(rt2x00dev, RF3070) || - rt2x00_rf(rt2x00dev, RF3290) || + if (rt2x00_rf(rt2x00dev, RF3290) || rt2x00_rf(rt2x00dev, RF3322) || rt2x00_rf(rt2x00dev, RF5360) || rt2x00_rf(rt2x00dev, RF5370) || @@ -3210,7 +3218,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, if (rf->channel <= 14) { if (!rt2x00_rt(rt2x00dev, RT5390) && !rt2x00_rt(rt2x00dev, RT5392)) { - if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { + if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, + &rt2x00dev->cap_flags)) { rt2800_bbp_write(rt2x00dev, 82, 0x62); rt2800_bbp_write(rt2x00dev, 75, 0x46); } else { @@ -3235,7 +3244,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, if (rt2x00_rt(rt2x00dev, RT3593)) rt2800_bbp_write(rt2x00dev, 83, 0x9a); - if (rt2x00_has_cap_external_lna_a(rt2x00dev)) + if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) rt2800_bbp_write(rt2x00dev, 75, 0x46); else rt2800_bbp_write(rt2x00dev, 75, 0x50); @@ -3271,7 +3280,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, /* Turn on primary PAs */ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, rf->channel > 14); - if (rt2x00_has_cap_bt_coexist(rt2x00dev)) + if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1); else rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, @@ -3302,49 +3311,32 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); - if (rt2x00_rt(rt2x00dev, RT3572)) { + if (rt2x00_rt(rt2x00dev, RT3572)) rt2800_rfcsr_write(rt2x00dev, 8, 0x80); - /* AGC init */ - if (rf->channel <= 14) - reg = 0x1c + (2 * rt2x00dev->lna_gain); - else - reg = 0x22 + ((rt2x00dev->lna_gain * 5) / 3); - - rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); - } - if (rt2x00_rt(rt2x00dev, RT3593)) { - rt2800_register_read(rt2x00dev, GPIO_CTRL, ®); + if (rt2x00_is_usb(rt2x00dev)) { + rt2800_register_read(rt2x00dev, GPIO_CTRL, ®); - /* Band selection */ - if (rt2x00_is_usb(rt2x00dev) || - rt2x00_is_pcie(rt2x00dev)) { - /* GPIO #8 controls all paths */ + /* Band selection. GPIO #8 controls all paths */ rt2x00_set_field32(®, GPIO_CTRL_DIR8, 0); if (rf->channel <= 14) rt2x00_set_field32(®, GPIO_CTRL_VAL8, 1); else rt2x00_set_field32(®, GPIO_CTRL_VAL8, 0); - } - /* LNA PE control. */ - if (rt2x00_is_usb(rt2x00dev)) { - /* GPIO #4 controls PE0 and PE1, - * GPIO #7 controls PE2 - */ rt2x00_set_field32(®, GPIO_CTRL_DIR4, 0); rt2x00_set_field32(®, GPIO_CTRL_DIR7, 0); + /* LNA PE control. + * GPIO #4 controls PE0 and PE1, + * GPIO #7 controls PE2 + */ rt2x00_set_field32(®, GPIO_CTRL_VAL4, 1); rt2x00_set_field32(®, GPIO_CTRL_VAL7, 1); - } else if (rt2x00_is_pcie(rt2x00dev)) { - /* GPIO #4 controls PE0, PE1 and PE2 */ - rt2x00_set_field32(®, GPIO_CTRL_DIR4, 0); - rt2x00_set_field32(®, GPIO_CTRL_VAL4, 1); - } - rt2800_register_write(rt2x00dev, GPIO_CTRL, reg); + rt2800_register_write(rt2x00dev, GPIO_CTRL, reg); + } /* AGC init */ if (rf->channel <= 14) @@ -3573,7 +3565,7 @@ static int rt2800_get_txpower_reg_delta(struct rt2x00_dev *rt2x00dev, { int delta; - if (rt2x00_has_cap_power_limit(rt2x00dev)) + if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) return 0; /* @@ -3602,7 +3594,7 @@ static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b, if (rt2x00_rt(rt2x00dev, RT3593)) return min_t(u8, txpower, 0xc); - if (rt2x00_has_cap_power_limit(rt2x00dev)) { + if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) { /* * Check if eirp txpower exceed txpower_limit. * We use OFDM 6M as criterion and its eirp txpower @@ -4272,7 +4264,6 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); break; case RF3053: - case RF3070: case RF3290: case RF5360: case RF5370: @@ -4414,7 +4405,6 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev) rt2x00_rt(rt2x00dev, RT3290) || rt2x00_rt(rt2x00dev, RT3390) || rt2x00_rt(rt2x00dev, RT3572) || - rt2x00_rt(rt2x00dev, RT3593) || rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392) || rt2x00_rt(rt2x00dev, RT5592)) @@ -4422,8 +4412,8 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev) else vgc = 0x2e + rt2x00dev->lna_gain; } else { /* 5GHZ band */ - if (rt2x00_rt(rt2x00dev, RT3593)) - vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3; + if (rt2x00_rt(rt2x00dev, RT3572)) + vgc = 0x22 + (rt2x00dev->lna_gain * 5) / 3; else if (rt2x00_rt(rt2x00dev, RT5592)) vgc = 0x24 + (2 * rt2x00dev->lna_gain); else { @@ -4441,17 +4431,11 @@ static inline void rt2800_set_vgc(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, u8 vgc_level) { if (qual->vgc_level != vgc_level) { - if (rt2x00_rt(rt2x00dev, RT3572) || - rt2x00_rt(rt2x00dev, RT3593)) { - rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, - vgc_level); - } else if (rt2x00_rt(rt2x00dev, RT5592)) { + if (rt2x00_rt(rt2x00dev, RT5592)) { rt2800_bbp_write(rt2x00dev, 83, qual->rssi > -65 ? 0x4a : 0x7a); rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, vgc_level); - } else { + } else rt2800_bbp_write(rt2x00dev, 66, vgc_level); - } - qual->vgc_level = vgc_level; qual->vgc_level_reg = vgc_level; } @@ -4470,35 +4454,17 @@ void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual, if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) return; - - /* When RSSI is better than a certain threshold, increase VGC - * with a chip specific value in order to improve the balance - * between sensibility and noise isolation. + /* + * When RSSI is better then -80 increase VGC level with 0x10, except + * for rt5592 chip. */ vgc = rt2800_get_default_vgc(rt2x00dev); - switch (rt2x00dev->chip.rt) { - case RT3572: - case RT3593: - if (qual->rssi > -65) { - if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) - vgc += 0x20; - else - vgc += 0x10; - } - break; - - case RT5592: - if (qual->rssi > -65) - vgc += 0x20; - break; - - default: - if (qual->rssi > -80) - vgc += 0x10; - break; - } + if (rt2x00_rt(rt2x00dev, RT5592) && qual->rssi > -65) + vgc += 0x20; + else if (qual->rssi > -80) + vgc += 0x10; rt2800_set_vgc(rt2x00dev, qual, vgc); } @@ -5523,7 +5489,7 @@ static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev) ant = (div_mode == 3) ? 1 : 0; /* check if this is a Bluetooth combo card */ - if (rt2x00_has_cap_bt_coexist(rt2x00dev)) { + if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) { u32 reg; rt2800_register_read(rt2x00dev, GPIO_CTRL, ®); @@ -5832,7 +5798,7 @@ static void rt2800_normal_mode_setup_3xxx(struct rt2x00_dev *rt2x00dev) rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { - if (!rt2x00_has_cap_external_lna_bg(rt2x00dev)) + if (!test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); } @@ -6019,7 +5985,7 @@ static void rt2800_init_rfcsr_30xx(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 20, 0xba); rt2800_rfcsr_write(rt2x00dev, 21, 0xdb); rt2800_rfcsr_write(rt2x00dev, 24, 0x16); - rt2800_rfcsr_write(rt2x00dev, 25, 0x03); + rt2800_rfcsr_write(rt2x00dev, 25, 0x01); rt2800_rfcsr_write(rt2x00dev, 29, 0x1f); if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { @@ -6475,7 +6441,7 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 28, 0x00); rt2800_rfcsr_write(rt2x00dev, 29, 0x10); - rt2800_rfcsr_write(rt2x00dev, 30, 0x10); + rt2800_rfcsr_write(rt2x00dev, 30, 0x00); rt2800_rfcsr_write(rt2x00dev, 31, 0x80); rt2800_rfcsr_write(rt2x00dev, 32, 0x80); rt2800_rfcsr_write(rt2x00dev, 33, 0x00); @@ -6513,7 +6479,7 @@ static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 56, 0x22); rt2800_rfcsr_write(rt2x00dev, 57, 0x80); rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); - rt2800_rfcsr_write(rt2x00dev, 59, 0x8f); + rt2800_rfcsr_write(rt2x00dev, 59, 0x63); rt2800_rfcsr_write(rt2x00dev, 60, 0x45); if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) @@ -6533,6 +6499,7 @@ static void rt2800_init_rfcsr_5392(struct rt2x00_dev *rt2x00dev) rt2800_rf_init_calibration(rt2x00dev, 2); rt2800_rfcsr_write(rt2x00dev, 1, 0x17); + rt2800_rfcsr_write(rt2x00dev, 2, 0x80); rt2800_rfcsr_write(rt2x00dev, 3, 0x88); rt2800_rfcsr_write(rt2x00dev, 5, 0x10); rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); @@ -6686,20 +6653,17 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) u16 word; /* - * Initialize MAC registers. + * Initialize all registers. */ if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) || rt2800_init_registers(rt2x00dev))) return -EIO; - /* - * Wait BBP/RF to wake up. - */ if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev))) return -EIO; /* - * Send signal during boot time to initialize firmware. + * Send signal to firmware during boot time. */ rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); @@ -6708,15 +6672,9 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); msleep(1); - /* - * Make sure BBP is up and running. - */ if (unlikely(rt2800_wait_bbp_ready(rt2x00dev))) return -EIO; - /* - * Initialize BBP/RF registers. - */ rt2800_init_bbp(rt2x00dev); rt2800_init_rfcsr(rt2x00dev); @@ -7063,7 +7021,6 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) case RF3022: case RF3052: case RF3053: - case RF3070: case RF3290: case RF3320: case RF3322: @@ -7246,7 +7203,7 @@ static const struct rf_channel rf_vals[] = { /* * RF value list for rt3xxx - * Supports: 2.4 GHz (all) & 5.2 GHz (RF3052 & RF3053) + * Supports: 2.4 GHz (all) & 5.2 GHz (RF3052) */ static const struct rf_channel rf_vals_3x[] = { {1, 241, 2, 2 }, @@ -7442,6 +7399,72 @@ static const struct rf_channel rf_vals_5592_xtal40[] = { {196, 83, 0, 12, 1}, }; +static const struct rf_channel rf_vals_3053[] = { + /* Channel, N, R, K */ + {1, 241, 2, 2}, + {2, 241, 2, 7}, + {3, 242, 2, 2}, + {4, 242, 2, 7}, + {5, 243, 2, 2}, + {6, 243, 2, 7}, + {7, 244, 2, 2}, + {8, 244, 2, 7}, + {9, 245, 2, 2}, + {10, 245, 2, 7}, + {11, 246, 2, 2}, + {12, 246, 2, 7}, + {13, 247, 2, 2}, + {14, 248, 2, 4}, + + {36, 0x56, 0, 4}, + {38, 0x56, 0, 6}, + {40, 0x56, 0, 8}, + {44, 0x57, 0, 0}, + {46, 0x57, 0, 2}, + {48, 0x57, 0, 4}, + {52, 0x57, 0, 8}, + {54, 0x57, 0, 10}, + {56, 0x58, 0, 0}, + {60, 0x58, 0, 4}, + {62, 0x58, 0, 6}, + {64, 0x58, 0, 8}, + + {100, 0x5B, 0, 8}, + {102, 0x5B, 0, 10}, + {104, 0x5C, 0, 0}, + {108, 0x5C, 0, 4}, + {110, 0x5C, 0, 6}, + {112, 0x5C, 0, 8}, + + /* NOTE: Channel 114 has been removed intentionally. + * The EEPROM contains no TX power values for that, + * and it is disabled in the vendor driver as well. + */ + + {116, 0x5D, 0, 0}, + {118, 0x5D, 0, 2}, + {120, 0x5D, 0, 4}, + {124, 0x5D, 0, 8}, + {126, 0x5D, 0, 10}, + {128, 0x5E, 0, 0}, + {132, 0x5E, 0, 4}, + {134, 0x5E, 0, 6}, + {136, 0x5E, 0, 8}, + {140, 0x5F, 0, 0}, + + {149, 0x5F, 0, 9}, + {151, 0x5F, 0, 11}, + {153, 0x60, 0, 1}, + {157, 0x60, 0, 5}, + {159, 0x60, 0, 7}, + {161, 0x60, 0, 9}, + {165, 0x61, 0, 1}, + {167, 0x61, 0, 3}, + {169, 0x61, 0, 5}, + {171, 0x61, 0, 7}, + {173, 0x61, 0, 9}, +}; + static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) { struct hw_mode_spec *spec = &rt2x00dev->spec; @@ -7450,6 +7473,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) char *default_power2; char *default_power3; unsigned int i; + u16 eeprom; u32 reg; /* @@ -7498,48 +7522,48 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) rt2x00dev->hw->max_report_rates = 7; rt2x00dev->hw->max_rate_tries = 1; + rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); + /* * Initialize hw_mode information. */ + spec->supported_bands = SUPPORT_BAND_2GHZ; spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; - switch (rt2x00dev->chip.rf) { - case RF2720: - case RF2820: + if (rt2x00_rf(rt2x00dev, RF2820) || + rt2x00_rf(rt2x00dev, RF2720)) { spec->num_channels = 14; spec->channels = rf_vals; - break; - - case RF2750: - case RF2850: + } else if (rt2x00_rf(rt2x00dev, RF2850) || + rt2x00_rf(rt2x00dev, RF2750)) { + spec->supported_bands |= SUPPORT_BAND_5GHZ; spec->num_channels = ARRAY_SIZE(rf_vals); spec->channels = rf_vals; - break; - - case RF2020: - case RF3020: - case RF3021: - case RF3022: - case RF3070: - case RF3290: - case RF3320: - case RF3322: - case RF5360: - case RF5370: - case RF5372: - case RF5390: - case RF5392: + } else if (rt2x00_rf(rt2x00dev, RF3020) || + rt2x00_rf(rt2x00dev, RF2020) || + rt2x00_rf(rt2x00dev, RF3021) || + rt2x00_rf(rt2x00dev, RF3022) || + rt2x00_rf(rt2x00dev, RF3290) || + rt2x00_rf(rt2x00dev, RF3320) || + rt2x00_rf(rt2x00dev, RF3322) || + rt2x00_rf(rt2x00dev, RF5360) || + rt2x00_rf(rt2x00dev, RF5370) || + rt2x00_rf(rt2x00dev, RF5372) || + rt2x00_rf(rt2x00dev, RF5390) || + rt2x00_rf(rt2x00dev, RF5392)) { spec->num_channels = 14; spec->channels = rf_vals_3x; - break; - - case RF3052: - case RF3053: + } else if (rt2x00_rf(rt2x00dev, RF3052)) { + spec->supported_bands |= SUPPORT_BAND_5GHZ; spec->num_channels = ARRAY_SIZE(rf_vals_3x); spec->channels = rf_vals_3x; - break; + } else if (rt2x00_rf(rt2x00dev, RF3053)) { + spec->supported_bands |= SUPPORT_BAND_5GHZ; + spec->num_channels = ARRAY_SIZE(rf_vals_3053); + spec->channels = rf_vals_3053; + } else if (rt2x00_rf(rt2x00dev, RF5592)) { + spec->supported_bands |= SUPPORT_BAND_5GHZ; - case RF5592: rt2800_register_read(rt2x00dev, MAC_DEBUG_INDEX, ®); if (rt2x00_get_field32(reg, MAC_DEBUG_INDEX_XTAL)) { spec->num_channels = ARRAY_SIZE(rf_vals_5592_xtal40); @@ -7548,16 +7572,11 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) spec->num_channels = ARRAY_SIZE(rf_vals_5592_xtal20); spec->channels = rf_vals_5592_xtal20; } - break; } if (WARN_ON_ONCE(!spec->channels)) return -ENODEV; - spec->supported_bands = SUPPORT_BAND_2GHZ; - if (spec->num_channels > 14) - spec->supported_bands |= SUPPORT_BAND_5GHZ; - /* * Initialize HT information. */ @@ -7572,21 +7591,22 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40; - if (rt2x00dev->default_ant.tx_chain_num >= 2) + if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) >= 2) spec->ht.cap |= IEEE80211_HT_CAP_TX_STBC; - spec->ht.cap |= rt2x00dev->default_ant.rx_chain_num << - IEEE80211_HT_CAP_RX_STBC_SHIFT; + spec->ht.cap |= + rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH) << + IEEE80211_HT_CAP_RX_STBC_SHIFT; spec->ht.ampdu_factor = 3; spec->ht.ampdu_density = 4; spec->ht.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED | IEEE80211_HT_MCS_TX_RX_DIFF | - ((rt2x00dev->default_ant.tx_chain_num - 1) << - IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); + ((rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH) - 1) << + IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); - switch (rt2x00dev->default_ant.rx_chain_num) { + switch (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH)) { case 3: spec->ht.mcs.rx_mask[2] = 0xff; case 2: @@ -7651,7 +7671,6 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) case RF3320: case RF3052: case RF3053: - case RF3070: case RF3290: case RF5360: case RF5370: diff --git a/drivers/net/wireless/rt2x00/rt2800mmio.c b/drivers/net/wireless/rt2x00/rt2800mmio.c deleted file mode 100644 index a8cc736..0000000 --- a/drivers/net/wireless/rt2x00/rt2800mmio.c +++ /dev/null @@ -1,873 +0,0 @@ -/* Copyright (C) 2009 - 2010 Ivo van Doorn <IvDoorn@gmail.com> - * Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> - * Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> - * Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> - * Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de> - * Copyright (C) 2009 Mark Asselstine <asselsm@gmail.com> - * Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com> - * Copyright (C) 2009 Bart Zolnierkiewicz <bzolnier@gmail.com> - * <http://rt2x00.serialmonkey.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the - * Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* Module: rt2800mmio - * Abstract: rt2800 MMIO device routines. - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/export.h> - -#include "rt2x00.h" -#include "rt2x00mmio.h" -#include "rt2800.h" -#include "rt2800lib.h" -#include "rt2800mmio.h" - -/* - * TX descriptor initialization - */ -__le32 *rt2800mmio_get_txwi(struct queue_entry *entry) -{ - return (__le32 *) entry->skb->data; -} -EXPORT_SYMBOL_GPL(rt2800mmio_get_txwi); - -void rt2800mmio_write_tx_desc(struct queue_entry *entry, - struct txentry_desc *txdesc) -{ - struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); - struct queue_entry_priv_mmio *entry_priv = entry->priv_data; - __le32 *txd = entry_priv->desc; - u32 word; - const unsigned int txwi_size = entry->queue->winfo_size; - - /* - * The buffers pointed by SD_PTR0/SD_LEN0 and SD_PTR1/SD_LEN1 - * must contains a TXWI structure + 802.11 header + padding + 802.11 - * data. We choose to have SD_PTR0/SD_LEN0 only contains TXWI and - * SD_PTR1/SD_LEN1 contains 802.11 header + padding + 802.11 - * data. It means that LAST_SEC0 is always 0. - */ - - /* - * Initialize TX descriptor - */ - word = 0; - rt2x00_set_field32(&word, TXD_W0_SD_PTR0, skbdesc->skb_dma); - rt2x00_desc_write(txd, 0, word); - - word = 0; - rt2x00_set_field32(&word, TXD_W1_SD_LEN1, entry->skb->len); - rt2x00_set_field32(&word, TXD_W1_LAST_SEC1, - !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); - rt2x00_set_field32(&word, TXD_W1_BURST, - test_bit(ENTRY_TXD_BURST, &txdesc->flags)); - rt2x00_set_field32(&word, TXD_W1_SD_LEN0, txwi_size); - rt2x00_set_field32(&word, TXD_W1_LAST_SEC0, 0); - rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0); - rt2x00_desc_write(txd, 1, word); - - word = 0; - rt2x00_set_field32(&word, TXD_W2_SD_PTR1, - skbdesc->skb_dma + txwi_size); - rt2x00_desc_write(txd, 2, word); - - word = 0; - rt2x00_set_field32(&word, TXD_W3_WIV, - !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); - rt2x00_set_field32(&word, TXD_W3_QSEL, 2); - rt2x00_desc_write(txd, 3, word); - - /* - * Register descriptor details in skb frame descriptor. - */ - skbdesc->desc = txd; - skbdesc->desc_len = TXD_DESC_SIZE; -} -EXPORT_SYMBOL_GPL(rt2800mmio_write_tx_desc); - -/* - * RX control handlers - */ -void rt2800mmio_fill_rxdone(struct queue_entry *entry, - struct rxdone_entry_desc *rxdesc) -{ - struct queue_entry_priv_mmio *entry_priv = entry->priv_data; - __le32 *rxd = entry_priv->desc; - u32 word; - - rt2x00_desc_read(rxd, 3, &word); - - if (rt2x00_get_field32(word, RXD_W3_CRC_ERROR)) - rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; - - /* - * Unfortunately we don't know the cipher type used during - * decryption. This prevents us from correct providing - * correct statistics through debugfs. - */ - rxdesc->cipher_status = rt2x00_get_field32(word, RXD_W3_CIPHER_ERROR); - - if (rt2x00_get_field32(word, RXD_W3_DECRYPTED)) { - /* - * Hardware has stripped IV/EIV data from 802.11 frame during - * decryption. Unfortunately the descriptor doesn't contain - * any fields with the EIV/IV data either, so they can't - * be restored by rt2x00lib. - */ - rxdesc->flags |= RX_FLAG_IV_STRIPPED; - - /* - * The hardware has already checked the Michael Mic and has - * stripped it from the frame. Signal this to mac80211. - */ - rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; - - if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) - rxdesc->flags |= RX_FLAG_DECRYPTED; - else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) - rxdesc->flags |= RX_FLAG_MMIC_ERROR; - } - - if (rt2x00_get_field32(word, RXD_W3_MY_BSS)) - rxdesc->dev_flags |= RXDONE_MY_BSS; - - if (rt2x00_get_field32(word, RXD_W3_L2PAD)) - rxdesc->dev_flags |= RXDONE_L2PAD; - - /* - * Process the RXWI structure that is at the start of the buffer. - */ - rt2800_process_rxwi(entry, rxdesc); -} -EXPORT_SYMBOL_GPL(rt2800mmio_fill_rxdone); - -/* - * Interrupt functions. - */ -static void rt2800mmio_wakeup(struct rt2x00_dev *rt2x00dev) -{ - struct ieee80211_conf conf = { .flags = 0 }; - struct rt2x00lib_conf libconf = { .conf = &conf }; - - rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); -} - -static bool rt2800mmio_txdone_entry_check(struct queue_entry *entry, u32 status) -{ - __le32 *txwi; - u32 word; - int wcid, tx_wcid; - - wcid = rt2x00_get_field32(status, TX_STA_FIFO_WCID); - - txwi = rt2800_drv_get_txwi(entry); - rt2x00_desc_read(txwi, 1, &word); - tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); - - return (tx_wcid == wcid); -} - -static bool rt2800mmio_txdone_find_entry(struct queue_entry *entry, void *data) -{ - u32 status = *(u32 *)data; - - /* - * rt2800pci hardware might reorder frames when exchanging traffic - * with multiple BA enabled STAs. - * - * For example, a tx queue - * [ STA1 | STA2 | STA1 | STA2 ] - * can result in tx status reports - * [ STA1 | STA1 | STA2 | STA2 ] - * when the hw decides to aggregate the frames for STA1 into one AMPDU. - * - * To mitigate this effect, associate the tx status to the first frame - * in the tx queue with a matching wcid. - */ - if (rt2800mmio_txdone_entry_check(entry, status) && - !test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) { - /* - * Got a matching frame, associate the tx status with - * the frame - */ - entry->status = status; - set_bit(ENTRY_DATA_STATUS_SET, &entry->flags); - return true; - } - - /* Check the next frame */ - return false; -} - -static bool rt2800mmio_txdone_match_first(struct queue_entry *entry, void *data) -{ - u32 status = *(u32 *)data; - - /* - * Find the first frame without tx status and assign this status to it - * regardless if it matches or not. - */ - if (!test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) { - /* - * Got a matching frame, associate the tx status with - * the frame - */ - entry->status = status; - set_bit(ENTRY_DATA_STATUS_SET, &entry->flags); - return true; - } - - /* Check the next frame */ - return false; -} -static bool rt2800mmio_txdone_release_entries(struct queue_entry *entry, - void *data) -{ - if (test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) { - rt2800_txdone_entry(entry, entry->status, - rt2800mmio_get_txwi(entry)); - return false; - } - - /* No more frames to release */ - return true; -} - -static bool rt2800mmio_txdone(struct rt2x00_dev *rt2x00dev) -{ - struct data_queue *queue; - u32 status; - u8 qid; - int max_tx_done = 16; - - while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) { - qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE); - if (unlikely(qid >= QID_RX)) { - /* - * Unknown queue, this shouldn't happen. Just drop - * this tx status. - */ - rt2x00_warn(rt2x00dev, "Got TX status report with unexpected pid %u, dropping\n", - qid); - break; - } - - queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); - if (unlikely(queue == NULL)) { - /* - * The queue is NULL, this shouldn't happen. Stop - * processing here and drop the tx status - */ - rt2x00_warn(rt2x00dev, "Got TX status for an unavailable queue %u, dropping\n", - qid); - break; - } - - if (unlikely(rt2x00queue_empty(queue))) { - /* - * The queue is empty. Stop processing here - * and drop the tx status. - */ - rt2x00_warn(rt2x00dev, "Got TX status for an empty queue %u, dropping\n", - qid); - break; - } - - /* - * Let's associate this tx status with the first - * matching frame. - */ - if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, - Q_INDEX, &status, - rt2800mmio_txdone_find_entry)) { - /* - * We cannot match the tx status to any frame, so just - * use the first one. - */ - if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, - Q_INDEX, &status, - rt2800mmio_txdone_match_first)) { - rt2x00_warn(rt2x00dev, "No frame found for TX status on queue %u, dropping\n", - qid); - break; - } - } - - /* - * Release all frames with a valid tx status. - */ - rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, - Q_INDEX, NULL, - rt2800mmio_txdone_release_entries); - - if (--max_tx_done == 0) - break; - } - - return !max_tx_done; -} - -static inline void rt2800mmio_enable_interrupt(struct rt2x00_dev *rt2x00dev, - struct rt2x00_field32 irq_field) -{ - u32 reg; - - /* - * Enable a single interrupt. The interrupt mask register - * access needs locking. - */ - spin_lock_irq(&rt2x00dev->irqmask_lock); - rt2x00mmio_register_read(rt2x00dev, INT_MASK_CSR, ®); - rt2x00_set_field32(®, irq_field, 1); - rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); - spin_unlock_irq(&rt2x00dev->irqmask_lock); -} - -void rt2800mmio_txstatus_tasklet(unsigned long data) -{ - struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; - if (rt2800mmio_txdone(rt2x00dev)) - tasklet_schedule(&rt2x00dev->txstatus_tasklet); - - /* - * No need to enable the tx status interrupt here as we always - * leave it enabled to minimize the possibility of a tx status - * register overflow. See comment in interrupt handler. - */ -} -EXPORT_SYMBOL_GPL(rt2800mmio_txstatus_tasklet); - -void rt2800mmio_pretbtt_tasklet(unsigned long data) -{ - struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; - rt2x00lib_pretbtt(rt2x00dev); - if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2800mmio_enable_interrupt(rt2x00dev, INT_MASK_CSR_PRE_TBTT); -} -EXPORT_SYMBOL_GPL(rt2800mmio_pretbtt_tasklet); - -void rt2800mmio_tbtt_tasklet(unsigned long data) -{ - struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; - struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; - u32 reg; - - rt2x00lib_beacondone(rt2x00dev); - - if (rt2x00dev->intf_ap_count) { - /* - * The rt2800pci hardware tbtt timer is off by 1us per tbtt - * causing beacon skew and as a result causing problems with - * some powersaving clients over time. Shorten the beacon - * interval every 64 beacons by 64us to mitigate this effect. - */ - if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 2)) { - rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®); - rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, - (rt2x00dev->beacon_int * 16) - 1); - rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg); - } else if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 1)) { - rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®); - rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, - (rt2x00dev->beacon_int * 16)); - rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg); - } - drv_data->tbtt_tick++; - drv_data->tbtt_tick %= BCN_TBTT_OFFSET; - } - - if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2800mmio_enable_interrupt(rt2x00dev, INT_MASK_CSR_TBTT); -} -EXPORT_SYMBOL_GPL(rt2800mmio_tbtt_tasklet); - -void rt2800mmio_rxdone_tasklet(unsigned long data) -{ - struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; - if (rt2x00mmio_rxdone(rt2x00dev)) - tasklet_schedule(&rt2x00dev->rxdone_tasklet); - else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2800mmio_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE); -} -EXPORT_SYMBOL_GPL(rt2800mmio_rxdone_tasklet); - -void rt2800mmio_autowake_tasklet(unsigned long data) -{ - struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; - rt2800mmio_wakeup(rt2x00dev); - if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - rt2800mmio_enable_interrupt(rt2x00dev, - INT_MASK_CSR_AUTO_WAKEUP); -} -EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet); - -static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) -{ - u32 status; - int i; - - /* - * The TX_FIFO_STATUS interrupt needs special care. We should - * read TX_STA_FIFO but we should do it immediately as otherwise - * the register can overflow and we would lose status reports. - * - * Hence, read the TX_STA_FIFO register and copy all tx status - * reports into a kernel FIFO which is handled in the txstatus - * tasklet. We use a tasklet to process the tx status reports - * because we can schedule the tasklet multiple times (when the - * interrupt fires again during tx status processing). - * - * Furthermore we don't disable the TX_FIFO_STATUS - * interrupt here but leave it enabled so that the TX_STA_FIFO - * can also be read while the tx status tasklet gets executed. - * - * Since we have only one producer and one consumer we don't - * need to lock the kfifo. - */ - for (i = 0; i < rt2x00dev->tx->limit; i++) { - rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status); - - if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) - break; - - if (!kfifo_put(&rt2x00dev->txstatus_fifo, status)) { - rt2x00_warn(rt2x00dev, "TX status FIFO overrun, drop tx status report\n"); - break; - } - } - - /* Schedule the tasklet for processing the tx status. */ - tasklet_schedule(&rt2x00dev->txstatus_tasklet); -} - -irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance) -{ - struct rt2x00_dev *rt2x00dev = dev_instance; - u32 reg, mask; - - /* Read status and ACK all interrupts */ - rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, ®); - rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg); - - if (!reg) - return IRQ_NONE; - - if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) - return IRQ_HANDLED; - - /* - * Since INT_MASK_CSR and INT_SOURCE_CSR use the same bits - * for interrupts and interrupt masks we can just use the value of - * INT_SOURCE_CSR to create the interrupt mask. - */ - mask = ~reg; - - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) { - rt2800mmio_txstatus_interrupt(rt2x00dev); - /* - * Never disable the TX_FIFO_STATUS interrupt. - */ - rt2x00_set_field32(&mask, INT_MASK_CSR_TX_FIFO_STATUS, 1); - } - - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT)) - tasklet_hi_schedule(&rt2x00dev->pretbtt_tasklet); - - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT)) - tasklet_hi_schedule(&rt2x00dev->tbtt_tasklet); - - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE)) - tasklet_schedule(&rt2x00dev->rxdone_tasklet); - - if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) - tasklet_schedule(&rt2x00dev->autowake_tasklet); - - /* - * Disable all interrupts for which a tasklet was scheduled right now, - * the tasklet will reenable the appropriate interrupts. - */ - spin_lock(&rt2x00dev->irqmask_lock); - rt2x00mmio_register_read(rt2x00dev, INT_MASK_CSR, ®); - reg &= mask; - rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); - spin_unlock(&rt2x00dev->irqmask_lock); - - return IRQ_HANDLED; -} -EXPORT_SYMBOL_GPL(rt2800mmio_interrupt); - -void rt2800mmio_toggle_irq(struct rt2x00_dev *rt2x00dev, - enum dev_state state) -{ - u32 reg; - unsigned long flags; - - /* - * When interrupts are being enabled, the interrupt registers - * should clear the register to assure a clean state. - */ - if (state == STATE_RADIO_IRQ_ON) { - rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, ®); - rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg); - } - - spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); - reg = 0; - if (state == STATE_RADIO_IRQ_ON) { - rt2x00_set_field32(®, INT_MASK_CSR_RX_DONE, 1); - rt2x00_set_field32(®, INT_MASK_CSR_TBTT, 1); - rt2x00_set_field32(®, INT_MASK_CSR_PRE_TBTT, 1); - rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, 1); - rt2x00_set_field32(®, INT_MASK_CSR_AUTO_WAKEUP, 1); - } - rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); - spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); - - if (state == STATE_RADIO_IRQ_OFF) { - /* - * Wait for possibly running tasklets to finish. - */ - tasklet_kill(&rt2x00dev->txstatus_tasklet); - tasklet_kill(&rt2x00dev->rxdone_tasklet); - tasklet_kill(&rt2x00dev->autowake_tasklet); - tasklet_kill(&rt2x00dev->tbtt_tasklet); - tasklet_kill(&rt2x00dev->pretbtt_tasklet); - } -} -EXPORT_SYMBOL_GPL(rt2800mmio_toggle_irq); - -/* - * Queue handlers. - */ -void rt2800mmio_start_queue(struct data_queue *queue) -{ - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - u32 reg; - - switch (queue->qid) { - case QID_RX: - rt2x00mmio_register_read(rt2x00dev, MAC_SYS_CTRL, ®); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); - rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg); - break; - case QID_BEACON: - rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®); - rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); - rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); - rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); - rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg); - - rt2x00mmio_register_read(rt2x00dev, INT_TIMER_EN, ®); - rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 1); - rt2x00mmio_register_write(rt2x00dev, INT_TIMER_EN, reg); - break; - default: - break; - } -} -EXPORT_SYMBOL_GPL(rt2800mmio_start_queue); - -void rt2800mmio_kick_queue(struct data_queue *queue) -{ - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - struct queue_entry *entry; - - switch (queue->qid) { - case QID_AC_VO: - case QID_AC_VI: - case QID_AC_BE: - case QID_AC_BK: - entry = rt2x00queue_get_entry(queue, Q_INDEX); - rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), - entry->entry_idx); - break; - case QID_MGMT: - entry = rt2x00queue_get_entry(queue, Q_INDEX); - rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(5), - entry->entry_idx); - break; - default: - break; - } -} -EXPORT_SYMBOL_GPL(rt2800mmio_kick_queue); - -void rt2800mmio_stop_queue(struct data_queue *queue) -{ - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - u32 reg; - - switch (queue->qid) { - case QID_RX: - rt2x00mmio_register_read(rt2x00dev, MAC_SYS_CTRL, ®); - rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); - rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg); - break; - case QID_BEACON: - rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®); - rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); - rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); - rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); - rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg); - - rt2x00mmio_register_read(rt2x00dev, INT_TIMER_EN, ®); - rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 0); - rt2x00mmio_register_write(rt2x00dev, INT_TIMER_EN, reg); - - /* - * Wait for current invocation to finish. The tasklet - * won't be scheduled anymore afterwards since we disabled - * the TBTT and PRE TBTT timer. - */ - tasklet_kill(&rt2x00dev->tbtt_tasklet); - tasklet_kill(&rt2x00dev->pretbtt_tasklet); - - break; - default: - break; - } -} -EXPORT_SYMBOL_GPL(rt2800mmio_stop_queue); - -void rt2800mmio_queue_init(struct data_queue *queue) -{ - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; - unsigned short txwi_size, rxwi_size; - - rt2800_get_txwi_rxwi_size(rt2x00dev, &txwi_size, &rxwi_size); - - switch (queue->qid) { - case QID_RX: - queue->limit = 128; - queue->data_size = AGGREGATION_SIZE; - queue->desc_size = RXD_DESC_SIZE; - queue->winfo_size = rxwi_size; - queue->priv_size = sizeof(struct queue_entry_priv_mmio); - break; - - case QID_AC_VO: - case QID_AC_VI: - case QID_AC_BE: - case QID_AC_BK: - queue->limit = 64; - queue->data_size = AGGREGATION_SIZE; - queue->desc_size = TXD_DESC_SIZE; - queue->winfo_size = txwi_size; - queue->priv_size = sizeof(struct queue_entry_priv_mmio); - break; - - case QID_BEACON: - queue->limit = 8; - queue->data_size = 0; /* No DMA required for beacons */ - queue->desc_size = TXD_DESC_SIZE; - queue->winfo_size = txwi_size; - queue->priv_size = sizeof(struct queue_entry_priv_mmio); - break; - - case QID_ATIM: - /* fallthrough */ - default: - BUG(); - break; - } -} -EXPORT_SYMBOL_GPL(rt2800mmio_queue_init); - -/* - * Initialization functions. - */ -bool rt2800mmio_get_entry_state(struct queue_entry *entry) -{ - struct queue_entry_priv_mmio *entry_priv = entry->priv_data; - u32 word; - - if (entry->queue->qid == QID_RX) { - rt2x00_desc_read(entry_priv->desc, 1, &word); - - return (!rt2x00_get_field32(word, RXD_W1_DMA_DONE)); - } else { - rt2x00_desc_read(entry_priv->desc, 1, &word); - - return (!rt2x00_get_field32(word, TXD_W1_DMA_DONE)); - } -} -EXPORT_SYMBOL_GPL(rt2800mmio_get_entry_state); - -void rt2800mmio_clear_entry(struct queue_entry *entry) -{ - struct queue_entry_priv_mmio *entry_priv = entry->priv_data; - struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; - u32 word; - - if (entry->queue->qid == QID_RX) { - rt2x00_desc_read(entry_priv->desc, 0, &word); - rt2x00_set_field32(&word, RXD_W0_SDP0, skbdesc->skb_dma); - rt2x00_desc_write(entry_priv->desc, 0, word); - - rt2x00_desc_read(entry_priv->desc, 1, &word); - rt2x00_set_field32(&word, RXD_W1_DMA_DONE, 0); - rt2x00_desc_write(entry_priv->desc, 1, word); - - /* - * Set RX IDX in register to inform hardware that we have - * handled this entry and it is available for reuse again. - */ - rt2x00mmio_register_write(rt2x00dev, RX_CRX_IDX, - entry->entry_idx); - } else { - rt2x00_desc_read(entry_priv->desc, 1, &word); - rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1); - rt2x00_desc_write(entry_priv->desc, 1, word); - } -} -EXPORT_SYMBOL_GPL(rt2800mmio_clear_entry); - -int rt2800mmio_init_queues(struct rt2x00_dev *rt2x00dev) -{ - struct queue_entry_priv_mmio *entry_priv; - - /* - * Initialize registers. - */ - entry_priv = rt2x00dev->tx[0].entries[0].priv_data; - rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR0, - entry_priv->desc_dma); - rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT0, - rt2x00dev->tx[0].limit); - rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX0, 0); - rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX0, 0); - - entry_priv = rt2x00dev->tx[1].entries[0].priv_data; - rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR1, - entry_priv->desc_dma); - rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT1, - rt2x00dev->tx[1].limit); - rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX1, 0); - rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX1, 0); - - entry_priv = rt2x00dev->tx[2].entries[0].priv_data; - rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR2, - entry_priv->desc_dma); - rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT2, - rt2x00dev->tx[2].limit); - rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX2, 0); - rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX2, 0); - - entry_priv = rt2x00dev->tx[3].entries[0].priv_data; - rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR3, - entry_priv->desc_dma); - rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT3, - rt2x00dev->tx[3].limit); - rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX3, 0); - rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX3, 0); - - rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR4, 0); - rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT4, 0); - rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX4, 0); - rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX4, 0); - - rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR5, 0); - rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT5, 0); - rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX5, 0); - rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX5, 0); - - entry_priv = rt2x00dev->rx->entries[0].priv_data; - rt2x00mmio_register_write(rt2x00dev, RX_BASE_PTR, - entry_priv->desc_dma); - rt2x00mmio_register_write(rt2x00dev, RX_MAX_CNT, - rt2x00dev->rx[0].limit); - rt2x00mmio_register_write(rt2x00dev, RX_CRX_IDX, - rt2x00dev->rx[0].limit - 1); - rt2x00mmio_register_write(rt2x00dev, RX_DRX_IDX, 0); - - rt2800_disable_wpdma(rt2x00dev); - - rt2x00mmio_register_write(rt2x00dev, DELAY_INT_CFG, 0); - - return 0; -} -EXPORT_SYMBOL_GPL(rt2800mmio_init_queues); - -int rt2800mmio_init_registers(struct rt2x00_dev *rt2x00dev) -{ - u32 reg; - - /* - * Reset DMA indexes - */ - rt2x00mmio_register_read(rt2x00dev, WPDMA_RST_IDX, ®); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX4, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX5, 1); - rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); - rt2x00mmio_register_write(rt2x00dev, WPDMA_RST_IDX, reg); - - rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); - rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); - - if (rt2x00_is_pcie(rt2x00dev) && - (rt2x00_rt(rt2x00dev, RT3090) || - rt2x00_rt(rt2x00dev, RT3390) || - rt2x00_rt(rt2x00dev, RT3572) || - rt2x00_rt(rt2x00dev, RT3593) || - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392) || - rt2x00_rt(rt2x00dev, RT5592))) { - rt2x00mmio_register_read(rt2x00dev, AUX_CTRL, ®); - rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); - rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); - rt2x00mmio_register_write(rt2x00dev, AUX_CTRL, reg); - } - - rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); - - reg = 0; - rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); - rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); - rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg); - - rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); - - return 0; -} -EXPORT_SYMBOL_GPL(rt2800mmio_init_registers); - -/* - * Device state switch handlers. - */ -int rt2800mmio_enable_radio(struct rt2x00_dev *rt2x00dev) -{ - /* Wait for DMA, ignore error until we initialize queues. */ - rt2800_wait_wpdma_ready(rt2x00dev); - - if (unlikely(rt2800mmio_init_queues(rt2x00dev))) - return -EIO; - - return rt2800_enable_radio(rt2x00dev); -} -EXPORT_SYMBOL_GPL(rt2800mmio_enable_radio); - -MODULE_AUTHOR(DRV_PROJECT); -MODULE_VERSION(DRV_VERSION); -MODULE_DESCRIPTION("rt2800 MMIO library"); -MODULE_LICENSE("GPL"); diff --git a/drivers/net/wireless/rt2x00/rt2800mmio.h b/drivers/net/wireless/rt2x00/rt2800mmio.h deleted file mode 100644 index 6a10de3..0000000 --- a/drivers/net/wireless/rt2x00/rt2800mmio.h +++ /dev/null @@ -1,165 +0,0 @@ -/* Copyright (C) 2009 - 2010 Ivo van Doorn <IvDoorn@gmail.com> - * Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> - * Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> - * Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> - * Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de> - * Copyright (C) 2009 Mark Asselstine <asselsm@gmail.com> - * Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com> - * Copyright (C) 2009 Bart Zolnierkiewicz <bzolnier@gmail.com> - * <http://rt2x00.serialmonkey.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the - * Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* Module: rt2800mmio - * Abstract: forward declarations for the rt2800mmio module. - */ - -#ifndef RT2800MMIO_H -#define RT2800MMIO_H - -/* - * Queue register offset macros - */ -#define TX_QUEUE_REG_OFFSET 0x10 -#define TX_BASE_PTR(__x) (TX_BASE_PTR0 + ((__x) * TX_QUEUE_REG_OFFSET)) -#define TX_MAX_CNT(__x) (TX_MAX_CNT0 + ((__x) * TX_QUEUE_REG_OFFSET)) -#define TX_CTX_IDX(__x) (TX_CTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET)) -#define TX_DTX_IDX(__x) (TX_DTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET)) - -/* - * DMA descriptor defines. - */ -#define TXD_DESC_SIZE (4 * sizeof(__le32)) -#define RXD_DESC_SIZE (4 * sizeof(__le32)) - -/* - * TX descriptor format for TX, PRIO and Beacon Ring. - */ - -/* - * Word0 - */ -#define TXD_W0_SD_PTR0 FIELD32(0xffffffff) - -/* - * Word1 - */ -#define TXD_W1_SD_LEN1 FIELD32(0x00003fff) -#define TXD_W1_LAST_SEC1 FIELD32(0x00004000) -#define TXD_W1_BURST FIELD32(0x00008000) -#define TXD_W1_SD_LEN0 FIELD32(0x3fff0000) -#define TXD_W1_LAST_SEC0 FIELD32(0x40000000) -#define TXD_W1_DMA_DONE FIELD32(0x80000000) - -/* - * Word2 - */ -#define TXD_W2_SD_PTR1 FIELD32(0xffffffff) - -/* - * Word3 - * WIV: Wireless Info Valid. 1: Driver filled WI, 0: DMA needs to copy WI - * QSEL: Select on-chip FIFO ID for 2nd-stage output scheduler. - * 0:MGMT, 1:HCCA 2:EDCA - */ -#define TXD_W3_WIV FIELD32(0x01000000) -#define TXD_W3_QSEL FIELD32(0x06000000) -#define TXD_W3_TCO FIELD32(0x20000000) -#define TXD_W3_UCO FIELD32(0x40000000) -#define TXD_W3_ICO FIELD32(0x80000000) - -/* - * RX descriptor format for RX Ring. - */ - -/* - * Word0 - */ -#define RXD_W0_SDP0 FIELD32(0xffffffff) - -/* - * Word1 - */ -#define RXD_W1_SDL1 FIELD32(0x00003fff) -#define RXD_W1_SDL0 FIELD32(0x3fff0000) -#define RXD_W1_LS0 FIELD32(0x40000000) -#define RXD_W1_DMA_DONE FIELD32(0x80000000) - -/* - * Word2 - */ -#define RXD_W2_SDP1 FIELD32(0xffffffff) - -/* - * Word3 - * AMSDU: RX with 802.3 header, not 802.11 header. - * DECRYPTED: This frame is being decrypted. - */ -#define RXD_W3_BA FIELD32(0x00000001) -#define RXD_W3_DATA FIELD32(0x00000002) -#define RXD_W3_NULLDATA FIELD32(0x00000004) -#define RXD_W3_FRAG FIELD32(0x00000008) -#define RXD_W3_UNICAST_TO_ME FIELD32(0x00000010) -#define RXD_W3_MULTICAST FIELD32(0x00000020) -#define RXD_W3_BROADCAST FIELD32(0x00000040) -#define RXD_W3_MY_BSS FIELD32(0x00000080) -#define RXD_W3_CRC_ERROR FIELD32(0x00000100) -#define RXD_W3_CIPHER_ERROR FIELD32(0x00000600) -#define RXD_W3_AMSDU FIELD32(0x00000800) -#define RXD_W3_HTC FIELD32(0x00001000) -#define RXD_W3_RSSI FIELD32(0x00002000) -#define RXD_W3_L2PAD FIELD32(0x00004000) -#define RXD_W3_AMPDU FIELD32(0x00008000) -#define RXD_W3_DECRYPTED FIELD32(0x00010000) -#define RXD_W3_PLCP_SIGNAL FIELD32(0x00020000) -#define RXD_W3_PLCP_RSSI FIELD32(0x00040000) - -/* TX descriptor initialization */ -__le32 *rt2800mmio_get_txwi(struct queue_entry *entry); -void rt2800mmio_write_tx_desc(struct queue_entry *entry, - struct txentry_desc *txdesc); - -/* RX control handlers */ -void rt2800mmio_fill_rxdone(struct queue_entry *entry, - struct rxdone_entry_desc *rxdesc); - -/* Interrupt functions */ -void rt2800mmio_txstatus_tasklet(unsigned long data); -void rt2800mmio_pretbtt_tasklet(unsigned long data); -void rt2800mmio_tbtt_tasklet(unsigned long data); -void rt2800mmio_rxdone_tasklet(unsigned long data); -void rt2800mmio_autowake_tasklet(unsigned long data); -irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance); -void rt2800mmio_toggle_irq(struct rt2x00_dev *rt2x00dev, - enum dev_state state); - -/* Queue handlers */ -void rt2800mmio_start_queue(struct data_queue *queue); -void rt2800mmio_kick_queue(struct data_queue *queue); -void rt2800mmio_stop_queue(struct data_queue *queue); -void rt2800mmio_queue_init(struct data_queue *queue); - -/* Initialization functions */ -bool rt2800mmio_get_entry_state(struct queue_entry *entry); -void rt2800mmio_clear_entry(struct queue_entry *entry); -int rt2800mmio_init_queues(struct rt2x00_dev *rt2x00dev); -int rt2800mmio_init_registers(struct rt2x00_dev *rt2x00dev); - -/* Device state switch handlers. */ -int rt2800mmio_enable_radio(struct rt2x00_dev *rt2x00dev); - -#endif /* RT2800MMIO_H */ diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index b504455..f8f2abb 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -37,13 +37,14 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> +#include <linux/platform_device.h> #include <linux/eeprom_93cx6.h> #include "rt2x00.h" #include "rt2x00mmio.h" #include "rt2x00pci.h" +#include "rt2x00soc.h" #include "rt2800lib.h" -#include "rt2800mmio.h" #include "rt2800.h" #include "rt2800pci.h" @@ -89,6 +90,27 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token) rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); } +#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) +static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) +{ + void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE); + + if (!base_addr) + return -ENOMEM; + + memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE); + + iounmap(base_addr); + return 0; +} +#else +static inline int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) +{ + return -ENOMEM; +} +#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */ + +#ifdef CONFIG_PCI static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom) { struct rt2x00_dev *rt2x00dev = eeprom->data; @@ -161,6 +183,112 @@ static inline int rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) { return rt2800_read_eeprom_efuse(rt2x00dev); } +#else +static inline int rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev) +{ + return -EOPNOTSUPP; +} + +static inline int rt2800pci_efuse_detect(struct rt2x00_dev *rt2x00dev) +{ + return 0; +} + +static inline int rt2800pci_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev) +{ + return -EOPNOTSUPP; +} +#endif /* CONFIG_PCI */ + +/* + * Queue handlers. + */ +static void rt2800pci_start_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + switch (queue->qid) { + case QID_RX: + rt2x00mmio_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 1); + rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + break; + case QID_BEACON: + rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); + rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); + rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg); + + rt2x00mmio_register_read(rt2x00dev, INT_TIMER_EN, ®); + rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 1); + rt2x00mmio_register_write(rt2x00dev, INT_TIMER_EN, reg); + break; + default: + break; + } +} + +static void rt2800pci_kick_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + struct queue_entry *entry; + + switch (queue->qid) { + case QID_AC_VO: + case QID_AC_VI: + case QID_AC_BE: + case QID_AC_BK: + entry = rt2x00queue_get_entry(queue, Q_INDEX); + rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), + entry->entry_idx); + break; + case QID_MGMT: + entry = rt2x00queue_get_entry(queue, Q_INDEX); + rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(5), + entry->entry_idx); + break; + default: + break; + } +} + +static void rt2800pci_stop_queue(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + u32 reg; + + switch (queue->qid) { + case QID_RX: + rt2x00mmio_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + rt2x00_set_field32(®, MAC_SYS_CTRL_ENABLE_RX, 0); + rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + break; + case QID_BEACON: + rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 0); + rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 0); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); + rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg); + + rt2x00mmio_register_read(rt2x00dev, INT_TIMER_EN, ®); + rt2x00_set_field32(®, INT_TIMER_EN_PRE_TBTT_TIMER, 0); + rt2x00mmio_register_write(rt2x00dev, INT_TIMER_EN, reg); + + /* + * Wait for current invocation to finish. The tasklet + * won't be scheduled anymore afterwards since we disabled + * the TBTT and PRE TBTT timer. + */ + tasklet_kill(&rt2x00dev->tbtt_tasklet); + tasklet_kill(&rt2x00dev->pretbtt_tasklet); + + break; + default: + break; + } +} /* * Firmware functions @@ -204,13 +332,217 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, } /* + * Initialization functions. + */ +static bool rt2800pci_get_entry_state(struct queue_entry *entry) +{ + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; + u32 word; + + if (entry->queue->qid == QID_RX) { + rt2x00_desc_read(entry_priv->desc, 1, &word); + + return (!rt2x00_get_field32(word, RXD_W1_DMA_DONE)); + } else { + rt2x00_desc_read(entry_priv->desc, 1, &word); + + return (!rt2x00_get_field32(word, TXD_W1_DMA_DONE)); + } +} + +static void rt2800pci_clear_entry(struct queue_entry *entry) +{ + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + u32 word; + + if (entry->queue->qid == QID_RX) { + rt2x00_desc_read(entry_priv->desc, 0, &word); + rt2x00_set_field32(&word, RXD_W0_SDP0, skbdesc->skb_dma); + rt2x00_desc_write(entry_priv->desc, 0, word); + + rt2x00_desc_read(entry_priv->desc, 1, &word); + rt2x00_set_field32(&word, RXD_W1_DMA_DONE, 0); + rt2x00_desc_write(entry_priv->desc, 1, word); + + /* + * Set RX IDX in register to inform hardware that we have + * handled this entry and it is available for reuse again. + */ + rt2x00mmio_register_write(rt2x00dev, RX_CRX_IDX, + entry->entry_idx); + } else { + rt2x00_desc_read(entry_priv->desc, 1, &word); + rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1); + rt2x00_desc_write(entry_priv->desc, 1, word); + } +} + +static int rt2800pci_init_queues(struct rt2x00_dev *rt2x00dev) +{ + struct queue_entry_priv_mmio *entry_priv; + + /* + * Initialize registers. + */ + entry_priv = rt2x00dev->tx[0].entries[0].priv_data; + rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR0, + entry_priv->desc_dma); + rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT0, + rt2x00dev->tx[0].limit); + rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX0, 0); + rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX0, 0); + + entry_priv = rt2x00dev->tx[1].entries[0].priv_data; + rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR1, + entry_priv->desc_dma); + rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT1, + rt2x00dev->tx[1].limit); + rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX1, 0); + rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX1, 0); + + entry_priv = rt2x00dev->tx[2].entries[0].priv_data; + rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR2, + entry_priv->desc_dma); + rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT2, + rt2x00dev->tx[2].limit); + rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX2, 0); + rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX2, 0); + + entry_priv = rt2x00dev->tx[3].entries[0].priv_data; + rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR3, + entry_priv->desc_dma); + rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT3, + rt2x00dev->tx[3].limit); + rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX3, 0); + rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX3, 0); + + rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR4, 0); + rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT4, 0); + rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX4, 0); + rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX4, 0); + + rt2x00mmio_register_write(rt2x00dev, TX_BASE_PTR5, 0); + rt2x00mmio_register_write(rt2x00dev, TX_MAX_CNT5, 0); + rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX5, 0); + rt2x00mmio_register_write(rt2x00dev, TX_DTX_IDX5, 0); + + entry_priv = rt2x00dev->rx->entries[0].priv_data; + rt2x00mmio_register_write(rt2x00dev, RX_BASE_PTR, + entry_priv->desc_dma); + rt2x00mmio_register_write(rt2x00dev, RX_MAX_CNT, + rt2x00dev->rx[0].limit); + rt2x00mmio_register_write(rt2x00dev, RX_CRX_IDX, + rt2x00dev->rx[0].limit - 1); + rt2x00mmio_register_write(rt2x00dev, RX_DRX_IDX, 0); + + rt2800_disable_wpdma(rt2x00dev); + + rt2x00mmio_register_write(rt2x00dev, DELAY_INT_CFG, 0); + + return 0; +} + +/* * Device state switch handlers. */ +static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, + enum dev_state state) +{ + u32 reg; + unsigned long flags; + + /* + * When interrupts are being enabled, the interrupt registers + * should clear the register to assure a clean state. + */ + if (state == STATE_RADIO_IRQ_ON) { + rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, ®); + rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg); + } + + spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); + reg = 0; + if (state == STATE_RADIO_IRQ_ON) { + rt2x00_set_field32(®, INT_MASK_CSR_RX_DONE, 1); + rt2x00_set_field32(®, INT_MASK_CSR_TBTT, 1); + rt2x00_set_field32(®, INT_MASK_CSR_PRE_TBTT, 1); + rt2x00_set_field32(®, INT_MASK_CSR_TX_FIFO_STATUS, 1); + rt2x00_set_field32(®, INT_MASK_CSR_AUTO_WAKEUP, 1); + } + rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); + spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + + if (state == STATE_RADIO_IRQ_OFF) { + /* + * Wait for possibly running tasklets to finish. + */ + tasklet_kill(&rt2x00dev->txstatus_tasklet); + tasklet_kill(&rt2x00dev->rxdone_tasklet); + tasklet_kill(&rt2x00dev->autowake_tasklet); + tasklet_kill(&rt2x00dev->tbtt_tasklet); + tasklet_kill(&rt2x00dev->pretbtt_tasklet); + } +} + +static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) +{ + u32 reg; + + /* + * Reset DMA indexes + */ + rt2x00mmio_register_read(rt2x00dev, WPDMA_RST_IDX, ®); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, 1); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, 1); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, 1); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, 1); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX4, 1); + rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX5, 1); + rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); + rt2x00mmio_register_write(rt2x00dev, WPDMA_RST_IDX, reg); + + rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); + rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); + + if (rt2x00_is_pcie(rt2x00dev) && + (rt2x00_rt(rt2x00dev, RT3090) || + rt2x00_rt(rt2x00dev, RT3390) || + rt2x00_rt(rt2x00dev, RT3572) || + rt2x00_rt(rt2x00dev, RT3593) || + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392) || + rt2x00_rt(rt2x00dev, RT5592))) { + rt2x00mmio_register_read(rt2x00dev, AUX_CTRL, ®); + rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); + rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); + rt2x00mmio_register_write(rt2x00dev, AUX_CTRL, reg); + } + + rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); + + reg = 0; + rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); + rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); + rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, reg); + + rt2x00mmio_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); + + return 0; +} + static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) { int retval; - retval = rt2800mmio_enable_radio(rt2x00dev); + /* Wait for DMA, ignore error until we initialize queues. */ + rt2800_wait_wpdma_ready(rt2x00dev); + + if (unlikely(rt2800pci_init_queues(rt2x00dev))) + return -EIO; + + retval = rt2800_enable_radio(rt2x00dev); if (retval) return retval; @@ -227,6 +559,15 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) return retval; } +static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev) +{ + if (rt2x00_is_soc(rt2x00dev)) { + rt2800_disable_radio(rt2x00dev); + rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0); + rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0); + } +} + static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) { @@ -260,11 +601,12 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, * After the radio has been disabled, the device should * be put to sleep for powersaving. */ + rt2800pci_disable_radio(rt2x00dev); rt2800pci_set_state(rt2x00dev, STATE_SLEEP); break; case STATE_RADIO_IRQ_ON: case STATE_RADIO_IRQ_OFF: - rt2800mmio_toggle_irq(rt2x00dev, state); + rt2800pci_toggle_irq(rt2x00dev, state); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: @@ -285,13 +627,479 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, } /* + * TX descriptor initialization + */ +static __le32 *rt2800pci_get_txwi(struct queue_entry *entry) +{ + return (__le32 *) entry->skb->data; +} + +static void rt2800pci_write_tx_desc(struct queue_entry *entry, + struct txentry_desc *txdesc) +{ + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; + __le32 *txd = entry_priv->desc; + u32 word; + const unsigned int txwi_size = entry->queue->winfo_size; + + /* + * The buffers pointed by SD_PTR0/SD_LEN0 and SD_PTR1/SD_LEN1 + * must contains a TXWI structure + 802.11 header + padding + 802.11 + * data. We choose to have SD_PTR0/SD_LEN0 only contains TXWI and + * SD_PTR1/SD_LEN1 contains 802.11 header + padding + 802.11 + * data. It means that LAST_SEC0 is always 0. + */ + + /* + * Initialize TX descriptor + */ + word = 0; + rt2x00_set_field32(&word, TXD_W0_SD_PTR0, skbdesc->skb_dma); + rt2x00_desc_write(txd, 0, word); + + word = 0; + rt2x00_set_field32(&word, TXD_W1_SD_LEN1, entry->skb->len); + rt2x00_set_field32(&word, TXD_W1_LAST_SEC1, + !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); + rt2x00_set_field32(&word, TXD_W1_BURST, + test_bit(ENTRY_TXD_BURST, &txdesc->flags)); + rt2x00_set_field32(&word, TXD_W1_SD_LEN0, txwi_size); + rt2x00_set_field32(&word, TXD_W1_LAST_SEC0, 0); + rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0); + rt2x00_desc_write(txd, 1, word); + + word = 0; + rt2x00_set_field32(&word, TXD_W2_SD_PTR1, + skbdesc->skb_dma + txwi_size); + rt2x00_desc_write(txd, 2, word); + + word = 0; + rt2x00_set_field32(&word, TXD_W3_WIV, + !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); + rt2x00_set_field32(&word, TXD_W3_QSEL, 2); + rt2x00_desc_write(txd, 3, word); + + /* + * Register descriptor details in skb frame descriptor. + */ + skbdesc->desc = txd; + skbdesc->desc_len = TXD_DESC_SIZE; +} + +/* + * RX control handlers + */ +static void rt2800pci_fill_rxdone(struct queue_entry *entry, + struct rxdone_entry_desc *rxdesc) +{ + struct queue_entry_priv_mmio *entry_priv = entry->priv_data; + __le32 *rxd = entry_priv->desc; + u32 word; + + rt2x00_desc_read(rxd, 3, &word); + + if (rt2x00_get_field32(word, RXD_W3_CRC_ERROR)) + rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; + + /* + * Unfortunately we don't know the cipher type used during + * decryption. This prevents us from correct providing + * correct statistics through debugfs. + */ + rxdesc->cipher_status = rt2x00_get_field32(word, RXD_W3_CIPHER_ERROR); + + if (rt2x00_get_field32(word, RXD_W3_DECRYPTED)) { + /* + * Hardware has stripped IV/EIV data from 802.11 frame during + * decryption. Unfortunately the descriptor doesn't contain + * any fields with the EIV/IV data either, so they can't + * be restored by rt2x00lib. + */ + rxdesc->flags |= RX_FLAG_IV_STRIPPED; + + /* + * The hardware has already checked the Michael Mic and has + * stripped it from the frame. Signal this to mac80211. + */ + rxdesc->flags |= RX_FLAG_MMIC_STRIPPED; + + if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) + rxdesc->flags |= RX_FLAG_DECRYPTED; + else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) + rxdesc->flags |= RX_FLAG_MMIC_ERROR; + } + + if (rt2x00_get_field32(word, RXD_W3_MY_BSS)) + rxdesc->dev_flags |= RXDONE_MY_BSS; + + if (rt2x00_get_field32(word, RXD_W3_L2PAD)) + rxdesc->dev_flags |= RXDONE_L2PAD; + + /* + * Process the RXWI structure that is at the start of the buffer. + */ + rt2800_process_rxwi(entry, rxdesc); +} + +/* + * Interrupt functions. + */ +static void rt2800pci_wakeup(struct rt2x00_dev *rt2x00dev) +{ + struct ieee80211_conf conf = { .flags = 0 }; + struct rt2x00lib_conf libconf = { .conf = &conf }; + + rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); +} + +static bool rt2800pci_txdone_entry_check(struct queue_entry *entry, u32 status) +{ + __le32 *txwi; + u32 word; + int wcid, tx_wcid; + + wcid = rt2x00_get_field32(status, TX_STA_FIFO_WCID); + + txwi = rt2800_drv_get_txwi(entry); + rt2x00_desc_read(txwi, 1, &word); + tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); + + return (tx_wcid == wcid); +} + +static bool rt2800pci_txdone_find_entry(struct queue_entry *entry, void *data) +{ + u32 status = *(u32 *)data; + + /* + * rt2800pci hardware might reorder frames when exchanging traffic + * with multiple BA enabled STAs. + * + * For example, a tx queue + * [ STA1 | STA2 | STA1 | STA2 ] + * can result in tx status reports + * [ STA1 | STA1 | STA2 | STA2 ] + * when the hw decides to aggregate the frames for STA1 into one AMPDU. + * + * To mitigate this effect, associate the tx status to the first frame + * in the tx queue with a matching wcid. + */ + if (rt2800pci_txdone_entry_check(entry, status) && + !test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) { + /* + * Got a matching frame, associate the tx status with + * the frame + */ + entry->status = status; + set_bit(ENTRY_DATA_STATUS_SET, &entry->flags); + return true; + } + + /* Check the next frame */ + return false; +} + +static bool rt2800pci_txdone_match_first(struct queue_entry *entry, void *data) +{ + u32 status = *(u32 *)data; + + /* + * Find the first frame without tx status and assign this status to it + * regardless if it matches or not. + */ + if (!test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) { + /* + * Got a matching frame, associate the tx status with + * the frame + */ + entry->status = status; + set_bit(ENTRY_DATA_STATUS_SET, &entry->flags); + return true; + } + + /* Check the next frame */ + return false; +} +static bool rt2800pci_txdone_release_entries(struct queue_entry *entry, + void *data) +{ + if (test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) { + rt2800_txdone_entry(entry, entry->status, + rt2800pci_get_txwi(entry)); + return false; + } + + /* No more frames to release */ + return true; +} + +static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) +{ + struct data_queue *queue; + u32 status; + u8 qid; + int max_tx_done = 16; + + while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) { + qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE); + if (unlikely(qid >= QID_RX)) { + /* + * Unknown queue, this shouldn't happen. Just drop + * this tx status. + */ + rt2x00_warn(rt2x00dev, "Got TX status report with unexpected pid %u, dropping\n", + qid); + break; + } + + queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); + if (unlikely(queue == NULL)) { + /* + * The queue is NULL, this shouldn't happen. Stop + * processing here and drop the tx status + */ + rt2x00_warn(rt2x00dev, "Got TX status for an unavailable queue %u, dropping\n", + qid); + break; + } + + if (unlikely(rt2x00queue_empty(queue))) { + /* + * The queue is empty. Stop processing here + * and drop the tx status. + */ + rt2x00_warn(rt2x00dev, "Got TX status for an empty queue %u, dropping\n", + qid); + break; + } + + /* + * Let's associate this tx status with the first + * matching frame. + */ + if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, + Q_INDEX, &status, + rt2800pci_txdone_find_entry)) { + /* + * We cannot match the tx status to any frame, so just + * use the first one. + */ + if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, + Q_INDEX, &status, + rt2800pci_txdone_match_first)) { + rt2x00_warn(rt2x00dev, "No frame found for TX status on queue %u, dropping\n", + qid); + break; + } + } + + /* + * Release all frames with a valid tx status. + */ + rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, + Q_INDEX, NULL, + rt2800pci_txdone_release_entries); + + if (--max_tx_done == 0) + break; + } + + return !max_tx_done; +} + +static inline void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev, + struct rt2x00_field32 irq_field) +{ + u32 reg; + + /* + * Enable a single interrupt. The interrupt mask register + * access needs locking. + */ + spin_lock_irq(&rt2x00dev->irqmask_lock); + rt2x00mmio_register_read(rt2x00dev, INT_MASK_CSR, ®); + rt2x00_set_field32(®, irq_field, 1); + rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); + spin_unlock_irq(&rt2x00dev->irqmask_lock); +} + +static void rt2800pci_txstatus_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + if (rt2800pci_txdone(rt2x00dev)) + tasklet_schedule(&rt2x00dev->txstatus_tasklet); + + /* + * No need to enable the tx status interrupt here as we always + * leave it enabled to minimize the possibility of a tx status + * register overflow. See comment in interrupt handler. + */ +} + +static void rt2800pci_pretbtt_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + rt2x00lib_pretbtt(rt2x00dev); + if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_PRE_TBTT); +} + +static void rt2800pci_tbtt_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; + u32 reg; + + rt2x00lib_beacondone(rt2x00dev); + + if (rt2x00dev->intf_ap_count) { + /* + * The rt2800pci hardware tbtt timer is off by 1us per tbtt + * causing beacon skew and as a result causing problems with + * some powersaving clients over time. Shorten the beacon + * interval every 64 beacons by 64us to mitigate this effect. + */ + if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 2)) { + rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, + (rt2x00dev->beacon_int * 16) - 1); + rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg); + } else if (drv_data->tbtt_tick == (BCN_TBTT_OFFSET - 1)) { + rt2x00mmio_register_read(rt2x00dev, BCN_TIME_CFG, ®); + rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_INTERVAL, + (rt2x00dev->beacon_int * 16)); + rt2x00mmio_register_write(rt2x00dev, BCN_TIME_CFG, reg); + } + drv_data->tbtt_tick++; + drv_data->tbtt_tick %= BCN_TBTT_OFFSET; + } + + if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_TBTT); +} + +static void rt2800pci_rxdone_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + if (rt2x00mmio_rxdone(rt2x00dev)) + tasklet_schedule(&rt2x00dev->rxdone_tasklet); + else if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE); +} + +static void rt2800pci_autowake_tasklet(unsigned long data) +{ + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + rt2800pci_wakeup(rt2x00dev); + if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_AUTO_WAKEUP); +} + +static void rt2800pci_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) +{ + u32 status; + int i; + + /* + * The TX_FIFO_STATUS interrupt needs special care. We should + * read TX_STA_FIFO but we should do it immediately as otherwise + * the register can overflow and we would lose status reports. + * + * Hence, read the TX_STA_FIFO register and copy all tx status + * reports into a kernel FIFO which is handled in the txstatus + * tasklet. We use a tasklet to process the tx status reports + * because we can schedule the tasklet multiple times (when the + * interrupt fires again during tx status processing). + * + * Furthermore we don't disable the TX_FIFO_STATUS + * interrupt here but leave it enabled so that the TX_STA_FIFO + * can also be read while the tx status tasklet gets executed. + * + * Since we have only one producer and one consumer we don't + * need to lock the kfifo. + */ + for (i = 0; i < rt2x00dev->tx->limit; i++) { + rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO, &status); + + if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) + break; + + if (!kfifo_put(&rt2x00dev->txstatus_fifo, &status)) { + rt2x00_warn(rt2x00dev, "TX status FIFO overrun, drop tx status report\n"); + break; + } + } + + /* Schedule the tasklet for processing the tx status. */ + tasklet_schedule(&rt2x00dev->txstatus_tasklet); +} + +static irqreturn_t rt2800pci_interrupt(int irq, void *dev_instance) +{ + struct rt2x00_dev *rt2x00dev = dev_instance; + u32 reg, mask; + + /* Read status and ACK all interrupts */ + rt2x00mmio_register_read(rt2x00dev, INT_SOURCE_CSR, ®); + rt2x00mmio_register_write(rt2x00dev, INT_SOURCE_CSR, reg); + + if (!reg) + return IRQ_NONE; + + if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + return IRQ_HANDLED; + + /* + * Since INT_MASK_CSR and INT_SOURCE_CSR use the same bits + * for interrupts and interrupt masks we can just use the value of + * INT_SOURCE_CSR to create the interrupt mask. + */ + mask = ~reg; + + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) { + rt2800pci_txstatus_interrupt(rt2x00dev); + /* + * Never disable the TX_FIFO_STATUS interrupt. + */ + rt2x00_set_field32(&mask, INT_MASK_CSR_TX_FIFO_STATUS, 1); + } + + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT)) + tasklet_hi_schedule(&rt2x00dev->pretbtt_tasklet); + + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TBTT)) + tasklet_hi_schedule(&rt2x00dev->tbtt_tasklet); + + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_RX_DONE)) + tasklet_schedule(&rt2x00dev->rxdone_tasklet); + + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_AUTO_WAKEUP)) + tasklet_schedule(&rt2x00dev->autowake_tasklet); + + /* + * Disable all interrupts for which a tasklet was scheduled right now, + * the tasklet will reenable the appropriate interrupts. + */ + spin_lock(&rt2x00dev->irqmask_lock); + rt2x00mmio_register_read(rt2x00dev, INT_MASK_CSR, ®); + reg &= mask; + rt2x00mmio_register_write(rt2x00dev, INT_MASK_CSR, reg); + spin_unlock(&rt2x00dev->irqmask_lock); + + return IRQ_HANDLED; +} + +/* * Device probe functions. */ static int rt2800pci_read_eeprom(struct rt2x00_dev *rt2x00dev) { int retval; - if (rt2800pci_efuse_detect(rt2x00dev)) + if (rt2x00_is_soc(rt2x00dev)) + retval = rt2800pci_read_eeprom_soc(rt2x00dev); + else if (rt2800pci_efuse_detect(rt2x00dev)) retval = rt2800pci_read_eeprom_efuse(rt2x00dev); else retval = rt2800pci_read_eeprom_pci(rt2x00dev); @@ -337,25 +1145,25 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = { .read_eeprom = rt2800pci_read_eeprom, .hwcrypt_disabled = rt2800pci_hwcrypt_disabled, .drv_write_firmware = rt2800pci_write_firmware, - .drv_init_registers = rt2800mmio_init_registers, - .drv_get_txwi = rt2800mmio_get_txwi, + .drv_init_registers = rt2800pci_init_registers, + .drv_get_txwi = rt2800pci_get_txwi, }; static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { - .irq_handler = rt2800mmio_interrupt, - .txstatus_tasklet = rt2800mmio_txstatus_tasklet, - .pretbtt_tasklet = rt2800mmio_pretbtt_tasklet, - .tbtt_tasklet = rt2800mmio_tbtt_tasklet, - .rxdone_tasklet = rt2800mmio_rxdone_tasklet, - .autowake_tasklet = rt2800mmio_autowake_tasklet, + .irq_handler = rt2800pci_interrupt, + .txstatus_tasklet = rt2800pci_txstatus_tasklet, + .pretbtt_tasklet = rt2800pci_pretbtt_tasklet, + .tbtt_tasklet = rt2800pci_tbtt_tasklet, + .rxdone_tasklet = rt2800pci_rxdone_tasklet, + .autowake_tasklet = rt2800pci_autowake_tasklet, .probe_hw = rt2800_probe_hw, .get_firmware_name = rt2800pci_get_firmware_name, .check_firmware = rt2800_check_firmware, .load_firmware = rt2800_load_firmware, .initialize = rt2x00mmio_initialize, .uninitialize = rt2x00mmio_uninitialize, - .get_entry_state = rt2800mmio_get_entry_state, - .clear_entry = rt2800mmio_clear_entry, + .get_entry_state = rt2800pci_get_entry_state, + .clear_entry = rt2800pci_clear_entry, .set_device_state = rt2800pci_set_device_state, .rfkill_poll = rt2800_rfkill_poll, .link_stats = rt2800_link_stats, @@ -363,15 +1171,15 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .link_tuner = rt2800_link_tuner, .gain_calibration = rt2800_gain_calibration, .vco_calibration = rt2800_vco_calibration, - .start_queue = rt2800mmio_start_queue, - .kick_queue = rt2800mmio_kick_queue, - .stop_queue = rt2800mmio_stop_queue, + .start_queue = rt2800pci_start_queue, + .kick_queue = rt2800pci_kick_queue, + .stop_queue = rt2800pci_stop_queue, .flush_queue = rt2x00mmio_flush_queue, - .write_tx_desc = rt2800mmio_write_tx_desc, + .write_tx_desc = rt2800pci_write_tx_desc, .write_tx_data = rt2800_write_tx_data, .write_beacon = rt2800_write_beacon, .clear_beacon = rt2800_clear_beacon, - .fill_rxdone = rt2800mmio_fill_rxdone, + .fill_rxdone = rt2800pci_fill_rxdone, .config_shared_key = rt2800_config_shared_key, .config_pairwise_key = rt2800_config_pairwise_key, .config_filter = rt2800_config_filter, @@ -383,6 +1191,49 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { .sta_remove = rt2800_sta_remove, }; +static void rt2800pci_queue_init(struct data_queue *queue) +{ + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + unsigned short txwi_size, rxwi_size; + + rt2800_get_txwi_rxwi_size(rt2x00dev, &txwi_size, &rxwi_size); + + switch (queue->qid) { + case QID_RX: + queue->limit = 128; + queue->data_size = AGGREGATION_SIZE; + queue->desc_size = RXD_DESC_SIZE; + queue->winfo_size = rxwi_size; + queue->priv_size = sizeof(struct queue_entry_priv_mmio); + break; + + case QID_AC_VO: + case QID_AC_VI: + case QID_AC_BE: + case QID_AC_BK: + queue->limit = 64; + queue->data_size = AGGREGATION_SIZE; + queue->desc_size = TXD_DESC_SIZE; + queue->winfo_size = txwi_size; + queue->priv_size = sizeof(struct queue_entry_priv_mmio); + break; + + case QID_BEACON: + queue->limit = 8; + queue->data_size = 0; /* No DMA required for beacons */ + queue->desc_size = TXD_DESC_SIZE; + queue->winfo_size = txwi_size; + queue->priv_size = sizeof(struct queue_entry_priv_mmio); + break; + + case QID_ATIM: + /* fallthrough */ + default: + BUG(); + break; + } +} + static const struct rt2x00_ops rt2800pci_ops = { .name = KBUILD_MODNAME, .drv_data_size = sizeof(struct rt2800_drv_data), @@ -390,7 +1241,7 @@ static const struct rt2x00_ops rt2800pci_ops = { .eeprom_size = EEPROM_SIZE, .rf_size = RF_SIZE, .tx_queues = NUM_TX_QUEUES, - .queue_init = rt2800mmio_queue_init, + .queue_init = rt2800pci_queue_init, .lib = &rt2800pci_rt2x00_ops, .drv = &rt2800pci_rt2800_ops, .hw = &rt2800pci_mac80211_ops, @@ -402,6 +1253,7 @@ static const struct rt2x00_ops rt2800pci_ops = { /* * RT2800pci module information. */ +#ifdef CONFIG_PCI static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { { PCI_DEVICE(0x1814, 0x0601) }, { PCI_DEVICE(0x1814, 0x0681) }, @@ -446,15 +1298,38 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { #endif { 0, } }; +#endif /* CONFIG_PCI */ MODULE_AUTHOR(DRV_PROJECT); MODULE_VERSION(DRV_VERSION); MODULE_DESCRIPTION("Ralink RT2800 PCI & PCMCIA Wireless LAN driver."); MODULE_SUPPORTED_DEVICE("Ralink RT2860 PCI & PCMCIA chipset based cards"); +#ifdef CONFIG_PCI MODULE_FIRMWARE(FIRMWARE_RT2860); MODULE_DEVICE_TABLE(pci, rt2800pci_device_table); +#endif /* CONFIG_PCI */ MODULE_LICENSE("GPL"); +#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) +static int rt2800soc_probe(struct platform_device *pdev) +{ + return rt2x00soc_probe(pdev, &rt2800pci_ops); +} + +static struct platform_driver rt2800soc_driver = { + .driver = { + .name = "rt2800_wmac", + .owner = THIS_MODULE, + .mod_name = KBUILD_MODNAME, + }, + .probe = rt2800soc_probe, + .remove = rt2x00soc_remove, + .suspend = rt2x00soc_suspend, + .resume = rt2x00soc_resume, +}; +#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */ + +#ifdef CONFIG_PCI static int rt2800pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) { @@ -469,5 +1344,39 @@ static struct pci_driver rt2800pci_driver = { .suspend = rt2x00pci_suspend, .resume = rt2x00pci_resume, }; +#endif /* CONFIG_PCI */ + +static int __init rt2800pci_init(void) +{ + int ret = 0; + +#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) + ret = platform_driver_register(&rt2800soc_driver); + if (ret) + return ret; +#endif +#ifdef CONFIG_PCI + ret = pci_register_driver(&rt2800pci_driver); + if (ret) { +#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) + platform_driver_unregister(&rt2800soc_driver); +#endif + return ret; + } +#endif + + return ret; +} + +static void __exit rt2800pci_exit(void) +{ +#ifdef CONFIG_PCI + pci_unregister_driver(&rt2800pci_driver); +#endif +#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) + platform_driver_unregister(&rt2800soc_driver); +#endif +} -module_pci_driver(rt2800pci_driver); +module_init(rt2800pci_init); +module_exit(rt2800pci_exit); diff --git a/drivers/net/wireless/rt2x00/rt2800pci.h b/drivers/net/wireless/rt2x00/rt2800pci.h index a81c9ee..ab22a08 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.h +++ b/drivers/net/wireless/rt2x00/rt2800pci.h @@ -35,10 +35,107 @@ #define RT2800PCI_H /* + * Queue register offset macros + */ +#define TX_QUEUE_REG_OFFSET 0x10 +#define TX_BASE_PTR(__x) (TX_BASE_PTR0 + ((__x) * TX_QUEUE_REG_OFFSET)) +#define TX_MAX_CNT(__x) (TX_MAX_CNT0 + ((__x) * TX_QUEUE_REG_OFFSET)) +#define TX_CTX_IDX(__x) (TX_CTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET)) +#define TX_DTX_IDX(__x) (TX_DTX_IDX0 + ((__x) * TX_QUEUE_REG_OFFSET)) + +/* * 8051 firmware image. */ #define FIRMWARE_RT2860 "rt2860.bin" #define FIRMWARE_RT3290 "rt3290.bin" #define FIRMWARE_IMAGE_BASE 0x2000 +/* + * DMA descriptor defines. + */ +#define TXD_DESC_SIZE (4 * sizeof(__le32)) +#define RXD_DESC_SIZE (4 * sizeof(__le32)) + +/* + * TX descriptor format for TX, PRIO and Beacon Ring. + */ + +/* + * Word0 + */ +#define TXD_W0_SD_PTR0 FIELD32(0xffffffff) + +/* + * Word1 + */ +#define TXD_W1_SD_LEN1 FIELD32(0x00003fff) +#define TXD_W1_LAST_SEC1 FIELD32(0x00004000) +#define TXD_W1_BURST FIELD32(0x00008000) +#define TXD_W1_SD_LEN0 FIELD32(0x3fff0000) +#define TXD_W1_LAST_SEC0 FIELD32(0x40000000) +#define TXD_W1_DMA_DONE FIELD32(0x80000000) + +/* + * Word2 + */ +#define TXD_W2_SD_PTR1 FIELD32(0xffffffff) + +/* + * Word3 + * WIV: Wireless Info Valid. 1: Driver filled WI, 0: DMA needs to copy WI + * QSEL: Select on-chip FIFO ID for 2nd-stage output scheduler. + * 0:MGMT, 1:HCCA 2:EDCA + */ +#define TXD_W3_WIV FIELD32(0x01000000) +#define TXD_W3_QSEL FIELD32(0x06000000) +#define TXD_W3_TCO FIELD32(0x20000000) +#define TXD_W3_UCO FIELD32(0x40000000) +#define TXD_W3_ICO FIELD32(0x80000000) + +/* + * RX descriptor format for RX Ring. + */ + +/* + * Word0 + */ +#define RXD_W0_SDP0 FIELD32(0xffffffff) + +/* + * Word1 + */ +#define RXD_W1_SDL1 FIELD32(0x00003fff) +#define RXD_W1_SDL0 FIELD32(0x3fff0000) +#define RXD_W1_LS0 FIELD32(0x40000000) +#define RXD_W1_DMA_DONE FIELD32(0x80000000) + +/* + * Word2 + */ +#define RXD_W2_SDP1 FIELD32(0xffffffff) + +/* + * Word3 + * AMSDU: RX with 802.3 header, not 802.11 header. + * DECRYPTED: This frame is being decrypted. + */ +#define RXD_W3_BA FIELD32(0x00000001) +#define RXD_W3_DATA FIELD32(0x00000002) +#define RXD_W3_NULLDATA FIELD32(0x00000004) +#define RXD_W3_FRAG FIELD32(0x00000008) +#define RXD_W3_UNICAST_TO_ME FIELD32(0x00000010) +#define RXD_W3_MULTICAST FIELD32(0x00000020) +#define RXD_W3_BROADCAST FIELD32(0x00000040) +#define RXD_W3_MY_BSS FIELD32(0x00000080) +#define RXD_W3_CRC_ERROR FIELD32(0x00000100) +#define RXD_W3_CIPHER_ERROR FIELD32(0x00000600) +#define RXD_W3_AMSDU FIELD32(0x00000800) +#define RXD_W3_HTC FIELD32(0x00001000) +#define RXD_W3_RSSI FIELD32(0x00002000) +#define RXD_W3_L2PAD FIELD32(0x00004000) +#define RXD_W3_AMPDU FIELD32(0x00008000) +#define RXD_W3_DECRYPTED FIELD32(0x00010000) +#define RXD_W3_PLCP_SIGNAL FIELD32(0x00020000) +#define RXD_W3_PLCP_RSSI FIELD32(0x00040000) + #endif /* RT2800PCI_H */ diff --git a/drivers/net/wireless/rt2x00/rt2800soc.c b/drivers/net/wireless/rt2x00/rt2800soc.c deleted file mode 100644 index 1359227..0000000 --- a/drivers/net/wireless/rt2x00/rt2800soc.c +++ /dev/null @@ -1,263 +0,0 @@ -/* Copyright (C) 2009 - 2010 Ivo van Doorn <IvDoorn@gmail.com> - * Copyright (C) 2009 Alban Browaeys <prahal@yahoo.com> - * Copyright (C) 2009 Felix Fietkau <nbd@openwrt.org> - * Copyright (C) 2009 Luis Correia <luis.f.correia@gmail.com> - * Copyright (C) 2009 Mattias Nissler <mattias.nissler@gmx.de> - * Copyright (C) 2009 Mark Asselstine <asselsm@gmail.com> - * Copyright (C) 2009 Xose Vazquez Perez <xose.vazquez@gmail.com> - * Copyright (C) 2009 Bart Zolnierkiewicz <bzolnier@gmail.com> - * <http://rt2x00.serialmonkey.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the - * Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* Module: rt2800soc - * Abstract: rt2800 WiSoC specific routines. - */ - -#include <linux/etherdevice.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> - -#include "rt2x00.h" -#include "rt2x00mmio.h" -#include "rt2x00soc.h" -#include "rt2800.h" -#include "rt2800lib.h" -#include "rt2800mmio.h" - -/* Allow hardware encryption to be disabled. */ -static bool modparam_nohwcrypt; -module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); -MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); - -static bool rt2800soc_hwcrypt_disabled(struct rt2x00_dev *rt2x00dev) -{ - return modparam_nohwcrypt; -} - -static void rt2800soc_disable_radio(struct rt2x00_dev *rt2x00dev) -{ - rt2800_disable_radio(rt2x00dev); - rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0); - rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0); -} - -static int rt2800soc_set_device_state(struct rt2x00_dev *rt2x00dev, - enum dev_state state) -{ - int retval = 0; - - switch (state) { - case STATE_RADIO_ON: - retval = rt2800mmio_enable_radio(rt2x00dev); - break; - - case STATE_RADIO_OFF: - rt2800soc_disable_radio(rt2x00dev); - break; - - case STATE_RADIO_IRQ_ON: - case STATE_RADIO_IRQ_OFF: - rt2800mmio_toggle_irq(rt2x00dev, state); - break; - - case STATE_DEEP_SLEEP: - case STATE_SLEEP: - case STATE_STANDBY: - case STATE_AWAKE: - /* These states are not supported, but don't report an error */ - retval = 0; - break; - - default: - retval = -ENOTSUPP; - break; - } - - if (unlikely(retval)) - rt2x00_err(rt2x00dev, "Device failed to enter state %d (%d)\n", - state, retval); - - return retval; -} - -static int rt2800soc_read_eeprom(struct rt2x00_dev *rt2x00dev) -{ - void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE); - - if (!base_addr) - return -ENOMEM; - - memcpy_fromio(rt2x00dev->eeprom, base_addr, EEPROM_SIZE); - - iounmap(base_addr); - return 0; -} - -/* Firmware functions */ -static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev) -{ - WARN_ON_ONCE(1); - return NULL; -} - -static int rt2800soc_load_firmware(struct rt2x00_dev *rt2x00dev, - const u8 *data, const size_t len) -{ - WARN_ON_ONCE(1); - return 0; -} - -static int rt2800soc_check_firmware(struct rt2x00_dev *rt2x00dev, - const u8 *data, const size_t len) -{ - WARN_ON_ONCE(1); - return 0; -} - -static int rt2800soc_write_firmware(struct rt2x00_dev *rt2x00dev, - const u8 *data, const size_t len) -{ - WARN_ON_ONCE(1); - return 0; -} - -static const struct ieee80211_ops rt2800soc_mac80211_ops = { - .tx = rt2x00mac_tx, - .start = rt2x00mac_start, - .stop = rt2x00mac_stop, - .add_interface = rt2x00mac_add_interface, - .remove_interface = rt2x00mac_remove_interface, - .config = rt2x00mac_config, - .configure_filter = rt2x00mac_configure_filter, - .set_key = rt2x00mac_set_key, - .sw_scan_start = rt2x00mac_sw_scan_start, - .sw_scan_complete = rt2x00mac_sw_scan_complete, - .get_stats = rt2x00mac_get_stats, - .get_tkip_seq = rt2800_get_tkip_seq, - .set_rts_threshold = rt2800_set_rts_threshold, - .sta_add = rt2x00mac_sta_add, - .sta_remove = rt2x00mac_sta_remove, - .bss_info_changed = rt2x00mac_bss_info_changed, - .conf_tx = rt2800_conf_tx, - .get_tsf = rt2800_get_tsf, - .rfkill_poll = rt2x00mac_rfkill_poll, - .ampdu_action = rt2800_ampdu_action, - .flush = rt2x00mac_flush, - .get_survey = rt2800_get_survey, - .get_ringparam = rt2x00mac_get_ringparam, - .tx_frames_pending = rt2x00mac_tx_frames_pending, -}; - -static const struct rt2800_ops rt2800soc_rt2800_ops = { - .register_read = rt2x00mmio_register_read, - .register_read_lock = rt2x00mmio_register_read, /* same for SoCs */ - .register_write = rt2x00mmio_register_write, - .register_write_lock = rt2x00mmio_register_write, /* same for SoCs */ - .register_multiread = rt2x00mmio_register_multiread, - .register_multiwrite = rt2x00mmio_register_multiwrite, - .regbusy_read = rt2x00mmio_regbusy_read, - .read_eeprom = rt2800soc_read_eeprom, - .hwcrypt_disabled = rt2800soc_hwcrypt_disabled, - .drv_write_firmware = rt2800soc_write_firmware, - .drv_init_registers = rt2800mmio_init_registers, - .drv_get_txwi = rt2800mmio_get_txwi, -}; - -static const struct rt2x00lib_ops rt2800soc_rt2x00_ops = { - .irq_handler = rt2800mmio_interrupt, - .txstatus_tasklet = rt2800mmio_txstatus_tasklet, - .pretbtt_tasklet = rt2800mmio_pretbtt_tasklet, - .tbtt_tasklet = rt2800mmio_tbtt_tasklet, - .rxdone_tasklet = rt2800mmio_rxdone_tasklet, - .autowake_tasklet = rt2800mmio_autowake_tasklet, - .probe_hw = rt2800_probe_hw, - .get_firmware_name = rt2800soc_get_firmware_name, - .check_firmware = rt2800soc_check_firmware, - .load_firmware = rt2800soc_load_firmware, - .initialize = rt2x00mmio_initialize, - .uninitialize = rt2x00mmio_uninitialize, - .get_entry_state = rt2800mmio_get_entry_state, - .clear_entry = rt2800mmio_clear_entry, - .set_device_state = rt2800soc_set_device_state, - .rfkill_poll = rt2800_rfkill_poll, - .link_stats = rt2800_link_stats, - .reset_tuner = rt2800_reset_tuner, - .link_tuner = rt2800_link_tuner, - .gain_calibration = rt2800_gain_calibration, - .vco_calibration = rt2800_vco_calibration, - .start_queue = rt2800mmio_start_queue, - .kick_queue = rt2800mmio_kick_queue, - .stop_queue = rt2800mmio_stop_queue, - .flush_queue = rt2x00mmio_flush_queue, - .write_tx_desc = rt2800mmio_write_tx_desc, - .write_tx_data = rt2800_write_tx_data, - .write_beacon = rt2800_write_beacon, - .clear_beacon = rt2800_clear_beacon, - .fill_rxdone = rt2800mmio_fill_rxdone, - .config_shared_key = rt2800_config_shared_key, - .config_pairwise_key = rt2800_config_pairwise_key, - .config_filter = rt2800_config_filter, - .config_intf = rt2800_config_intf, - .config_erp = rt2800_config_erp, - .config_ant = rt2800_config_ant, - .config = rt2800_config, - .sta_add = rt2800_sta_add, - .sta_remove = rt2800_sta_remove, -}; - -static const struct rt2x00_ops rt2800soc_ops = { - .name = KBUILD_MODNAME, - .drv_data_size = sizeof(struct rt2800_drv_data), - .max_ap_intf = 8, - .eeprom_size = EEPROM_SIZE, - .rf_size = RF_SIZE, - .tx_queues = NUM_TX_QUEUES, - .queue_init = rt2800mmio_queue_init, - .lib = &rt2800soc_rt2x00_ops, - .drv = &rt2800soc_rt2800_ops, - .hw = &rt2800soc_mac80211_ops, -#ifdef CONFIG_RT2X00_LIB_DEBUGFS - .debugfs = &rt2800_rt2x00debug, -#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ -}; - -static int rt2800soc_probe(struct platform_device *pdev) -{ - return rt2x00soc_probe(pdev, &rt2800soc_ops); -} - -static struct platform_driver rt2800soc_driver = { - .driver = { - .name = "rt2800_wmac", - .owner = THIS_MODULE, - .mod_name = KBUILD_MODNAME, - }, - .probe = rt2800soc_probe, - .remove = rt2x00soc_remove, - .suspend = rt2x00soc_suspend, - .resume = rt2x00soc_resume, -}; - -module_platform_driver(rt2800soc_driver); - -MODULE_AUTHOR(DRV_PROJECT); -MODULE_VERSION(DRV_VERSION); -MODULE_DESCRIPTION("Ralink WiSoC Wireless LAN driver."); -MODULE_LICENSE("GPL"); diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index a81ceb6..96961b9 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -148,8 +148,6 @@ static bool rt2800usb_txstatus_timeout(struct rt2x00_dev *rt2x00dev) return false; } -#define TXSTATUS_READ_INTERVAL 1000000 - static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, int urb_status, u32 tx_status) { @@ -164,7 +162,7 @@ static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, valid = rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID); if (valid) { - if (!kfifo_put(&rt2x00dev->txstatus_fifo, tx_status)) + if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) rt2x00_warn(rt2x00dev, "TX status FIFO overrun\n"); queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); @@ -178,9 +176,8 @@ static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); if (rt2800usb_txstatus_pending(rt2x00dev)) { - /* Read register after 1 ms */ - hrtimer_start(&rt2x00dev->txstatus_timer, - ktime_set(0, TXSTATUS_READ_INTERVAL), + /* Read register after 250 us */ + hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 250000), HRTIMER_MODE_REL); return false; } @@ -205,9 +202,8 @@ static void rt2800usb_async_read_tx_status(struct rt2x00_dev *rt2x00dev) if (test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) return; - /* Read TX_STA_FIFO register after 2 ms */ - hrtimer_start(&rt2x00dev->txstatus_timer, - ktime_set(0, 2*TXSTATUS_READ_INTERVAL), + /* Read TX_STA_FIFO register after 500 us */ + hrtimer_start(&rt2x00dev->txstatus_timer, ktime_set(0, 500000), HRTIMER_MODE_REL); } @@ -1180,8 +1176,6 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Linksys */ { USB_DEVICE(0x13b1, 0x002f) }, { USB_DEVICE(0x1737, 0x0079) }, - /* Logitec */ - { USB_DEVICE(0x0789, 0x0170) }, /* Ralink */ { USB_DEVICE(0x148f, 0x3572) }, /* Sitecom */ @@ -1205,8 +1199,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x050d, 0x1103) }, /* Cameo */ { USB_DEVICE(0x148f, 0xf301) }, - /* D-Link */ - { USB_DEVICE(0x2001, 0x3c1f) }, /* Edimax */ { USB_DEVICE(0x7392, 0x7733) }, /* Hawking */ @@ -1220,7 +1212,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0789, 0x016b) }, /* NETGEAR */ { USB_DEVICE(0x0846, 0x9012) }, - { USB_DEVICE(0x0846, 0x9013) }, { USB_DEVICE(0x0846, 0x9019) }, /* Planex */ { USB_DEVICE(0x2019, 0xed19) }, @@ -1229,7 +1220,6 @@ static struct usb_device_id rt2800usb_device_table[] = { /* Sitecom */ { USB_DEVICE(0x0df6, 0x0067) }, { USB_DEVICE(0x0df6, 0x006a) }, - { USB_DEVICE(0x0df6, 0x006e) }, /* ZyXEL */ { USB_DEVICE(0x0586, 0x3421) }, #endif @@ -1246,9 +1236,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x2001, 0x3c1c) }, { USB_DEVICE(0x2001, 0x3c1d) }, { USB_DEVICE(0x2001, 0x3c1e) }, - { USB_DEVICE(0x2001, 0x3c20) }, - { USB_DEVICE(0x2001, 0x3c22) }, - { USB_DEVICE(0x2001, 0x3c23) }, /* LG innotek */ { USB_DEVICE(0x043e, 0x7a22) }, { USB_DEVICE(0x043e, 0x7a42) }, @@ -1271,17 +1258,12 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x043e, 0x7a32) }, /* AVM GmbH */ { USB_DEVICE(0x057c, 0x8501) }, - /* Buffalo */ - { USB_DEVICE(0x0411, 0x0241) }, - /* D-Link */ + /* D-Link DWA-160-B2 */ { USB_DEVICE(0x2001, 0x3c1a) }, - { USB_DEVICE(0x2001, 0x3c21) }, /* Proware */ { USB_DEVICE(0x043e, 0x7a13) }, /* Ralink */ { USB_DEVICE(0x148f, 0x5572) }, - /* TRENDnet */ - { USB_DEVICE(0x20f4, 0x724a) }, #endif #ifdef CONFIG_RT2800USB_UNKNOWN /* @@ -1351,7 +1333,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x1d4d, 0x0010) }, /* Planex */ { USB_DEVICE(0x2019, 0xab24) }, - { USB_DEVICE(0x2019, 0xab29) }, /* Qcom */ { USB_DEVICE(0x18e8, 0x6259) }, /* RadioShack */ diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index e4ba2ce..fe4c572 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -39,7 +39,6 @@ #include <linux/input-polldev.h> #include <linux/kfifo.h> #include <linux/hrtimer.h> -#include <linux/average.h> #include <net/mac80211.h> @@ -139,6 +138,17 @@ #define SHORT_EIFS ( SIFS + SHORT_DIFS + \ GET_DURATION(IEEE80211_HEADER + ACK_SIZE, 10) ) +/* + * Structure for average calculation + * The avg field contains the actual average value, + * but avg_weight is internally used during calculations + * to prevent rounding errors. + */ +struct avg_val { + int avg; + int avg_weight; +}; + enum rt2x00_chip_intf { RT2X00_CHIP_INTF_PCI, RT2X00_CHIP_INTF_PCIE, @@ -287,7 +297,7 @@ struct link_ant { * Similar to the avg_rssi in the link_qual structure * this value is updated by using the walking average. */ - struct ewma rssi_ant; + struct avg_val rssi_ant; }; /* @@ -316,7 +326,7 @@ struct link { /* * Currently active average RSSI value */ - struct ewma avg_rssi; + struct avg_val avg_rssi; /* * Work structure for scheduling periodic link tuning. @@ -1169,93 +1179,6 @@ static inline bool rt2x00_is_soc(struct rt2x00_dev *rt2x00dev) return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC); } -/* Helpers for capability flags */ - -static inline bool -rt2x00_has_cap_flag(struct rt2x00_dev *rt2x00dev, - enum rt2x00_capability_flags cap_flag) -{ - return test_bit(cap_flag, &rt2x00dev->cap_flags); -} - -static inline bool -rt2x00_has_cap_hw_crypto(struct rt2x00_dev *rt2x00dev) -{ - return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_HW_CRYPTO); -} - -static inline bool -rt2x00_has_cap_power_limit(struct rt2x00_dev *rt2x00dev) -{ - return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_POWER_LIMIT); -} - -static inline bool -rt2x00_has_cap_control_filters(struct rt2x00_dev *rt2x00dev) -{ - return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_CONTROL_FILTERS); -} - -static inline bool -rt2x00_has_cap_control_filter_pspoll(struct rt2x00_dev *rt2x00dev) -{ - return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_CONTROL_FILTER_PSPOLL); -} - -static inline bool -rt2x00_has_cap_pre_tbtt_interrupt(struct rt2x00_dev *rt2x00dev) -{ - return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_PRE_TBTT_INTERRUPT); -} - -static inline bool -rt2x00_has_cap_link_tuning(struct rt2x00_dev *rt2x00dev) -{ - return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_LINK_TUNING); -} - -static inline bool -rt2x00_has_cap_frame_type(struct rt2x00_dev *rt2x00dev) -{ - return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_FRAME_TYPE); -} - -static inline bool -rt2x00_has_cap_rf_sequence(struct rt2x00_dev *rt2x00dev) -{ - return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_RF_SEQUENCE); -} - -static inline bool -rt2x00_has_cap_external_lna_a(struct rt2x00_dev *rt2x00dev) -{ - return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_EXTERNAL_LNA_A); -} - -static inline bool -rt2x00_has_cap_external_lna_bg(struct rt2x00_dev *rt2x00dev) -{ - return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_EXTERNAL_LNA_BG); -} - -static inline bool -rt2x00_has_cap_double_antenna(struct rt2x00_dev *rt2x00dev) -{ - return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_DOUBLE_ANTENNA); -} - -static inline bool -rt2x00_has_cap_bt_coexist(struct rt2x00_dev *rt2x00dev) -{ - return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_BT_COEXIST); -} - -static inline bool -rt2x00_has_cap_vco_recalibration(struct rt2x00_dev *rt2x00dev) -{ - return rt2x00_has_cap_flag(rt2x00dev, CAPABILITY_VCO_RECALIBRATION); -} - /** * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes. * @entry: Pointer to &struct queue_entry diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c index 3db0d99..1ca4c7f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00crypto.c +++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c @@ -52,7 +52,7 @@ void rt2x00crypto_create_tx_descriptor(struct rt2x00_dev *rt2x00dev, struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; - if (!rt2x00_has_cap_hw_crypto(rt2x00dev) || !hw_key) + if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags) || !hw_key) return; __set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags); @@ -80,7 +80,7 @@ unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev, struct ieee80211_key_conf *key = tx_info->control.hw_key; unsigned int overhead = 0; - if (!rt2x00_has_cap_hw_crypto(rt2x00dev) || !key) + if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags) || !key) return overhead; /* diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index 7f7baae..fe7a7f6 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -750,7 +750,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) intf, &rt2x00debug_fop_queue_stats); #ifdef CONFIG_RT2X00_LIB_CRYPTO - if (rt2x00_has_cap_hw_crypto(rt2x00dev)) + if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) intf->crypto_stats_entry = debugfs_create_file("crypto", S_IRUGO, intf->queue_folder, intf, &rt2x00debug_fop_crypto_stats); diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 9dd92a7..712eea9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -88,7 +88,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) rt2x00queue_start_queues(rt2x00dev); rt2x00link_start_tuner(rt2x00dev); rt2x00link_start_agc(rt2x00dev); - if (rt2x00_has_cap_vco_recalibration(rt2x00dev)) + if (test_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags)) rt2x00link_start_vcocal(rt2x00dev); /* @@ -113,7 +113,7 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) * Stop all queues */ rt2x00link_stop_agc(rt2x00dev); - if (rt2x00_has_cap_vco_recalibration(rt2x00dev)) + if (test_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags)) rt2x00link_stop_vcocal(rt2x00dev); rt2x00link_stop_tuner(rt2x00dev); rt2x00queue_stop_queues(rt2x00dev); @@ -181,7 +181,6 @@ static void rt2x00lib_autowakeup(struct work_struct *work) static void rt2x00lib_bc_buffer_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { - struct ieee80211_tx_control control = {}; struct rt2x00_dev *rt2x00dev = data; struct sk_buff *skb; @@ -196,7 +195,7 @@ static void rt2x00lib_bc_buffer_iter(void *data, u8 *mac, */ skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif); while (skb) { - rt2x00mac_tx(rt2x00dev->hw, &control, skb); + rt2x00mac_tx(rt2x00dev->hw, NULL, skb); skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif); } } @@ -235,7 +234,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) * here as they will fetch the next beacon directly prior to * transmission. */ - if (rt2x00_has_cap_pre_tbtt_interrupt(rt2x00dev)) + if (test_bit(CAPABILITY_PRE_TBTT_INTERRUPT, &rt2x00dev->cap_flags)) return; /* fetch next beacon */ @@ -359,7 +358,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, * mac80211 will expect the same data to be present it the * frame as it was passed to us. */ - if (rt2x00_has_cap_hw_crypto(rt2x00dev)) + if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) rt2x00crypto_tx_insert_iv(entry->skb, header_length); /* diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 7f40ab8..a093598 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -146,7 +146,7 @@ void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length); * @local: frame is not from mac80211 */ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, - struct ieee80211_sta *sta, bool local); + bool local); /** * rt2x00queue_update_beacon - Send new beacon from mac80211 diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index c2b3b66..8368aab 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c @@ -35,28 +35,50 @@ */ #define DEFAULT_RSSI -128 -/* Constants for EWMA calculations. */ -#define RT2X00_EWMA_FACTOR 1024 -#define RT2X00_EWMA_WEIGHT 8 - -static inline int rt2x00link_get_avg_rssi(struct ewma *ewma) -{ - unsigned long avg; - - avg = ewma_read(ewma); - if (avg) - return -avg; - - return DEFAULT_RSSI; -} +/* + * Helper struct and macro to work with moving/walking averages. + * When adding a value to the average value the following calculation + * is needed: + * + * avg_rssi = ((avg_rssi * 7) + rssi) / 8; + * + * The advantage of this approach is that we only need 1 variable + * to store the average in (No need for a count and a total). + * But more importantly, normal average values will over time + * move less and less towards newly added values this results + * that with link tuning, the device can have a very good RSSI + * for a few minutes but when the device is moved away from the AP + * the average will not decrease fast enough to compensate. + * The walking average compensates this and will move towards + * the new values correctly allowing a effective link tuning, + * the speed of the average moving towards other values depends + * on the value for the number of samples. The higher the number + * of samples, the slower the average will move. + * We use two variables to keep track of the average value to + * compensate for the rounding errors. This can be a significant + * error (>5dBm) if the factor is too low. + */ +#define AVG_SAMPLES 8 +#define AVG_FACTOR 1000 +#define MOVING_AVERAGE(__avg, __val) \ +({ \ + struct avg_val __new; \ + __new.avg_weight = \ + (__avg).avg_weight ? \ + ((((__avg).avg_weight * ((AVG_SAMPLES) - 1)) + \ + ((__val) * (AVG_FACTOR))) / \ + (AVG_SAMPLES)) : \ + ((__val) * (AVG_FACTOR)); \ + __new.avg = __new.avg_weight / (AVG_FACTOR); \ + __new; \ +}) static int rt2x00link_antenna_get_link_rssi(struct rt2x00_dev *rt2x00dev) { struct link_ant *ant = &rt2x00dev->link.ant; - if (rt2x00dev->link.qual.rx_success) - return rt2x00link_get_avg_rssi(&ant->rssi_ant); - + if (ant->rssi_ant.avg && rt2x00dev->link.qual.rx_success) + return ant->rssi_ant.avg; return DEFAULT_RSSI; } @@ -78,8 +100,8 @@ static void rt2x00link_antenna_update_rssi_history(struct rt2x00_dev *rt2x00dev, static void rt2x00link_antenna_reset(struct rt2x00_dev *rt2x00dev) { - ewma_init(&rt2x00dev->link.ant.rssi_ant, RT2X00_EWMA_FACTOR, - RT2X00_EWMA_WEIGHT); + rt2x00dev->link.ant.rssi_ant.avg = 0; + rt2x00dev->link.ant.rssi_ant.avg_weight = 0; } static void rt2x00lib_antenna_diversity_sample(struct rt2x00_dev *rt2x00dev) @@ -227,12 +249,12 @@ void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev, /* * Update global RSSI */ - ewma_add(&link->avg_rssi, -rxdesc->rssi); + link->avg_rssi = MOVING_AVERAGE(link->avg_rssi, rxdesc->rssi); /* * Update antenna RSSI */ - ewma_add(&ant->rssi_ant, -rxdesc->rssi); + ant->rssi_ant = MOVING_AVERAGE(ant->rssi_ant, rxdesc->rssi); } void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev) @@ -287,8 +309,6 @@ void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna) */ rt2x00dev->link.count = 0; memset(qual, 0, sizeof(*qual)); - ewma_init(&rt2x00dev->link.avg_rssi, RT2X00_EWMA_FACTOR, - RT2X00_EWMA_WEIGHT); /* * Restore the VGC level as stored in the registers, @@ -343,17 +363,17 @@ static void rt2x00link_tuner(struct work_struct *work) * collect the RSSI data we could use this. Otherwise we * must fallback to the default RSSI value. */ - if (!qual->rx_success) + if (!link->avg_rssi.avg || !qual->rx_success) qual->rssi = DEFAULT_RSSI; else - qual->rssi = rt2x00link_get_avg_rssi(&link->avg_rssi); + qual->rssi = link->avg_rssi.avg; /* * Check if link tuning is supported by the hardware, some hardware * do not support link tuning at all, while other devices can disable * the feature from the EEPROM. */ - if (rt2x00_has_cap_link_tuning(rt2x00dev)) + if (test_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags)) rt2x00dev->ops->lib->link_tuner(rt2x00dev, qual, link->count); /* @@ -493,7 +513,7 @@ static void rt2x00link_vcocal(struct work_struct *work) void rt2x00link_register(struct rt2x00_dev *rt2x00dev) { INIT_DELAYED_WORK(&rt2x00dev->link.agc_work, rt2x00link_agc); - if (rt2x00_has_cap_vco_recalibration(rt2x00dev)) + if (test_bit(CAPABILITY_VCO_RECALIBRATION, &rt2x00dev->cap_flags)) INIT_DELAYED_WORK(&rt2x00dev->link.vco_work, rt2x00link_vcocal); INIT_DELAYED_WORK(&rt2x00dev->link.watchdog_work, rt2x00link_watchdog); INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner); diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 2183e79..f883802 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -90,7 +90,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, frag_skb->data, data_length, tx_info, (struct ieee80211_rts *)(skb->data)); - retval = rt2x00queue_write_tx_frame(queue, skb, NULL, true); + retval = rt2x00queue_write_tx_frame(queue, skb, true); if (retval) { dev_kfree_skb_any(skb); rt2x00_warn(rt2x00dev, "Failed to send RTS/CTS frame\n"); @@ -151,7 +151,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, goto exit_fail; } - if (unlikely(rt2x00queue_write_tx_frame(queue, skb, control->sta, false))) + if (unlikely(rt2x00queue_write_tx_frame(queue, skb, false))) goto exit_fail; /* @@ -382,11 +382,11 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw, * of different types, but has no a separate filter for PS Poll frames, * FIF_CONTROL flag implies FIF_PSPOLL. */ - if (!rt2x00_has_cap_control_filters(rt2x00dev)) { + if (!test_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags)) { if (*total_flags & FIF_CONTROL || *total_flags & FIF_PSPOLL) *total_flags |= FIF_CONTROL | FIF_PSPOLL; } - if (!rt2x00_has_cap_control_filter_pspoll(rt2x00dev)) { + if (!test_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags)) { if (*total_flags & FIF_CONTROL) *total_flags |= FIF_PSPOLL; } @@ -469,7 +469,7 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) return 0; - if (!rt2x00_has_cap_hw_crypto(rt2x00dev)) + if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) return -EOPNOTSUPP; /* @@ -754,9 +754,6 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) struct rt2x00_dev *rt2x00dev = hw->priv; struct data_queue *queue; - if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) - return; - tx_queue_for_each(rt2x00dev, queue) rt2x00queue_flush_queue(queue, drop); } diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 25da20e..dc49e52 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -119,7 +119,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops) rt2x00dev->ops = ops; rt2x00dev->hw = hw; rt2x00dev->irq = pci_dev->irq; - rt2x00dev->name = ops->name; + rt2x00dev->name = pci_name(pci_dev); if (pci_is_pcie(pci_dev)) rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE); diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index a5d38e8..6c8a33b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -61,7 +61,7 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct queue_entry *entry, gfp_t gfp) * at least 8 bytes bytes available in headroom for IV/EIV * and 8 bytes for ICV data as tailroon. */ - if (rt2x00_has_cap_hw_crypto(rt2x00dev)) { + if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) { head_size += 8; tail_size += 8; } @@ -635,7 +635,7 @@ static void rt2x00queue_bar_check(struct queue_entry *entry) } int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, - struct ieee80211_sta *sta, bool local) + bool local) { struct ieee80211_tx_info *tx_info; struct queue_entry *entry; @@ -649,7 +649,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, * after that we are free to use the skb->cb array * for our information. */ - rt2x00queue_create_tx_descriptor(queue->rt2x00dev, skb, &txdesc, sta); + rt2x00queue_create_tx_descriptor(queue->rt2x00dev, skb, &txdesc, NULL); /* * All information is retrieved from the skb->cb array, @@ -1033,21 +1033,38 @@ EXPORT_SYMBOL_GPL(rt2x00queue_stop_queue); void rt2x00queue_flush_queue(struct data_queue *queue, bool drop) { + bool started; bool tx_queue = (queue->qid == QID_AC_VO) || (queue->qid == QID_AC_VI) || (queue->qid == QID_AC_BE) || (queue->qid == QID_AC_BK); + mutex_lock(&queue->status_lock); /* - * If we are not supposed to drop any pending - * frames, this means we must force a start (=kick) - * to the queue to make sure the hardware will - * start transmitting. + * If the queue has been started, we must stop it temporarily + * to prevent any new frames to be queued on the device. If + * we are not dropping the pending frames, the queue must + * only be stopped in the software and not the hardware, + * otherwise the queue will never become empty on its own. */ - if (!drop && tx_queue) - queue->rt2x00dev->ops->lib->kick_queue(queue); + started = test_bit(QUEUE_STARTED, &queue->flags); + if (started) { + /* + * Pause the queue + */ + rt2x00queue_pause_queue(queue); + + /* + * If we are not supposed to drop any pending + * frames, this means we must force a start (=kick) + * to the queue to make sure the hardware will + * start transmitting. + */ + if (!drop && tx_queue) + queue->rt2x00dev->ops->lib->kick_queue(queue); + } /* * Check if driver supports flushing, if that is the case we can @@ -1063,6 +1080,14 @@ void rt2x00queue_flush_queue(struct data_queue *queue, bool drop) if (unlikely(!rt2x00queue_empty(queue))) rt2x00_warn(queue->rt2x00dev, "Queue %d failed to flush\n", queue->qid); + + /* + * Restore the queue to the previous status + */ + if (started) + rt2x00queue_unpause_queue(queue); + + mutex_unlock(&queue->status_lock); } EXPORT_SYMBOL_GPL(rt2x00queue_flush_queue); diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 4e12162..8828987 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -523,9 +523,7 @@ static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) rt2x00_warn(queue->rt2x00dev, "TX queue %d DMA timed out, invoke forced forced reset\n", queue->qid); - rt2x00queue_stop_queue(queue); rt2x00queue_flush_queue(queue, true); - rt2x00queue_start_queue(queue); } static int rt2x00usb_dma_timeout(struct data_queue *queue) diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index a5b69cb..54d3ddf 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -685,7 +685,7 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev, rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, rt2x00_rf(rt2x00dev, RF2529)); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, - !rt2x00_has_cap_frame_type(rt2x00dev)); + !test_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags)); /* * Configure the RX antenna. @@ -813,10 +813,10 @@ static void rt61pci_config_ant(struct rt2x00_dev *rt2x00dev, if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { sel = antenna_sel_a; - lna = rt2x00_has_cap_external_lna_a(rt2x00dev); + lna = test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags); } else { sel = antenna_sel_bg; - lna = rt2x00_has_cap_external_lna_bg(rt2x00dev); + lna = test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags); } for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) @@ -836,7 +836,7 @@ static void rt61pci_config_ant(struct rt2x00_dev *rt2x00dev, else if (rt2x00_rf(rt2x00dev, RF2527)) rt61pci_config_antenna_2x(rt2x00dev, ant); else if (rt2x00_rf(rt2x00dev, RF2529)) { - if (rt2x00_has_cap_double_antenna(rt2x00dev)) + if (test_bit(CAPABILITY_DOUBLE_ANTENNA, &rt2x00dev->cap_flags)) rt61pci_config_antenna_2x(rt2x00dev, ant); else rt61pci_config_antenna_2529(rt2x00dev, ant); @@ -850,13 +850,13 @@ static void rt61pci_config_lna_gain(struct rt2x00_dev *rt2x00dev, short lna_gain = 0; if (libconf->conf->chandef.chan->band == IEEE80211_BAND_2GHZ) { - if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) + if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) lna_gain += 14; rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom); lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1); } else { - if (rt2x00_has_cap_external_lna_a(rt2x00dev)) + if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) lna_gain += 14; rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom); @@ -1054,14 +1054,14 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev, if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { low_bound = 0x28; up_bound = 0x48; - if (rt2x00_has_cap_external_lna_a(rt2x00dev)) { + if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) { low_bound += 0x10; up_bound += 0x10; } } else { low_bound = 0x20; up_bound = 0x40; - if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { + if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) { low_bound += 0x10; up_bound += 0x10; } @@ -2578,7 +2578,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) * eeprom word. */ if (rt2x00_rf(rt2x00dev, RF2529) && - !rt2x00_has_cap_double_antenna(rt2x00dev)) { + !test_bit(CAPABILITY_DOUBLE_ANTENNA, &rt2x00dev->cap_flags)) { rt2x00dev->default_ant.rx = ANTENNA_A + rt2x00_get_field16(eeprom, EEPROM_NIC_RX_FIXED); rt2x00dev->default_ant.tx = @@ -2793,7 +2793,7 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) spec->supported_bands = SUPPORT_BAND_2GHZ; spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM; - if (!rt2x00_has_cap_rf_sequence(rt2x00dev)) { + if (!test_bit(CAPABILITY_RF_SEQUENCE, &rt2x00dev->cap_flags)) { spec->num_channels = 14; spec->channels = rf_vals_noseq; } else { diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 1baf9c8..1d3880e 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -595,8 +595,8 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, switch (ant->rx) { case ANTENNA_HW_DIVERSITY: rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2); - temp = !rt2x00_has_cap_frame_type(rt2x00dev) && - (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ); + temp = !test_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags) + && (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp); break; case ANTENNA_A: @@ -636,7 +636,7 @@ static void rt73usb_config_antenna_2x(struct rt2x00_dev *rt2x00dev, rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0); rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, - !rt2x00_has_cap_frame_type(rt2x00dev)); + !test_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags)); /* * Configure the RX antenna. @@ -709,10 +709,10 @@ static void rt73usb_config_ant(struct rt2x00_dev *rt2x00dev, if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { sel = antenna_sel_a; - lna = rt2x00_has_cap_external_lna_a(rt2x00dev); + lna = test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags); } else { sel = antenna_sel_bg; - lna = rt2x00_has_cap_external_lna_bg(rt2x00dev); + lna = test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags); } for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++) @@ -740,7 +740,7 @@ static void rt73usb_config_lna_gain(struct rt2x00_dev *rt2x00dev, short lna_gain = 0; if (libconf->conf->chandef.chan->band == IEEE80211_BAND_2GHZ) { - if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) + if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) lna_gain += 14; rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom); @@ -930,7 +930,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev, low_bound = 0x28; up_bound = 0x48; - if (rt2x00_has_cap_external_lna_a(rt2x00dev)) { + if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) { low_bound += 0x10; up_bound += 0x10; } @@ -946,7 +946,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev, up_bound = 0x1c; } - if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { + if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) { low_bound += 0x14; up_bound += 0x10; } @@ -1661,7 +1661,7 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) } if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { - if (rt2x00_has_cap_external_lna_a(rt2x00dev)) { + if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) { if (lna == 3 || lna == 2) offset += 10; } else { diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c index a91506b..fc207b2 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c @@ -1122,6 +1122,7 @@ static int rtl8180_probe(struct pci_dev *pdev, iounmap(priv->map); err_free_dev: + pci_set_drvdata(pdev, NULL); ieee80211_free_hw(dev); err_free_reg: diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index ff78407..8bb4a9a 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -37,7 +37,6 @@ #include <linux/ip.h> #include <linux/module.h> -#include <linux/udp.h> /* *NOTICE!!!: This file will be very big, we should @@ -1075,52 +1074,64 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) if (!ieee80211_is_data(fc)) return false; - ip = (const struct iphdr *)(skb->data + mac_hdr_len + - SNAP_SIZE + PROTOC_TYPE_SIZE); - ether_type = be16_to_cpup((__be16 *) - (skb->data + mac_hdr_len + SNAP_SIZE)); - switch (ether_type) { - case ETH_P_IP: { - struct udphdr *udp; - u16 src; - u16 dst; - - if (ip->protocol != IPPROTO_UDP) - return false; - udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2)); - src = be16_to_cpu(udp->source); - dst = be16_to_cpu(udp->dest); + ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len + + SNAP_SIZE + PROTOC_TYPE_SIZE); + ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE); + /* ether_type = ntohs(ether_type); */ + + if (ETH_P_IP == ether_type) { + if (IPPROTO_UDP == ip->protocol) { + struct udphdr *udp = (struct udphdr *)((u8 *) ip + + (ip->ihl << 2)); + if (((((u8 *) udp)[1] == 68) && + (((u8 *) udp)[3] == 67)) || + ((((u8 *) udp)[1] == 67) && + (((u8 *) udp)[3] == 68))) { + /* + * 68 : UDP BOOTP client + * 67 : UDP BOOTP server + */ + RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), + DBG_DMESG, "dhcp %s !!\n", + is_tx ? "Tx" : "Rx"); + + if (is_tx) { + rtlpriv->enter_ps = false; + schedule_work(&rtlpriv-> + works.lps_change_work); + ppsc->last_delaylps_stamp_jiffies = + jiffies; + } - /* If this case involves port 68 (UDP BOOTP client) connecting - * with port 67 (UDP BOOTP server), then return true so that - * the lowest speed is used. - */ - if (!((src == 68 && dst == 67) || (src == 67 && dst == 68))) - return false; + return true; + } + } + } else if (ETH_P_ARP == ether_type) { + if (is_tx) { + rtlpriv->enter_ps = false; + schedule_work(&rtlpriv->works.lps_change_work); + ppsc->last_delaylps_stamp_jiffies = jiffies; + } - RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - "dhcp %s !!\n", is_tx ? "Tx" : "Rx"); - break; - } - case ETH_P_ARP: - break; - case ETH_P_PAE: + return true; + } else if (ETH_P_PAE == ether_type) { RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx"); - break; - case ETH_P_IPV6: - /* TODO: Is this right? */ - return false; - default: - return false; - } - if (is_tx) { - rtlpriv->enter_ps = false; - schedule_work(&rtlpriv->works.lps_change_work); - ppsc->last_delaylps_stamp_jiffies = jiffies; + + if (is_tx) { + rtlpriv->enter_ps = false; + schedule_work(&rtlpriv->works.lps_change_work); + ppsc->last_delaylps_stamp_jiffies = jiffies; + } + + return true; + } else if (ETH_P_IPV6 == ether_type) { + /* IPv6 */ + return true; } - return true; + + return false; } EXPORT_SYMBOL_GPL(rtl_is_special_data); @@ -1602,35 +1613,6 @@ err_free: } EXPORT_SYMBOL(rtl_send_smps_action); -void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - enum io_type iotype; - - if (!is_hal_stop(rtlhal)) { - switch (operation) { - case SCAN_OPT_BACKUP: - iotype = IO_CMD_PAUSE_DM_BY_SCAN; - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_IO_CMD, - (u8 *)&iotype); - break; - case SCAN_OPT_RESTORE: - iotype = IO_CMD_RESUME_DM_BY_SCAN; - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_IO_CMD, - (u8 *)&iotype); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Unknown Scan Backup operation.\n"); - break; - } - } -} -EXPORT_SYMBOL(rtl_phy_scan_operation_backup); - /* There seem to be issues in mac80211 regarding when del ba frames can be * received. As a work around, we make a fake del_ba if we receive a ba_req; * however, rx_agg was opened to let mac80211 release some ba related diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h index 0cd0742..0e5fe09 100644 --- a/drivers/net/wireless/rtlwifi/base.h +++ b/drivers/net/wireless/rtlwifi/base.h @@ -114,6 +114,7 @@ void rtl_init_rfkill(struct ieee80211_hw *hw); void rtl_deinit_rfkill(struct ieee80211_hw *hw); void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb); +void rtl_watch_dog_timer_callback(unsigned long data); void rtl_deinit_deferred_work(struct ieee80211_hw *hw); bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); @@ -152,6 +153,5 @@ int rtlwifi_rate_mapping(struct ieee80211_hw *hw, bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb); struct sk_buff *rtl_make_del_ba(struct ieee80211_hw *hw, u8 *sa, u8 *bssid, u16 tid); -void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation); #endif diff --git a/drivers/net/wireless/rtlwifi/cam.h b/drivers/net/wireless/rtlwifi/cam.h index 0105e6c..35e0008 100644 --- a/drivers/net/wireless/rtlwifi/cam.h +++ b/drivers/net/wireless/rtlwifi/cam.h @@ -41,12 +41,12 @@ #define CAM_CONFIG_USEDK 1 #define CAM_CONFIG_NO_USEDK 0 -void rtl_cam_reset_all_entry(struct ieee80211_hw *hw); -u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, - u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg, - u32 ul_default_key, u8 *key_content); +extern void rtl_cam_reset_all_entry(struct ieee80211_hw *hw); +extern u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, + u32 ul_key_id, u32 ul_entry_idx, u32 ul_enc_alg, + u32 ul_default_key, u8 *key_content); int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, - u32 ul_key_id); + u32 ul_key_id); void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index); void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index); void rtl_cam_reset_sec_info(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 210ce7c..733b7ce 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -115,7 +115,7 @@ static void rtl_op_stop(struct ieee80211_hw *hw) mutex_lock(&rtlpriv->locks.conf_mutex); mac->link_state = MAC80211_NOLINK; - memset(mac->bssid, 0, ETH_ALEN); + memset(mac->bssid, 0, 6); mac->vendor = PEER_UNKNOWN; /*reset sec info */ @@ -280,7 +280,7 @@ static void rtl_op_remove_interface(struct ieee80211_hw *hw, mac->p2p = 0; mac->vif = NULL; mac->link_state = MAC80211_NOLINK; - memset(mac->bssid, 0, ETH_ALEN); + memset(mac->bssid, 0, 6); mac->vendor = PEER_UNKNOWN; mac->opmode = NL80211_IFTYPE_UNSPECIFIED; rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); @@ -721,7 +721,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, mac->link_state = MAC80211_LINKED; mac->cnt_after_linked = 0; mac->assoc_id = bss_conf->aid; - memcpy(mac->bssid, bss_conf->bssid, ETH_ALEN); + memcpy(mac->bssid, bss_conf->bssid, 6); if (rtlpriv->cfg->ops->linked_set_reg) rtlpriv->cfg->ops->linked_set_reg(hw); @@ -750,7 +750,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, if (ppsc->p2p_ps_info.p2p_ps_mode > P2P_PS_NONE) rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE); mac->link_state = MAC80211_NOLINK; - memset(mac->bssid, 0, ETH_ALEN); + memset(mac->bssid, 0, 6); mac->vendor = PEER_UNKNOWN; if (rtlpriv->dm.supp_phymode_switch) { @@ -826,7 +826,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, bss_conf->bssid); mac->vendor = PEER_UNKNOWN; - memcpy(mac->bssid, bss_conf->bssid, ETH_ALEN); + memcpy(mac->bssid, bss_conf->bssid, 6); rtlpriv->cfg->ops->set_network_type(hw, vif->type); rcu_read_lock(); diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 2ffc729..838a1ed 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -262,9 +262,9 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) sizeof(u8), GFP_ATOMIC); if (!efuse_tbl) return; - efuse_word = kzalloc(EFUSE_MAX_WORD_UNIT * sizeof(u16 *), GFP_ATOMIC); + efuse_word = kmalloc(EFUSE_MAX_WORD_UNIT * sizeof(u16 *), GFP_ATOMIC); if (!efuse_word) - goto out; + goto done; for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { efuse_word[i] = kmalloc(efuse_max_section * sizeof(u16), GFP_ATOMIC); @@ -378,7 +378,6 @@ done: for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) kfree(efuse_word[i]); kfree(efuse_word); -out: kfree(efuse_tbl); } @@ -1204,18 +1203,20 @@ static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate) static u16 efuse_get_current_size(struct ieee80211_hw *hw) { + int continual = true; u16 efuse_addr = 0; u8 hworden; u8 efuse_data, word_cnts; - while (efuse_one_byte_read(hw, efuse_addr, &efuse_data) && - efuse_addr < EFUSE_MAX_SIZE) { - if (efuse_data == 0xFF) - break; - - hworden = efuse_data & 0x0F; - word_cnts = efuse_calculate_word_cnts(hworden); - efuse_addr = efuse_addr + (word_cnts * 2) + 1; + while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data) + && (efuse_addr < EFUSE_MAX_SIZE)) { + if (efuse_data != 0xFF) { + hworden = efuse_data & 0x0F; + word_cnts = efuse_calculate_word_cnts(hworden); + efuse_addr = efuse_addr + (word_cnts * 2) + 1; + } else { + continual = false; + } } return efuse_addr; diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/rtlwifi/efuse.h index 1663b3a..395a326 100644 --- a/drivers/net/wireless/rtlwifi/efuse.h +++ b/drivers/net/wireless/rtlwifi/efuse.h @@ -104,19 +104,20 @@ struct efuse_priv { u8 tx_power_g[14]; }; -void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf); -void efuse_initialize(struct ieee80211_hw *hw); -u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address); -void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value); -void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf); -void efuse_shadow_read(struct ieee80211_hw *hw, u8 type, u16 offset, - u32 *value); -void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, u16 offset, - u32 value); -bool efuse_shadow_update(struct ieee80211_hw *hw); -bool efuse_shadow_update_chk(struct ieee80211_hw *hw); -void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw); -void efuse_force_write_vendor_Id(struct ieee80211_hw *hw); -void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx); +extern void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf); +extern void efuse_initialize(struct ieee80211_hw *hw); +extern u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address); +extern void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value); +extern void read_efuse(struct ieee80211_hw *hw, u16 _offset, + u16 _size_byte, u8 *pbuf); +extern void efuse_shadow_read(struct ieee80211_hw *hw, u8 type, + u16 offset, u32 *value); +extern void efuse_shadow_write(struct ieee80211_hw *hw, u8 type, + u16 offset, u32 value); +extern bool efuse_shadow_update(struct ieee80211_hw *hw); +extern bool efuse_shadow_update_chk(struct ieee80211_hw *hw); +extern void rtl_efuse_shadow_map_update(struct ieee80211_hw *hw); +extern void efuse_force_write_vendor_Id(struct ieee80211_hw *hw); +extern void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx); #endif diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 0f49444..703f839 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -736,6 +736,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) struct rtl_stats stats = { .signal = 0, + .noise = -98, .rate = 0, }; int index = rtlpci->rx_ring[rx_queue_idx].idx; @@ -2008,6 +2009,7 @@ fail2: fail1: if (hw) ieee80211_free_hw(hw); + pci_set_drvdata(pdev, NULL); pci_disable_device(pdev); return err; @@ -2062,6 +2064,8 @@ void rtl_pci_disconnect(struct pci_dev *pdev) rtl_pci_disable_aspm(hw); + pci_set_drvdata(pdev, NULL); + ieee80211_free_hw(hw); } EXPORT_SYMBOL(rtl_pci_disconnect); diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c index e06971b..b68cae3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c @@ -143,7 +143,6 @@ static void _rtl88ee_set_fw_clock_on(struct ieee80211_hw *hw, } else { rtlhal->fw_clk_change_in_progress = false; spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); - break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c index d67f9c7..e655c04 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.c @@ -1136,6 +1136,34 @@ void rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) &bw40_pwr[0], channel); } +void rtl88e_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum io_type iotype; + + if (!is_hal_stop(rtlhal)) { + switch (operation) { + case SCAN_OPT_BACKUP: + iotype = IO_CMD_PAUSE_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + case SCAN_OPT_RESTORE: + iotype = IO_CMD_RESUME_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Unknown Scan Backup operation.\n"); + break; + } + } +} + void rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h index 89f0f1e..f1acd6d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/phy.h @@ -200,35 +200,37 @@ enum _ANT_DIV_TYPE { CGCS_RX_SW_ANTDIV = 0x05, }; -u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask); -void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, u32 data); -u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask); -void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask, u32 data); -bool rtl88e_phy_mac_config(struct ieee80211_hw *hw); -bool rtl88e_phy_bb_config(struct ieee80211_hw *hw); -bool rtl88e_phy_rf_config(struct ieee80211_hw *hw); -void rtl88e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); -void rtl88e_phy_get_txpower_level(struct ieee80211_hw *hw, - long *powerlevel); -void rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); -void rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw); -void rtl88e_phy_set_bw_mode(struct ieee80211_hw *hw, - enum nl80211_channel_type ch_type); -void rtl88e_phy_sw_chnl_callback(struct ieee80211_hw *hw); -u8 rtl88e_phy_sw_chnl(struct ieee80211_hw *hw); -void rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); +extern u32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +extern void rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +extern u32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask); +extern void rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data); +extern bool rtl88e_phy_mac_config(struct ieee80211_hw *hw); +extern bool rtl88e_phy_bb_config(struct ieee80211_hw *hw); +extern bool rtl88e_phy_rf_config(struct ieee80211_hw *hw); +extern void rtl88e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +extern void rtl88e_phy_get_txpower_level(struct ieee80211_hw *hw, + long *powerlevel); +extern void rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +extern void rtl88e_phy_scan_operation_backup(struct ieee80211_hw *hw, + u8 operation); +extern void rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +extern void rtl88e_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +extern void rtl88e_phy_sw_chnl_callback(struct ieee80211_hw *hw); +extern u8 rtl88e_phy_sw_chnl(struct ieee80211_hw *hw); +extern void rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); void rtl88e_phy_lc_calibrate(struct ieee80211_hw *hw); void rtl88e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); bool rtl88e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, enum radio_path rfpath); bool rtl88e_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); -bool rtl88e_phy_set_rf_power_state(struct ieee80211_hw *hw, - enum rf_pwrstate rfpwr_state); +extern bool rtl88e_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c index 347af1e..c254693 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c @@ -30,7 +30,6 @@ #include "../wifi.h" #include "../core.h" #include "../pci.h" -#include "../base.h" #include "reg.h" #include "def.h" #include "phy.h" @@ -245,7 +244,7 @@ static struct rtl_hal_ops rtl8188ee_hal_ops = { .set_bw_mode = rtl88e_phy_set_bw_mode, .switch_channel = rtl88e_phy_sw_chnl, .dm_watchdog = rtl88e_dm_watchdog, - .scan_operation_backup = rtl_phy_scan_operation_backup, + .scan_operation_backup = rtl88e_phy_scan_operation_backup, .set_rf_power_state = rtl88e_phy_set_rf_power_state, .led_control = rtl88ee_led_control, .set_desc = rtl88ee_set_desc, diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c index aece6c9..68685a8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c @@ -478,6 +478,7 @@ bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw, /*rx_status->qual = status->signal; */ rx_status->signal = status->recvsignalpower + 10; + /*rx_status->noise = -status->noise; */ if (status->packet_report_type == TX_REPORT2) { status->macid_valid_entry[0] = GET_RX_RPT2_DESC_MACID_VALID_1(pdesc); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index e9caa5d..d2d57a2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -541,6 +541,29 @@ EXPORT_SYMBOL(rtl92c_dm_write_dig); static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) { + struct rtl_priv *rtlpriv = rtl_priv(hw); + long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff; + + u8 h2c_parameter[3] = { 0 }; + + return; + + if (tmpentry_max_pwdb != 0) { + rtlpriv->dm.entry_max_undec_sm_pwdb = tmpentry_max_pwdb; + } else { + rtlpriv->dm.entry_max_undec_sm_pwdb = 0; + } + + if (tmpentry_min_pwdb != 0xff) { + rtlpriv->dm.entry_min_undec_sm_pwdb = tmpentry_min_pwdb; + } else { + rtlpriv->dm.entry_min_undec_sm_pwdb = 0; + } + + h2c_parameter[2] = (u8) (rtlpriv->dm.undec_sm_pwdb & 0xFF); + h2c_parameter[0] = 0; + + rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter); } void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw) @@ -650,7 +673,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw s8 cck_index = 0; int i; bool is2t = IS_92C_SERIAL(rtlhal->version); - s8 txpwr_level[3] = {0, 0, 0}; + s8 txpwr_level[2] = {0, 0}; u8 ofdm_min_index = 6, rf; rtlpriv->dm.txpower_trackinginit = true; diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index 0c0e782..246e535 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -592,6 +592,36 @@ long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, } EXPORT_SYMBOL(_rtl92c_phy_txpwr_idx_to_dbm); +void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum io_type iotype; + + if (!is_hal_stop(rtlhal)) { + switch (operation) { + case SCAN_OPT_BACKUP: + iotype = IO_CMD_PAUSE_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + + break; + case SCAN_OPT_RESTORE: + iotype = IO_CMD_RESUME_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Unknown Scan Backup operation\n"); + break; + } + } +} +EXPORT_SYMBOL(rtl92c_phy_scan_operation_backup); + void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, enum nl80211_channel_type ch_type) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h index e79dabe..cec10d6 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h @@ -39,7 +39,9 @@ #define RT_CANNOT_IO(hw) false #define HIGHPOWER_RADIOA_ARRAYLEN 22 +#define IQK_ADDA_REG_NUM 16 #define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 1 #define APK_BB_REG_NUM 5 #define APK_AFE_REG_NUM 16 @@ -203,6 +205,8 @@ void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm); +void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, + u8 operation); void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, enum nl80211_channel_type ch_type); void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h index fa24de4..3cfa1bb 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h @@ -152,6 +152,8 @@ enum version_8192c { #define IS_VENDOR_UMC_A_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) ? \ ((GET_CVID_CUT_VERSION(version)) ? false : true) : false) #define IS_CHIP_VER_B(version) ((version & CHIP_VER_B) ? true : false) +#define IS_VENDOR_UMC_A_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) ? \ + ((GET_CVID_CUT_VERSION(version)) ? false : true) : false) #define IS_92C_SERIAL(version) ((version & CHIP_92C_BITMASK) ? true : false) #define IS_CHIP_VENDOR_UMC(version) \ ((version & CHIP_VENDOR_UMC) ? true : false) diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h index 94486cc..d5e3b70 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h @@ -39,7 +39,9 @@ #define RT_CANNOT_IO(hw) false #define HIGHPOWER_RADIOA_ARRAYLEN 22 +#define IQK_ADDA_REG_NUM 16 #define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 1 #define APK_BB_REG_NUM 5 #define APK_AFE_REG_NUM 16 @@ -186,29 +188,36 @@ struct tx_power_struct { }; bool rtl92c_phy_bb_config(struct ieee80211_hw *hw); -u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask); -void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, - u32 data); -u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, - u32 regaddr, u32 bitmask); -void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, - u32 regaddr, u32 bitmask, u32 data); +u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask); +extern void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data); bool rtl92c_phy_mac_config(struct ieee80211_hw *hw); bool rtl92ce_phy_bb_config(struct ieee80211_hw *hw); bool rtl92c_phy_rf_config(struct ieee80211_hw *hw); bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, - enum radio_path rfpath); + enum radio_path rfpath); void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); -void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel); +void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, + long *powerlevel); void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm); +void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, + u8 operation); void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, - enum nl80211_channel_type ch_type); + enum nl80211_channel_type ch_type); void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw); u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw); void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery); -void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval); +void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, + u16 beaconinterval); void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta); void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw); void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); @@ -216,25 +225,28 @@ void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, enum radio_path rfpath); bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, - u32 rfpath); + u32 rfpath); +bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); bool rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, - enum rf_pwrstate rfpwr_state); + enum rf_pwrstate rfpwr_state); void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); void rtl92c_phy_set_io(struct ieee80211_hw *hw); void rtl92c_bb_block_on(struct ieee80211_hw *hw); -u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, enum radio_path rfpath, - u32 offset); +u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 offset); u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset); + enum radio_path rfpath, u32 offset); u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, u32 data); + enum radio_path rfpath, u32 offset, + u32 data); void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, - u32 data); + enum radio_path rfpath, u32 offset, + u32 data); void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, u32 data); + u32 regaddr, u32 bitmask, + u32 data); bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h index 8922ecb..bd4aef7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h @@ -560,6 +560,7 @@ #define EEPROM_DEFAULT_TXPOWERLEVEL 0x22 #define EEPROM_DEFAULT_HT40_2SDIFF 0x0 #define EEPROM_DEFAULT_HT20_DIFF 2 +#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 #define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0 #define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0 @@ -638,8 +639,17 @@ #define EEPROM_TXPWR_GROUP 0x6F +#define EEPROM_TSSI_A 0x76 +#define EEPROM_TSSI_B 0x77 +#define EEPROM_THERMAL_METER 0x78 + #define EEPROM_CHANNELPLAN 0x75 +#define RF_OPTION1 0x79 +#define RF_OPTION2 0x7A +#define RF_OPTION3 0x7B +#define RF_OPTION4 0x7C + #define STOPBECON BIT(6) #define STOPHIGHT BIT(5) #define STOPMGT BIT(4) @@ -679,6 +689,13 @@ #define RSV_CTRL 0x001C #define RD_CTRL 0x0524 +#define REG_USB_INFO 0xFE17 +#define REG_USB_SPECIAL_OPTION 0xFE55 + +#define REG_USB_DMA_AGG_TO 0xFE5B +#define REG_USB_AGG_TO 0xFE5C +#define REG_USB_AGG_TH 0xFE5D + #define REG_USB_VID 0xFE60 #define REG_USB_PID 0xFE62 #define REG_USB_OPTIONAL 0xFE64 @@ -1179,6 +1196,9 @@ #define POLLING_LLT_THRESHOLD 20 #define POLLING_READY_TIMEOUT_COUNT 1000 +#define MAX_MSS_DENSITY_2T 0x13 +#define MAX_MSS_DENSITY_1T 0x0A + #define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6)) #define EPROM_CMD_CONFIG 0x3 #define EPROM_CMD_LOAD 1 diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h index d8fe68b..6c8d56e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h @@ -34,10 +34,11 @@ #define RF6052_MAX_REG 0x3F #define RF6052_MAX_PATH 2 -void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); -void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel); -void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel, u8 channel); -bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw); +extern void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, + u8 bandwidth); +extern void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +extern void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); +extern bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index b790320..1420356 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -30,7 +30,6 @@ #include "../wifi.h" #include "../core.h" #include "../pci.h" -#include "../base.h" #include "reg.h" #include "def.h" #include "phy.h" @@ -220,7 +219,7 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = { .set_bw_mode = rtl92c_phy_set_bw_mode, .switch_channel = rtl92c_phy_sw_chnl, .dm_watchdog = rtl92c_dm_watchdog, - .scan_operation_backup = rtl_phy_scan_operation_backup, + .scan_operation_backup = rtl92c_phy_scan_operation_backup, .set_rf_power_state = rtl92c_phy_set_rf_power_state, .led_control = rtl92ce_led_control, .set_desc = rtl92ce_set_desc, diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 52abf0a..6ad23b4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -420,6 +420,7 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, /*rx_status->qual = stats->signal; */ rx_status->signal = stats->recvsignalpower + 10; + /*rx_status->noise = -stats->noise; */ return true; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index e26312f..da4f587 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -32,7 +32,6 @@ #include "../usb.h" #include "../ps.h" #include "../cam.h" -#include "../stats.h" #include "reg.h" #include "def.h" #include "phy.h" @@ -739,6 +738,16 @@ static u8 _rtl92c_evm_db_to_percentage(char value) return ret_val; } +static long _rtl92c_translate_todbm(struct ieee80211_hw *hw, + u8 signal_strength_index) +{ + long signal_power; + + signal_power = (long)((signal_strength_index + 1) >> 1); + signal_power -= 95; + return signal_power; +} + static long _rtl92c_signal_scale_mapping(struct ieee80211_hw *hw, long currsig) { @@ -769,7 +778,7 @@ static long _rtl92c_signal_scale_mapping(struct ieee80211_hw *hw, static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw, struct rtl_stats *pstats, - struct rx_desc_92c *p_desc, + struct rx_desc_92c *pdesc, struct rx_fwinfo_92c *p_drvinfo, bool packet_match_bssid, bool packet_toself, @@ -784,11 +793,11 @@ static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw, u32 rssi, total_rssi = 0; bool in_powersavemode = false; bool is_cck_rate; - u8 *pdesc = (u8 *)p_desc; - is_cck_rate = RX_HAL_IS_CCK_RATE(p_desc); + is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); pstats->packet_matchbssid = packet_match_bssid; pstats->packet_toself = packet_toself; + pstats->is_cck = is_cck_rate; pstats->packet_beacon = packet_beacon; pstats->is_cck = is_cck_rate; pstats->RX_SIGQ[0] = -1; @@ -904,6 +913,180 @@ static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw, (hw, total_rssi /= rf_rx_num)); } +static void _rtl92c_process_ui_rssi(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_phy *rtlphy = &(rtlpriv->phy); + u8 rfpath; + u32 last_rssi, tmpval; + + if (pstats->packet_toself || pstats->packet_beacon) { + rtlpriv->stats.rssi_calculate_cnt++; + if (rtlpriv->stats.ui_rssi.total_num++ >= + PHY_RSSI_SLID_WIN_MAX) { + rtlpriv->stats.ui_rssi.total_num = + PHY_RSSI_SLID_WIN_MAX; + last_rssi = + rtlpriv->stats.ui_rssi.elements[rtlpriv-> + stats.ui_rssi.index]; + rtlpriv->stats.ui_rssi.total_val -= last_rssi; + } + rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength; + rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi. + index++] = pstats->signalstrength; + if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) + rtlpriv->stats.ui_rssi.index = 0; + tmpval = rtlpriv->stats.ui_rssi.total_val / + rtlpriv->stats.ui_rssi.total_num; + rtlpriv->stats.signal_strength = + _rtl92c_translate_todbm(hw, (u8) tmpval); + pstats->rssi = rtlpriv->stats.signal_strength; + } + if (!pstats->is_cck && pstats->packet_toself) { + for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; + rfpath++) { + if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath)) + continue; + if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + pstats->rx_mimo_signalstrength[rfpath]; + } + if (pstats->rx_mimo_signalstrength[rfpath] > + rtlpriv->stats.rx_rssi_percentage[rfpath]) { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats. + rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + + rtlpriv->stats.rx_rssi_percentage[rfpath] = + rtlpriv->stats.rx_rssi_percentage[rfpath] + + 1; + } else { + rtlpriv->stats.rx_rssi_percentage[rfpath] = + ((rtlpriv->stats. + rx_rssi_percentage[rfpath] * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_mimo_signalstrength[rfpath])) / + (RX_SMOOTH_FACTOR); + } + } + } +} + +static void _rtl92c_update_rxsignalstatistics(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + int weighting = 0; + + if (rtlpriv->stats.recv_signal_power == 0) + rtlpriv->stats.recv_signal_power = pstats->recvsignalpower; + if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power) + weighting = 5; + else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power) + weighting = (-5); + rtlpriv->stats.recv_signal_power = + (rtlpriv->stats.recv_signal_power * 5 + + pstats->recvsignalpower + weighting) / 6; +} + +static void _rtl92c_process_pwdb(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); + long undec_sm_pwdb = 0; + + if (mac->opmode == NL80211_IFTYPE_ADHOC) { + return; + } else { + undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + } + if (pstats->packet_toself || pstats->packet_beacon) { + if (undec_sm_pwdb < 0) + undec_sm_pwdb = pstats->rx_pwdb_all; + if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) { + undec_sm_pwdb = (((undec_sm_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + undec_sm_pwdb += 1; + } else { + undec_sm_pwdb = (((undec_sm_pwdb) * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); + } + rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; + _rtl92c_update_rxsignalstatistics(hw, pstats); + } +} + +static void _rtl92c_process_LINK_Q(struct ieee80211_hw *hw, + struct rtl_stats *pstats) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 last_evm = 0, n_stream, tmpval; + + if (pstats->signalquality != 0) { + if (pstats->packet_toself || pstats->packet_beacon) { + if (rtlpriv->stats.LINK_Q.total_num++ >= + PHY_LINKQUALITY_SLID_WIN_MAX) { + rtlpriv->stats.LINK_Q.total_num = + PHY_LINKQUALITY_SLID_WIN_MAX; + last_evm = + rtlpriv->stats.LINK_Q.elements + [rtlpriv->stats.LINK_Q.index]; + rtlpriv->stats.LINK_Q.total_val -= + last_evm; + } + rtlpriv->stats.LINK_Q.total_val += + pstats->signalquality; + rtlpriv->stats.LINK_Q.elements + [rtlpriv->stats.LINK_Q.index++] = + pstats->signalquality; + if (rtlpriv->stats.LINK_Q.index >= + PHY_LINKQUALITY_SLID_WIN_MAX) + rtlpriv->stats.LINK_Q.index = 0; + tmpval = rtlpriv->stats.LINK_Q.total_val / + rtlpriv->stats.LINK_Q.total_num; + rtlpriv->stats.signal_quality = tmpval; + rtlpriv->stats.last_sigstrength_inpercent = tmpval; + for (n_stream = 0; n_stream < 2; + n_stream++) { + if (pstats->RX_SIGQ[n_stream] != -1) { + if (!rtlpriv->stats.RX_EVM[n_stream]) { + rtlpriv->stats.RX_EVM[n_stream] + = pstats->RX_SIGQ[n_stream]; + } + rtlpriv->stats.RX_EVM[n_stream] = + ((rtlpriv->stats.RX_EVM + [n_stream] * + (RX_SMOOTH_FACTOR - 1)) + + (pstats->RX_SIGQ + [n_stream] * 1)) / + (RX_SMOOTH_FACTOR); + } + } + } + } else { + ; + } +} + +static void _rtl92c_process_phyinfo(struct ieee80211_hw *hw, + u8 *buffer, + struct rtl_stats *pcurrent_stats) +{ + if (!pcurrent_stats->packet_matchbssid && + !pcurrent_stats->packet_beacon) + return; + _rtl92c_process_ui_rssi(hw, pcurrent_stats); + _rtl92c_process_pwdb(hw, pcurrent_stats); + _rtl92c_process_LINK_Q(hw, pcurrent_stats); +} + void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw, struct sk_buff *skb, struct rtl_stats *pstats, @@ -940,5 +1123,5 @@ void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw, _rtl92c_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, packet_matchbssid, packet_toself, packet_beacon); - rtl_process_phyinfo(hw, tmp_buf, pstats); + _rtl92c_process_phyinfo(hw, tmp_buf, pstats); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h index 11b439d..090fd33 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h @@ -34,14 +34,15 @@ #define RF6052_MAX_REG 0x3F #define RF6052_MAX_PATH 2 -void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); -void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel); -void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel, u8 channel); +extern void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, + u8 bandwidth); +extern void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); bool rtl92cu_phy_rf6052_config(struct ieee80211_hw *hw); bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, - enum radio_path rfpath); + enum radio_path rfpath); void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, u8 *ppowerlevel); void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 9936de7..2bd5985 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -31,7 +31,6 @@ #include "../core.h" #include "../usb.h" #include "../efuse.h" -#include "../base.h" #include "reg.h" #include "def.h" #include "phy.h" @@ -118,7 +117,7 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = { .set_bw_mode = rtl92c_phy_set_bw_mode, .switch_channel = rtl92c_phy_sw_chnl, .dm_watchdog = rtl92c_dm_watchdog, - .scan_operation_backup = rtl_phy_scan_operation_backup, + .scan_operation_backup = rtl92c_phy_scan_operation_backup, .set_rf_power_state = rtl92cu_phy_set_rf_power_state, .led_control = rtl92cu_led_control, .enable_hw_sec = rtl92cu_enable_hw_security_config, diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 1bc21cc..5a060e5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -303,10 +303,10 @@ out: bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, struct ieee80211_rx_status *rx_status, - u8 *pdesc, struct sk_buff *skb) + u8 *p_desc, struct sk_buff *skb) { struct rx_fwinfo_92c *p_drvinfo; - struct rx_desc_92c *p_desc = (struct rx_desc_92c *)pdesc; + struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; u32 phystatus = GET_RX_DESC_PHY_STATUS(pdesc); stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc); @@ -345,11 +345,12 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, if (phystatus) { p_drvinfo = (struct rx_fwinfo_92c *)(skb->data + stats->rx_bufshift); - rtl92c_translate_rx_signal_stuff(hw, skb, stats, p_desc, + rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc, p_drvinfo); } /*rx_status->qual = stats->signal; */ - rx_status->signal = stats->recvsignalpower + 10; + rx_status->signal = stats->rssi + 10; + /*rx_status->noise = -stats->noise; */ return true; } @@ -364,6 +365,7 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb) u8 *rxdesc; struct rtl_stats stats = { .signal = 0, + .noise = -98, .rate = 0, }; struct rx_fwinfo_92c *p_drvinfo; diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c index 7908e1c..f700f7a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c @@ -840,9 +840,9 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( bool internal_pa = false; long ele_a = 0, ele_d, temp_cck, val_x, value32; long val_y, ele_c = 0; - u8 ofdm_index[3]; + u8 ofdm_index[2]; s8 cck_index = 0; - u8 ofdm_index_old[3] = {0, 0, 0}; + u8 ofdm_index_old[2] = {0, 0}; s8 cck_index_old = 0; u8 index; int i; @@ -1118,10 +1118,6 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( val_x, val_y, ele_a, ele_c, ele_d, val_x, val_y); - if (cck_index >= CCK_TABLE_SIZE) - cck_index = CCK_TABLE_SIZE - 1; - if (cck_index < 0) - cck_index = 0; if (rtlhal->current_bandtype == BAND_ON_2_4G) { /* Adjust CCK according to IQK result */ if (!rtlpriv->dm.cck_inch14) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index c4a7db9..7dd8f6d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -1194,7 +1194,25 @@ void rtl92d_linked_set_reg(struct ieee80211_hw *hw) * mac80211 will send pkt when scan */ void rtl92de_set_qos(struct ieee80211_hw *hw, int aci) { + struct rtl_priv *rtlpriv = rtl_priv(hw); rtl92d_dm_init_edca_turbo(hw); + return; + switch (aci) { + case AC1_BK: + rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f); + break; + case AC0_BE: + break; + case AC2_VI: + rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322); + break; + case AC3_VO: + rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); + break; + default: + RT_ASSERT(false, "invalid aci: %d !\n", aci); + break; + } } void rtl92de_enable_interrupt(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h b/drivers/net/wireless/rtlwifi/rtl8192de/hw.h index 1bc7b1a..7c9f7a2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.h @@ -55,9 +55,10 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, bool is_group, u8 enc_algo, bool is_wepkey, bool clear_all); -void rtl92de_write_dword_dbi(struct ieee80211_hw *hw, u16 offset, u32 value, - u8 direct); -u32 rtl92de_read_dword_dbi(struct ieee80211_hw *hw, u16 offset, u8 direct); +extern void rtl92de_write_dword_dbi(struct ieee80211_hw *hw, u16 offset, + u32 value, u8 direct); +extern u32 rtl92de_read_dword_dbi(struct ieee80211_hw *hw, u16 offset, + u8 direct); void rtl92de_suspend(struct ieee80211_hw *hw); void rtl92de_resume(struct ieee80211_hw *hw); void rtl92d_linked_set_reg(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 13196cc..840bac5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -1022,6 +1022,34 @@ void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) rtl92d_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); } +void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum io_type iotype; + + if (!is_hal_stop(rtlhal)) { + switch (operation) { + case SCAN_OPT_BACKUP: + rtlhal->current_bandtypebackup = + rtlhal->current_bandtype; + iotype = IO_CMD_PAUSE_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + case SCAN_OPT_RESTORE: + iotype = IO_CMD_RESUME_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Unknown Scan Backup operation\n"); + break; + } + } +} + void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, enum nl80211_channel_type ch_type) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h index 48d5c68..f074952 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h @@ -39,7 +39,9 @@ #define RT_CANNOT_IO(hw) false #define HIGHPOWER_RADIOA_ARRAYLEN 22 +#define IQK_ADDA_REG_NUM 16 #define MAX_TOLERANCE 5 +#define IQK_DELAY_TIME 1 #define APK_BB_REG_NUM 5 #define APK_AFE_REG_NUM 16 @@ -125,32 +127,34 @@ static inline void rtl92d_release_cckandrw_pagea_ctl(struct ieee80211_hw *hw, *flag); } -u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask); -void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, u32 data); -u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask); -void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask, u32 data); -bool rtl92d_phy_mac_config(struct ieee80211_hw *hw); -bool rtl92d_phy_bb_config(struct ieee80211_hw *hw); -bool rtl92d_phy_rf_config(struct ieee80211_hw *hw); -bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, - enum radio_path rfpath); -void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); -void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); -void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, - enum nl80211_channel_type ch_type); -u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw); +extern u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +extern void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +extern u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask); +extern void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data); +extern bool rtl92d_phy_mac_config(struct ieee80211_hw *hw); +extern bool rtl92d_phy_bb_config(struct ieee80211_hw *hw); +extern bool rtl92d_phy_rf_config(struct ieee80211_hw *hw); +extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +extern void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +extern void rtl92d_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel); +extern void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw, + u8 operation); +extern void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +extern u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw); bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, enum rf_content content, enum radio_path rfpath); bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); -bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, - enum rf_pwrstate rfpwr_state); +extern bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw); void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw); @@ -169,5 +173,6 @@ void rtl92d_acquire_cckandrw_pagea_ctl(struct ieee80211_hw *hw, unsigned long *flag); u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl); void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel); +void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h b/drivers/net/wireless/rtlwifi/rtl8192de/rf.h index 7303d12..0fe1a48 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.h @@ -30,13 +30,15 @@ #ifndef __RTL92D_RF_H__ #define __RTL92D_RF_H__ -void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); -void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel); -void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel, u8 channel); -bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw); -bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0); -void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0); +extern void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, + u8 bandwidth); +extern void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +extern void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); +extern bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw); +extern bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0); +extern void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, + bool bmac0); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index edab5a5..c18c04b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -30,7 +30,6 @@ #include "../wifi.h" #include "../core.h" #include "../pci.h" -#include "../base.h" #include "reg.h" #include "def.h" #include "phy.h" @@ -237,7 +236,7 @@ static struct rtl_hal_ops rtl8192de_hal_ops = { .set_bw_mode = rtl92d_phy_set_bw_mode, .switch_channel = rtl92d_phy_sw_chnl, .dm_watchdog = rtl92d_dm_watchdog, - .scan_operation_backup = rtl_phy_scan_operation_backup, + .scan_operation_backup = rtl92d_phy_scan_operation_backup, .set_rf_power_state = rtl92d_phy_set_rf_power_state, .led_control = rtl92de_led_control, .set_desc = rtl92de_set_desc, diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index 0eb0f4a..b8ec718 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -525,7 +525,8 @@ bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, p_drvinfo); } /*rx_status->qual = stats->signal; */ - rx_status->signal = stats->recvsignalpower + 10; + rx_status->signal = stats->rssi + 10; + /*rx_status->noise = -stats->noise; */ return true; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h index c81c835..84d1181 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h @@ -425,9 +425,14 @@ #define EXT_IMEM_CODE_DONE BIT(2) #define IMEM_CHK_RPT BIT(1) #define IMEM_CODE_DONE BIT(0) +#define IMEM_CODE_DONE BIT(0) +#define IMEM_CHK_RPT BIT(1) #define EMEM_CODE_DONE BIT(2) #define EMEM_CHK_RPT BIT(3) +#define DMEM_CODE_DONE BIT(4) #define IMEM_RDY BIT(5) +#define BASECHG BIT(6) +#define FWRDY BIT(7) #define LOAD_FW_READY (IMEM_CODE_DONE | \ IMEM_CHK_RPT | \ EMEM_CODE_DONE | \ diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c index 92d38ab..5061f1d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c @@ -265,7 +265,7 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, rtlefuse->pwrgroup_ht40 [RF90_PATH_A][chnl - 1]) { pwrdiff_limit[i] = - rtlefuse->pwrgroup_ht40 + rtlefuse->pwrgroup_ht20 [RF90_PATH_A][chnl - 1]; } } else { diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 27efbcd..c709511 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -329,7 +329,8 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, } /*rx_status->qual = stats->signal; */ - rx_status->signal = stats->recvsignalpower + 10; + rx_status->signal = stats->rssi + 10; + /*rx_status->noise = -stats->noise; */ return true; } diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c index 5d318a8..eafbb18 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c @@ -934,6 +934,35 @@ static long _phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, return pwrout_dbm; } +void rtl8723ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + enum io_type iotype; + + if (!is_hal_stop(rtlhal)) { + switch (operation) { + case SCAN_OPT_BACKUP: + iotype = IO_CMD_PAUSE_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + + break; + case SCAN_OPT_RESTORE: + iotype = IO_CMD_RESUME_DM_BY_SCAN; + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_IO_CMD, + (u8 *)&iotype); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Unknown Scan Backup operation.\n"); + break; + } + } +} + void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h index 007ebdb..e7a59eb 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h @@ -183,40 +183,42 @@ struct tx_power_struct { u32 mcs_original_offset[4][16]; }; -u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask); -void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, u32 data); -u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask); -void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask, u32 data); -bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw); -bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw); -bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw); -bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, - enum radio_path rfpath); -void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); -void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, - long *powerlevel); -void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, - u8 channel); -bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, - long power_indbm); -void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw); -void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw, - enum nl80211_channel_type ch_type); -void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw); -u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw); -void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); +extern u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask); +extern void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw, + u32 regaddr, u32 bitmask, u32 data); +extern u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask); +extern void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw, + enum radio_path rfpath, u32 regaddr, + u32 bitmask, u32 data); +extern bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw); +extern bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw); +extern bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw); +extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, + enum radio_path rfpath); +extern void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); +extern void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, + long *powerlevel); +extern void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, + u8 channel); +extern bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, + long power_indbm); +extern void rtl8723ae_phy_scan_operation_backup(struct ieee80211_hw *hw, + u8 operation); +extern void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw); +extern void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw, + enum nl80211_channel_type ch_type); +extern void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw); +extern u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw); +extern void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw); void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, enum radio_path rfpath); bool rtl8723ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); -bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw, - enum rf_pwrstate rfpwr_state); +extern bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw, + enum rf_pwrstate rfpwr_state); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h index 57f1933..d0f9dd7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h @@ -32,11 +32,12 @@ #define RF6052_MAX_TX_PWR 0x3F -void rtl8723ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth); -void rtl8723ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel); -void rtl8723ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel, u8 channel); -bool rtl8723ae_phy_rf6052_config(struct ieee80211_hw *hw); +extern void rtl8723ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, + u8 bandwidth); +extern void rtl8723ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel); +extern void rtl8723ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, + u8 *ppowerlevel, u8 channel); +extern bool rtl8723ae_phy_rf6052_config(struct ieee80211_hw *hw); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c index 62b204f..d9ee2ef 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c @@ -33,7 +33,6 @@ #include "../core.h" #include "../pci.h" -#include "../base.h" #include "reg.h" #include "def.h" #include "phy.h" @@ -221,7 +220,7 @@ static struct rtl_hal_ops rtl8723ae_hal_ops = { .set_bw_mode = rtl8723ae_phy_set_bw_mode, .switch_channel = rtl8723ae_phy_sw_chnl, .dm_watchdog = rtl8723ae_dm_watchdog, - .scan_operation_backup = rtl_phy_scan_operation_backup, + .scan_operation_backup = rtl8723ae_phy_scan_operation_backup, .set_rf_power_state = rtl8723ae_phy_set_rf_power_state, .led_control = rtl8723ae_led_control, .set_desc = rtl8723ae_set_desc, diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c index 50b7be3..bcd82a1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c @@ -359,6 +359,7 @@ bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw, /*rx_status->qual = status->signal; */ rx_status->signal = status->recvsignalpower + 10; + /*rx_status->noise = -status->noise; */ return true; } diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 6e2b5c5..e56778c 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -455,6 +455,7 @@ static void _rtl_usb_rx_process_agg(struct ieee80211_hw *hw, struct ieee80211_rx_status rx_status = {0}; struct rtl_stats stats = { .signal = 0, + .noise = -98, .rate = 0, }; @@ -497,6 +498,7 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw, struct ieee80211_rx_status rx_status = {0}; struct rtl_stats stats = { .signal = 0, + .noise = -98, .rate = 0, }; @@ -580,15 +582,12 @@ static void _rtl_rx_work(unsigned long param) static unsigned int _rtl_rx_get_padding(struct ieee80211_hdr *hdr, unsigned int len) { -#if NET_IP_ALIGN != 0 unsigned int padding = 0; -#endif /* make function no-op when possible */ if (NET_IP_ALIGN == 0 || len < sizeof(*hdr)) return 0; -#if NET_IP_ALIGN != 0 /* alignment calculation as in lbtf_rx() / carl9170_rx_copy_data() */ /* TODO: deduplicate common code, define helper function instead? */ @@ -609,7 +608,6 @@ static unsigned int _rtl_rx_get_padding(struct ieee80211_hdr *hdr, padding ^= NET_IP_ALIGN; return padding; -#endif } #define __RADIO_TAP_SIZE_RSV 32 diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 0c65386..7032587 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -77,7 +77,11 @@ #define RTL_SLOT_TIME_9 9 #define RTL_SLOT_TIME_20 20 -/*related to tcp/ip. */ +/*related with tcp/ip. */ +/*if_ehther.h*/ +#define ETH_P_PAE 0x888E /*Port Access Entity (IEEE 802.1X) */ +#define ETH_P_IP 0x0800 /*Internet Protocol packet */ +#define ETH_P_ARP 0x0806 /*Address Resolution packet */ #define SNAP_SIZE 6 #define PROTOC_TYPE_SIZE 2 @@ -188,6 +192,8 @@ enum hardware_type { (IS_HARDWARE_TYPE_8192DE(rtlhal) || IS_HARDWARE_TYPE_8192DU(rtlhal)) #define IS_HARDWARE_TYPE_8723(rtlhal) \ (IS_HARDWARE_TYPE_8723E(rtlhal) || IS_HARDWARE_TYPE_8723U(rtlhal)) +#define IS_HARDWARE_TYPE_8723U(rtlhal) \ + (rtlhal->hw_type == HARDWARE_TYPE_RTL8723U) #define RX_HAL_IS_CCK_RATE(_pdesc)\ (_pdesc->rxmcs == DESC92_RATE1M || \ diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c index 1342f81..c7dc6fe 100644 --- a/drivers/net/wireless/ti/wl1251/spi.c +++ b/drivers/net/wireless/ti/wl1251/spi.c @@ -243,7 +243,7 @@ static int wl1251_spi_probe(struct spi_device *spi) struct wl1251 *wl; int ret; - pdata = dev_get_platdata(&spi->dev); + pdata = spi->dev.platform_data; if (!pdata) { wl1251_error("no platform data"); return -ENODEV; diff --git a/drivers/net/wireless/ti/wl1251/wl1251.h b/drivers/net/wireless/ti/wl1251/wl1251.h index 2c3bd1b..fd02060 100644 --- a/drivers/net/wireless/ti/wl1251/wl1251.h +++ b/drivers/net/wireless/ti/wl1251/wl1251.h @@ -424,8 +424,8 @@ void wl1251_disable_interrupts(struct wl1251 *wl); #define CHIP_ID_1271_PG10 (0x4030101) #define CHIP_ID_1271_PG20 (0x4030111) -#define WL1251_FW_NAME "ti-connectivity/wl1251-fw.bin" -#define WL1251_NVS_NAME "ti-connectivity/wl1251-nvs.bin" +#define WL1251_FW_NAME "wl1251-fw.bin" +#define WL1251_NVS_NAME "wl1251-nvs.bin" #define WL1251_POWER_ON_SLEEP 10 /* in milliseconds */ diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index be7129b..1c627da 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -333,11 +333,11 @@ static struct wlcore_conf wl12xx_conf = { .always = 0, }, .fwlog = { - .mode = WL12XX_FWLOG_CONTINUOUS, + .mode = WL12XX_FWLOG_ON_DEMAND, .mem_blocks = 2, .severity = 0, .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED, - .output = WL12XX_FWLOG_OUTPUT_DBG_PINS, + .output = WL12XX_FWLOG_OUTPUT_HOST, .threshold = 0, }, .rate = { @@ -717,9 +717,6 @@ static int wl12xx_identify_chip(struct wl1271 *wl) goto out; } - wl->fw_mem_block_size = 256; - wl->fwlog_end = 0x2000000; - /* common settings */ wl->scan_templ_id_2_4 = CMD_TEMPL_APP_PROBE_REQ_2_4_LEGACY; wl->scan_templ_id_5 = CMD_TEMPL_APP_PROBE_REQ_5_LEGACY; @@ -1265,10 +1262,9 @@ static int wl12xx_boot(struct wl1271 *wl) BA_SESSION_RX_CONSTRAINT_EVENT_ID | REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID | INACTIVE_STA_EVENT_ID | + MAX_TX_RETRY_EVENT_ID | CHANNEL_SWITCH_COMPLETE_EVENT_ID; - wl->ap_event_mask = MAX_TX_RETRY_EVENT_ID; - ret = wlcore_boot_run_firmware(wl); if (ret < 0) goto out; @@ -1652,11 +1648,6 @@ static bool wl12xx_lnk_low_prio(struct wl1271 *wl, u8 hlid, return true; } -static u32 wl12xx_convert_hwaddr(struct wl1271 *wl, u32 hwaddr) -{ - return hwaddr << 5; -} - static int wl12xx_setup(struct wl1271 *wl); static struct wlcore_ops wl12xx_ops = { @@ -1693,7 +1684,6 @@ static struct wlcore_ops wl12xx_ops = { .channel_switch = wl12xx_cmd_channel_switch, .pre_pkt_send = NULL, .set_peer_cap = wl12xx_set_peer_cap, - .convert_hwaddr = wl12xx_convert_hwaddr, .lnk_high_prio = wl12xx_lnk_high_prio, .lnk_low_prio = wl12xx_lnk_low_prio, }; @@ -1714,7 +1704,7 @@ static struct ieee80211_sta_ht_cap wl12xx_ht_cap = { static int wl12xx_setup(struct wl1271 *wl) { struct wl12xx_priv *priv = wl->priv; - struct wlcore_platdev_data *pdev_data = dev_get_platdata(&wl->pdev->dev); + struct wlcore_platdev_data *pdev_data = wl->pdev->dev.platform_data; struct wl12xx_platform_data *pdata = pdev_data->pdata; wl->rtable = wl12xx_rtable; diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index ec37b16..7aa0eb8 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -456,11 +456,11 @@ static struct wlcore_conf wl18xx_conf = { .always = 0, }, .fwlog = { - .mode = WL12XX_FWLOG_CONTINUOUS, + .mode = WL12XX_FWLOG_ON_DEMAND, .mem_blocks = 2, .severity = 0, .timestamp = WL12XX_FWLOG_TIMESTAMP_DISABLED, - .output = WL12XX_FWLOG_OUTPUT_DBG_PINS, + .output = WL12XX_FWLOG_OUTPUT_HOST, .threshold = 0, }, .rate = { @@ -505,7 +505,7 @@ static struct wlcore_conf wl18xx_conf = { static struct wl18xx_priv_conf wl18xx_default_priv_conf = { .ht = { - .mode = HT_MODE_WIDE, + .mode = HT_MODE_DEFAULT, }, .phy = { .phy_standalone = 0x00, @@ -516,7 +516,7 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = { .auto_detect = 0x00, .dedicated_fem = FEM_NONE, .low_band_component = COMPONENT_3_WAY_SWITCH, - .low_band_component_type = 0x05, + .low_band_component_type = 0x04, .high_band_component = COMPONENT_2_WAY_SWITCH, .high_band_component_type = 0x09, .tcxo_ldo_voltage = 0x00, @@ -556,15 +556,15 @@ static struct wl18xx_priv_conf wl18xx_default_priv_conf = { .per_chan_pwr_limit_arr_11p = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, .psat = 0, + .low_power_val = 0x08, + .med_power_val = 0x12, + .high_power_val = 0x18, + .low_power_val_2nd = 0x05, + .med_power_val_2nd = 0x0a, + .high_power_val_2nd = 0x14, .external_pa_dc2dc = 0, .number_of_assembled_ant2_4 = 2, .number_of_assembled_ant5 = 1, - .low_power_val = 0xff, - .med_power_val = 0xff, - .high_power_val = 0xff, - .low_power_val_2nd = 0xff, - .med_power_val_2nd = 0xff, - .high_power_val_2nd = 0xff, .tx_rf_margin = 1, }, }; @@ -623,18 +623,6 @@ static const int wl18xx_rtable[REG_TABLE_LEN] = { [REG_RAW_FW_STATUS_ADDR] = WL18XX_FW_STATUS_ADDR, }; -static const struct wl18xx_clk_cfg wl18xx_clk_table_coex[NUM_CLOCK_CONFIGS] = { - [CLOCK_CONFIG_16_2_M] = { 8, 121, 0, 0, false }, - [CLOCK_CONFIG_16_368_M] = { 8, 120, 0, 0, false }, - [CLOCK_CONFIG_16_8_M] = { 8, 117, 0, 0, false }, - [CLOCK_CONFIG_19_2_M] = { 10, 128, 0, 0, false }, - [CLOCK_CONFIG_26_M] = { 11, 104, 0, 0, false }, - [CLOCK_CONFIG_32_736_M] = { 8, 120, 0, 0, false }, - [CLOCK_CONFIG_33_6_M] = { 8, 117, 0, 0, false }, - [CLOCK_CONFIG_38_468_M] = { 10, 128, 0, 0, false }, - [CLOCK_CONFIG_52_M] = { 11, 104, 0, 0, false }, -}; - static const struct wl18xx_clk_cfg wl18xx_clk_table[NUM_CLOCK_CONFIGS] = { [CLOCK_CONFIG_16_2_M] = { 7, 104, 801, 4, true }, [CLOCK_CONFIG_16_368_M] = { 9, 132, 3751, 4, true }, @@ -686,9 +674,6 @@ static int wl18xx_identify_chip(struct wl1271 *wl) goto out; } - wl->fw_mem_block_size = 272; - wl->fwlog_end = 0x40000000; - wl->scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4; wl->scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5; wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC; @@ -719,23 +704,6 @@ static int wl18xx_set_clk(struct wl1271 *wl) wl18xx_clk_table[clk_freq].p, wl18xx_clk_table[clk_freq].q, wl18xx_clk_table[clk_freq].swallow ? "swallow" : "spit"); - /* coex PLL configuration */ - ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_N, - wl18xx_clk_table_coex[clk_freq].n); - if (ret < 0) - goto out; - - ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_M, - wl18xx_clk_table_coex[clk_freq].m); - if (ret < 0) - goto out; - - /* bypass the swallowing logic */ - ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_SWALLOW_EN, - PLLSH_COEX_PLL_SWALLOW_EN_VAL1); - if (ret < 0) - goto out; - ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_N, wl18xx_clk_table[clk_freq].n); if (ret < 0) @@ -777,30 +745,6 @@ static int wl18xx_set_clk(struct wl1271 *wl) PLLSH_WCS_PLL_SWALLOW_EN_VAL2); } - /* choose WCS PLL */ - ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_SEL, - PLLSH_WL_PLL_SEL_WCS_PLL); - if (ret < 0) - goto out; - - /* enable both PLLs */ - ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_EN, PLLSH_WL_PLL_EN_VAL1); - if (ret < 0) - goto out; - - udelay(1000); - - /* disable coex PLL */ - ret = wl18xx_top_reg_write(wl, PLLSH_WL_PLL_EN, PLLSH_WL_PLL_EN_VAL2); - if (ret < 0) - goto out; - - /* reset the swallowing logic */ - ret = wl18xx_top_reg_write(wl, PLLSH_COEX_PLL_SWALLOW_EN, - PLLSH_COEX_PLL_SWALLOW_EN_VAL2); - if (ret < 0) - goto out; - out: return ret; } @@ -991,11 +935,10 @@ static int wl18xx_boot(struct wl1271 *wl) BA_SESSION_RX_CONSTRAINT_EVENT_ID | REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID | INACTIVE_STA_EVENT_ID | + MAX_TX_FAILURE_EVENT_ID | CHANNEL_SWITCH_COMPLETE_EVENT_ID | DFS_CHANNELS_CONFIG_COMPLETE_EVENT; - wl->ap_event_mask = MAX_TX_FAILURE_EVENT_ID; - ret = wlcore_boot_run_firmware(wl); if (ret < 0) goto out; @@ -1232,48 +1175,16 @@ static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl, } } -static const char *wl18xx_rdl_name(enum wl18xx_rdl_num rdl_num) -{ - switch (rdl_num) { - case RDL_1_HP: - return "183xH"; - case RDL_2_SP: - return "183x or 180x"; - case RDL_3_HP: - return "187xH"; - case RDL_4_SP: - return "187x"; - case RDL_5_SP: - return "RDL11 - Not Supported"; - case RDL_6_SP: - return "180xD"; - case RDL_7_SP: - return "RDL13 - Not Supported (1893Q)"; - case RDL_8_SP: - return "18xxQ"; - case RDL_NONE: - return "UNTRIMMED"; - default: - return "UNKNOWN"; - } -} - static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver) { u32 fuse; - s8 rom = 0, metal = 0, pg_ver = 0, rdl_ver = 0, package_type = 0; + s8 rom = 0, metal = 0, pg_ver = 0, rdl_ver = 0; int ret; ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); if (ret < 0) goto out; - ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_2_3, &fuse); - if (ret < 0) - goto out; - - package_type = (fuse >> WL18XX_PACKAGE_TYPE_OFFSET) & 1; - ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_1_3, &fuse); if (ret < 0) goto out; @@ -1281,7 +1192,7 @@ static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver) pg_ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET; rom = (fuse & WL18XX_ROM_VER_MASK) >> WL18XX_ROM_VER_OFFSET; - if ((rom <= 0xE) && (package_type == WL18XX_PACKAGE_TYPE_WSP)) + if (rom <= 0xE) metal = (fuse & WL18XX_METAL_VER_MASK) >> WL18XX_METAL_VER_OFFSET; else @@ -1293,9 +1204,11 @@ static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver) goto out; rdl_ver = (fuse & WL18XX_RDL_VER_MASK) >> WL18XX_RDL_VER_OFFSET; + if (rdl_ver > RDL_MAX) + rdl_ver = RDL_NONE; - wl1271_info("wl18xx HW: %s, PG %d.%d (ROM 0x%x)", - wl18xx_rdl_name(rdl_ver), pg_ver, metal, rom); + wl1271_info("wl18xx HW: RDL %d, %s, PG %x.%x (ROM %x)", + rdl_ver, rdl_names[rdl_ver], pg_ver, metal, rom); if (ver) *ver = pg_ver; @@ -1608,11 +1521,6 @@ static bool wl18xx_lnk_low_prio(struct wl1271 *wl, u8 hlid, return lnk->allocated_pkts < thold; } -static u32 wl18xx_convert_hwaddr(struct wl1271 *wl, u32 hwaddr) -{ - return hwaddr & ~0x80000000; -} - static int wl18xx_setup(struct wl1271 *wl); static struct wlcore_ops wl18xx_ops = { @@ -1650,7 +1558,6 @@ static struct wlcore_ops wl18xx_ops = { .pre_pkt_send = wl18xx_pre_pkt_send, .sta_rc_update = wl18xx_sta_rc_update, .set_peer_cap = wl18xx_set_peer_cap, - .convert_hwaddr = wl18xx_convert_hwaddr, .lnk_high_prio = wl18xx_lnk_high_prio, .lnk_low_prio = wl18xx_lnk_low_prio, }; diff --git a/drivers/net/wireless/ti/wl18xx/reg.h b/drivers/net/wireless/ti/wl18xx/reg.h index a433a75..05dd8ba 100644 --- a/drivers/net/wireless/ti/wl18xx/reg.h +++ b/drivers/net/wireless/ti/wl18xx/reg.h @@ -114,11 +114,6 @@ #define PLATFORM_DETECTION 0xA0E3E0 #define OCS_EN 0xA02080 #define PRIMARY_CLK_DETECT 0xA020A6 -#define PLLSH_COEX_PLL_N 0xA02384 -#define PLLSH_COEX_PLL_M 0xA02382 -#define PLLSH_COEX_PLL_SWALLOW_EN 0xA0238E -#define PLLSH_WL_PLL_SEL 0xA02398 - #define PLLSH_WCS_PLL_N 0xA02362 #define PLLSH_WCS_PLL_M 0xA02360 #define PLLSH_WCS_PLL_Q_FACTOR_CFG_1 0xA02364 @@ -133,30 +128,19 @@ #define PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK 0xFFFF #define PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK 0x000F -#define PLLSH_WL_PLL_EN_VAL1 0x7 -#define PLLSH_WL_PLL_EN_VAL2 0x2 -#define PLLSH_COEX_PLL_SWALLOW_EN_VAL1 0x2 -#define PLLSH_COEX_PLL_SWALLOW_EN_VAL2 0x11 - #define PLLSH_WCS_PLL_SWALLOW_EN_VAL1 0x1 #define PLLSH_WCS_PLL_SWALLOW_EN_VAL2 0x12 -#define PLLSH_WL_PLL_SEL_WCS_PLL 0x0 -#define PLLSH_WL_PLL_SEL_COEX_PLL 0x1 - #define WL18XX_REG_FUSE_DATA_1_3 0xA0260C #define WL18XX_PG_VER_MASK 0x70 #define WL18XX_PG_VER_OFFSET 4 -#define WL18XX_ROM_VER_MASK 0x3e00 -#define WL18XX_ROM_VER_OFFSET 9 +#define WL18XX_ROM_VER_MASK 0x3 +#define WL18XX_ROM_VER_OFFSET 0 #define WL18XX_METAL_VER_MASK 0xC #define WL18XX_METAL_VER_OFFSET 2 #define WL18XX_NEW_METAL_VER_MASK 0x180 #define WL18XX_NEW_METAL_VER_OFFSET 7 -#define WL18XX_PACKAGE_TYPE_OFFSET 13 -#define WL18XX_PACKAGE_TYPE_WSP 0 - #define WL18XX_REG_FUSE_DATA_2_3 0xA02614 #define WL18XX_RDL_VER_MASK 0x1f00 #define WL18XX_RDL_VER_OFFSET 8 @@ -217,21 +201,24 @@ enum { NUM_BOARD_TYPES, }; -enum wl18xx_rdl_num { +enum { RDL_NONE = 0, RDL_1_HP = 1, RDL_2_SP = 2, RDL_3_HP = 3, RDL_4_SP = 4, - RDL_5_SP = 0x11, - RDL_6_SP = 0x12, - RDL_7_SP = 0x13, - RDL_8_SP = 0x14, _RDL_LAST, RDL_MAX = _RDL_LAST - 1, }; +static const char * const rdl_names[] = { + [RDL_NONE] = "", + [RDL_1_HP] = "1853 SISO", + [RDL_2_SP] = "1857 MIMO", + [RDL_3_HP] = "1893 SISO", + [RDL_4_SP] = "1897 MIMO", +}; /* FPGA_SPARE_1 register - used to change the PHY ATPG clock at boot time */ #define WL18XX_PHY_FPGA_SPARE_1 0x8093CA40 diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c index ec83675..7a970cd 100644 --- a/drivers/net/wireless/ti/wlcore/acx.c +++ b/drivers/net/wireless/ti/wlcore/acx.c @@ -162,8 +162,7 @@ int wl1271_acx_mem_map(struct wl1271 *wl, struct acx_header *mem_map, wl1271_debug(DEBUG_ACX, "acx mem map"); - ret = wl1271_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, - sizeof(struct acx_header), len); + ret = wl1271_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len); if (ret < 0) return ret; @@ -723,7 +722,6 @@ int wl1271_acx_statistics(struct wl1271 *wl, void *stats) wl1271_debug(DEBUG_ACX, "acx statistics"); ret = wl1271_cmd_interrogate(wl, ACX_STATISTICS, stats, - sizeof(struct acx_header), wl->stats.fw_stats_len); if (ret < 0) { wl1271_warning("acx statistics failed: %d", ret); @@ -1472,8 +1470,8 @@ int wl12xx_acx_tsf_info(struct wl1271 *wl, struct wl12xx_vif *wlvif, tsf_info->role_id = wlvif->role_id; - ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO, tsf_info, - sizeof(struct acx_header), sizeof(*tsf_info)); + ret = wl1271_cmd_interrogate(wl, ACX_TSF_INFO, + tsf_info, sizeof(*tsf_info)); if (ret < 0) { wl1271_warning("acx tsf info interrogate failed"); goto out; @@ -1754,7 +1752,7 @@ int wlcore_acx_average_rssi(struct wl1271 *wl, struct wl12xx_vif *wlvif, acx->role_id = wlvif->role_id; ret = wl1271_cmd_interrogate(wl, ACX_ROAMING_STATISTICS_TBL, - acx, sizeof(*acx), sizeof(*acx)); + acx, sizeof(*acx)); if (ret < 0) { wl1271_warning("acx roaming statistics failed: %d", ret); ret = -ENOMEM; diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 34d9dff..c9e0607 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -60,8 +60,7 @@ static int __wlcore_cmd_send(struct wl1271 *wl, u16 id, void *buf, u16 status; u16 poll_count = 0; - if (WARN_ON(wl->state == WLCORE_STATE_RESTARTING && - id != CMD_STOP_FWLOGGER)) + if (WARN_ON(unlikely(wl->state == WLCORE_STATE_RESTARTING))) return -EIO; cmd = buf; @@ -846,8 +845,7 @@ EXPORT_SYMBOL_GPL(wl1271_cmd_test); * @buf: buffer for the response, including all headers, must work with dma * @len: length of buf */ -int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, - size_t cmd_len, size_t res_len) +int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len) { struct acx_header *acx = buf; int ret; @@ -856,10 +854,10 @@ int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, acx->id = cpu_to_le16(id); - /* response payload length, does not include any headers */ - acx->len = cpu_to_le16(res_len - sizeof(*acx)); + /* payload length, does not include any headers */ + acx->len = cpu_to_le16(len - sizeof(*acx)); - ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, cmd_len, res_len); + ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx), len); if (ret < 0) wl1271_error("INTERROGATE command failed"); @@ -1128,8 +1126,6 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif, u16 template_id_2_4 = wl->scan_templ_id_2_4; u16 template_id_5 = wl->scan_templ_id_5; - wl1271_debug(DEBUG_SCAN, "build probe request band %d", band); - skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len, ie_len); if (!skb) { @@ -1139,6 +1135,8 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (ie_len) memcpy(skb_put(skb, ie_len), ie, ie_len); + wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len); + if (sched_scan && (wl->quirks & WLCORE_QUIRK_DUAL_PROBE_TMPL)) { template_id_2_4 = wl->sched_scan_templ_id_2_4; @@ -1174,7 +1172,7 @@ struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl, if (!skb) goto out; - wl1271_debug(DEBUG_SCAN, "set ap probe request template"); + wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len); rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[wlvif->band]); if (wlvif->band == IEEE80211_BAND_2GHZ) @@ -1609,43 +1607,33 @@ out: static int wlcore_get_reg_conf_ch_idx(enum ieee80211_band band, u16 ch) { - /* - * map the given band/channel to the respective predefined - * bit expected by the fw - */ + int idx = -1; + switch (band) { + case IEEE80211_BAND_5GHZ: + if (ch >= 8 && ch <= 16) + idx = ((ch-8)/4 + 18); + else if (ch >= 34 && ch <= 64) + idx = ((ch-34)/2 + 3 + 18); + else if (ch >= 100 && ch <= 140) + idx = ((ch-100)/4 + 15 + 18); + else if (ch >= 149 && ch <= 165) + idx = ((ch-149)/4 + 26 + 18); + else + idx = -1; + break; case IEEE80211_BAND_2GHZ: - /* channels 1..14 are mapped to 0..13 */ if (ch >= 1 && ch <= 14) - return ch - 1; - break; - case IEEE80211_BAND_5GHZ: - switch (ch) { - case 8 ... 16: - /* channels 8,12,16 are mapped to 18,19,20 */ - return 18 + (ch-8)/4; - case 34 ... 48: - /* channels 34,36..48 are mapped to 21..28 */ - return 21 + (ch-34)/2; - case 52 ... 64: - /* channels 52,56..64 are mapped to 29..32 */ - return 29 + (ch-52)/4; - case 100 ... 140: - /* channels 100,104..140 are mapped to 33..43 */ - return 33 + (ch-100)/4; - case 149 ... 165: - /* channels 149,153..165 are mapped to 44..48 */ - return 44 + (ch-149)/4; - default: - break; - } + idx = ch - 1; + else + idx = -1; break; default: - break; + wl1271_error("get reg conf ch idx - unknown band: %d", + (int)band); } - wl1271_error("%s: unknown band/channel: %d/%d", __func__, band, ch); - return -1; + return idx; } void wlcore_set_pending_regdomain_ch(struct wl1271 *wl, u16 channel, @@ -1658,7 +1646,7 @@ void wlcore_set_pending_regdomain_ch(struct wl1271 *wl, u16 channel, ch_bit_idx = wlcore_get_reg_conf_ch_idx(band, channel); - if (ch_bit_idx >= 0 && ch_bit_idx <= WL1271_MAX_CHANNELS) + if (ch_bit_idx > 0 && ch_bit_idx <= WL1271_MAX_CHANNELS) set_bit(ch_bit_idx, (long *)wl->reg_ch_conf_pending); } diff --git a/drivers/net/wireless/ti/wlcore/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h index 323d4a8..fd34123 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.h +++ b/drivers/net/wireless/ti/wlcore/cmd.h @@ -45,8 +45,7 @@ int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif, enum ieee80211_band band, int channel); int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif); int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); -int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, - size_t cmd_len, size_t res_len); +int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); int wlcore_cmd_configure_failsafe(struct wl1271 *wl, u16 id, void *buf, size_t len, unsigned long valid_rets); diff --git a/drivers/net/wireless/ti/wlcore/conf.h b/drivers/net/wireless/ti/wlcore/conf.h index 40995c4..2b96ff8 100644 --- a/drivers/net/wireless/ti/wlcore/conf.h +++ b/drivers/net/wireless/ti/wlcore/conf.h @@ -1274,9 +1274,6 @@ struct conf_rx_streaming_settings { u8 always; } __packed; -#define CONF_FWLOG_MIN_MEM_BLOCKS 2 -#define CONF_FWLOG_MAX_MEM_BLOCKS 16 - struct conf_fwlog { /* Continuous or on-demand */ u8 mode; @@ -1284,7 +1281,7 @@ struct conf_fwlog { /* * Number of memory blocks dedicated for the FW logger * - * Range: 2-16, or 0 to disable the FW logger + * Range: 1-3, or 0 to disable the FW logger */ u8 mem_blocks; diff --git a/drivers/net/wireless/ti/wlcore/debugfs.c b/drivers/net/wireless/ti/wlcore/debugfs.c index 89893c7..e17630c 100644 --- a/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/drivers/net/wireless/ti/wlcore/debugfs.c @@ -437,7 +437,6 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf, int res = 0; ssize_t ret; char *buf; - struct wl12xx_vif *wlvif; #define DRIVER_STATE_BUF_LEN 1024 @@ -451,28 +450,12 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf, (res += scnprintf(buf + res, DRIVER_STATE_BUF_LEN - res,\ #x " = " fmt "\n", wl->x)) -#define DRIVER_STATE_PRINT_GENERIC(x, fmt, args...) \ - (res += scnprintf(buf + res, DRIVER_STATE_BUF_LEN - res,\ - #x " = " fmt "\n", args)) - #define DRIVER_STATE_PRINT_LONG(x) DRIVER_STATE_PRINT(x, "%ld") #define DRIVER_STATE_PRINT_INT(x) DRIVER_STATE_PRINT(x, "%d") #define DRIVER_STATE_PRINT_STR(x) DRIVER_STATE_PRINT(x, "%s") #define DRIVER_STATE_PRINT_LHEX(x) DRIVER_STATE_PRINT(x, "0x%lx") #define DRIVER_STATE_PRINT_HEX(x) DRIVER_STATE_PRINT(x, "0x%x") - wl12xx_for_each_wlvif_sta(wl, wlvif) { - if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) - continue; - - DRIVER_STATE_PRINT_GENERIC(channel, "%d (%s)", wlvif->channel, - wlvif->p2p ? "P2P-CL" : "STA"); - } - - wl12xx_for_each_wlvif_ap(wl, wlvif) - DRIVER_STATE_PRINT_GENERIC(channel, "%d (%s)", wlvif->channel, - wlvif->p2p ? "P2P-GO" : "AP"); - DRIVER_STATE_PRINT_INT(tx_blocks_available); DRIVER_STATE_PRINT_INT(tx_allocated_blocks); DRIVER_STATE_PRINT_INT(tx_allocated_pkts[0]); @@ -491,6 +474,7 @@ static ssize_t driver_state_read(struct file *file, char __user *user_buf, DRIVER_STATE_PRINT_INT(tx_blocks_freed); DRIVER_STATE_PRINT_INT(rx_counter); DRIVER_STATE_PRINT_INT(state); + DRIVER_STATE_PRINT_INT(channel); DRIVER_STATE_PRINT_INT(band); DRIVER_STATE_PRINT_INT(power_level); DRIVER_STATE_PRINT_INT(sg_enabled); diff --git a/drivers/net/wireless/ti/wlcore/event.c b/drivers/net/wireless/ti/wlcore/event.c index 8d3b349..67f6168 100644 --- a/drivers/net/wireless/ti/wlcore/event.c +++ b/drivers/net/wireless/ti/wlcore/event.c @@ -266,7 +266,6 @@ int wl1271_event_unmask(struct wl1271 *wl) { int ret; - wl1271_debug(DEBUG_EVENT, "unmasking event_mask 0x%x", wl->event_mask); ret = wl1271_acx_event_mbox_mask(wl, ~(wl->event_mask)); if (ret < 0) return ret; diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h index 51f8d63..7fd260c 100644 --- a/drivers/net/wireless/ti/wlcore/hw_ops.h +++ b/drivers/net/wireless/ti/wlcore/hw_ops.h @@ -222,15 +222,6 @@ wlcore_hw_set_peer_cap(struct wl1271 *wl, return 0; } -static inline u32 -wlcore_hw_convert_hwaddr(struct wl1271 *wl, u32 hwaddr) -{ - if (!wl->ops->convert_hwaddr) - BUG_ON(1); - - return wl->ops->convert_hwaddr(wl, hwaddr); -} - static inline bool wlcore_hw_lnk_high_prio(struct wl1271 *wl, u8 hlid, struct wl1271_link *lnk) diff --git a/drivers/net/wireless/ti/wlcore/init.c b/drivers/net/wireless/ti/wlcore/init.c index 7699f9d..5c6f11e 100644 --- a/drivers/net/wireless/ti/wlcore/init.c +++ b/drivers/net/wireless/ti/wlcore/init.c @@ -571,12 +571,6 @@ int wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif) ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); if (ret < 0) return ret; - - /* unmask ap events */ - wl->event_mask |= wl->ap_event_mask; - ret = wl1271_event_unmask(wl); - if (ret < 0) - return ret; /* first STA, no APs */ } else if (wl->sta_count == 0 && wl->ap_count == 0 && !is_ap) { u8 sta_auth = wl->conf.conn.sta_sleep_auth; diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h index 07e3d6a..af7d9f9 100644 --- a/drivers/net/wireless/ti/wlcore/io.h +++ b/drivers/net/wireless/ti/wlcore/io.h @@ -165,8 +165,8 @@ static inline int __must_check wlcore_read_hwaddr(struct wl1271 *wl, int hwaddr, int physical; int addr; - /* Convert from FW internal address which is chip arch dependent */ - addr = wl->ops->convert_hwaddr(wl, hwaddr); + /* Addresses are stored internally as addresses to 32 bytes blocks */ + addr = hwaddr << 5; physical = wlcore_translate_addr(wl, addr); diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 0368b9c..38995f9 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -44,7 +44,6 @@ #define WL1271_BOOT_RETRIES 3 static char *fwlog_param; -static int fwlog_mem_blocks = -1; static int bug_on_recovery = -1; static int no_recovery = -1; @@ -292,18 +291,6 @@ static void wlcore_adjust_conf(struct wl1271 *wl) { /* Adjust settings according to optional module parameters */ - /* Firmware Logger params */ - if (fwlog_mem_blocks != -1) { - if (fwlog_mem_blocks >= CONF_FWLOG_MIN_MEM_BLOCKS && - fwlog_mem_blocks <= CONF_FWLOG_MAX_MEM_BLOCKS) { - wl->conf.fwlog.mem_blocks = fwlog_mem_blocks; - } else { - wl1271_error( - "Illegal fwlog_mem_blocks=%d using default %d", - fwlog_mem_blocks, wl->conf.fwlog.mem_blocks); - } - } - if (fwlog_param) { if (!strcmp(fwlog_param, "continuous")) { wl->conf.fwlog.mode = WL12XX_FWLOG_CONTINUOUS; @@ -793,7 +780,6 @@ void wl12xx_queue_recovery_work(struct wl1271 *wl) if (wl->state == WLCORE_STATE_ON) { wl->state = WLCORE_STATE_RESTARTING; set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags); - wl1271_ps_elp_wakeup(wl); wlcore_disable_interrupts_nosync(wl); ieee80211_queue_work(wl->hw, &wl->recovery_work); } @@ -801,10 +787,19 @@ void wl12xx_queue_recovery_work(struct wl1271 *wl) size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen) { - size_t len; + size_t len = 0; + + /* The FW log is a length-value list, find where the log end */ + while (len < maxlen) { + if (memblock[len] == 0) + break; + if (len + memblock[len] + 1 > maxlen) + break; + len += memblock[len] + 1; + } /* Make sure we have enough room */ - len = min(maxlen, (size_t)(PAGE_SIZE - wl->fwlog_size)); + len = min(len, (size_t)(PAGE_SIZE - wl->fwlog_size)); /* Fill the FW log file, consumed by the sysfs fwlog entry */ memcpy(wl->fwlog + wl->fwlog_size, memblock, len); @@ -813,9 +808,10 @@ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen) return len; } +#define WLCORE_FW_LOG_END 0x2000000 + static void wl12xx_read_fwlog_panic(struct wl1271 *wl) { - struct wlcore_partition_set part, old_part; u32 addr; u32 offset; u32 end_of_log; @@ -828,7 +824,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) wl1271_info("Reading FW panic log"); - block = kmalloc(wl->fw_mem_block_size, GFP_KERNEL); + block = kmalloc(WL12XX_HW_BLOCK_SIZE, GFP_KERNEL); if (!block) return; @@ -854,31 +850,17 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) if (wl->conf.fwlog.mode == WL12XX_FWLOG_CONTINUOUS) { offset = sizeof(addr) + sizeof(struct wl1271_rx_descriptor); - end_of_log = wl->fwlog_end; + end_of_log = WLCORE_FW_LOG_END; } else { offset = sizeof(addr); end_of_log = addr; } - old_part = wl->curr_part; - memset(&part, 0, sizeof(part)); - /* Traverse the memory blocks linked list */ do { - part.mem.start = wlcore_hw_convert_hwaddr(wl, addr); - part.mem.size = PAGE_SIZE; - - ret = wlcore_set_partition(wl, &part); - if (ret < 0) { - wl1271_error("%s: set_partition start=0x%X size=%d", - __func__, part.mem.start, part.mem.size); - goto out; - } - - memset(block, 0, wl->fw_mem_block_size); - ret = wlcore_read_hwaddr(wl, addr, block, - wl->fw_mem_block_size, false); - + memset(block, 0, WL12XX_HW_BLOCK_SIZE); + ret = wlcore_read_hwaddr(wl, addr, block, WL12XX_HW_BLOCK_SIZE, + false); if (ret < 0) goto out; @@ -889,9 +871,8 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) * on demand mode and is equal to 0x2000000 in continuous mode. */ addr = le32_to_cpup((__le32 *)block); - if (!wl12xx_copy_fwlog(wl, block + offset, - wl->fw_mem_block_size - offset)) + WL12XX_HW_BLOCK_SIZE - offset)) break; } while (addr && (addr != end_of_log)); @@ -899,7 +880,6 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) out: kfree(block); - wlcore_set_partition(wl, &old_part); } static void wlcore_print_recovery(struct wl1271 *wl) @@ -944,8 +924,7 @@ static void wl1271_recovery_work(struct work_struct *work) goto out_unlock; if (!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)) { - if (wl->conf.fwlog.output == WL12XX_FWLOG_OUTPUT_HOST) - wl12xx_read_fwlog_panic(wl); + wl12xx_read_fwlog_panic(wl); wlcore_print_recovery(wl); } @@ -1083,8 +1062,7 @@ int wl1271_plt_start(struct wl1271 *wl, const enum plt_mode plt_mode) static const char* const PLT_MODE[] = { "PLT_OFF", "PLT_ON", - "PLT_FEM_DETECT", - "PLT_CHIP_AWAKE" + "PLT_FEM_DETECT" }; int ret; @@ -1110,11 +1088,9 @@ int wl1271_plt_start(struct wl1271 *wl, const enum plt_mode plt_mode) if (ret < 0) goto power_off; - if (plt_mode != PLT_CHIP_AWAKE) { - ret = wl->ops->plt_init(wl); - if (ret < 0) - goto power_off; - } + ret = wl->ops->plt_init(wl); + if (ret < 0) + goto power_off; wl->state = WLCORE_STATE_ON; wl1271_notice("firmware booted in PLT mode %s (%s)", @@ -1949,10 +1925,8 @@ static void wlcore_op_stop_locked(struct wl1271 *wl) /* * FW channels must be re-calibrated after recovery, - * save current Reg-Domain channel configuration and clear it. + * clear the last Reg-Domain channel configuration. */ - memcpy(wl->reg_ch_conf_pending, wl->reg_ch_conf_last, - sizeof(wl->reg_ch_conf_pending)); memset(wl->reg_ch_conf_last, 0, sizeof(wl->reg_ch_conf_last)); } @@ -2034,47 +2008,6 @@ out: mutex_unlock(&wl->mutex); } -static void wlcore_pending_auth_complete_work(struct work_struct *work) -{ - struct delayed_work *dwork; - struct wl1271 *wl; - struct wl12xx_vif *wlvif; - unsigned long time_spare; - int ret; - - dwork = container_of(work, struct delayed_work, work); - wlvif = container_of(dwork, struct wl12xx_vif, - pending_auth_complete_work); - wl = wlvif->wl; - - mutex_lock(&wl->mutex); - - if (unlikely(wl->state != WLCORE_STATE_ON)) - goto out; - - /* - * Make sure a second really passed since the last auth reply. Maybe - * a second auth reply arrived while we were stuck on the mutex. - * Check for a little less than the timeout to protect from scheduler - * irregularities. - */ - time_spare = jiffies + - msecs_to_jiffies(WLCORE_PEND_AUTH_ROC_TIMEOUT - 50); - if (!time_after(time_spare, wlvif->pending_auth_reply_time)) - goto out; - - ret = wl1271_ps_elp_wakeup(wl); - if (ret < 0) - goto out; - - /* cancel the ROC if active */ - wlcore_update_inconn_sta(wl, wlvif, NULL, false); - - wl1271_ps_elp_sleep(wl); -out: - mutex_unlock(&wl->mutex); -} - static int wl12xx_allocate_rate_policy(struct wl1271 *wl, u8 *idx) { u8 policy = find_first_zero_bit(wl->rate_policies_map, @@ -2226,8 +2159,6 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif) wlcore_channel_switch_work); INIT_DELAYED_WORK(&wlvif->connection_loss_work, wlcore_connection_loss_work); - INIT_DELAYED_WORK(&wlvif->pending_auth_complete_work, - wlcore_pending_auth_complete_work); INIT_LIST_HEAD(&wlvif->list); setup_timer(&wlvif->rx_streaming_timer, wl1271_rx_streaming_timer, @@ -2445,11 +2376,6 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, int ret = 0; u8 role_type; - if (wl->plt) { - wl1271_error("Adding Interface not allowed while in PLT mode"); - return -EBUSY; - } - vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | IEEE80211_VIF_SUPPORTS_CQM_RSSI; @@ -2646,12 +2572,6 @@ deinit: !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)) goto unlock; - if (wl->ap_count == 0 && is_ap) { - /* mask ap events */ - wl->event_mask &= ~wl->ap_event_mask; - wl1271_event_unmask(wl); - } - if (wl->ap_count == 0 && is_ap && wl->sta_count) { u8 sta_auth = wl->conf.conn.sta_sleep_auth; /* Configure for power according to debugfs */ @@ -2670,7 +2590,6 @@ unlock: cancel_work_sync(&wlvif->rx_streaming_disable_work); cancel_delayed_work_sync(&wlvif->connection_loss_work); cancel_delayed_work_sync(&wlvif->channel_switch_work); - cancel_delayed_work_sync(&wlvif->pending_auth_complete_work); mutex_lock(&wl->mutex); } @@ -2956,25 +2875,6 @@ static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif) wlvif->rate_set = wlvif->basic_rate_set; } -static void wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif, - bool idle) -{ - bool cur_idle = !test_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags); - - if (idle == cur_idle) - return; - - if (idle) { - clear_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags); - } else { - /* The current firmware only supports sched_scan in idle */ - if (wl->sched_vif == wlvif) - wl->ops->sched_scan_stop(wl, wlvif); - - set_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags); - } -} - static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, struct ieee80211_conf *conf, u32 changed) { @@ -4069,13 +3969,6 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl, } } else { if (test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) { - /* - * AP might be in ROC in case we have just - * sent auth reply. handle it. - */ - if (test_bit(wlvif->role_id, wl->roc_map)) - wl12xx_croc(wl, wlvif->role_id); - ret = wl12xx_cmd_role_stop_ap(wl, wlvif); if (ret < 0) goto out; @@ -4227,9 +4120,6 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, do_join = true; } - if (changed & BSS_CHANGED_IDLE && !is_ibss) - wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle); - if (changed & BSS_CHANGED_CQM) { bool enable = false; if (bss_conf->cqm_rssi_thold) @@ -4766,49 +4656,29 @@ static void wlcore_roc_if_possible(struct wl1271 *wl, wl12xx_roc(wl, wlvif, wlvif->role_id, wlvif->band, wlvif->channel); } -/* - * when wl_sta is NULL, we treat this call as if coming from a - * pending auth reply. - * wl->mutex must be taken and the FW must be awake when the call - * takes place. - */ -void wlcore_update_inconn_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, - struct wl1271_station *wl_sta, bool in_conn) +static void wlcore_update_inconn_sta(struct wl1271 *wl, + struct wl12xx_vif *wlvif, + struct wl1271_station *wl_sta, + bool in_connection) { - if (in_conn) { - if (WARN_ON(wl_sta && wl_sta->in_connection)) + if (in_connection) { + if (WARN_ON(wl_sta->in_connection)) return; - - if (!wlvif->ap_pending_auth_reply && - !wlvif->inconn_count) + wl_sta->in_connection = true; + if (!wlvif->inconn_count++) wlcore_roc_if_possible(wl, wlvif); - - if (wl_sta) { - wl_sta->in_connection = true; - wlvif->inconn_count++; - } else { - wlvif->ap_pending_auth_reply = true; - } } else { - if (wl_sta && !wl_sta->in_connection) + if (!wl_sta->in_connection) return; - if (WARN_ON(!wl_sta && !wlvif->ap_pending_auth_reply)) + wl_sta->in_connection = false; + wlvif->inconn_count--; + if (WARN_ON(wlvif->inconn_count < 0)) return; - if (WARN_ON(wl_sta && !wlvif->inconn_count)) - return; - - if (wl_sta) { - wl_sta->in_connection = false; - wlvif->inconn_count--; - } else { - wlvif->ap_pending_auth_reply = false; - } - - if (!wlvif->inconn_count && !wlvif->ap_pending_auth_reply && - test_bit(wlvif->role_id, wl->roc_map)) - wl12xx_croc(wl, wlvif->role_id); + if (!wlvif->inconn_count) + if (test_bit(wlvif->role_id, wl->roc_map)) + wl12xx_croc(wl, wlvif->role_id); } } @@ -5443,7 +5313,10 @@ static struct ieee80211_rate wl1271_rates_5ghz[] = { /* 5 GHz band channels for WL1273 */ static struct ieee80211_channel wl1271_channels_5ghz[] = { + { .hw_value = 7, .center_freq = 5035, .max_power = WLCORE_MAX_TXPWR }, { .hw_value = 8, .center_freq = 5040, .max_power = WLCORE_MAX_TXPWR }, + { .hw_value = 9, .center_freq = 5045, .max_power = WLCORE_MAX_TXPWR }, + { .hw_value = 11, .center_freq = 5055, .max_power = WLCORE_MAX_TXPWR }, { .hw_value = 12, .center_freq = 5060, .max_power = WLCORE_MAX_TXPWR }, { .hw_value = 16, .center_freq = 5080, .max_power = WLCORE_MAX_TXPWR }, { .hw_value = 34, .center_freq = 5170, .max_power = WLCORE_MAX_TXPWR }, @@ -6023,20 +5896,14 @@ static const struct wiphy_wowlan_support wlcore_wowlan_support = { }; #endif -static irqreturn_t wlcore_hardirq(int irq, void *cookie) -{ - return IRQ_WAKE_THREAD; -} - static void wlcore_nvs_cb(const struct firmware *fw, void *context) { struct wl1271 *wl = context; struct platform_device *pdev = wl->pdev; - struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev); + struct wlcore_platdev_data *pdev_data = pdev->dev.platform_data; struct wl12xx_platform_data *pdata = pdev_data->pdata; unsigned long irqflags; int ret; - irq_handler_t hardirq_fn = NULL; if (fw) { wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL); @@ -6065,14 +5932,12 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context) wl->platform_quirks = pdata->platform_quirks; wl->if_ops = pdev_data->if_ops; - if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) { + if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) irqflags = IRQF_TRIGGER_RISING; - hardirq_fn = wlcore_hardirq; - } else { + else irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT; - } - ret = request_threaded_irq(wl->irq, hardirq_fn, wlcore_irq, + ret = request_threaded_irq(wl->irq, NULL, wlcore_irq, irqflags, pdev->name, wl); if (ret < 0) { wl1271_error("request_irq() failed: %d", ret); @@ -6181,9 +6046,6 @@ module_param_named(fwlog, fwlog_param, charp, 0); MODULE_PARM_DESC(fwlog, "FW logger options: continuous, ondemand, dbgpins or disable"); -module_param(fwlog_mem_blocks, int, S_IRUSR | S_IWUSR); -MODULE_PARM_DESC(fwlog_mem_blocks, "fwlog mem_blocks"); - module_param(bug_on_recovery, int, S_IRUSR | S_IWUSR); MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery"); diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c index 26bfc36..98066d4 100644 --- a/drivers/net/wireless/ti/wlcore/ps.c +++ b/drivers/net/wireless/ti/wlcore/ps.c @@ -83,10 +83,6 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) struct wl12xx_vif *wlvif; u32 timeout; - /* We do not enter elp sleep in PLT mode */ - if (wl->plt) - return; - if (wl->sleep_auth != WL1271_PSM_ELP) return; diff --git a/drivers/net/wireless/ti/wlcore/scan.c b/drivers/net/wireless/ti/wlcore/scan.c index 7ed8620..f407101 100644 --- a/drivers/net/wireless/ti/wlcore/scan.c +++ b/drivers/net/wireless/ti/wlcore/scan.c @@ -92,31 +92,9 @@ out: static void wlcore_started_vifs_iter(void *data, u8 *mac, struct ieee80211_vif *vif) { - struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); - bool active = false; int *count = (int *)data; - /* - * count active interfaces according to interface type. - * checking only bss_conf.idle is bad for some cases, e.g. - * we don't want to count sta in p2p_find as active interface. - */ - switch (wlvif->bss_type) { - case BSS_TYPE_STA_BSS: - if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) - active = true; - break; - - case BSS_TYPE_AP_BSS: - if (wlvif->wl->active_sta_count > 0) - active = true; - break; - - default: - break; - } - - if (active) + if (!vif->bss_conf.idle) (*count)++; } @@ -196,7 +174,17 @@ wlcore_scan_get_channels(struct wl1271 *wl, /* if radar is set, we ignore the passive flag */ (radar || !!(flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive)) { - + wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", + req_channels[i]->band, + req_channels[i]->center_freq); + wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X", + req_channels[i]->hw_value, + req_channels[i]->flags); + wl1271_debug(DEBUG_SCAN, "max_power %d", + req_channels[i]->max_power); + wl1271_debug(DEBUG_SCAN, "min_dwell_time %d max dwell time %d", + min_dwell_time_active, + max_dwell_time_active); if (flags & IEEE80211_CHAN_RADAR) { channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS; @@ -234,17 +222,6 @@ wlcore_scan_get_channels(struct wl1271 *wl, *n_pactive_ch); } - wl1271_debug(DEBUG_SCAN, "freq %d, ch. %d, flags 0x%x, power %d, min/max_dwell %d/%d%s%s", - req_channels[i]->center_freq, - req_channels[i]->hw_value, - req_channels[i]->flags, - req_channels[i]->max_power, - min_dwell_time_active, - max_dwell_time_active, - flags & IEEE80211_CHAN_RADAR ? - ", DFS" : "", - flags & IEEE80211_CHAN_PASSIVE_SCAN ? - ", PASSIVE" : ""); j++; } } @@ -387,7 +364,7 @@ wlcore_scan_sched_scan_ssid_list(struct wl1271 *wl, struct cfg80211_ssid *ssids = req->ssids; int ret = 0, type, i, j, n_match_ssids = 0; - wl1271_debug((DEBUG_CMD | DEBUG_SCAN), "cmd sched scan ssid list"); + wl1271_debug(DEBUG_CMD, "cmd sched scan ssid list"); /* count the match sets that contain SSIDs */ for (i = 0; i < req->n_match_sets; i++) @@ -465,6 +442,8 @@ wlcore_scan_sched_scan_ssid_list(struct wl1271 *wl, } } + wl1271_dump(DEBUG_SCAN, "SSID_LIST: ", cmd, sizeof(*cmd)); + ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_SSID_CFG, cmd, sizeof(*cmd), 0); if (ret < 0) { diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti/wlcore/spi.c index b2c018d..1b0cd98 100644 --- a/drivers/net/wireless/ti/wlcore/spi.c +++ b/drivers/net/wireless/ti/wlcore/spi.c @@ -335,7 +335,7 @@ static int wl1271_probe(struct spi_device *spi) if (!pdev_data) goto out; - pdev_data->pdata = dev_get_platdata(&spi->dev); + pdev_data->pdata = spi->dev.platform_data; if (!pdev_data->pdata) { dev_err(&spi->dev, "no platform data\n"); ret = -ENODEV; diff --git a/drivers/net/wireless/ti/wlcore/testmode.c b/drivers/net/wireless/ti/wlcore/testmode.c index ddad58f..527590f 100644 --- a/drivers/net/wireless/ti/wlcore/testmode.c +++ b/drivers/net/wireless/ti/wlcore/testmode.c @@ -179,8 +179,7 @@ static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[]) goto out_sleep; } - ret = wl1271_cmd_interrogate(wl, ie_id, cmd, - sizeof(struct acx_header), sizeof(*cmd)); + ret = wl1271_cmd_interrogate(wl, ie_id, cmd, sizeof(*cmd)); if (ret < 0) { wl1271_warning("testmode cmd interrogate failed: %d", ret); goto out_free; @@ -298,8 +297,7 @@ static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[]) ret = wl1271_plt_stop(wl); break; case PLT_ON: - case PLT_CHIP_AWAKE: - ret = wl1271_plt_start(wl, val); + ret = wl1271_plt_start(wl, PLT_ON); break; case PLT_FEM_DETECT: ret = wl1271_tm_detect_fem(wl, tb); @@ -363,7 +361,6 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, { struct wl1271 *wl = hw->priv; struct nlattr *tb[WL1271_TM_ATTR_MAX + 1]; - u32 nla_cmd; int err; err = nla_parse(tb, WL1271_TM_ATTR_MAX, data, len, wl1271_tm_policy); @@ -373,14 +370,7 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, if (!tb[WL1271_TM_ATTR_CMD_ID]) return -EINVAL; - nla_cmd = nla_get_u32(tb[WL1271_TM_ATTR_CMD_ID]); - - /* Only SET_PLT_MODE is allowed in case of mode PLT_CHIP_AWAKE */ - if (wl->plt_mode == PLT_CHIP_AWAKE && - nla_cmd != WL1271_TM_CMD_SET_PLT_MODE) - return -EOPNOTSUPP; - - switch (nla_cmd) { + switch (nla_get_u32(tb[WL1271_TM_ATTR_CMD_ID])) { case WL1271_TM_CMD_TEST: return wl1271_tm_cmd_test(wl, tb); case WL1271_TM_CMD_INTERROGATE: diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index 87cd707..7e93fe6 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -86,34 +86,19 @@ void wl1271_free_tx_id(struct wl1271 *wl, int id) EXPORT_SYMBOL(wl1271_free_tx_id); static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl, - struct wl12xx_vif *wlvif, struct sk_buff *skb) { struct ieee80211_hdr *hdr; - hdr = (struct ieee80211_hdr *)(skb->data + - sizeof(struct wl1271_tx_hw_descr)); - if (!ieee80211_is_auth(hdr->frame_control)) - return; - /* * add the station to the known list before transmitting the * authentication response. this way it won't get de-authed by FW * when transmitting too soon. */ - wl1271_acx_set_inconnection_sta(wl, hdr->addr1); - - /* - * ROC for 1 second on the AP channel for completing the connection. - * Note the ROC will be continued by the update_sta_state callbacks - * once the station reaches the associated state. - */ - wlcore_update_inconn_sta(wl, wlvif, NULL, true); - wlvif->pending_auth_reply_time = jiffies; - cancel_delayed_work(&wlvif->pending_auth_complete_work); - ieee80211_queue_delayed_work(wl->hw, - &wlvif->pending_auth_complete_work, - msecs_to_jiffies(WLCORE_PEND_AUTH_ROC_TIMEOUT)); + hdr = (struct ieee80211_hdr *)(skb->data + + sizeof(struct wl1271_tx_hw_descr)); + if (ieee80211_is_auth(hdr->frame_control)) + wl1271_acx_set_inconnection_sta(wl, hdr->addr1); } static void wl1271_tx_regulate_link(struct wl1271 *wl, @@ -401,7 +386,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, is_wep = (cipher == WLAN_CIPHER_SUITE_WEP40) || (cipher == WLAN_CIPHER_SUITE_WEP104); - if (WARN_ON(is_wep && wlvif && wlvif->default_key != idx)) { + if (WARN_ON(is_wep && wlvif->default_key != idx)) { ret = wl1271_set_default_wep_key(wl, wlvif, idx); if (ret < 0) return ret; @@ -419,7 +404,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_tx_fill_hdr(wl, wlvif, skb, extra, info, hlid); if (!is_dummy && wlvif && wlvif->bss_type == BSS_TYPE_AP_BSS) { - wl1271_tx_ap_update_inconnection_sta(wl, wlvif, skb); + wl1271_tx_ap_update_inconnection_sta(wl, skb); wl1271_tx_regulate_link(wl, wlvif, hlid); } diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h index 35489c3..55aa4ac 100644 --- a/drivers/net/wireless/ti/wlcore/tx.h +++ b/drivers/net/wireless/ti/wlcore/tx.h @@ -56,9 +56,6 @@ /* Used for management frames and dummy packets */ #define WL1271_TID_MGMT 7 -/* stop a ROC for pending authentication reply after this time (ms) */ -#define WLCORE_PEND_AUTH_ROC_TIMEOUT 1000 - struct wl127x_tx_mem { /* * Number of extra memory blocks to allocate for this packet diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 06efc12..0034979 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h @@ -110,7 +110,6 @@ struct wlcore_ops { struct ieee80211_sta_ht_cap *ht_cap, bool allow_ht_operation, u32 rate_set, u8 hlid); - u32 (*convert_hwaddr)(struct wl1271 *wl, u32 hwaddr); bool (*lnk_high_prio)(struct wl1271 *wl, u8 hlid, struct wl1271_link *lnk); bool (*lnk_low_prio)(struct wl1271 *wl, u8 hlid, @@ -291,12 +290,6 @@ struct wl1271 { /* Number of valid bytes in the FW log buffer */ ssize_t fwlog_size; - /* FW log end marker */ - u32 fwlog_end; - - /* FW memory block size */ - u32 fw_mem_block_size; - /* Sysfs FW log entry readers wait queue */ wait_queue_head_t fwlog_waitq; @@ -314,8 +307,6 @@ struct wl1271 { /* The mbox event mask */ u32 event_mask; - /* events to unmask only when ap interface is up */ - u32 ap_event_mask; /* Mailbox pointers */ u32 mbox_size; @@ -490,8 +481,6 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, struct ieee80211_sta *sta, struct ieee80211_key_conf *key_conf); void wlcore_regdomain_config(struct wl1271 *wl); -void wlcore_update_inconn_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif, - struct wl1271_station *wl_sta, bool in_conn); static inline void wlcore_set_ht_cap(struct wl1271 *wl, enum ieee80211_band band, diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h index ce7261c..e5e1464 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore_i.h +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h @@ -255,7 +255,6 @@ enum wl12xx_vif_flags { WLVIF_FLAG_CS_PROGRESS, WLVIF_FLAG_AP_PROBE_RESP_SET, WLVIF_FLAG_IN_USE, - WLVIF_FLAG_ACTIVE, }; struct wl12xx_vif; @@ -308,7 +307,6 @@ enum plt_mode { PLT_OFF = 0, PLT_ON = 1, PLT_FEM_DETECT = 2, - PLT_CHIP_AWAKE = 3 }; struct wl12xx_rx_filter_field { @@ -458,15 +456,6 @@ struct wl12xx_vif { */ int hw_queue_base; - /* do we have a pending auth reply? (and ROC) */ - bool ap_pending_auth_reply; - - /* time when we sent the pending auth reply */ - unsigned long pending_auth_reply_time; - - /* work for canceling ROC after pending auth reply */ - struct delayed_work pending_auth_complete_work; - /* * This struct must be last! * data that has to be saved acrossed reconfigs (e.g. recovery) @@ -550,4 +539,6 @@ void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter, #define HW_HT_RATES_OFFSET 16 #define HW_MIMO_RATES_OFFSET 24 +#define WL12XX_HW_BLOCK_SIZE 256 + #endif /* __WLCORE_I_H__ */ diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index 84d94f5..7ef0b4a 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -1619,7 +1619,7 @@ static void prepare_read_regs_int(struct zd_usb *usb, atomic_set(&intr->read_regs_enabled, 1); intr->read_regs.req = req; intr->read_regs.req_count = count; - reinit_completion(&intr->read_regs.completion); + INIT_COMPLETION(intr->read_regs.completion); spin_unlock_irq(&intr->lock); } |