aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlegacy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlegacy')
-rw-r--r--drivers/net/wireless/iwlegacy/3945-debug.c12
-rw-r--r--drivers/net/wireless/iwlegacy/3945-mac.c437
-rw-r--r--drivers/net/wireless/iwlegacy/3945-rs.c25
-rw-r--r--drivers/net/wireless/iwlegacy/3945.c289
-rw-r--r--drivers/net/wireless/iwlegacy/3945.h98
-rw-r--r--drivers/net/wireless/iwlegacy/4965-calib.c36
-rw-r--r--drivers/net/wireless/iwlegacy/4965-debug.c12
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c1327
-rw-r--r--drivers/net/wireless/iwlegacy/4965-rs.c75
-rw-r--r--drivers/net/wireless/iwlegacy/4965.c704
-rw-r--r--drivers/net/wireless/iwlegacy/4965.h55
-rw-r--r--drivers/net/wireless/iwlegacy/Kconfig78
-rw-r--r--drivers/net/wireless/iwlegacy/commands.h14
-rw-r--r--drivers/net/wireless/iwlegacy/common.c1399
-rw-r--r--drivers/net/wireless/iwlegacy/common.h602
-rw-r--r--drivers/net/wireless/iwlegacy/debug.c311
16 files changed, 2430 insertions, 3044 deletions
diff --git a/drivers/net/wireless/iwlegacy/3945-debug.c b/drivers/net/wireless/iwlegacy/3945-debug.c
index 5e1a19fd354..c1b4441fb8b 100644
--- a/drivers/net/wireless/iwlegacy/3945-debug.c
+++ b/drivers/net/wireless/iwlegacy/3945-debug.c
@@ -48,7 +48,7 @@ il3945_stats_flag(struct il_priv *il, char *buf, int bufsz)
return p;
}
-ssize_t
+static ssize_t
il3945_ucode_rx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -313,7 +313,7 @@ il3945_ucode_rx_stats_read(struct file *file, char __user *user_buf,
return ret;
}
-ssize_t
+static ssize_t
il3945_ucode_tx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -403,7 +403,7 @@ il3945_ucode_tx_stats_read(struct file *file, char __user *user_buf,
return ret;
}
-ssize_t
+static ssize_t
il3945_ucode_general_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -503,3 +503,9 @@ il3945_ucode_general_stats_read(struct file *file, char __user *user_buf,
kfree(buf);
return ret;
}
+
+const struct il_debugfs_ops il3945_debugfs_ops = {
+ .rx_stats_read = il3945_ucode_rx_stats_read,
+ .tx_stats_read = il3945_ucode_tx_stats_read,
+ .general_stats_read = il3945_ucode_general_stats_read,
+};
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c
index a7dfba8d164..dc1d20cf64e 100644
--- a/drivers/net/wireless/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/iwlegacy/3945-mac.c
@@ -140,7 +140,7 @@ il3945_set_ccmp_dynamic_key_info(struct il_priv *il,
key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
- if (sta_id == il->ctx.bcast_sta_id)
+ if (sta_id == il->hw_params.bcast_id)
key_flags |= STA_KEY_MULTICAST_MSK;
keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -341,7 +341,7 @@ il3945_send_beacon_cmd(struct il_priv *il)
return -ENOMEM;
}
- rate = il_get_lowest_plcp(il, &il->ctx);
+ rate = il_get_lowest_plcp(il);
frame_size = il3945_hw_get_beacon_cmd(il, frame, rate);
@@ -460,7 +460,9 @@ il3945_build_tx_cmd_basic(struct il_priv *il, struct il_device_cmd *cmd,
* start C_TX command process
*/
static int
-il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
+il3945_tx_skb(struct il_priv *il,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -473,6 +475,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
dma_addr_t txcmd_phys;
int txq_id = skb_get_queue_mapping(skb);
u16 len, idx, hdr_len;
+ u16 firstlen, secondlen;
u8 id;
u8 unicast;
u8 sta_id;
@@ -512,7 +515,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
hdr_len = ieee80211_hdrlen(fc);
/* Find idx into station table for destination station */
- sta_id = il_sta_id_or_broadcast(il, &il->ctx, info->control.sta);
+ sta_id = il_sta_id_or_broadcast(il, sta);
if (sta_id == IL_INVALID_STATION) {
D_DROP("Dropping - INVALID STATION: %pM\n", hdr->addr1);
goto drop;
@@ -538,10 +541,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
idx = il_get_cmd_idx(q, q->write_ptr, 0);
- /* Set up driver data for this TFD */
- memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct il_tx_info));
- txq->txb[q->write_ptr].skb = skb;
- txq->txb[q->write_ptr].ctx = &il->ctx;
+ txq->skbs[q->write_ptr] = skb;
/* Init first empty entry in queue's array of Tx/cmd buffers */
out_cmd = txq->cmd[idx];
@@ -573,27 +573,11 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
il3945_hw_build_tx_cmd_rate(il, out_cmd, info, hdr, sta_id);
/* Total # bytes to be transmitted */
- len = (u16) skb->len;
- tx_cmd->len = cpu_to_le16(len);
+ tx_cmd->len = cpu_to_le16((u16) skb->len);
- il_dbg_log_tx_data_frame(il, len, hdr);
- il_update_stats(il, true, fc, len);
tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
tx_cmd->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
- if (!ieee80211_has_morefrags(hdr->frame_control)) {
- txq->need_update = 1;
- } else {
- wait_write_ptr = 1;
- txq->need_update = 0;
- }
-
- D_TX("sequence nr = 0X%x\n", le16_to_cpu(out_cmd->hdr.sequence));
- D_TX("tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags));
- il_print_hex_dump(il, IL_DL_TX, tx_cmd, sizeof(*tx_cmd));
- il_print_hex_dump(il, IL_DL_TX, (u8 *) tx_cmd->hdr,
- ieee80211_hdrlen(fc));
-
/*
* Use the first empty entry in this queue's command buffer array
* to contain the Tx command and MAC header concatenated together
@@ -606,33 +590,51 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb)
len =
sizeof(struct il3945_tx_cmd) + sizeof(struct il_cmd_header) +
hdr_len;
- len = (len + 3) & ~3;
+ firstlen = (len + 3) & ~3;
/* Physical address of this Tx command's header (not MAC header!),
* within command buffer array. */
txcmd_phys =
- pci_map_single(il->pci_dev, &out_cmd->hdr, len, PCI_DMA_TODEVICE);
- /* we do not map meta data ... so we can safely access address to
- * provide to unmap command*/
- dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
- dma_unmap_len_set(out_meta, len, len);
-
- /* Add buffer containing Tx command and MAC(!) header to TFD's
- * first entry */
- il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1,
- 0);
+ pci_map_single(il->pci_dev, &out_cmd->hdr, firstlen,
+ PCI_DMA_TODEVICE);
+ if (unlikely(pci_dma_mapping_error(il->pci_dev, txcmd_phys)))
+ goto drop_unlock;
/* Set up TFD's 2nd entry to point directly to remainder of skb,
* if any (802.11 null frames have no payload). */
- len = skb->len - hdr_len;
- if (len) {
+ secondlen = skb->len - hdr_len;
+ if (secondlen > 0) {
phys_addr =
- pci_map_single(il->pci_dev, skb->data + hdr_len, len,
+ pci_map_single(il->pci_dev, skb->data + hdr_len, secondlen,
PCI_DMA_TODEVICE);
- il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr,
- len, 0, U32_PAD(len));
+ if (unlikely(pci_dma_mapping_error(il->pci_dev, phys_addr)))
+ goto drop_unlock;
}
+ /* Add buffer containing Tx command and MAC(!) header to TFD's
+ * first entry */
+ il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, 1, 0);
+ dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
+ dma_unmap_len_set(out_meta, len, firstlen);
+ if (secondlen > 0)
+ il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, secondlen, 0,
+ U32_PAD(secondlen));
+
+ if (!ieee80211_has_morefrags(hdr->frame_control)) {
+ txq->need_update = 1;
+ } else {
+ wait_write_ptr = 1;
+ txq->need_update = 0;
+ }
+
+ il_update_stats(il, true, fc, skb->len);
+
+ D_TX("sequence nr = 0X%x\n", le16_to_cpu(out_cmd->hdr.sequence));
+ D_TX("tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags));
+ il_print_hex_dump(il, IL_DL_TX, tx_cmd, sizeof(*tx_cmd));
+ il_print_hex_dump(il, IL_DL_TX, (u8 *) tx_cmd->hdr,
+ ieee80211_hdrlen(fc));
+
/* Tell device the write idx *just past* this latest filled TFD */
q->write_ptr = il_queue_inc_wrap(q->write_ptr, q->n_bd);
il_txq_update_write_ptr(il, txq);
@@ -672,15 +674,13 @@ il3945_get_measurement(struct il_priv *il,
int rc;
int spectrum_resp_status;
int duration = le16_to_cpu(params->duration);
- struct il_rxon_context *ctx = &il->ctx;
if (il_is_associated(il))
add_time =
il_usecs_to_beacons(il,
le64_to_cpu(params->start_time) -
il->_3945.last_tsf,
- le16_to_cpu(ctx->timing.
- beacon_interval));
+ le16_to_cpu(il->timing.beacon_interval));
memset(&spectrum, 0, sizeof(spectrum));
@@ -694,15 +694,14 @@ il3945_get_measurement(struct il_priv *il,
if (il_is_associated(il))
spectrum.start_time =
il_add_beacon_time(il, il->_3945.last_beacon_time, add_time,
- le16_to_cpu(ctx->timing.
- beacon_interval));
+ le16_to_cpu(il->timing.beacon_interval));
else
spectrum.start_time = 0;
spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
spectrum.channels[0].channel = params->channel;
spectrum.channels[0].type = type;
- if (ctx->active.flags & RXON_FLG_BAND_24G_MSK)
+ if (il->active.flags & RXON_FLG_BAND_24G_MSK)
spectrum.flags |=
RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK |
RXON_FLG_TGG_PROTECT_MSK;
@@ -817,16 +816,16 @@ il3945_hdl_card_state(struct il_priv *il, struct il_rx_buf *rxb)
_il_wr(il, CSR_UCODE_DRV_GP1_SET, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
if (flags & HW_CARD_DISABLED)
- set_bit(S_RF_KILL_HW, &il->status);
+ set_bit(S_RFKILL, &il->status);
else
- clear_bit(S_RF_KILL_HW, &il->status);
+ clear_bit(S_RFKILL, &il->status);
il_scan_cancel(il);
- if ((test_bit(S_RF_KILL_HW, &status) !=
- test_bit(S_RF_KILL_HW, &il->status)))
+ if ((test_bit(S_RFKILL, &status) !=
+ test_bit(S_RFKILL, &il->status)))
wiphy_rfkill_set_hw_state(il->hw->wiphy,
- test_bit(S_RF_KILL_HW, &il->status));
+ test_bit(S_RFKILL, &il->status));
else
wake_up(&il->wait_command_queue);
}
@@ -1007,12 +1006,12 @@ il3945_rx_allocate(struct il_priv *il, gfp_t priority)
struct list_head *element;
struct il_rx_buf *rxb;
struct page *page;
+ dma_addr_t page_dma;
unsigned long flags;
gfp_t gfp_mask = priority;
while (1) {
spin_lock_irqsave(&rxq->lock, flags);
-
if (list_empty(&rxq->rx_used)) {
spin_unlock_irqrestore(&rxq->lock, flags);
return;
@@ -1041,26 +1040,34 @@ il3945_rx_allocate(struct il_priv *il, gfp_t priority)
break;
}
+ /* Get physical address of RB/SKB */
+ page_dma =
+ pci_map_page(il->pci_dev, page, 0,
+ PAGE_SIZE << il->hw_params.rx_page_order,
+ PCI_DMA_FROMDEVICE);
+
+ if (unlikely(pci_dma_mapping_error(il->pci_dev, page_dma))) {
+ __free_pages(page, il->hw_params.rx_page_order);
+ break;
+ }
+
spin_lock_irqsave(&rxq->lock, flags);
+
if (list_empty(&rxq->rx_used)) {
spin_unlock_irqrestore(&rxq->lock, flags);
+ pci_unmap_page(il->pci_dev, page_dma,
+ PAGE_SIZE << il->hw_params.rx_page_order,
+ PCI_DMA_FROMDEVICE);
__free_pages(page, il->hw_params.rx_page_order);
return;
}
+
element = rxq->rx_used.next;
rxb = list_entry(element, struct il_rx_buf, list);
list_del(element);
- spin_unlock_irqrestore(&rxq->lock, flags);
rxb->page = page;
- /* Get physical address of RB/SKB */
- rxb->page_dma =
- pci_map_page(il->pci_dev, page, 0,
- PAGE_SIZE << il->hw_params.rx_page_order,
- PCI_DMA_FROMDEVICE);
-
- spin_lock_irqsave(&rxq->lock, flags);
-
+ rxb->page_dma = page_dma;
list_add_tail(&rxb->list, &rxq->rx_free);
rxq->free_count++;
il->alloc_rxb_page++;
@@ -1241,14 +1248,7 @@ il3945_rx_handle(struct il_priv *il)
len = le32_to_cpu(pkt->len_n_flags) & IL_RX_FRAME_SIZE_MSK;
len += sizeof(u32); /* account for status word */
- /* Reclaim a command buffer only if this packet is a response
- * to a (driver-originated) command.
- * If the packet (e.g. Rx frame) originated from uCode,
- * there is no command buffer to reclaim.
- * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
- * but apparently a few don't get set; catch them here. */
- reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
- pkt->hdr.cmd != N_STATS && pkt->hdr.cmd != C_TX;
+ reclaim = il_need_reclaim(il, pkt);
/* Based on type of command response or notification,
* handle those that need handling via function in
@@ -1290,8 +1290,15 @@ il3945_rx_handle(struct il_priv *il)
pci_map_page(il->pci_dev, rxb->page, 0,
PAGE_SIZE << il->hw_params.
rx_page_order, PCI_DMA_FROMDEVICE);
- list_add_tail(&rxb->list, &rxq->rx_free);
- rxq->free_count++;
+ if (unlikely(pci_dma_mapping_error(il->pci_dev,
+ rxb->page_dma))) {
+ __il_free_pages(il, rxb->page);
+ rxb->page = NULL;
+ list_add_tail(&rxb->list, &rxq->rx_used);
+ } else {
+ list_add_tail(&rxb->list, &rxq->rx_free);
+ rxq->free_count++;
+ }
} else
list_add_tail(&rxb->list, &rxq->rx_used);
@@ -1481,12 +1488,14 @@ il3945_irq_tasklet(struct il_priv *il)
if (inta & CSR_INT_BIT_WAKEUP) {
D_ISR("Wakeup interrupt\n");
il_rx_queue_update_write_ptr(il, &il->rxq);
+
+ spin_lock_irqsave(&il->lock, flags);
il_txq_update_write_ptr(il, &il->txq[0]);
il_txq_update_write_ptr(il, &il->txq[1]);
il_txq_update_write_ptr(il, &il->txq[2]);
il_txq_update_write_ptr(il, &il->txq[3]);
il_txq_update_write_ptr(il, &il->txq[4]);
- il_txq_update_write_ptr(il, &il->txq[5]);
+ spin_unlock_irqrestore(&il->lock, flags);
il->isr_stats.wakeup++;
handled |= CSR_INT_BIT_WAKEUP;
@@ -1581,7 +1590,7 @@ il3945_get_channels_for_scan(struct il_priv *il, enum ieee80211_band band,
* and use long active_dwell time.
*/
if (!is_active || il_is_channel_passive(ch_info) ||
- (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) {
+ (chan->flags & IEEE80211_CHAN_NO_IR)) {
scan_ch->type = 0; /* passive */
if (IL_UCODE_API(il->ucode_ver) == 1)
scan_ch->active_dwell =
@@ -2150,7 +2159,6 @@ il3945_alive_start(struct il_priv *il)
{
int thermal_spin = 0;
u32 rfkill;
- struct il_rxon_context *ctx = &il->ctx;
D_INFO("Runtime Alive received.\n");
@@ -2175,7 +2183,7 @@ il3945_alive_start(struct il_priv *il)
D_INFO("RFKILL status: 0x%x\n", rfkill);
if (rfkill & 0x1) {
- clear_bit(S_RF_KILL_HW, &il->status);
+ clear_bit(S_RFKILL, &il->status);
/* if RFKILL is not on, then wait for thermal
* sensor in adapter to kick in */
while (il3945_hw_get_temperature(il) == 0) {
@@ -2187,7 +2195,7 @@ il3945_alive_start(struct il_priv *il)
D_INFO("Thermal calibration took %dus\n",
thermal_spin * 10);
} else
- set_bit(S_RF_KILL_HW, &il->status);
+ set_bit(S_RFKILL, &il->status);
/* After the ALIVE response, we can send commands to 3945 uCode */
set_bit(S_ALIVE, &il->status);
@@ -2206,13 +2214,13 @@ il3945_alive_start(struct il_priv *il)
if (il_is_associated(il)) {
struct il3945_rxon_cmd *active_rxon =
- (struct il3945_rxon_cmd *)(&ctx->active);
+ (struct il3945_rxon_cmd *)(&il->active);
- ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
} else {
/* Initialize our rx_config data */
- il_connection_init_rx_config(il, ctx);
+ il_connection_init_rx_config(il);
}
/* Configure Bluetooth device coexistence support */
@@ -2221,7 +2229,7 @@ il3945_alive_start(struct il_priv *il)
set_bit(S_READY, &il->status);
/* Configure the adapter for unassociated operation */
- il3945_commit_rxon(il, ctx);
+ il3945_commit_rxon(il);
il3945_reg_txpower_periodic(il);
@@ -2253,7 +2261,7 @@ __il3945_down(struct il_priv *il)
del_timer_sync(&il->watchdog);
/* Station information will now be cleared in device */
- il_clear_ucode_stations(il, NULL);
+ il_clear_ucode_stations(il);
il_dealloc_bcast_stations(il);
il_clear_driver_stations(il);
@@ -2281,12 +2289,8 @@ __il3945_down(struct il_priv *il)
* clear all bits but the RF Kill bits and return */
if (!il_is_init(il)) {
il->status =
- test_bit(S_RF_KILL_HW,
- &il->
- status) << S_RF_KILL_HW |
- test_bit(S_GEO_CONFIGURED,
- &il->
- status) << S_GEO_CONFIGURED |
+ test_bit(S_RFKILL, &il->status) << S_RFKILL |
+ test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED |
test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;
goto exit;
}
@@ -2294,25 +2298,30 @@ __il3945_down(struct il_priv *il)
/* ...otherwise clear out all the status bits but the RF Kill
* bit and continue taking the NIC down. */
il->status &=
- test_bit(S_RF_KILL_HW,
- &il->status) << S_RF_KILL_HW | test_bit(S_GEO_CONFIGURED,
- &il->
- status) <<
- S_GEO_CONFIGURED | test_bit(S_FW_ERROR,
- &il->
- status) << S_FW_ERROR |
+ test_bit(S_RFKILL, &il->status) << S_RFKILL |
+ test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED |
+ test_bit(S_FW_ERROR, &il->status) << S_FW_ERROR |
test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;
+ /*
+ * We disabled and synchronized interrupt, and priv->mutex is taken, so
+ * here is the only thread which will program device registers, but
+ * still have lockdep assertions, so we are taking reg_lock.
+ */
+ spin_lock_irq(&il->reg_lock);
+ /* FIXME: il_grab_nic_access if rfkill is off ? */
+
il3945_hw_txq_ctx_stop(il);
il3945_hw_rxq_stop(il);
-
/* Power-down device's busmaster DMA clocks */
- il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
+ _il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
udelay(5);
-
/* Stop the device, and put it in low power state */
- il_apm_stop(il);
+ _il_apm_stop(il);
+ spin_unlock_irq(&il->reg_lock);
+
+ il3945_hw_txq_ctx_free(il);
exit:
memset(&il->card_alive, 0, sizeof(struct il_alive_resp));
@@ -2339,12 +2348,11 @@ il3945_down(struct il_priv *il)
static int
il3945_alloc_bcast_station(struct il_priv *il)
{
- struct il_rxon_context *ctx = &il->ctx;
unsigned long flags;
u8 sta_id;
spin_lock_irqsave(&il->sta_lock, flags);
- sta_id = il_prep_station(il, ctx, il_bcast_addr, false, NULL);
+ sta_id = il_prep_station(il, il_bcast_addr, false, NULL);
if (sta_id == IL_INVALID_STATION) {
IL_ERR("Unable to prepare broadcast station\n");
spin_unlock_irqrestore(&il->sta_lock, flags);
@@ -2380,11 +2388,10 @@ __il3945_up(struct il_priv *il)
/* If platform's RF_KILL switch is NOT set to KILL */
if (_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
- clear_bit(S_RF_KILL_HW, &il->status);
+ clear_bit(S_RFKILL, &il->status);
else {
- set_bit(S_RF_KILL_HW, &il->status);
- IL_WARN("Radio disabled by HW RF Kill switch\n");
- return -ENODEV;
+ set_bit(S_RFKILL, &il->status);
+ return -ERFKILL;
}
_il_wr(il, CSR_INT, 0xFFFFFFFF);
@@ -2414,7 +2421,7 @@ __il3945_up(struct il_priv *il)
il->ucode_data.len);
/* We return success when we resume from suspend and rf_kill is on. */
- if (test_bit(S_RF_KILL_HW, &il->status))
+ if (test_bit(S_RFKILL, &il->status))
return 0;
for (i = 0; i < MAX_HW_RESTARTS; i++) {
@@ -2422,7 +2429,7 @@ __il3945_up(struct il_priv *il)
/* load bootstrap state machine,
* load bootstrap program into processor's memory,
* prepare to load the "initialize" uCode */
- rc = il->cfg->ops->lib->load_ucode(il);
+ rc = il->ops->load_ucode(il);
if (rc) {
IL_ERR("Unable to set up bootstrap uCode: %d\n", rc);
@@ -2494,15 +2501,15 @@ il3945_rfkill_poll(struct work_struct *data)
{
struct il_priv *il =
container_of(data, struct il_priv, _3945.rfkill_poll.work);
- bool old_rfkill = test_bit(S_RF_KILL_HW, &il->status);
+ bool old_rfkill = test_bit(S_RFKILL, &il->status);
bool new_rfkill =
!(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW);
if (new_rfkill != old_rfkill) {
if (new_rfkill)
- set_bit(S_RF_KILL_HW, &il->status);
+ set_bit(S_RFKILL, &il->status);
else
- clear_bit(S_RF_KILL_HW, &il->status);
+ clear_bit(S_RFKILL, &il->status);
wiphy_rfkill_set_hw_state(il->hw->wiphy, new_rfkill);
@@ -2602,7 +2609,7 @@ il3945_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
/* We don't build a direct scan probe request; the uCode will do
* that based on the direct_mask added to each channel entry */
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
- scan->tx_cmd.sta_id = il->ctx.bcast_sta_id;
+ scan->tx_cmd.sta_id = il->hw_params.bcast_id;
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
/* flags + rate selection */
@@ -2664,14 +2671,12 @@ il3945_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
void
il3945_post_scan(struct il_priv *il)
{
- struct il_rxon_context *ctx = &il->ctx;
-
/*
* Since setting the RXON may have been deferred while
* performing the scan, fire one off if needed
*/
- if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
- il3945_commit_rxon(il, ctx);
+ if (memcmp(&il->staging, &il->active, sizeof(il->staging)))
+ il3945_commit_rxon(il);
}
static void
@@ -2684,7 +2689,6 @@ il3945_bg_restart(struct work_struct *data)
if (test_and_clear_bit(S_FW_ERROR, &il->status)) {
mutex_lock(&il->mutex);
- il->ctx.vif = NULL;
il->is_open = 0;
mutex_unlock(&il->mutex);
il3945_down(il);
@@ -2722,13 +2726,12 @@ il3945_post_associate(struct il_priv *il)
{
int rc = 0;
struct ieee80211_conf *conf = NULL;
- struct il_rxon_context *ctx = &il->ctx;
- if (!ctx->vif || !il->is_open)
+ if (!il->vif || !il->is_open)
return;
- D_ASSOC("Associated as %d to: %pM\n", ctx->vif->bss_conf.aid,
- ctx->active.bssid_addr);
+ D_ASSOC("Associated as %d to: %pM\n", il->vif->bss_conf.aid,
+ il->active.bssid_addr);
if (test_bit(S_EXIT_PENDING, &il->status))
return;
@@ -2737,35 +2740,35 @@ il3945_post_associate(struct il_priv *il)
conf = &il->hw->conf;
- ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- il3945_commit_rxon(il, ctx);
+ il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ il3945_commit_rxon(il);
- rc = il_send_rxon_timing(il, ctx);
+ rc = il_send_rxon_timing(il);
if (rc)
IL_WARN("C_RXON_TIMING failed - " "Attempting to continue.\n");
- ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
- ctx->staging.assoc_id = cpu_to_le16(ctx->vif->bss_conf.aid);
+ il->staging.assoc_id = cpu_to_le16(il->vif->bss_conf.aid);
- D_ASSOC("assoc id %d beacon interval %d\n", ctx->vif->bss_conf.aid,
- ctx->vif->bss_conf.beacon_int);
+ D_ASSOC("assoc id %d beacon interval %d\n", il->vif->bss_conf.aid,
+ il->vif->bss_conf.beacon_int);
- if (ctx->vif->bss_conf.use_short_preamble)
- ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ if (il->vif->bss_conf.use_short_preamble)
+ il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
- ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
- if (ctx->vif->bss_conf.use_short_slot)
- ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ if (il->staging.flags & RXON_FLG_BAND_24G_MSK) {
+ if (il->vif->bss_conf.use_short_slot)
+ il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
- ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
}
- il3945_commit_rxon(il, ctx);
+ il3945_commit_rxon(il);
- switch (ctx->vif->type) {
+ switch (il->vif->type) {
case NL80211_IFTYPE_STATION:
il3945_rate_scale_init(il->hw, IL_AP_ID);
break;
@@ -2774,7 +2777,7 @@ il3945_post_associate(struct il_priv *il)
break;
default:
IL_ERR("%s Should not be called in %d mode\n", __func__,
- ctx->vif->type);
+ il->vif->type);
break;
}
}
@@ -2793,10 +2796,9 @@ il3945_mac_start(struct ieee80211_hw *hw)
struct il_priv *il = hw->priv;
int ret;
- D_MAC80211("enter\n");
-
/* we should be verifying the device is ready to be opened */
mutex_lock(&il->mutex);
+ D_MAC80211("enter\n");
/* fetch ucode file from disk, alloc and copy to bus-master buffers ...
* ucode filename and max sizes are card-specific. */
@@ -2873,7 +2875,9 @@ il3945_mac_stop(struct ieee80211_hw *hw)
}
static void
-il3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+il3945_mac_tx(struct ieee80211_hw *hw,
+ struct ieee80211_tx_control *control,
+ struct sk_buff *skb)
{
struct il_priv *il = hw->priv;
@@ -2882,7 +2886,7 @@ il3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
D_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
- if (il3945_tx_skb(il, skb))
+ if (il3945_tx_skb(il, control->sta, skb))
dev_kfree_skb_any(skb);
D_MAC80211("leave\n");
@@ -2891,8 +2895,7 @@ il3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
void
il3945_config_ap(struct il_priv *il)
{
- struct il_rxon_context *ctx = &il->ctx;
- struct ieee80211_vif *vif = ctx->vif;
+ struct ieee80211_vif *vif = il->vif;
int rc = 0;
if (test_bit(S_EXIT_PENDING, &il->status))
@@ -2902,31 +2905,31 @@ il3945_config_ap(struct il_priv *il)
if (!(il_is_associated(il))) {
/* RXON - unassoc (to set timing command) */
- ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- il3945_commit_rxon(il, ctx);
+ il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ il3945_commit_rxon(il);
/* RXON Timing */
- rc = il_send_rxon_timing(il, ctx);
+ rc = il_send_rxon_timing(il);
if (rc)
IL_WARN("C_RXON_TIMING failed - "
"Attempting to continue.\n");
- ctx->staging.assoc_id = 0;
+ il->staging.assoc_id = 0;
if (vif->bss_conf.use_short_preamble)
- ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
- ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
+ if (il->staging.flags & RXON_FLG_BAND_24G_MSK) {
if (vif->bss_conf.use_short_slot)
- ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
- ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
}
/* restore RXON assoc */
- ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
- il3945_commit_rxon(il, ctx);
+ il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ il3945_commit_rxon(il);
}
il3945_send_beacon_cmd(il);
}
@@ -2953,15 +2956,19 @@ il3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
* hardware will then not attempt to decrypt the frames.
*/
if (vif->type == NL80211_IFTYPE_ADHOC &&
- !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+ !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+ D_MAC80211("leave - IBSS RSN\n");
return -EOPNOTSUPP;
+ }
static_key = !il_is_associated(il);
if (!static_key) {
- sta_id = il_sta_id_or_broadcast(il, &il->ctx, sta);
- if (sta_id == IL_INVALID_STATION)
+ sta_id = il_sta_id_or_broadcast(il, sta);
+ if (sta_id == IL_INVALID_STATION) {
+ D_MAC80211("leave - station not found\n");
return -EINVAL;
+ }
}
mutex_lock(&il->mutex);
@@ -2986,8 +2993,8 @@ il3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
ret = -EINVAL;
}
+ D_MAC80211("leave ret %d\n", ret);
mutex_unlock(&il->mutex);
- D_MAC80211("leave\n");
return ret;
}
@@ -3002,13 +3009,11 @@ il3945_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
bool is_ap = vif->type == NL80211_IFTYPE_STATION;
u8 sta_id;
- D_INFO("received request to add station %pM\n", sta->addr);
mutex_lock(&il->mutex);
- D_INFO("proceeding to add station %pM\n", sta->addr);
+ D_INFO("station %pM\n", sta->addr);
sta_priv->common.sta_id = IL_INVALID_STATION;
- ret =
- il_add_station_common(il, &il->ctx, sta->addr, is_ap, sta, &sta_id);
+ ret = il_add_station_common(il, sta->addr, is_ap, sta, &sta_id);
if (ret) {
IL_ERR("Unable to add station %pM (%d)\n", sta->addr, ret);
/* Should we return success if return code is EEXIST ? */
@@ -3032,7 +3037,6 @@ il3945_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
{
struct il_priv *il = hw->priv;
__le32 filter_or = 0, filter_nand = 0;
- struct il_rxon_context *ctx = &il->ctx;
#define CHK(test, flag) do { \
if (*total_flags & (test)) \
@@ -3052,8 +3056,8 @@ il3945_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
mutex_lock(&il->mutex);
- ctx->staging.filter_flags &= ~filter_nand;
- ctx->staging.filter_flags |= filter_or;
+ il->staging.filter_flags &= ~filter_nand;
+ il->staging.filter_flags |= filter_or;
/*
* Not committing directly because hardware can perform a scan,
@@ -3109,14 +3113,12 @@ il3945_store_debug_level(struct device *d, struct device_attribute *attr,
unsigned long val;
int ret;
- ret = strict_strtoul(buf, 0, &val);
+ ret = kstrtoul(buf, 0, &val);
if (ret)
IL_INFO("%s is not in hex or decimal form.\n", buf);
- else {
+ else
il->debug_level = val;
- if (il_alloc_traffic_mem(il))
- IL_ERR("Not enough memory to generate traffic log\n");
- }
+
return strnlen(buf, count);
}
@@ -3170,9 +3172,8 @@ static ssize_t
il3945_show_flags(struct device *d, struct device_attribute *attr, char *buf)
{
struct il_priv *il = dev_get_drvdata(d);
- struct il_rxon_context *ctx = &il->ctx;
- return sprintf(buf, "0x%04X\n", ctx->active.flags);
+ return sprintf(buf, "0x%04X\n", il->active.flags);
}
static ssize_t
@@ -3181,17 +3182,16 @@ il3945_store_flags(struct device *d, struct device_attribute *attr,
{
struct il_priv *il = dev_get_drvdata(d);
u32 flags = simple_strtoul(buf, NULL, 0);
- struct il_rxon_context *ctx = &il->ctx;
mutex_lock(&il->mutex);
- if (le32_to_cpu(ctx->staging.flags) != flags) {
+ if (le32_to_cpu(il->staging.flags) != flags) {
/* Cancel any currently running scans... */
if (il_scan_cancel_timeout(il, 100))
IL_WARN("Could not cancel scan.\n");
else {
D_INFO("Committing rxon.flags = 0x%04X\n", flags);
- ctx->staging.flags = cpu_to_le32(flags);
- il3945_commit_rxon(il, ctx);
+ il->staging.flags = cpu_to_le32(flags);
+ il3945_commit_rxon(il);
}
}
mutex_unlock(&il->mutex);
@@ -3207,9 +3207,8 @@ il3945_show_filter_flags(struct device *d, struct device_attribute *attr,
char *buf)
{
struct il_priv *il = dev_get_drvdata(d);
- struct il_rxon_context *ctx = &il->ctx;
- return sprintf(buf, "0x%04X\n", le32_to_cpu(ctx->active.filter_flags));
+ return sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.filter_flags));
}
static ssize_t
@@ -3217,19 +3216,18 @@ il3945_store_filter_flags(struct device *d, struct device_attribute *attr,
const char *buf, size_t count)
{
struct il_priv *il = dev_get_drvdata(d);
- struct il_rxon_context *ctx = &il->ctx;
u32 filter_flags = simple_strtoul(buf, NULL, 0);
mutex_lock(&il->mutex);
- if (le32_to_cpu(ctx->staging.filter_flags) != filter_flags) {
+ if (le32_to_cpu(il->staging.filter_flags) != filter_flags) {
/* Cancel any currently running scans... */
if (il_scan_cancel_timeout(il, 100))
IL_WARN("Could not cancel scan.\n");
else {
D_INFO("Committing rxon.filter_flags = " "0x%04X\n",
filter_flags);
- ctx->staging.filter_flags = cpu_to_le32(filter_flags);
- il3945_commit_rxon(il, ctx);
+ il->staging.filter_flags = cpu_to_le32(filter_flags);
+ il3945_commit_rxon(il);
}
}
mutex_unlock(&il->mutex);
@@ -3278,9 +3276,8 @@ il3945_store_measurement(struct device *d, struct device_attribute *attr,
const char *buf, size_t count)
{
struct il_priv *il = dev_get_drvdata(d);
- struct il_rxon_context *ctx = &il->ctx;
struct ieee80211_measurement_params params = {
- .channel = le16_to_cpu(ctx->active.channel),
+ .channel = le16_to_cpu(il->active.channel),
.start_time = cpu_to_le64(il->_3945.last_tsf),
.duration = cpu_to_le16(1),
};
@@ -3290,7 +3287,7 @@ il3945_store_measurement(struct device *d, struct device_attribute *attr,
if (count) {
char *p = buffer;
- strncpy(buffer, buf, min(sizeof(buffer), count));
+ strlcpy(buffer, buf, sizeof(buffer));
channel = simple_strtoul(p, NULL, 0);
if (channel)
params.channel = channel;
@@ -3474,7 +3471,7 @@ static struct attribute_group il3945_attribute_group = {
.attrs = il3945_sysfs_entries,
};
-struct ieee80211_ops il3945_hw_ops = {
+static struct ieee80211_ops il3945_mac_ops __read_mostly = {
.tx = il3945_mac_tx,
.start = il3945_mac_start,
.stop = il3945_mac_stop,
@@ -3491,6 +3488,7 @@ struct ieee80211_ops il3945_hw_ops = {
.sta_add = il3945_mac_sta_add,
.sta_remove = il_mac_sta_remove,
.tx_last_beacon = il_mac_tx_last_beacon,
+ .flush = il_mac_flush,
};
static int
@@ -3565,13 +3563,17 @@ il3945_setup_mac(struct il_priv *il)
hw->vif_data_size = sizeof(struct il_vif_priv);
/* Tell mac80211 our characteristics */
- hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SPECTRUM_MGMT;
+ hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SPECTRUM_MGMT |
+ IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
+
+ hw->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
- hw->wiphy->interface_modes = il->ctx.interface_modes;
+ hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+ hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
+ REGULATORY_DISABLE_BEACON_HINTS;
- hw->wiphy->flags |=
- WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS |
- WIPHY_FLAG_IBSS_RSN;
+ hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;
/* we create the 802.11 header and a zero-length SSID element */
@@ -3614,50 +3616,35 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* 1. Allocating HW data
* ********************/
- /* mac80211 allocates memory for this device instance, including
- * space for this driver's ilate structure */
- hw = il_alloc_all(cfg);
- if (hw == NULL) {
- pr_err("Can not allocate network device\n");
+ hw = ieee80211_alloc_hw(sizeof(struct il_priv), &il3945_mac_ops);
+ if (!hw) {
err = -ENOMEM;
goto out;
}
il = hw->priv;
+ il->hw = hw;
SET_IEEE80211_DEV(hw, &pdev->dev);
il->cmd_queue = IL39_CMD_QUEUE_NUM;
- il->ctx.ctxid = 0;
-
- il->ctx.rxon_cmd = C_RXON;
- il->ctx.rxon_timing_cmd = C_RXON_TIMING;
- il->ctx.rxon_assoc_cmd = C_RXON_ASSOC;
- il->ctx.qos_cmd = C_QOS_PARAM;
- il->ctx.ap_sta_id = IL_AP_ID;
- il->ctx.wep_key_cmd = C_WEPKEY;
- il->ctx.interface_modes =
- BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
- il->ctx.ibss_devtype = RXON_DEV_TYPE_IBSS;
- il->ctx.station_devtype = RXON_DEV_TYPE_ESS;
- il->ctx.unused_devtype = RXON_DEV_TYPE_ESS;
-
/*
* Disabling hardware scan means that mac80211 will perform scans
* "the hard way", rather than using device's scan.
*/
if (il3945_mod_params.disable_hw_scan) {
D_INFO("Disabling hw_scan\n");
- il3945_hw_ops.hw_scan = NULL;
+ il3945_mac_ops.hw_scan = NULL;
}
D_INFO("*** LOAD DRIVER ***\n");
il->cfg = cfg;
+ il->ops = &il3945_ops;
+#ifdef CONFIG_IWLEGACY_DEBUGFS
+ il->debugfs_ops = &il3945_debugfs_ops;
+#endif
il->pci_dev = pdev;
il->inta_mask = CSR_INI_SET_MASK;
- if (il_alloc_traffic_mem(il))
- IL_ERR("Not enough memory to generate traffic log\n");
-
/***************************
* 2. Initializing PCI bus
* *************************/
@@ -3688,7 +3675,7 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/***********************
* 3. Read REV Register
* ********************/
- il->hw_base = pci_iomap(pdev, 0, 0);
+ il->hw_base = pci_ioremap_bar(pdev, 0);
if (!il->hw_base) {
err = -ENODEV;
goto out_pci_release_regions;
@@ -3702,7 +3689,7 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* PCI Tx retries from interfering with C3 CPU state */
pci_write_config_byte(pdev, 0x41, 0x00);
- /* these spin locks will be used in apm_ops.init and EEPROM access
+ /* these spin locks will be used in apm_init and EEPROM access
* we should init now
*/
spin_lock_init(&il->reg_lock);
@@ -3734,7 +3721,8 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* 5. Setup HW Constants
* ********************/
/* Device-specific setup */
- if (il3945_hw_set_hw_params(il)) {
+ err = il3945_hw_set_hw_params(il);
+ if (err) {
IL_ERR("failed to set hw settings\n");
goto out_eeprom_free;
}
@@ -3773,8 +3761,7 @@ il3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto out_release_irq;
}
- il_set_rxon_channel(il, &il->bands[IEEE80211_BAND_2GHZ].channels[5],
- &il->ctx);
+ il_set_rxon_channel(il, &il->bands[IEEE80211_BAND_2GHZ].channels[5]);
il3945_setup_deferred_work(il);
il3945_setup_handlers(il);
il_power_initialize(il);
@@ -3814,20 +3801,18 @@ out_unset_hw_params:
out_eeprom_free:
il_eeprom_free(il);
out_iounmap:
- pci_iounmap(pdev, il->hw_base);
+ iounmap(il->hw_base);
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:
- il_free_traffic_mem(il);
ieee80211_free_hw(il->hw);
out:
return err;
}
-static void __devexit
+static void
il3945_pci_remove(struct pci_dev *pdev)
{
struct il_priv *il = pci_get_drvdata(pdev);
@@ -3889,15 +3874,13 @@ il3945_pci_remove(struct pci_dev *pdev)
* until now... */
destroy_workqueue(il->workqueue);
il->workqueue = NULL;
- il_free_traffic_mem(il);
free_irq(pdev->irq, il);
pci_disable_msi(pdev);
- pci_iounmap(pdev, il->hw_base);
+ 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);
@@ -3918,7 +3901,7 @@ static struct pci_driver il3945_driver = {
.name = DRV_NAME,
.id_table = il3945_hw_card_ids,
.probe = il3945_pci_probe,
- .remove = __devexit_p(il3945_pci_remove),
+ .remove = il3945_pci_remove,
.driver.pm = IL_LEGACY_PM_OPS,
};
diff --git a/drivers/net/wireless/iwlegacy/3945-rs.c b/drivers/net/wireless/iwlegacy/3945-rs.c
index d7a83f22919..76b0729ade1 100644
--- a/drivers/net/wireless/iwlegacy/3945-rs.c
+++ b/drivers/net/wireless/iwlegacy/3945-rs.c
@@ -25,7 +25,6 @@
*****************************************************************************/
#include <linux/kernel.h>
-#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <net/mac80211.h>
@@ -342,12 +341,12 @@ il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id)
int i;
D_INFO("enter\n");
- if (sta_id == il->ctx.bcast_sta_id)
+ if (sta_id == il->hw_params.bcast_id)
goto out;
psta = (struct il3945_sta_priv *)sta->drv_priv;
rs_sta = &psta->rs_sta;
- sband = hw->wiphy->bands[conf->channel->band];
+ sband = hw->wiphy->bands[conf->chandef.chan->band];
rs_sta->il = il;
@@ -816,17 +815,12 @@ out:
rs_sta->last_txrate_idx = idx;
info->control.rates[0].idx = rs_sta->last_txrate_idx;
}
+ info->control.rates[0].count = 1;
D_RATE("leave: %d\n", idx);
}
#ifdef CONFIG_MAC80211_DEBUGFS
-static int
-il3945_open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
static ssize_t
il3945_sta_dbgfs_stats_table_read(struct file *file, char __user *user_buf,
@@ -862,7 +856,7 @@ il3945_sta_dbgfs_stats_table_read(struct file *file, char __user *user_buf,
static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
.read = il3945_sta_dbgfs_stats_table_read,
- .open = il3945_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -892,12 +886,12 @@ il3945_remove_debugfs(void *il, void *il_sta)
*/
static void
il3945_rs_rate_init_stub(void *il_r, struct ieee80211_supported_band *sband,
+ struct cfg80211_chan_def *chandef,
struct ieee80211_sta *sta, void *il_sta)
{
}
-static struct rate_control_ops rs_ops = {
- .module = NULL,
+static const struct rate_control_ops rs_ops = {
.name = RS_NAME,
.tx_status = il3945_rs_tx_status,
.get_rate = il3945_rs_get_rate,
@@ -927,8 +921,7 @@ il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
rcu_read_lock();
- sta =
- ieee80211_find_sta(il->ctx.vif, il->stations[sta_id].sta.sta.addr);
+ sta = ieee80211_find_sta(il->vif, il->stations[sta_id].sta.sta.addr);
if (!sta) {
D_RATE("Unable to find station to initialize rate scaling.\n");
rcu_read_unlock();
@@ -944,7 +937,7 @@ il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
switch (il->band) {
case IEEE80211_BAND_2GHZ:
/* TODO: this always does G, not a regression */
- if (il->ctx.active.flags & RXON_FLG_TGG_PROTECT_MSK) {
+ if (il->active.flags & RXON_FLG_TGG_PROTECT_MSK) {
rs_sta->tgg = 1;
rs_sta->expected_tpt = il3945_expected_tpt_g_prot;
} else
@@ -953,7 +946,7 @@ il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
case IEEE80211_BAND_5GHZ:
rs_sta->expected_tpt = il3945_expected_tpt_a;
break;
- case IEEE80211_NUM_BANDS:
+ default:
BUG();
break;
}
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c
index c80eb9b3155..b598e280350 100644
--- a/drivers/net/wireless/iwlegacy/3945.c
+++ b/drivers/net/wireless/iwlegacy/3945.c
@@ -26,7 +26,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/init.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
@@ -57,10 +56,6 @@ il3945_send_led_cmd(struct il_priv *il, struct il_led_cmd *led_cmd)
return il_send_cmd(il, &cmd);
}
-const struct il_led_ops il3945_led_ops = {
- .cmd = il3945_send_led_cmd,
-};
-
#define IL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np) \
[RATE_##r##M_IDX] = { RATE_##r##M_PLCP, \
RATE_##r##M_IEEE, \
@@ -293,17 +288,17 @@ il3945_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx)
{
struct il_tx_queue *txq = &il->txq[txq_id];
struct il_queue *q = &txq->q;
- struct il_tx_info *tx_info;
+ struct sk_buff *skb;
BUG_ON(txq_id == IL39_CMD_QUEUE_NUM);
for (idx = il_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd)) {
- tx_info = &txq->txb[txq->q.read_ptr];
- ieee80211_tx_status_irqsafe(il->hw, tx_info->skb);
- tx_info->skb = NULL;
- il->cfg->ops->lib->txq_free_tfd(il, txq);
+ skb = txq->skbs[txq->q.read_ptr];
+ ieee80211_tx_status_irqsafe(il->hw, skb);
+ txq->skbs[txq->q.read_ptr] = NULL;
+ il->ops->txq_free_tfd(il, txq);
}
if (il_queue_space(q) > q->low_mark && txq_id >= 0 &&
@@ -335,8 +330,21 @@ il3945_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)
return;
}
+ /*
+ * Firmware will not transmit frame on passive channel, if it not yet
+ * received some valid frame on that channel. When this error happen
+ * we have to wait until firmware will unblock itself i.e. when we
+ * note received beacon or other frame. We unblock queues in
+ * il3945_pass_packet_to_mac80211 or in il_mac_bss_info_changed.
+ */
+ if (unlikely((status & TX_STATUS_MSK) == TX_STATUS_FAIL_PASSIVE_NO_RX) &&
+ il->iw_mode == NL80211_IFTYPE_STATION) {
+ il_stop_queues_by_reason(il, IL_STOP_REASON_PASSIVE);
+ D_INFO("Stopped queues - RX waiting on passive channel\n");
+ }
+
txq->time_stamp = jiffies;
- info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
+ info = IEEE80211_SKB_CB(txq->skbs[txq->q.read_ptr]);
ieee80211_tx_info_clear_status(info);
/* Fill the MRR chain with some info about on-chip retransmissions */
@@ -457,15 +465,17 @@ il3945_is_network_packet(struct il_priv *il, struct ieee80211_hdr *header)
switch (il->iw_mode) {
case NL80211_IFTYPE_ADHOC: /* Header: Dest. | Source | BSSID */
/* packets to our IBSS update information */
- return !compare_ether_addr(header->addr3, il->bssid);
+ return ether_addr_equal_64bits(header->addr3, il->bssid);
case NL80211_IFTYPE_STATION: /* Header: Dest. | AP{BSSID} | Source */
/* packets to our IBSS update information */
- return !compare_ether_addr(header->addr2, il->bssid);
+ return ether_addr_equal_64bits(header->addr2, il->bssid);
default:
return 1;
}
}
+#define SMALL_PACKET_SIZE 256
+
static void
il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb,
struct ieee80211_rx_status *stats)
@@ -474,14 +484,13 @@ il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb,
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)IL_RX_DATA(pkt);
struct il3945_rx_frame_hdr *rx_hdr = IL_RX_HDR(pkt);
struct il3945_rx_frame_end *rx_end = IL_RX_END(pkt);
- u16 len = le16_to_cpu(rx_hdr->len);
+ u32 len = le16_to_cpu(rx_hdr->len);
struct sk_buff *skb;
__le16 fc = hdr->frame_control;
+ u32 fraglen = PAGE_SIZE << il->hw_params.rx_page_order;
/* We received data from the HW, so stop the watchdog */
- if (unlikely
- (len + IL39_RX_FRAME_SIZE >
- PAGE_SIZE << il->hw_params.rx_page_order)) {
+ if (unlikely(len + IL39_RX_FRAME_SIZE > fraglen)) {
D_DROP("Corruption detected!\n");
return;
}
@@ -492,25 +501,37 @@ il3945_pass_packet_to_mac80211(struct il_priv *il, struct il_rx_buf *rxb,
return;
}
- skb = dev_alloc_skb(128);
+ if (unlikely(test_bit(IL_STOP_REASON_PASSIVE, &il->stop_reason))) {
+ il_wake_queues_by_reason(il, IL_STOP_REASON_PASSIVE);
+ D_INFO("Woke queues - frame received on passive channel\n");
+ }
+
+ skb = dev_alloc_skb(SMALL_PACKET_SIZE);
if (!skb) {
IL_ERR("dev_alloc_skb failed\n");
return;
}
if (!il3945_mod_params.sw_crypto)
- il_set_decrypted_flag(il, (struct ieee80211_hdr *)rxb_addr(rxb),
+ il_set_decrypted_flag(il, (struct ieee80211_hdr *)pkt,
le32_to_cpu(rx_end->status), stats);
- skb_add_rx_frag(skb, 0, rxb->page,
- (void *)rx_hdr->payload - (void *)pkt, len);
-
+ /* If frame is small enough to fit into skb->head, copy it
+ * and do not consume a full page
+ */
+ if (len <= SMALL_PACKET_SIZE) {
+ memcpy(skb_put(skb, len), rx_hdr->payload, len);
+ } else {
+ skb_add_rx_frag(skb, 0, rxb->page,
+ (void *)rx_hdr->payload - (void *)pkt, len,
+ fraglen);
+ il->alloc_rxb_page--;
+ rxb->page = NULL;
+ }
il_update_stats(il, false, fc, len);
memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
ieee80211_rx(il->hw, skb);
- il->alloc_rxb_page--;
- rxb->page = NULL;
}
#define IL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
@@ -519,7 +540,7 @@ static void
il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
{
struct ieee80211_hdr *header;
- struct ieee80211_rx_status rx_status;
+ struct ieee80211_rx_status rx_status = {};
struct il_rx_pkt *pkt = rxb_addr(rxb);
struct il3945_rx_frame_stats *rx_stats = IL_RX_STATS(pkt);
struct il3945_rx_frame_hdr *rx_hdr = IL_RX_HDR(pkt);
@@ -552,7 +573,7 @@ il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
rx_status.flag |= RX_FLAG_SHORTPRE;
if ((unlikely(rx_stats->phy_count > 20))) {
- D_DROP("dsp size out of range [0,20]: %d/n",
+ D_DROP("dsp size out of range [0,20]: %d\n",
rx_stats->phy_count);
return;
}
@@ -577,8 +598,6 @@ il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
network_packet ? '*' : ' ', le16_to_cpu(rx_hdr->channel),
rx_status.signal, rx_status.signal, rx_status.rate_idx);
- il_dbg_log_rx_data_frame(il, le16_to_cpu(rx_hdr->len), header);
-
if (network_packet) {
il->_3945.last_beacon_time =
le32_to_cpu(rx_end->beacon_timestamp);
@@ -660,15 +679,13 @@ il3945_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq)
PCI_DMA_TODEVICE);
/* free SKB */
- if (txq->txb) {
- struct sk_buff *skb;
-
- skb = txq->txb[txq->q.read_ptr].skb;
+ if (txq->skbs) {
+ struct sk_buff *skb = txq->skbs[txq->q.read_ptr];
/* can be called from irqs-disabled context */
if (skb) {
dev_kfree_skb_any(skb);
- txq->txb[txq->q.read_ptr].skb = NULL;
+ txq->skbs[txq->q.read_ptr] = NULL;
}
}
}
@@ -798,7 +815,6 @@ il3945_rx_init(struct il_priv *il, struct il_rx_queue *rxq)
static int
il3945_tx_reset(struct il_priv *il)
{
-
/* bypass mode */
il_wr_prph(il, ALM_SCD_MODE_REG, 0x2);
@@ -835,8 +851,7 @@ il3945_tx_reset(struct il_priv *il)
static int
il3945_txq_ctx_reset(struct il_priv *il)
{
- int rc;
- int txq_id, slots_num;
+ int rc, txq_id;
il3945_hw_txq_ctx_free(il);
@@ -852,10 +867,7 @@ il3945_txq_ctx_reset(struct il_priv *il)
/* Tx queue(s) */
for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
- slots_num =
- (txq_id ==
- IL39_CMD_QUEUE_NUM) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
- rc = il_tx_queue_init(il, &il->txq[txq_id], slots_num, txq_id);
+ rc = il_tx_queue_init(il, txq_id);
if (rc) {
IL_ERR("Tx %d queue init failed\n", txq_id);
goto error;
@@ -960,12 +972,11 @@ il3945_hw_nic_init(struct il_priv *il)
struct il_rx_queue *rxq = &il->rxq;
spin_lock_irqsave(&il->lock, flags);
- il->cfg->ops->lib->apm_ops.init(il);
+ il3945_apm_init(il);
spin_unlock_irqrestore(&il->lock, flags);
il3945_set_pwr_vmain(il);
-
- il->cfg->ops->lib->apm_ops.config(il);
+ il3945_nic_config(il);
/* Allocate the RX queue, or reset if it is already allocated */
if (!rxq->bd) {
@@ -1016,7 +1027,7 @@ il3945_hw_txq_ctx_free(struct il_priv *il)
il_tx_queue_free(il, txq_id);
/* free tx queue structure */
- il_txq_mem(il);
+ il_free_txq_mem(il);
}
void
@@ -1025,18 +1036,17 @@ il3945_hw_txq_ctx_stop(struct il_priv *il)
int txq_id;
/* stop SCD */
- il_wr_prph(il, ALM_SCD_MODE_REG, 0);
- il_wr_prph(il, ALM_SCD_TXFACT_REG, 0);
+ _il_wr_prph(il, ALM_SCD_MODE_REG, 0);
+ _il_wr_prph(il, ALM_SCD_TXFACT_REG, 0);
/* reset TFD queues */
for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
- il_wr(il, FH39_TCSR_CONFIG(txq_id), 0x0);
- il_poll_bit(il, FH39_TSSR_TX_STATUS,
- FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
- 1000);
+ _il_wr(il, FH39_TCSR_CONFIG(txq_id), 0x0);
+ _il_poll_bit(il, FH39_TSSR_TX_STATUS,
+ FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
+ FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
+ 1000);
}
-
- il3945_hw_txq_ctx_free(il);
}
/**
@@ -1388,7 +1398,7 @@ il3945_send_tx_power(struct il_priv *il)
int rate_idx, i;
const struct il_channel_info *ch_info = NULL;
struct il3945_txpowertable_cmd txpower = {
- .channel = il->ctx.active.channel,
+ .channel = il->active.channel,
};
u16 chan;
@@ -1397,7 +1407,7 @@ il3945_send_tx_power(struct il_priv *il)
"TX Power requested while scanning!\n"))
return -EAGAIN;
- chan = le16_to_cpu(il->ctx.active.channel);
+ chan = le16_to_cpu(il->active.channel);
txpower.band = (il->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
ch_info = il_get_channel_info(il, il->band, chan);
@@ -1615,7 +1625,7 @@ il3945_hw_reg_comp_txpower_temp(struct il_priv *il)
}
/* send Txpower command for current channel to ucode */
- return il->cfg->ops->lib->send_tx_power(il);
+ return il->ops->send_tx_power(il);
}
int
@@ -1662,7 +1672,7 @@ il3945_hw_reg_set_txpower(struct il_priv *il, s8 power)
}
static int
-il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
+il3945_send_rxon_assoc(struct il_priv *il)
{
int rc = 0;
struct il_rx_pkt *pkt;
@@ -1673,8 +1683,8 @@ il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
.flags = CMD_WANT_SKB,
.data = &rxon_assoc,
};
- const struct il_rxon_cmd *rxon1 = &ctx->staging;
- const struct il_rxon_cmd *rxon2 = &ctx->active;
+ const struct il_rxon_cmd *rxon1 = &il->staging;
+ const struct il_rxon_cmd *rxon2 = &il->active;
if (rxon1->flags == rxon2->flags &&
rxon1->filter_flags == rxon2->filter_flags &&
@@ -1684,10 +1694,10 @@ il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
return 0;
}
- rxon_assoc.flags = ctx->staging.flags;
- rxon_assoc.filter_flags = ctx->staging.filter_flags;
- rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
- rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
+ rxon_assoc.flags = il->staging.flags;
+ rxon_assoc.filter_flags = il->staging.filter_flags;
+ rxon_assoc.ofdm_basic_rates = il->staging.ofdm_basic_rates;
+ rxon_assoc.cck_basic_rates = il->staging.cck_basic_rates;
rxon_assoc.reserved = 0;
rc = il_send_cmd_sync(il, &cmd);
@@ -1714,11 +1724,11 @@ il3945_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
* a HW tune is required based on the RXON structure changes.
*/
int
-il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
+il3945_commit_rxon(struct il_priv *il)
{
/* cast away the const for active_rxon in this function */
- struct il3945_rxon_cmd *active_rxon = (void *)&ctx->active;
- struct il3945_rxon_cmd *staging_rxon = (void *)&ctx->staging;
+ struct il3945_rxon_cmd *active_rxon = (void *)&il->active;
+ struct il3945_rxon_cmd *staging_rxon = (void *)&il->staging;
int rc = 0;
bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK);
@@ -1735,7 +1745,7 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
staging_rxon->flags &= ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
staging_rxon->flags |= il3945_get_antenna_flags(il);
- rc = il_check_rxon_cmd(il, ctx);
+ rc = il_check_rxon_cmd(il);
if (rc) {
IL_ERR("Invalid RXON configuration. Not committing.\n");
return -EINVAL;
@@ -1744,8 +1754,8 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
/* If we don't need to send a full RXON, we can use
* il3945_rxon_assoc_cmd which is used to reconfigure filter
* and other flags for the current radio configuration. */
- if (!il_full_rxon_required(il, &il->ctx)) {
- rc = il_send_rxon_assoc(il, &il->ctx);
+ if (!il_full_rxon_required(il)) {
+ rc = il_send_rxon_assoc(il);
if (rc) {
IL_ERR("Error setting RXON_ASSOC "
"configuration (%d).\n", rc);
@@ -1776,7 +1786,7 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
active_rxon->reserved4 = 0;
active_rxon->reserved5 = 0;
rc = il_send_cmd_pdu(il, C_RXON, sizeof(struct il3945_rxon_cmd),
- &il->ctx.active);
+ &il->active);
/* If the mask clearing failed then we set
* active_rxon back to what it was previously */
@@ -1786,8 +1796,8 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
"configuration (%d).\n", rc);
return rc;
}
- il_clear_ucode_stations(il, &il->ctx);
- il_restore_stations(il, &il->ctx);
+ il_clear_ucode_stations(il);
+ il_restore_stations(il);
}
D_INFO("Sending RXON\n" "* with%s RXON_FILTER_ASSOC_MSK\n"
@@ -1801,7 +1811,7 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
staging_rxon->reserved4 = 0;
staging_rxon->reserved5 = 0;
- il_set_rxon_hwcrypto(il, ctx, !il3945_mod_params.sw_crypto);
+ il_set_rxon_hwcrypto(il, !il3945_mod_params.sw_crypto);
/* Apply the new configuration */
rc = il_send_cmd_pdu(il, C_RXON, sizeof(struct il3945_rxon_cmd),
@@ -1814,8 +1824,8 @@ il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
if (!new_assoc) {
- il_clear_ucode_stations(il, &il->ctx);
- il_restore_stations(il, &il->ctx);
+ il_clear_ucode_stations(il);
+ il_restore_stations(il);
}
/* If we issue a new RXON command which required a tune then we must
@@ -2186,12 +2196,14 @@ il3945_txpower_set_from_eeprom(struct il_priv *il)
int
il3945_hw_rxq_stop(struct il_priv *il)
{
- int rc;
+ int ret;
- il_wr(il, FH39_RCSR_CONFIG(0), 0);
- rc = il_poll_bit(il, FH39_RSSR_STATUS,
- FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
- if (rc < 0)
+ _il_wr(il, FH39_RCSR_CONFIG(0), 0);
+ ret = _il_poll_bit(il, FH39_RSSR_STATUS,
+ FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
+ FH39_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
+ 1000);
+ if (ret < 0)
IL_ERR("Can't stop Rx DMA.\n");
return 0;
@@ -2259,7 +2271,6 @@ il3945_build_addsta_hcmd(const struct il_addsta_cmd *cmd, u8 * data)
static int
il3945_add_bssid_station(struct il_priv *il, const u8 * addr, u8 * sta_id_r)
{
- struct il_rxon_context *ctx = &il->ctx;
int ret;
u8 sta_id;
unsigned long flags;
@@ -2267,7 +2278,7 @@ il3945_add_bssid_station(struct il_priv *il, const u8 * addr, u8 * sta_id_r)
if (sta_id_r)
*sta_id_r = IL_INVALID_STATION;
- ret = il_add_station_common(il, ctx, addr, 0, NULL, &sta_id);
+ ret = il_add_station_common(il, addr, 0, NULL, &sta_id);
if (ret) {
IL_ERR("Unable to add station %pM\n", addr);
return ret;
@@ -2392,20 +2403,19 @@ il3945_hw_set_hw_params(struct il_priv *il)
il->_3945.shared_virt =
dma_alloc_coherent(&il->pci_dev->dev, sizeof(struct il3945_shared),
&il->_3945.shared_phys, GFP_KERNEL);
- if (!il->_3945.shared_virt) {
- IL_ERR("failed to allocate pci memory\n");
+ if (!il->_3945.shared_virt)
return -ENOMEM;
- }
+
+ il->hw_params.bcast_id = IL3945_BROADCAST_ID;
/* Assign number of Usable TX queues */
- il->hw_params.max_txq_num = il->cfg->base_params->num_of_queues;
+ il->hw_params.max_txq_num = il->cfg->num_of_queues;
il->hw_params.tfd_size = sizeof(struct il3945_tfd);
il->hw_params.rx_page_order = get_order(IL_RX_BUF_SIZE_3K);
il->hw_params.max_rxq_size = RX_QUEUE_SIZE;
il->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
il->hw_params.max_stations = IL3945_STATION_COUNT;
- il->ctx.bcast_sta_id = IL3945_BROADCAST_ID;
il->sta_key_max_num = STA_KEY_MAX_NUM;
@@ -2426,7 +2436,7 @@ il3945_hw_get_beacon_cmd(struct il_priv *il, struct il3945_frame *frame,
tx_beacon_cmd = (struct il3945_tx_beacon_cmd *)&frame->u;
memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
- tx_beacon_cmd->tx.sta_id = il->ctx.bcast_sta_id;
+ tx_beacon_cmd->tx.sta_id = il->hw_params.bcast_id;
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
frame_size =
@@ -2633,76 +2643,31 @@ il3945_load_bsm(struct il_priv *il)
return 0;
}
-static struct il_hcmd_ops il3945_hcmd = {
- .rxon_assoc = il3945_send_rxon_assoc,
- .commit_rxon = il3945_commit_rxon,
-};
-
-static struct il_lib_ops il3945_lib = {
+const struct il_ops il3945_ops = {
.txq_attach_buf_to_tfd = il3945_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = il3945_hw_txq_free_tfd,
.txq_init = il3945_hw_tx_queue_init,
.load_ucode = il3945_load_bsm,
.dump_nic_error_log = il3945_dump_nic_error_log,
- .apm_ops = {
- .init = il3945_apm_init,
- .config = il3945_nic_config,
- },
- .eeprom_ops = {
- .regulatory_bands = {
- EEPROM_REGULATORY_BAND_1_CHANNELS,
- EEPROM_REGULATORY_BAND_2_CHANNELS,
- EEPROM_REGULATORY_BAND_3_CHANNELS,
- EEPROM_REGULATORY_BAND_4_CHANNELS,
- EEPROM_REGULATORY_BAND_5_CHANNELS,
- EEPROM_REGULATORY_BAND_NO_HT40,
- EEPROM_REGULATORY_BAND_NO_HT40,
- },
- .acquire_semaphore = il3945_eeprom_acquire_semaphore,
- .release_semaphore = il3945_eeprom_release_semaphore,
- },
+ .apm_init = il3945_apm_init,
.send_tx_power = il3945_send_tx_power,
.is_valid_rtc_data_addr = il3945_hw_valid_rtc_data_addr,
+ .eeprom_acquire_semaphore = il3945_eeprom_acquire_semaphore,
+ .eeprom_release_semaphore = il3945_eeprom_release_semaphore,
-#ifdef CONFIG_IWLEGACY_DEBUGFS
- .debugfs_ops = {
- .rx_stats_read = il3945_ucode_rx_stats_read,
- .tx_stats_read = il3945_ucode_tx_stats_read,
- .general_stats_read = il3945_ucode_general_stats_read,
- },
-#endif
-};
-
-static const struct il_legacy_ops il3945_legacy_ops = {
- .post_associate = il3945_post_associate,
- .config_ap = il3945_config_ap,
- .manage_ibss_station = il3945_manage_ibss_station,
-};
+ .rxon_assoc = il3945_send_rxon_assoc,
+ .commit_rxon = il3945_commit_rxon,
-static struct il_hcmd_utils_ops il3945_hcmd_utils = {
.get_hcmd_size = il3945_get_hcmd_size,
.build_addsta_hcmd = il3945_build_addsta_hcmd,
.request_scan = il3945_request_scan,
.post_scan = il3945_post_scan,
-};
-static const struct il_ops il3945_ops = {
- .lib = &il3945_lib,
- .hcmd = &il3945_hcmd,
- .utils = &il3945_hcmd_utils,
- .led = &il3945_led_ops,
- .legacy = &il3945_legacy_ops,
- .ieee80211_ops = &il3945_hw_ops,
-};
+ .post_associate = il3945_post_associate,
+ .config_ap = il3945_config_ap,
+ .manage_ibss_station = il3945_manage_ibss_station,
-static struct il_base_params il3945_base_params = {
- .eeprom_size = IL3945_EEPROM_IMG_SIZE,
- .num_of_queues = IL39_NUM_QUEUES,
- .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
- .set_l0s = false,
- .use_bsm = true,
- .led_compensation = 64,
- .wd_timeout = IL_DEF_WD_TIMEOUT,
+ .send_led_cmd = il3945_send_led_cmd,
};
static struct il_cfg il3945_bg_cfg = {
@@ -2712,10 +2677,26 @@ static struct il_cfg il3945_bg_cfg = {
.ucode_api_min = IL3945_UCODE_API_MIN,
.sku = IL_SKU_G,
.eeprom_ver = EEPROM_3945_EEPROM_VERSION,
- .ops = &il3945_ops,
.mod_params = &il3945_mod_params,
- .base_params = &il3945_base_params,
.led_mode = IL_LED_BLINK,
+
+ .eeprom_size = IL3945_EEPROM_IMG_SIZE,
+ .num_of_queues = IL39_NUM_QUEUES,
+ .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
+ .set_l0s = false,
+ .use_bsm = true,
+ .led_compensation = 64,
+ .wd_timeout = IL_DEF_WD_TIMEOUT,
+
+ .regulatory_bands = {
+ EEPROM_REGULATORY_BAND_1_CHANNELS,
+ EEPROM_REGULATORY_BAND_2_CHANNELS,
+ EEPROM_REGULATORY_BAND_3_CHANNELS,
+ EEPROM_REGULATORY_BAND_4_CHANNELS,
+ EEPROM_REGULATORY_BAND_5_CHANNELS,
+ EEPROM_REGULATORY_BAND_NO_HT40,
+ EEPROM_REGULATORY_BAND_NO_HT40,
+ },
};
static struct il_cfg il3945_abg_cfg = {
@@ -2725,10 +2706,26 @@ static struct il_cfg il3945_abg_cfg = {
.ucode_api_min = IL3945_UCODE_API_MIN,
.sku = IL_SKU_A | IL_SKU_G,
.eeprom_ver = EEPROM_3945_EEPROM_VERSION,
- .ops = &il3945_ops,
.mod_params = &il3945_mod_params,
- .base_params = &il3945_base_params,
.led_mode = IL_LED_BLINK,
+
+ .eeprom_size = IL3945_EEPROM_IMG_SIZE,
+ .num_of_queues = IL39_NUM_QUEUES,
+ .pll_cfg_val = CSR39_ANA_PLL_CFG_VAL,
+ .set_l0s = false,
+ .use_bsm = true,
+ .led_compensation = 64,
+ .wd_timeout = IL_DEF_WD_TIMEOUT,
+
+ .regulatory_bands = {
+ EEPROM_REGULATORY_BAND_1_CHANNELS,
+ EEPROM_REGULATORY_BAND_2_CHANNELS,
+ EEPROM_REGULATORY_BAND_3_CHANNELS,
+ EEPROM_REGULATORY_BAND_4_CHANNELS,
+ EEPROM_REGULATORY_BAND_5_CHANNELS,
+ EEPROM_REGULATORY_BAND_NO_HT40,
+ EEPROM_REGULATORY_BAND_NO_HT40,
+ },
};
DEFINE_PCI_DEVICE_TABLE(il3945_hw_card_ids) = {
diff --git a/drivers/net/wireless/iwlegacy/3945.h b/drivers/net/wireless/iwlegacy/3945.h
index 9f42f79f877..00030d43a19 100644
--- a/drivers/net/wireless/iwlegacy/3945.h
+++ b/drivers/net/wireless/iwlegacy/3945.h
@@ -36,6 +36,8 @@ extern const struct pci_device_id il3945_hw_card_ids[];
#include "common.h"
+extern const struct il_ops il3945_ops;
+
/* Highest firmware API version supported */
#define IL3945_UCODE_API_MAX 2
@@ -148,10 +150,6 @@ struct il3945_frame {
struct list_head list;
};
-#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
-#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
-#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
-
#define SUP_RATE_11A_MAX_NUM_CHANNELS 8
#define SUP_RATE_11B_MAX_NUM_CHANNELS 4
#define SUP_RATE_11G_MAX_NUM_CHANNELS 12
@@ -191,15 +189,14 @@ struct il3945_ibss_seq {
* for use by iwl-*.c
*
*****************************************************************************/
-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);
+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);
/******************************************************************************
*
@@ -217,39 +214,36 @@ extern void il3945_dump_nic_error_log(struct il_priv *il);
* il3945_mac_ <-- mac80211 callback
*
****************************************************************************/
-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_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);
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);
-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);
+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);
void il3945_hdl_c_stats(struct il_priv *il, struct il_rx_buf *rxb);
-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);
+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 int il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx);
+int il3945_commit_rxon(struct il_priv *il);
/**
* il3945_hw_find_station - Find station id for a given BSSID
@@ -259,16 +253,14 @@ extern int il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx);
* not yet been merged into a single common layer for managing the
* station tables.
*/
-extern u8 il3945_hw_find_station(struct il_priv *il, const u8 * bssid);
-
-extern struct ieee80211_ops il3945_hw_ops;
+u8 il3945_hw_find_station(struct il_priv *il, const u8 *bssid);
-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);
+__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 int il3945_rs_next_rate(struct il_priv *il, int rate);
+int il3945_rs_next_rate(struct il_priv *il, int rate);
/* scanning */
int il3945_request_scan(struct il_priv *il, struct ieee80211_vif *vif);
@@ -595,13 +587,7 @@ struct il3945_tfd {
} __packed;
#ifdef CONFIG_IWLEGACY_DEBUGFS
-ssize_t il3945_ucode_rx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-ssize_t il3945_ucode_tx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-ssize_t il3945_ucode_general_stats_read(struct file *file,
- char __user *user_buf, size_t count,
- loff_t *ppos);
+extern const struct il_debugfs_ops il3945_debugfs_ops;
#endif
#endif
diff --git a/drivers/net/wireless/iwlegacy/4965-calib.c b/drivers/net/wireless/iwlegacy/4965-calib.c
index d3248e3ef23..e78bdefb895 100644
--- a/drivers/net/wireless/iwlegacy/4965-calib.c
+++ b/drivers/net/wireless/iwlegacy/4965-calib.c
@@ -79,18 +79,6 @@ struct stats_general_data {
u32 beacon_energy_c;
};
-void
-il4965_calib_free_results(struct il_priv *il)
-{
- int i;
-
- for (i = 0; i < IL_CALIB_MAX; i++) {
- kfree(il->calib_results[i].buf);
- il->calib_results[i].buf = NULL;
- il->calib_results[i].buf_len = 0;
- }
-}
-
/*****************************************************************************
* RUNTIME calibrations framework
*****************************************************************************/
@@ -627,13 +615,13 @@ il4965_find_disconn_antenna(struct il_priv *il, u32 * average_sig,
average_sig[0] =
data->chain_signal_a /
- il->cfg->base_params->chain_noise_num_beacons;
+ il->cfg->chain_noise_num_beacons;
average_sig[1] =
data->chain_signal_b /
- il->cfg->base_params->chain_noise_num_beacons;
+ il->cfg->chain_noise_num_beacons;
average_sig[2] =
data->chain_signal_c /
- il->cfg->base_params->chain_noise_num_beacons;
+ il->cfg->chain_noise_num_beacons;
if (average_sig[0] >= average_sig[1]) {
max_average_sig = average_sig[0];
@@ -806,8 +794,6 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp)
unsigned long flags;
struct stats_rx_non_phy *rx_info;
- struct il_rxon_context *ctx = &il->ctx;
-
if (il->disable_chain_noise_cal)
return;
@@ -833,8 +819,8 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp)
return;
}
- rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK);
- rxon_chnum = le16_to_cpu(ctx->staging.channel);
+ rxon_band24 = !!(il->staging.flags & RXON_FLG_BAND_24G_MSK);
+ rxon_chnum = le16_to_cpu(il->staging.channel);
stat_band24 =
!!(((struct il_notif_stats *)stat_resp)->
@@ -888,7 +874,7 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp)
/* If this is the "chain_noise_num_beacons", determine:
* 1) Disconnected antennas (using signal strengths)
* 2) Differential gain (using silence noise) to balance receivers */
- if (data->beacon_count != il->cfg->base_params->chain_noise_num_beacons)
+ if (data->beacon_count != il->cfg->chain_noise_num_beacons)
return;
/* Analyze signal for disconnected antenna */
@@ -896,11 +882,11 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp)
/* Analyze noise for rx balance */
average_noise[0] =
- data->chain_noise_a / il->cfg->base_params->chain_noise_num_beacons;
+ data->chain_noise_a / il->cfg->chain_noise_num_beacons;
average_noise[1] =
- data->chain_noise_b / il->cfg->base_params->chain_noise_num_beacons;
+ data->chain_noise_b / il->cfg->chain_noise_num_beacons;
average_noise[2] =
- data->chain_noise_c / il->cfg->base_params->chain_noise_num_beacons;
+ data->chain_noise_c / il->cfg->chain_noise_num_beacons;
for (i = 0; i < NUM_RX_CHAINS; i++) {
if (!data->disconn_array[i] &&
@@ -925,8 +911,8 @@ il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp)
/* Some power changes may have been made during the calibration.
* Update and commit the RXON
*/
- if (il->cfg->ops->lib->update_chain_flags)
- il->cfg->ops->lib->update_chain_flags(il);
+ if (il->ops->update_chain_flags)
+ il->ops->update_chain_flags(il);
data->state = IL_CHAIN_NOISE_DONE;
il_power_update_mode(il, false);
diff --git a/drivers/net/wireless/iwlegacy/4965-debug.c b/drivers/net/wireless/iwlegacy/4965-debug.c
index 98ec39f56ba..e0597bfdddb 100644
--- a/drivers/net/wireless/iwlegacy/4965-debug.c
+++ b/drivers/net/wireless/iwlegacy/4965-debug.c
@@ -55,7 +55,7 @@ il4965_stats_flag(struct il_priv *il, char *buf, int bufsz)
return p;
}
-ssize_t
+static ssize_t
il4965_ucode_rx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -467,7 +467,7 @@ il4965_ucode_rx_stats_read(struct file *file, char __user *user_buf,
return ret;
}
-ssize_t
+static ssize_t
il4965_ucode_tx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -633,7 +633,7 @@ il4965_ucode_tx_stats_read(struct file *file, char __user *user_buf,
return ret;
}
-ssize_t
+static ssize_t
il4965_ucode_general_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -744,3 +744,9 @@ il4965_ucode_general_stats_read(struct file *file, char __user *user_buf,
kfree(buf);
return ret;
}
+
+const struct il_debugfs_ops il4965_debugfs_ops = {
+ .rx_stats_read = il4965_ucode_rx_stats_read,
+ .tx_stats_read = il4965_ucode_tx_stats_read,
+ .general_stats_read = il4965_ucode_general_stats_read,
+};
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index 1667232af64..c159c05db6e 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -92,7 +92,6 @@ il4965_check_abort_status(struct il_priv *il, u8 frame_count, u32 status)
* EEPROM
*/
struct il_mod_params il4965_mod_params = {
- .amsdu_size_8K = 1,
.restart_fw = 1,
/* the rest are 0 by default */
};
@@ -199,18 +198,14 @@ il4965_hw_nic_init(struct il_priv *il)
struct il_rx_queue *rxq = &il->rxq;
int ret;
- /* nic_init */
spin_lock_irqsave(&il->lock, flags);
- il->cfg->ops->lib->apm_ops.init(il);
-
+ il_apm_init(il);
/* Set interrupt coalescing calibration timer to default (512 usecs) */
il_write8(il, CSR_INT_COALESCING, IL_HOST_INT_CALIB_TIMEOUT_DEF);
-
spin_unlock_irqrestore(&il->lock, flags);
il4965_set_pwr_vmain(il);
-
- il->cfg->ops->lib->apm_ops.config(il);
+ il4965_nic_config(il);
/* Allocate the RX queue, or reset if it is already allocated */
if (!rxq->bd) {
@@ -323,6 +318,7 @@ il4965_rx_allocate(struct il_priv *il, gfp_t priority)
struct list_head *element;
struct il_rx_buf *rxb;
struct page *page;
+ dma_addr_t page_dma;
unsigned long flags;
gfp_t gfp_mask = priority;
@@ -360,33 +356,35 @@ il4965_rx_allocate(struct il_priv *il, gfp_t priority)
return;
}
+ /* Get physical address of the RB */
+ page_dma =
+ pci_map_page(il->pci_dev, page, 0,
+ PAGE_SIZE << il->hw_params.rx_page_order,
+ PCI_DMA_FROMDEVICE);
+ if (unlikely(pci_dma_mapping_error(il->pci_dev, page_dma))) {
+ __free_pages(page, il->hw_params.rx_page_order);
+ break;
+ }
+
spin_lock_irqsave(&rxq->lock, flags);
if (list_empty(&rxq->rx_used)) {
spin_unlock_irqrestore(&rxq->lock, flags);
+ pci_unmap_page(il->pci_dev, page_dma,
+ PAGE_SIZE << il->hw_params.rx_page_order,
+ PCI_DMA_FROMDEVICE);
__free_pages(page, il->hw_params.rx_page_order);
return;
}
+
element = rxq->rx_used.next;
rxb = list_entry(element, struct il_rx_buf, list);
list_del(element);
- spin_unlock_irqrestore(&rxq->lock, flags);
-
BUG_ON(rxb->page);
- rxb->page = page;
- /* Get physical address of the RB */
- rxb->page_dma =
- pci_map_page(il->pci_dev, page, 0,
- PAGE_SIZE << il->hw_params.rx_page_order,
- PCI_DMA_FROMDEVICE);
- /* dma address must be no more than 36 bits */
- BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));
- /* and also 256 byte aligned! */
- BUG_ON(rxb->page_dma & DMA_BIT_MASK(8));
-
- spin_lock_irqsave(&rxq->lock, flags);
+ rxb->page = page;
+ rxb->page_dma = page_dma;
list_add_tail(&rxb->list, &rxq->rx_free);
rxq->free_count++;
il->alloc_rxb_page++;
@@ -445,11 +443,15 @@ il4965_rx_queue_free(struct il_priv *il, struct il_rx_queue *rxq)
int
il4965_rxq_stop(struct il_priv *il)
{
+ int ret;
- /* stop Rx DMA */
- il_wr(il, FH49_MEM_RCSR_CHNL0_CONFIG_REG, 0);
- il_poll_bit(il, FH49_MEM_RSSR_RX_STATUS_REG,
- FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
+ _il_wr(il, FH49_MEM_RCSR_CHNL0_CONFIG_REG, 0);
+ ret = _il_poll_bit(il, FH49_MEM_RSSR_RX_STATUS_REG,
+ FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
+ FH49_RSSR_CHNL0_RX_STATUS_CHNL_IDLE,
+ 1000);
+ if (ret < 0)
+ IL_ERR("Can't stop Rx DMA.\n");
return 0;
}
@@ -571,9 +573,11 @@ il4965_translate_rx_status(struct il_priv *il, u32 decrypt_in)
return decrypt_out;
}
+#define SMALL_PACKET_SIZE 256
+
static void
il4965_pass_packet_to_mac80211(struct il_priv *il, struct ieee80211_hdr *hdr,
- u16 len, u32 ampdu_status, struct il_rx_buf *rxb,
+ u32 len, u32 ampdu_status, struct il_rx_buf *rxb,
struct ieee80211_rx_status *stats)
{
struct sk_buff *skb;
@@ -585,34 +589,44 @@ il4965_pass_packet_to_mac80211(struct il_priv *il, struct ieee80211_hdr *hdr,
return;
}
+ if (unlikely(test_bit(IL_STOP_REASON_PASSIVE, &il->stop_reason))) {
+ il_wake_queues_by_reason(il, IL_STOP_REASON_PASSIVE);
+ D_INFO("Woke queues - frame received on passive channel\n");
+ }
+
/* In case of HW accelerated crypto and bad decryption, drop */
if (!il->cfg->mod_params->sw_crypto &&
il_set_decrypted_flag(il, hdr, ampdu_status, stats))
return;
- skb = dev_alloc_skb(128);
+ skb = dev_alloc_skb(SMALL_PACKET_SIZE);
if (!skb) {
IL_ERR("dev_alloc_skb failed\n");
return;
}
- skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
+ if (len <= SMALL_PACKET_SIZE) {
+ memcpy(skb_put(skb, len), hdr, len);
+ } else {
+ skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb),
+ len, PAGE_SIZE << il->hw_params.rx_page_order);
+ il->alloc_rxb_page--;
+ rxb->page = NULL;
+ }
il_update_stats(il, false, fc, len);
memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
ieee80211_rx(il->hw, skb);
- il->alloc_rxb_page--;
- rxb->page = NULL;
}
/* Called for N_RX (legacy ABG frames), or
* N_RX_MPDU (HT high-throughput N frames). */
-void
+static void
il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
{
struct ieee80211_hdr *header;
- struct ieee80211_rx_status rx_status;
+ struct ieee80211_rx_status rx_status = {};
struct il_rx_pkt *pkt = rxb_addr(rxb);
struct il_rx_phy_res *phy_res;
__le32 rx_pkt_status;
@@ -656,7 +670,7 @@ il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
}
if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
- D_DROP("dsp size out of range [0,20]: %d/n",
+ D_DROP("dsp size out of range [0,20]: %d\n",
phy_res->cfg_phy_cnt);
return;
}
@@ -685,14 +699,13 @@ il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
/* TSF isn't reliable. In order to allow smooth user experience,
* this W/A doesn't propagate it to the mac80211 */
- /*rx_status.flag |= RX_FLAG_MACTIME_MPDU; */
+ /*rx_status.flag |= RX_FLAG_MACTIME_START; */
il->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp);
/* Find max signal strength (dBm) among 3 antenna/receiver chains */
rx_status.signal = il4965_calc_rssi(il, phy_res);
- il_dbg_log_rx_data_frame(il, len, header);
D_STATS("Rssi %d, TSF %llu\n", rx_status.signal,
(unsigned long long)rx_status.mactime);
@@ -725,17 +738,28 @@ il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
if (rate_n_flags & RATE_MCS_SGI_MSK)
rx_status.flag |= RX_FLAG_SHORT_GI;
+ if (phy_res->phy_flags & RX_RES_PHY_FLAGS_AGG_MSK) {
+ /* We know which subframes of an A-MPDU belong
+ * together since we get a single PHY response
+ * from the firmware for all of them.
+ */
+
+ rx_status.flag |= RX_FLAG_AMPDU_DETAILS;
+ rx_status.ampdu_reference = il->_4965.ampdu_ref;
+ }
+
il4965_pass_packet_to_mac80211(il, header, len, ampdu_status, rxb,
&rx_status);
}
/* Cache phy data (Rx signal strength, etc) for HT frame (N_RX_PHY).
* This will be used later in il_hdl_rx() for N_RX_MPDU. */
-void
+static void
il4965_hdl_rx_phy(struct il_priv *il, struct il_rx_buf *rxb)
{
struct il_rx_pkt *pkt = rxb_addr(rxb);
il->_4965.last_phy_res_valid = true;
+ il->_4965.ampdu_ref++;
memcpy(&il->_4965.last_phy_res, pkt->u.raw,
sizeof(struct il_rx_phy_res));
}
@@ -780,7 +804,7 @@ il4965_get_channels_for_scan(struct il_priv *il, struct ieee80211_vif *vif,
}
if (!is_active || il_is_channel_passive(ch_info) ||
- (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
+ (chan->flags & IEEE80211_CHAN_NO_IR))
scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
else
scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
@@ -843,7 +867,6 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
.flags = CMD_SIZE_HUGE,
};
struct il_scan_cmd *scan;
- struct il_rxon_context *ctx = &il->ctx;
u32 rate_flags = 0;
u16 cmd_len;
u16 rx_chain = 0;
@@ -859,8 +882,6 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
lockdep_assert_held(&il->mutex);
- ctx = il_rxon_ctx_from_vif(vif);
-
if (!il->scan_cmd) {
il->scan_cmd =
kmalloc(sizeof(struct il_scan_cmd) + IL_MAX_SCAN_SIZE,
@@ -919,15 +940,14 @@ il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif)
D_SCAN("Start passive scan.\n");
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
- scan->tx_cmd.sta_id = ctx->bcast_sta_id;
+ scan->tx_cmd.sta_id = il->hw_params.bcast_id;
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
switch (il->scan_band) {
case IEEE80211_BAND_2GHZ:
scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
chan_mod =
- le32_to_cpu(il->ctx.active.
- flags & RXON_FLG_CHANNEL_MODE_MSK) >>
+ le32_to_cpu(il->active.flags & RXON_FLG_CHANNEL_MODE_MSK) >>
RXON_FLG_CHANNEL_MODE_POS;
if (chan_mod == CHANNEL_MODE_PURE_40) {
rate = RATE_6M_PLCP;
@@ -1034,8 +1054,7 @@ il4965_manage_ibss_station(struct il_priv *il, struct ieee80211_vif *vif,
struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
if (add)
- return il4965_add_bssid_station(il, vif_priv->ctx,
- vif->bss_conf.bssid,
+ return il4965_add_bssid_station(il, vif->bss_conf.bssid,
&vif_priv->ibss_bssid_sta_id);
return il_remove_station(il, vif_priv->ibss_bssid_sta_id,
vif->bss_conf.bssid);
@@ -1128,7 +1147,7 @@ il4965_count_chain_bitmap(u32 chain_bitmap)
* This should not be used for scan command ... it puts data in wrong place.
*/
void
-il4965_set_rxon_chain(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_set_rxon_chain(struct il_priv *il)
{
bool is_single = il4965_is_single_rx_stream(il);
bool is_cam = !test_bit(S_POWER_PMI, &il->status);
@@ -1164,14 +1183,14 @@ il4965_set_rxon_chain(struct il_priv *il, struct il_rxon_context *ctx)
rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
- ctx->staging.rx_chain = cpu_to_le16(rx_chain);
+ il->staging.rx_chain = cpu_to_le16(rx_chain);
if (!is_single && active_rx_cnt >= IL_NUM_RX_CHAINS_SINGLE && is_cam)
- ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
+ il->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
else
- ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
+ il->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
- D_ASSOC("rx_chain=0x%X active=%d idle=%d\n", ctx->staging.rx_chain,
+ D_ASSOC("rx_chain=0x%X active=%d idle=%d\n", il->staging.rx_chain,
active_rx_cnt, idle_rx_cnt);
WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 ||
@@ -1241,7 +1260,7 @@ il4965_dump_fh(struct il_priv *il, char **buf, bool display)
return 0;
}
-void
+static void
il4965_hdl_missed_beacon(struct il_priv *il, struct il_rx_buf *rxb)
{
struct il_rx_pkt *pkt = rxb_addr(rxb);
@@ -1348,12 +1367,11 @@ il4965_accumulative_stats(struct il_priv *il, __le32 * stats)
}
#endif
-#define REG_RECALIB_PERIOD (60)
-
-void
+static void
il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb)
{
- int change;
+ const int recalib_seconds = 60;
+ bool change;
struct il_rx_pkt *pkt = rxb_addr(rxb);
D_RX("Statistics notification received (%d vs %d).\n",
@@ -1374,23 +1392,24 @@ il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb)
set_bit(S_STATS, &il->status);
- /* Reschedule the stats timer to occur in
- * REG_RECALIB_PERIOD seconds to ensure we get a
- * thermal update even if the uCode doesn't give
- * us one */
+ /*
+ * Reschedule the stats timer to occur in recalib_seconds to ensure
+ * we get a thermal update even if the uCode doesn't give us one
+ */
mod_timer(&il->stats_periodic,
- jiffies + msecs_to_jiffies(REG_RECALIB_PERIOD * 1000));
+ jiffies + msecs_to_jiffies(recalib_seconds * 1000));
if (unlikely(!test_bit(S_SCANNING, &il->status)) &&
(pkt->hdr.cmd == N_STATS)) {
il4965_rx_calc_noise(il);
queue_work(il->workqueue, &il->run_time_calib_work);
}
- if (il->cfg->ops->lib->temp_ops.temperature && change)
- il->cfg->ops->lib->temp_ops.temperature(il);
+
+ if (change)
+ il4965_temperature_calib(il);
}
-void
+static void
il4965_hdl_c_stats(struct il_priv *il, struct il_rx_buf *rxb)
{
struct il_rx_pkt *pkt = rxb_addr(rxb);
@@ -1457,10 +1476,17 @@ il4965_get_ac_from_tid(u16 tid)
}
static inline int
-il4965_get_fifo_from_tid(struct il_rxon_context *ctx, u16 tid)
+il4965_get_fifo_from_tid(u16 tid)
{
+ const u8 ac_to_fifo[] = {
+ IL_TX_FIFO_VO,
+ IL_TX_FIFO_VI,
+ IL_TX_FIFO_BE,
+ IL_TX_FIFO_BK,
+ };
+
if (likely(tid < ARRAY_SIZE(tid_to_ac)))
- return ctx->ac_to_fifo[tid_to_ac[tid]];
+ return ac_to_fifo[tid_to_ac[tid]];
/* no support for TIDs 8-15 yet */
return -EINVAL;
@@ -1524,8 +1550,11 @@ il4965_tx_cmd_build_basic(struct il_priv *il, struct sk_buff *skb,
}
static void
-il4965_tx_cmd_build_rate(struct il_priv *il, struct il_tx_cmd *tx_cmd,
- struct ieee80211_tx_info *info, __le16 fc)
+il4965_tx_cmd_build_rate(struct il_priv *il,
+ struct il_tx_cmd *tx_cmd,
+ struct ieee80211_tx_info *info,
+ struct ieee80211_sta *sta,
+ __le16 fc)
{
const u8 rts_retry_limit = 60;
u32 rate_flags;
@@ -1559,9 +1588,7 @@ il4965_tx_cmd_build_rate(struct il_priv *il, struct il_tx_cmd *tx_cmd,
rate_idx = info->control.rates[0].idx;
if ((info->control.rates[0].flags & IEEE80211_TX_RC_MCS) || rate_idx < 0
|| rate_idx > RATE_COUNT_LEGACY)
- rate_idx =
- rate_lowest_index(&il->bands[info->band],
- info->control.sta);
+ rate_idx = rate_lowest_index(&il->bands[info->band], sta);
/* For 5 GHZ band, remap mac80211 rate indices into driver indices */
if (info->band == IEEE80211_BAND_5GHZ)
rate_idx += IL_FIRST_OFDM_RATE;
@@ -1628,18 +1655,18 @@ il4965_tx_cmd_build_hwcrypto(struct il_priv *il, struct ieee80211_tx_info *info,
* start C_TX command process
*/
int
-il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
+il4965_tx_skb(struct il_priv *il,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ieee80211_sta *sta = info->control.sta;
struct il_station_priv *sta_priv = NULL;
struct il_tx_queue *txq;
struct il_queue *q;
struct il_device_cmd *out_cmd;
struct il_cmd_meta *out_meta;
struct il_tx_cmd *tx_cmd;
- struct il_rxon_context *ctx = &il->ctx;
int txq_id;
dma_addr_t phys_addr;
dma_addr_t txcmd_phys;
@@ -1655,9 +1682,6 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
unsigned long flags;
bool is_agg = false;
- if (info->control.vif)
- ctx = il_rxon_ctx_from_vif(info->control.vif);
-
spin_lock_irqsave(&il->lock, flags);
if (il_is_rfkill(il)) {
D_DROP("Dropping - RF KILL\n");
@@ -1679,10 +1703,10 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
/* For management frames use broadcast id to do not break aggregation */
if (!ieee80211_is_data(fc))
- sta_id = ctx->bcast_sta_id;
+ sta_id = il->hw_params.bcast_id;
else {
/* Find idx into station table for destination station */
- sta_id = il_sta_id_or_broadcast(il, ctx, info->control.sta);
+ sta_id = il_sta_id_or_broadcast(il, sta);
if (sta_id == IL_INVALID_STATION) {
D_DROP("Dropping - INVALID STATION: %pM\n", hdr->addr1);
@@ -1696,7 +1720,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
sta_priv = (void *)sta->drv_priv;
if (sta_priv && sta_priv->asleep &&
- (info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)) {
+ (info->flags & IEEE80211_TX_CTL_NO_PS_BUFFER)) {
/*
* This sends an asynchronous command to the device,
* but we can rely on it being processed before the
@@ -1709,19 +1733,11 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
il4965_sta_modify_sleep_tx_count(il, sta_id, 1);
}
- /*
- * Send this frame after DTIM -- there's a special queue
- * reserved for this for contexts that support AP mode.
- */
- if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
- 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
- txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)];
+ /* FIXME: remove me ? */
+ WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM);
+
+ /* Access category (AC) is also the queue number */
+ txq_id = skb_get_queue_mapping(skb);
/* irqs already disabled/saved above when locking il->lock */
spin_lock(&il->sta_lock);
@@ -1763,10 +1779,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
spin_unlock(&il->sta_lock);
- /* Set up driver data for this TFD */
- memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct il_tx_info));
- txq->txb[q->write_ptr].skb = skb;
- txq->txb[q->write_ptr].ctx = ctx;
+ txq->skbs[q->write_ptr] = skb;
/* Set up first empty entry in queue's array of Tx/cmd buffers */
out_cmd = txq->cmd[q->write_ptr];
@@ -1790,19 +1803,16 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
memcpy(tx_cmd->hdr, hdr, hdr_len);
/* Total # bytes to be transmitted */
- len = (u16) skb->len;
- tx_cmd->len = cpu_to_le16(len);
+ tx_cmd->len = cpu_to_le16((u16) skb->len);
if (info->control.hw_key)
il4965_tx_cmd_build_hwcrypto(il, info, tx_cmd, skb, sta_id);
/* TODO need this for burst mode later on */
il4965_tx_cmd_build_basic(il, skb, tx_cmd, info, hdr, sta_id);
- il_dbg_log_tx_data_frame(il, len, hdr);
- il4965_tx_cmd_build_rate(il, tx_cmd, info, fc);
+ il4965_tx_cmd_build_rate(il, tx_cmd, info, sta, fc);
- il_update_stats(il, true, fc, len);
/*
* Use the first empty entry in this queue's command buffer array
* to contain the Tx command and MAC header concatenated together
@@ -1824,19 +1834,8 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
txcmd_phys =
pci_map_single(il->pci_dev, &out_cmd->hdr, firstlen,
PCI_DMA_BIDIRECTIONAL);
- dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
- dma_unmap_len_set(out_meta, len, firstlen);
- /* Add buffer containing Tx command and MAC(!) header to TFD's
- * first entry */
- il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen,
- 1, 0);
-
- if (!ieee80211_has_morefrags(hdr->frame_control)) {
- txq->need_update = 1;
- } else {
- wait_write_ptr = 1;
- txq->need_update = 0;
- }
+ if (unlikely(pci_dma_mapping_error(il->pci_dev, txcmd_phys)))
+ goto drop_unlock;
/* Set up TFD's 2nd entry to point directly to remainder of skb,
* if any (802.11 null frames have no payload). */
@@ -1845,8 +1844,24 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
phys_addr =
pci_map_single(il->pci_dev, skb->data + hdr_len, secondlen,
PCI_DMA_TODEVICE);
- il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr,
- secondlen, 0, 0);
+ if (unlikely(pci_dma_mapping_error(il->pci_dev, phys_addr)))
+ goto drop_unlock;
+ }
+
+ /* Add buffer containing Tx command and MAC(!) header to TFD's
+ * first entry */
+ il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, 1, 0);
+ dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
+ dma_unmap_len_set(out_meta, len, firstlen);
+ if (secondlen)
+ il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, secondlen,
+ 0, 0);
+
+ if (!ieee80211_has_morefrags(hdr->frame_control)) {
+ txq->need_update = 1;
+ } else {
+ wait_write_ptr = 1;
+ txq->need_update = 0;
}
scratch_phys =
@@ -1859,6 +1874,8 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
tx_cmd->dram_msb_ptr = il_get_dma_hi_addr(scratch_phys);
+ il_update_stats(il, true, fc, skb->len);
+
D_TX("sequence nr = 0X%x\n", le16_to_cpu(out_cmd->hdr.sequence));
D_TX("tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags));
il_print_hex_dump(il, IL_DL_TX, (u8 *) tx_cmd, sizeof(*tx_cmd));
@@ -1866,9 +1883,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
/* Set up entry for this TFD in Tx byte-count array */
if (info->flags & IEEE80211_TX_CTL_AMPDU)
- il->cfg->ops->lib->txq_update_byte_cnt_tbl(il, txq,
- le16_to_cpu(tx_cmd->
- len));
+ il->ops->txq_update_byte_cnt_tbl(il, txq, le16_to_cpu(tx_cmd->len));
pci_dma_sync_single_for_device(il->pci_dev, txcmd_phys, firstlen,
PCI_DMA_BIDIRECTIONAL);
@@ -1916,8 +1931,8 @@ drop_unlock:
static inline int
il4965_alloc_dma_ptr(struct il_priv *il, struct il_dma_ptr *ptr, size_t size)
{
- ptr->addr =
- dma_alloc_coherent(&il->pci_dev->dev, size, &ptr->dma, GFP_KERNEL);
+ ptr->addr = dma_alloc_coherent(&il->pci_dev->dev, size, &ptr->dma,
+ GFP_KERNEL);
if (!ptr->addr)
return -ENOMEM;
ptr->size = size;
@@ -1957,7 +1972,7 @@ il4965_hw_txq_ctx_free(struct il_priv *il)
il4965_free_dma_ptr(il, &il->scd_bc_tbls);
/* free tx queue structure */
- il_txq_mem(il);
+ il_free_txq_mem(il);
}
/**
@@ -1970,8 +1985,7 @@ il4965_hw_txq_ctx_free(struct il_priv *il)
int
il4965_txq_ctx_alloc(struct il_priv *il)
{
- int ret;
- int txq_id, slots_num;
+ int ret, txq_id;
unsigned long flags;
/* Free all tx/cmd queues and keep-warm buffer */
@@ -2008,10 +2022,7 @@ il4965_txq_ctx_alloc(struct il_priv *il)
/* Alloc and init all Tx queues, including the command queue (#4/#9) */
for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
- slots_num =
- (txq_id ==
- il->cmd_queue) ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
- ret = il_tx_queue_init(il, &il->txq[txq_id], slots_num, txq_id);
+ ret = il_tx_queue_init(il, txq_id);
if (ret) {
IL_ERR("Tx %d queue init failed\n", txq_id);
goto error;
@@ -2032,52 +2043,27 @@ error_bc_tbls:
void
il4965_txq_ctx_reset(struct il_priv *il)
{
- int txq_id, slots_num;
+ int txq_id;
unsigned long flags;
spin_lock_irqsave(&il->lock, flags);
/* Turn off all Tx DMA fifos */
il4965_txq_set_sched(il, 0);
-
/* Tell NIC where to find the "keep warm" buffer */
il_wr(il, FH49_KW_MEM_ADDR_REG, il->kw.dma >> 4);
spin_unlock_irqrestore(&il->lock, flags);
/* Alloc and init all Tx queues, including the command queue (#4) */
- for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
- slots_num =
- txq_id == il->cmd_queue ? TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
- il_tx_queue_reset(il, &il->txq[txq_id], slots_num, txq_id);
- }
+ for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++)
+ il_tx_queue_reset(il, txq_id);
}
-/**
- * il4965_txq_ctx_stop - Stop all Tx DMA channels
- */
-void
-il4965_txq_ctx_stop(struct il_priv *il)
+static void
+il4965_txq_ctx_unmap(struct il_priv *il)
{
- int ch, txq_id;
- unsigned long flags;
-
- /* Turn off all Tx DMA fifos */
- spin_lock_irqsave(&il->lock, flags);
-
- il4965_txq_set_sched(il, 0);
-
- /* Stop each Tx DMA channel, and wait for it to be idle */
- for (ch = 0; ch < il->hw_params.dma_chnl_num; ch++) {
- il_wr(il, FH49_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
- if (il_poll_bit
- (il, FH49_TSSR_TX_STATUS_REG,
- FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000))
- IL_ERR("Failing on timeout while stopping"
- " DMA channel %d [0x%08x]", ch,
- il_rd(il, FH49_TSSR_TX_STATUS_REG));
- }
- spin_unlock_irqrestore(&il->lock, flags);
+ int txq_id;
if (!il->txq)
return;
@@ -2090,6 +2076,30 @@ il4965_txq_ctx_stop(struct il_priv *il)
il_tx_queue_unmap(il, txq_id);
}
+/**
+ * il4965_txq_ctx_stop - Stop all Tx DMA channels
+ */
+void
+il4965_txq_ctx_stop(struct il_priv *il)
+{
+ int ch, ret;
+
+ _il_wr_prph(il, IL49_SCD_TXFACT, 0);
+
+ /* Stop each Tx DMA channel, and wait for it to be idle */
+ for (ch = 0; ch < il->hw_params.dma_chnl_num; ch++) {
+ _il_wr(il, FH49_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
+ ret =
+ _il_poll_bit(il, FH49_TSSR_TX_STATUS_REG,
+ FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
+ FH49_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
+ 1000);
+ if (ret < 0)
+ IL_ERR("Timeout stopping DMA channel %d [0x%08x]",
+ ch, _il_rd(il, FH49_TSSR_TX_STATUS_REG));
+ }
+}
+
/*
* Find first available (lowest unused) Tx Queue, mark it "active".
* Called only when finding queue for aggregation.
@@ -2163,11 +2173,11 @@ il4965_txq_agg_enable(struct il_priv *il, int txq_id, int tx_fifo, int sta_id,
if ((IL49_FIRST_AMPDU_QUEUE > txq_id) ||
(IL49_FIRST_AMPDU_QUEUE +
- il->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
+ il->cfg->num_of_ampdu_queues <= txq_id)) {
IL_WARN("queue number out of range: %d, must be %d to %d\n",
txq_id, IL49_FIRST_AMPDU_QUEUE,
IL49_FIRST_AMPDU_QUEUE +
- il->cfg->base_params->num_of_ampdu_queues - 1);
+ il->cfg->num_of_ampdu_queues - 1);
return -EINVAL;
}
@@ -2230,7 +2240,8 @@ il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif,
unsigned long flags;
struct il_tid_data *tid_data;
- tx_fifo = il4965_get_fifo_from_tid(il_rxon_ctx_from_vif(vif), tid);
+ /* FIXME: warning if tx fifo not found ? */
+ tx_fifo = il4965_get_fifo_from_tid(tid);
if (unlikely(tx_fifo < 0))
return tx_fifo;
@@ -2257,7 +2268,7 @@ il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif,
spin_lock_irqsave(&il->sta_lock, flags);
tid_data = &il->stations[sta_id].tid[tid];
- *ssn = SEQ_TO_SN(tid_data->seq_number);
+ *ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
tid_data->agg.txq_id = txq_id;
il_set_swq_id(&il->txq[txq_id], il4965_get_ac_from_tid(tid), txq_id);
spin_unlock_irqrestore(&il->sta_lock, flags);
@@ -2290,11 +2301,11 @@ il4965_txq_agg_disable(struct il_priv *il, u16 txq_id, u16 ssn_idx, u8 tx_fifo)
{
if ((IL49_FIRST_AMPDU_QUEUE > txq_id) ||
(IL49_FIRST_AMPDU_QUEUE +
- il->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
+ il->cfg->num_of_ampdu_queues <= txq_id)) {
IL_WARN("queue number out of range: %d, must be %d to %d\n",
txq_id, IL49_FIRST_AMPDU_QUEUE,
IL49_FIRST_AMPDU_QUEUE +
- il->cfg->base_params->num_of_ampdu_queues - 1);
+ il->cfg->num_of_ampdu_queues - 1);
return -EINVAL;
}
@@ -2323,7 +2334,8 @@ il4965_tx_agg_stop(struct il_priv *il, struct ieee80211_vif *vif,
int write_ptr, read_ptr;
unsigned long flags;
- tx_fifo_id = il4965_get_fifo_from_tid(il_rxon_ctx_from_vif(vif), tid);
+ /* FIXME: warning if tx_fifo_id not found ? */
+ tx_fifo_id = il4965_get_fifo_from_tid(tid);
if (unlikely(tx_fifo_id < 0))
return tx_fifo_id;
@@ -2397,9 +2409,6 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id)
struct il_queue *q = &il->txq[txq_id].q;
u8 *addr = il->stations[sta_id].sta.sta.addr;
struct il_tid_data *tid_data = &il->stations[sta_id].tid[tid];
- struct il_rxon_context *ctx;
-
- ctx = &il->ctx;
lockdep_assert_held(&il->sta_lock);
@@ -2409,12 +2418,12 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id)
/* aggregated HW queue */
if (txq_id == tid_data->agg.txq_id &&
q->read_ptr == q->write_ptr) {
- u16 ssn = SEQ_TO_SN(tid_data->seq_number);
- int tx_fifo = il4965_get_fifo_from_tid(ctx, tid);
+ u16 ssn = IEEE80211_SEQ_TO_SN(tid_data->seq_number);
+ int tx_fifo = il4965_get_fifo_from_tid(tid);
D_HT("HW queue empty: continue DELBA flow\n");
il4965_txq_agg_disable(il, txq_id, ssn, tx_fifo);
tid_data->agg.state = IL_AGG_OFF;
- ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
+ ieee80211_stop_tx_ba_cb_irqsafe(il->vif, addr, tid);
}
break;
case IL_EMPTYING_HW_QUEUE_ADDBA:
@@ -2422,7 +2431,7 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id)
if (tid_data->tfds_in_queue == 0) {
D_HT("HW queue empty: continue ADDBA flow\n");
tid_data->agg.state = IL_AGG_ON;
- ieee80211_start_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
+ ieee80211_start_tx_ba_cb_irqsafe(il->vif, addr, tid);
}
break;
}
@@ -2431,14 +2440,13 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id)
}
static void
-il4965_non_agg_tx_status(struct il_priv *il, struct il_rxon_context *ctx,
- const u8 *addr1)
+il4965_non_agg_tx_status(struct il_priv *il, const u8 *addr1)
{
struct ieee80211_sta *sta;
struct il_station_priv *sta_priv;
rcu_read_lock();
- sta = ieee80211_find_sta(ctx->vif, addr1);
+ sta = ieee80211_find_sta(il->vif, addr1);
if (sta) {
sta_priv = (void *)sta->drv_priv;
/* avoid atomic ops if this isn't a client */
@@ -2450,14 +2458,14 @@ il4965_non_agg_tx_status(struct il_priv *il, struct il_rxon_context *ctx,
}
static void
-il4965_tx_status(struct il_priv *il, struct il_tx_info *tx_info, bool is_agg)
+il4965_tx_status(struct il_priv *il, struct sk_buff *skb, bool is_agg)
{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx_info->skb->data;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
if (!is_agg)
- il4965_non_agg_tx_status(il, tx_info->ctx, hdr->addr1);
+ il4965_non_agg_tx_status(il, hdr->addr1);
- ieee80211_tx_status_irqsafe(il->hw, tx_info->skb);
+ ieee80211_tx_status_irqsafe(il->hw, skb);
}
int
@@ -2465,9 +2473,9 @@ il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx)
{
struct il_tx_queue *txq = &il->txq[txq_id];
struct il_queue *q = &txq->q;
- struct il_tx_info *tx_info;
int nfreed = 0;
struct ieee80211_hdr *hdr;
+ struct sk_buff *skb;
if (idx >= q->n_bd || il_queue_used(q, idx) == 0) {
IL_ERR("Read idx for DMA queue txq id (%d), idx %d, "
@@ -2479,20 +2487,19 @@ il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx)
for (idx = il_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd)) {
- tx_info = &txq->txb[txq->q.read_ptr];
+ skb = txq->skbs[txq->q.read_ptr];
- if (WARN_ON_ONCE(tx_info->skb == NULL))
+ if (WARN_ON_ONCE(skb == NULL))
continue;
- hdr = (struct ieee80211_hdr *)tx_info->skb->data;
+ hdr = (struct ieee80211_hdr *) skb->data;
if (ieee80211_is_data_qos(hdr->frame_control))
nfreed++;
- il4965_tx_status(il, tx_info,
- txq_id >= IL4965_FIRST_AMPDU_QUEUE);
- tx_info->skb = NULL;
+ il4965_tx_status(il, skb, txq_id >= IL4965_FIRST_AMPDU_QUEUE);
- il->cfg->ops->lib->txq_free_tfd(il, txq);
+ txq->skbs[txq->q.read_ptr] = NULL;
+ il->ops->txq_free_tfd(il, txq);
}
return nfreed;
}
@@ -2555,7 +2562,7 @@ il4965_tx_status_reply_compressed_ba(struct il_priv *il, struct il_ht_agg *agg,
D_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap);
- info = IEEE80211_SKB_CB(il->txq[scd_flow].txb[agg->start_idx].skb);
+ info = IEEE80211_SKB_CB(il->txq[scd_flow].skbs[agg->start_idx]);
memset(&info->status, 0, sizeof(info->status));
info->flags |= IEEE80211_TX_STAT_ACK;
info->flags |= IEEE80211_TX_STAT_AMPDU;
@@ -2566,6 +2573,322 @@ il4965_tx_status_reply_compressed_ba(struct il_priv *il, struct il_ht_agg *agg,
return 0;
}
+static inline bool
+il4965_is_tx_success(u32 status)
+{
+ status &= TX_STATUS_MSK;
+ return (status == TX_STATUS_SUCCESS || status == TX_STATUS_DIRECT_DONE);
+}
+
+static u8
+il4965_find_station(struct il_priv *il, const u8 *addr)
+{
+ int i;
+ int start = 0;
+ int ret = IL_INVALID_STATION;
+ unsigned long flags;
+
+ if (il->iw_mode == NL80211_IFTYPE_ADHOC)
+ start = IL_STA_ID;
+
+ if (is_broadcast_ether_addr(addr))
+ return il->hw_params.bcast_id;
+
+ spin_lock_irqsave(&il->sta_lock, flags);
+ for (i = start; i < il->hw_params.max_stations; i++)
+ if (il->stations[i].used &&
+ ether_addr_equal(il->stations[i].sta.sta.addr, addr)) {
+ ret = i;
+ goto out;
+ }
+
+ D_ASSOC("can not find STA %pM total %d\n", addr, il->num_stations);
+
+out:
+ /*
+ * It may be possible that more commands interacting with stations
+ * arrive before we completed processing the adding of
+ * station
+ */
+ if (ret != IL_INVALID_STATION &&
+ (!(il->stations[ret].used & IL_STA_UCODE_ACTIVE) ||
+ ((il->stations[ret].used & IL_STA_UCODE_ACTIVE) &&
+ (il->stations[ret].used & IL_STA_UCODE_INPROGRESS)))) {
+ IL_ERR("Requested station info for sta %d before ready.\n",
+ ret);
+ ret = IL_INVALID_STATION;
+ }
+ spin_unlock_irqrestore(&il->sta_lock, flags);
+ return ret;
+}
+
+static int
+il4965_get_ra_sta_id(struct il_priv *il, struct ieee80211_hdr *hdr)
+{
+ if (il->iw_mode == NL80211_IFTYPE_STATION)
+ return IL_AP_ID;
+ else {
+ u8 *da = ieee80211_get_DA(hdr);
+
+ return il4965_find_station(il, da);
+ }
+}
+
+static inline u32
+il4965_get_scd_ssn(struct il4965_tx_resp *tx_resp)
+{
+ return le32_to_cpup(&tx_resp->u.status +
+ tx_resp->frame_count) & IEEE80211_MAX_SN;
+}
+
+static inline u32
+il4965_tx_status_to_mac80211(u32 status)
+{
+ status &= TX_STATUS_MSK;
+
+ switch (status) {
+ case TX_STATUS_SUCCESS:
+ case TX_STATUS_DIRECT_DONE:
+ return IEEE80211_TX_STAT_ACK;
+ case TX_STATUS_FAIL_DEST_PS:
+ return IEEE80211_TX_STAT_TX_FILTERED;
+ default:
+ return 0;
+ }
+}
+
+/**
+ * il4965_tx_status_reply_tx - Handle Tx response for frames in aggregation queue
+ */
+static int
+il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg,
+ struct il4965_tx_resp *tx_resp, int txq_id,
+ u16 start_idx)
+{
+ u16 status;
+ struct agg_tx_status *frame_status = tx_resp->u.agg_status;
+ struct ieee80211_tx_info *info = NULL;
+ struct ieee80211_hdr *hdr = NULL;
+ u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
+ int i, sh, idx;
+ u16 seq;
+ if (agg->wait_for_ba)
+ D_TX_REPLY("got tx response w/o block-ack\n");
+
+ agg->frame_count = tx_resp->frame_count;
+ agg->start_idx = start_idx;
+ agg->rate_n_flags = rate_n_flags;
+ agg->bitmap = 0;
+
+ /* num frames attempted by Tx command */
+ if (agg->frame_count == 1) {
+ /* Only one frame was attempted; no block-ack will arrive */
+ status = le16_to_cpu(frame_status[0].status);
+ idx = start_idx;
+
+ D_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
+ agg->frame_count, agg->start_idx, idx);
+
+ info = IEEE80211_SKB_CB(il->txq[txq_id].skbs[idx]);
+ info->status.rates[0].count = tx_resp->failure_frame + 1;
+ info->flags &= ~IEEE80211_TX_CTL_AMPDU;
+ info->flags |= il4965_tx_status_to_mac80211(status);
+ il4965_hwrate_to_tx_control(il, rate_n_flags, info);
+
+ D_TX_REPLY("1 Frame 0x%x failure :%d\n", status & 0xff,
+ tx_resp->failure_frame);
+ D_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);
+
+ agg->wait_for_ba = 0;
+ } else {
+ /* Two or more frames were attempted; expect block-ack */
+ u64 bitmap = 0;
+ int start = agg->start_idx;
+ struct sk_buff *skb;
+
+ /* Construct bit-map of pending frames within Tx win */
+ for (i = 0; i < agg->frame_count; i++) {
+ u16 sc;
+ status = le16_to_cpu(frame_status[i].status);
+ seq = le16_to_cpu(frame_status[i].sequence);
+ idx = SEQ_TO_IDX(seq);
+ txq_id = SEQ_TO_QUEUE(seq);
+
+ if (status &
+ (AGG_TX_STATE_FEW_BYTES_MSK |
+ AGG_TX_STATE_ABORT_MSK))
+ continue;
+
+ D_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
+ agg->frame_count, txq_id, idx);
+
+ skb = il->txq[txq_id].skbs[idx];
+ if (WARN_ON_ONCE(skb == NULL))
+ return -1;
+ hdr = (struct ieee80211_hdr *) skb->data;
+
+ sc = le16_to_cpu(hdr->seq_ctrl);
+ if (idx != (IEEE80211_SEQ_TO_SN(sc) & 0xff)) {
+ IL_ERR("BUG_ON idx doesn't match seq control"
+ " idx=%d, seq_idx=%d, seq=%d\n", idx,
+ IEEE80211_SEQ_TO_SN(sc), hdr->seq_ctrl);
+ return -1;
+ }
+
+ D_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n", i, idx,
+ IEEE80211_SEQ_TO_SN(sc));
+
+ sh = idx - start;
+ if (sh > 64) {
+ sh = (start - idx) + 0xff;
+ bitmap = bitmap << sh;
+ sh = 0;
+ start = idx;
+ } else if (sh < -64)
+ sh = 0xff - (start - idx);
+ else if (sh < 0) {
+ sh = start - idx;
+ start = idx;
+ bitmap = bitmap << sh;
+ sh = 0;
+ }
+ bitmap |= 1ULL << sh;
+ D_TX_REPLY("start=%d bitmap=0x%llx\n", start,
+ (unsigned long long)bitmap);
+ }
+
+ agg->bitmap = bitmap;
+ agg->start_idx = start;
+ D_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
+ agg->frame_count, agg->start_idx,
+ (unsigned long long)agg->bitmap);
+
+ if (bitmap)
+ agg->wait_for_ba = 1;
+ }
+ return 0;
+}
+
+/**
+ * il4965_hdl_tx - Handle standard (non-aggregation) Tx response
+ */
+static void
+il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)
+{
+ struct il_rx_pkt *pkt = rxb_addr(rxb);
+ u16 sequence = le16_to_cpu(pkt->hdr.sequence);
+ int txq_id = SEQ_TO_QUEUE(sequence);
+ int idx = SEQ_TO_IDX(sequence);
+ struct il_tx_queue *txq = &il->txq[txq_id];
+ struct sk_buff *skb;
+ struct ieee80211_hdr *hdr;
+ struct ieee80211_tx_info *info;
+ struct il4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
+ u32 status = le32_to_cpu(tx_resp->u.status);
+ int uninitialized_var(tid);
+ int sta_id;
+ int freed;
+ u8 *qc = NULL;
+ unsigned long flags;
+
+ if (idx >= txq->q.n_bd || il_queue_used(&txq->q, idx) == 0) {
+ IL_ERR("Read idx for DMA queue txq_id (%d) idx %d "
+ "is out of range [0-%d] %d %d\n", txq_id, idx,
+ txq->q.n_bd, txq->q.write_ptr, txq->q.read_ptr);
+ return;
+ }
+
+ txq->time_stamp = jiffies;
+
+ skb = txq->skbs[txq->q.read_ptr];
+ info = IEEE80211_SKB_CB(skb);
+ memset(&info->status, 0, sizeof(info->status));
+
+ hdr = (struct ieee80211_hdr *) skb->data;
+ if (ieee80211_is_data_qos(hdr->frame_control)) {
+ qc = ieee80211_get_qos_ctl(hdr);
+ tid = qc[0] & 0xf;
+ }
+
+ sta_id = il4965_get_ra_sta_id(il, hdr);
+ if (txq->sched_retry && unlikely(sta_id == IL_INVALID_STATION)) {
+ IL_ERR("Station not known\n");
+ return;
+ }
+
+ /*
+ * Firmware will not transmit frame on passive channel, if it not yet
+ * received some valid frame on that channel. When this error happen
+ * we have to wait until firmware will unblock itself i.e. when we
+ * note received beacon or other frame. We unblock queues in
+ * il4965_pass_packet_to_mac80211 or in il_mac_bss_info_changed.
+ */
+ if (unlikely((status & TX_STATUS_MSK) == TX_STATUS_FAIL_PASSIVE_NO_RX) &&
+ il->iw_mode == NL80211_IFTYPE_STATION) {
+ il_stop_queues_by_reason(il, IL_STOP_REASON_PASSIVE);
+ D_INFO("Stopped queues - RX waiting on passive channel\n");
+ }
+
+ spin_lock_irqsave(&il->sta_lock, flags);
+ if (txq->sched_retry) {
+ const u32 scd_ssn = il4965_get_scd_ssn(tx_resp);
+ struct il_ht_agg *agg = NULL;
+ WARN_ON(!qc);
+
+ agg = &il->stations[sta_id].tid[tid].agg;
+
+ il4965_tx_status_reply_tx(il, agg, tx_resp, txq_id, idx);
+
+ /* check if BAR is needed */
+ if (tx_resp->frame_count == 1 &&
+ !il4965_is_tx_success(status))
+ info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
+
+ if (txq->q.read_ptr != (scd_ssn & 0xff)) {
+ idx = il_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
+ D_TX_REPLY("Retry scheduler reclaim scd_ssn "
+ "%d idx %d\n", scd_ssn, idx);
+ freed = il4965_tx_queue_reclaim(il, txq_id, idx);
+ if (qc)
+ il4965_free_tfds_in_queue(il, sta_id, tid,
+ freed);
+
+ if (il->mac80211_registered &&
+ il_queue_space(&txq->q) > txq->q.low_mark &&
+ agg->state != IL_EMPTYING_HW_QUEUE_DELBA)
+ il_wake_queue(il, txq);
+ }
+ } else {
+ info->status.rates[0].count = tx_resp->failure_frame + 1;
+ info->flags |= il4965_tx_status_to_mac80211(status);
+ il4965_hwrate_to_tx_control(il,
+ le32_to_cpu(tx_resp->rate_n_flags),
+ info);
+
+ D_TX_REPLY("TXQ %d status %s (0x%08x) "
+ "rate_n_flags 0x%x retries %d\n", txq_id,
+ il4965_get_tx_fail_reason(status), status,
+ le32_to_cpu(tx_resp->rate_n_flags),
+ tx_resp->failure_frame);
+
+ freed = il4965_tx_queue_reclaim(il, txq_id, idx);
+ if (qc && likely(sta_id != IL_INVALID_STATION))
+ il4965_free_tfds_in_queue(il, sta_id, tid, freed);
+ else if (sta_id == IL_INVALID_STATION)
+ D_TX_REPLY("Station not known\n");
+
+ if (il->mac80211_registered &&
+ il_queue_space(&txq->q) > txq->q.low_mark)
+ il_wake_queue(il, txq);
+ }
+ if (qc && likely(sta_id != IL_INVALID_STATION))
+ il4965_txq_check_empty(il, sta_id, tid, txq_id);
+
+ il4965_check_abort_status(il, tx_resp->frame_count, status);
+
+ spin_unlock_irqrestore(&il->sta_lock, flags);
+}
+
/**
* translate ucode response to mac80211 tx status control values
*/
@@ -2573,9 +2896,9 @@ void
il4965_hwrate_to_tx_control(struct il_priv *il, u32 rate_n_flags,
struct ieee80211_tx_info *info)
{
- struct ieee80211_tx_rate *r = &info->control.rates[0];
+ struct ieee80211_tx_rate *r = &info->status.rates[0];
- info->antenna_sel_tx =
+ info->status.antenna =
((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
if (rate_n_flags & RATE_MCS_HT_MSK)
r->flags |= IEEE80211_TX_RC_MCS;
@@ -2596,7 +2919,7 @@ il4965_hwrate_to_tx_control(struct il_priv *il, u32 rate_n_flags,
* Handles block-acknowledge notification from device, which reports success
* of frames sent via aggregation.
*/
-void
+static void
il4965_hdl_compressed_ba(struct il_priv *il, struct il_rx_buf *rxb)
{
struct il_rx_pkt *pkt = rxb_addr(rxb);
@@ -2771,8 +3094,7 @@ il4965_sta_alloc_lq(struct il_priv *il, u8 sta_id)
* Function sleeps.
*/
int
-il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx,
- const u8 *addr, u8 *sta_id_r)
+il4965_add_bssid_station(struct il_priv *il, const u8 *addr, u8 *sta_id_r)
{
int ret;
u8 sta_id;
@@ -2782,7 +3104,7 @@ il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx,
if (sta_id_r)
*sta_id_r = IL_INVALID_STATION;
- ret = il_add_station_common(il, ctx, addr, 0, NULL, &sta_id);
+ ret = il_add_station_common(il, addr, 0, NULL, &sta_id);
if (ret) {
IL_ERR("Unable to add station %pM\n", addr);
return ret;
@@ -2803,7 +3125,7 @@ il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx,
return -ENOMEM;
}
- ret = il_send_lq_cmd(il, ctx, link_cmd, CMD_SYNC, true);
+ ret = il_send_lq_cmd(il, link_cmd, CMD_SYNC, true);
if (ret)
IL_ERR("Link quality command failed (%d)\n", ret);
@@ -2815,19 +3137,19 @@ il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx,
}
static int
-il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx,
- bool send_if_empty)
+il4965_static_wepkey_cmd(struct il_priv *il, bool send_if_empty)
{
- int i, not_empty = 0;
+ int i;
u8 buff[sizeof(struct il_wep_cmd) +
sizeof(struct il_wep_key) * WEP_KEYS_MAX];
struct il_wep_cmd *wep_cmd = (struct il_wep_cmd *)buff;
size_t cmd_size = sizeof(struct il_wep_cmd);
struct il_host_cmd cmd = {
- .id = ctx->wep_key_cmd,
+ .id = C_WEPKEY,
.data = wep_cmd,
.flags = CMD_SYNC,
};
+ bool not_empty = false;
might_sleep();
@@ -2835,24 +3157,23 @@ il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx,
cmd_size + (sizeof(struct il_wep_key) * WEP_KEYS_MAX));
for (i = 0; i < WEP_KEYS_MAX; i++) {
+ u8 key_size = il->_4965.wep_keys[i].key_size;
+
wep_cmd->key[i].key_idx = i;
- if (ctx->wep_keys[i].key_size) {
+ if (key_size) {
wep_cmd->key[i].key_offset = i;
- not_empty = 1;
- } else {
+ not_empty = true;
+ } else
wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET;
- }
- wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size;
- memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key,
- ctx->wep_keys[i].key_size);
+ wep_cmd->key[i].key_size = key_size;
+ memcpy(&wep_cmd->key[i].key[3], il->_4965.wep_keys[i].key, key_size);
}
wep_cmd->global_key_type = WEP_KEY_WEP_TYPE;
wep_cmd->num_keys = WEP_KEYS_MAX;
cmd_size += sizeof(struct il_wep_key) * WEP_KEYS_MAX;
-
cmd.len = cmd_size;
if (not_empty || send_if_empty)
@@ -2862,66 +3183,66 @@ il4965_static_wepkey_cmd(struct il_priv *il, struct il_rxon_context *ctx,
}
int
-il4965_restore_default_wep_keys(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_restore_default_wep_keys(struct il_priv *il)
{
lockdep_assert_held(&il->mutex);
- return il4965_static_wepkey_cmd(il, ctx, false);
+ return il4965_static_wepkey_cmd(il, false);
}
int
-il4965_remove_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx,
+il4965_remove_default_wep_key(struct il_priv *il,
struct ieee80211_key_conf *keyconf)
{
int ret;
+ int idx = keyconf->keyidx;
lockdep_assert_held(&il->mutex);
- D_WEP("Removing default WEP key: idx=%d\n", keyconf->keyidx);
+ D_WEP("Removing default WEP key: idx=%d\n", idx);
- memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
+ memset(&il->_4965.wep_keys[idx], 0, sizeof(struct il_wep_key));
if (il_is_rfkill(il)) {
D_WEP("Not sending C_WEPKEY command due to RFKILL.\n");
/* but keys in device are clear anyway so return success */
return 0;
}
- ret = il4965_static_wepkey_cmd(il, ctx, 1);
- D_WEP("Remove default WEP key: idx=%d ret=%d\n", keyconf->keyidx, ret);
+ ret = il4965_static_wepkey_cmd(il, 1);
+ D_WEP("Remove default WEP key: idx=%d ret=%d\n", idx, ret);
return ret;
}
int
-il4965_set_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx,
+il4965_set_default_wep_key(struct il_priv *il,
struct ieee80211_key_conf *keyconf)
{
int ret;
+ int len = keyconf->keylen;
+ int idx = keyconf->keyidx;
lockdep_assert_held(&il->mutex);
- if (keyconf->keylen != WEP_KEY_LEN_128 &&
- keyconf->keylen != WEP_KEY_LEN_64) {
+ if (len != WEP_KEY_LEN_128 && len != WEP_KEY_LEN_64) {
D_WEP("Bad WEP key length %d\n", keyconf->keylen);
return -EINVAL;
}
keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
keyconf->hw_key_idx = HW_KEY_DEFAULT;
- il->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher;
+ il->stations[IL_AP_ID].keyinfo.cipher = keyconf->cipher;
- ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
- memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key,
- keyconf->keylen);
+ il->_4965.wep_keys[idx].key_size = len;
+ memcpy(&il->_4965.wep_keys[idx].key, &keyconf->key, len);
- ret = il4965_static_wepkey_cmd(il, ctx, false);
- D_WEP("Set default WEP key: len=%d idx=%d ret=%d\n", keyconf->keylen,
- keyconf->keyidx, ret);
+ ret = il4965_static_wepkey_cmd(il, false);
+ D_WEP("Set default WEP key: len=%d idx=%d ret=%d\n", len, idx, ret);
return ret;
}
static int
-il4965_set_wep_dynamic_key_info(struct il_priv *il, struct il_rxon_context *ctx,
+il4965_set_wep_dynamic_key_info(struct il_priv *il,
struct ieee80211_key_conf *keyconf, u8 sta_id)
{
unsigned long flags;
@@ -2939,7 +3260,7 @@ il4965_set_wep_dynamic_key_info(struct il_priv *il, struct il_rxon_context *ctx,
if (keyconf->keylen == WEP_KEY_LEN_128)
key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
- if (sta_id == ctx->bcast_sta_id)
+ if (sta_id == il->hw_params.bcast_id)
key_flags |= STA_KEY_MULTICAST_MSK;
spin_lock_irqsave(&il->sta_lock, flags);
@@ -2976,7 +3297,6 @@ il4965_set_wep_dynamic_key_info(struct il_priv *il, struct il_rxon_context *ctx,
static int
il4965_set_ccmp_dynamic_key_info(struct il_priv *il,
- struct il_rxon_context *ctx,
struct ieee80211_key_conf *keyconf, u8 sta_id)
{
unsigned long flags;
@@ -2989,7 +3309,7 @@ il4965_set_ccmp_dynamic_key_info(struct il_priv *il,
key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
key_flags &= ~STA_KEY_FLG_INVALID;
- if (sta_id == ctx->bcast_sta_id)
+ if (sta_id == il->hw_params.bcast_id)
key_flags |= STA_KEY_MULTICAST_MSK;
keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -3025,7 +3345,6 @@ il4965_set_ccmp_dynamic_key_info(struct il_priv *il,
static int
il4965_set_tkip_dynamic_key_info(struct il_priv *il,
- struct il_rxon_context *ctx,
struct ieee80211_key_conf *keyconf, u8 sta_id)
{
unsigned long flags;
@@ -3036,7 +3355,7 @@ il4965_set_tkip_dynamic_key_info(struct il_priv *il,
key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
key_flags &= ~STA_KEY_FLG_INVALID;
- if (sta_id == ctx->bcast_sta_id)
+ if (sta_id == il->hw_params.bcast_id)
key_flags |= STA_KEY_MULTICAST_MSK;
keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -3070,9 +3389,8 @@ il4965_set_tkip_dynamic_key_info(struct il_priv *il,
}
void
-il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx,
- struct ieee80211_key_conf *keyconf,
- struct ieee80211_sta *sta, u32 iv32, u16 * phase1key)
+il4965_update_tkip_key(struct il_priv *il, struct ieee80211_key_conf *keyconf,
+ struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
{
u8 sta_id;
unsigned long flags;
@@ -3084,7 +3402,7 @@ il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx,
return;
}
- sta_id = il_sta_id_or_broadcast(il, ctx, sta);
+ sta_id = il_sta_id_or_broadcast(il, sta);
if (sta_id == IL_INVALID_STATION)
return;
@@ -3102,11 +3420,10 @@ il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx,
il_send_add_sta(il, &il->stations[sta_id].sta, CMD_ASYNC);
spin_unlock_irqrestore(&il->sta_lock, flags);
-
}
int
-il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
+il4965_remove_dynamic_key(struct il_priv *il,
struct ieee80211_key_conf *keyconf, u8 sta_id)
{
unsigned long flags;
@@ -3116,7 +3433,7 @@ il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
lockdep_assert_held(&il->mutex);
- ctx->key_mapping_keys--;
+ il->_4965.key_mapping_keys--;
spin_lock_irqsave(&il->sta_lock, flags);
key_flags = le16_to_cpu(il->stations[sta_id].sta.key.key_flags);
@@ -3134,7 +3451,7 @@ il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
return 0;
}
- if (il->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) {
+ if (il->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_INVALID) {
IL_WARN("Removing wrong key %d 0x%x\n", keyconf->keyidx,
key_flags);
spin_unlock_irqrestore(&il->sta_lock, flags);
@@ -3149,7 +3466,7 @@ il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
memset(&il->stations[sta_id].sta.key, 0, sizeof(struct il4965_keyinfo));
il->stations[sta_id].sta.key.key_flags =
STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
- il->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET;
+ il->stations[sta_id].sta.key.key_offset = keyconf->hw_key_idx;
il->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
il->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
@@ -3167,28 +3484,28 @@ il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
}
int
-il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
- struct ieee80211_key_conf *keyconf, u8 sta_id)
+il4965_set_dynamic_key(struct il_priv *il, struct ieee80211_key_conf *keyconf,
+ u8 sta_id)
{
int ret;
lockdep_assert_held(&il->mutex);
- ctx->key_mapping_keys++;
+ il->_4965.key_mapping_keys++;
keyconf->hw_key_idx = HW_KEY_DYNAMIC;
switch (keyconf->cipher) {
case WLAN_CIPHER_SUITE_CCMP:
ret =
- il4965_set_ccmp_dynamic_key_info(il, ctx, keyconf, sta_id);
+ il4965_set_ccmp_dynamic_key_info(il, keyconf, sta_id);
break;
case WLAN_CIPHER_SUITE_TKIP:
ret =
- il4965_set_tkip_dynamic_key_info(il, ctx, keyconf, sta_id);
+ il4965_set_tkip_dynamic_key_info(il, keyconf, sta_id);
break;
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_WEP104:
- ret = il4965_set_wep_dynamic_key_info(il, ctx, keyconf, sta_id);
+ ret = il4965_set_wep_dynamic_key_info(il, keyconf, sta_id);
break;
default:
IL_ERR("Unknown alg: %s cipher = %x\n", __func__,
@@ -3210,14 +3527,14 @@ il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
* device at the next best time.
*/
int
-il4965_alloc_bcast_station(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_alloc_bcast_station(struct il_priv *il)
{
struct il_link_quality_cmd *link_cmd;
unsigned long flags;
u8 sta_id;
spin_lock_irqsave(&il->sta_lock, flags);
- sta_id = il_prep_station(il, ctx, il_bcast_addr, false, NULL);
+ sta_id = il_prep_station(il, il_bcast_addr, false, NULL);
if (sta_id == IL_INVALID_STATION) {
IL_ERR("Unable to prepare broadcast station\n");
spin_unlock_irqrestore(&il->sta_lock, flags);
@@ -3250,11 +3567,11 @@ il4965_alloc_bcast_station(struct il_priv *il, struct il_rxon_context *ctx)
* code together.
*/
static int
-il4965_update_bcast_station(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_update_bcast_station(struct il_priv *il)
{
unsigned long flags;
struct il_link_quality_cmd *link_cmd;
- u8 sta_id = ctx->bcast_sta_id;
+ u8 sta_id = il->hw_params.bcast_id;
link_cmd = il4965_sta_alloc_lq(il, sta_id);
if (!link_cmd) {
@@ -3276,7 +3593,7 @@ il4965_update_bcast_station(struct il_priv *il, struct il_rxon_context *ctx)
int
il4965_update_bcast_stations(struct il_priv *il)
{
- return il4965_update_bcast_station(il, &il->ctx);
+ return il4965_update_bcast_station(il);
}
/**
@@ -3376,10 +3693,10 @@ il4965_sta_modify_sleep_tx_count(struct il_priv *il, int sta_id, int cnt)
void
il4965_update_chain_flags(struct il_priv *il)
{
- if (il->cfg->ops->hcmd->set_rxon_chain) {
- il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx);
- if (il->ctx.active.rx_chain != il->ctx.staging.rx_chain)
- il_commit_rxon(il, &il->ctx);
+ if (il->ops->set_rxon_chain) {
+ il->ops->set_rxon_chain(il);
+ if (il->active.rx_chain != il->staging.rx_chain)
+ il_commit_rxon(il);
}
}
@@ -3491,8 +3808,8 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame)
lockdep_assert_held(&il->mutex);
- if (!il->beacon_ctx) {
- IL_ERR("trying to build beacon w/o beacon context!\n");
+ if (!il->beacon_enabled) {
+ IL_ERR("Trying to build beacon without beaconing enabled\n");
return 0;
}
@@ -3511,7 +3828,7 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame)
/* Set up TX command fields */
tx_beacon_cmd->tx.len = cpu_to_le16((u16) frame_size);
- tx_beacon_cmd->tx.sta_id = il->beacon_ctx->bcast_sta_id;
+ tx_beacon_cmd->tx.sta_id = il->hw_params.bcast_id;
tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
tx_beacon_cmd->tx.tx_flags =
TX_CMD_FLG_SEQ_CTL_MSK | TX_CMD_FLG_TSF_MSK |
@@ -3522,7 +3839,7 @@ il4965_hw_get_beacon_cmd(struct il_priv *il, struct il_frame *frame)
frame_size);
/* Set up packet rate and flags */
- rate = il_get_lowest_plcp(il, il->beacon_ctx);
+ rate = il_get_lowest_plcp(il);
il4965_toggle_tx_ant(il, &il->mgmt_tx_ant, il->hw_params.valid_tx_ant);
rate_flags = BIT(il->mgmt_tx_ant) << RATE_MCS_ANT_POS;
if ((rate >= IL_FIRST_CCK_RATE) && (rate <= IL_LAST_CCK_RATE))
@@ -3645,15 +3962,13 @@ il4965_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq)
PCI_DMA_TODEVICE);
/* free SKB */
- if (txq->txb) {
- struct sk_buff *skb;
-
- skb = txq->txb[txq->q.read_ptr].skb;
+ if (txq->skbs) {
+ struct sk_buff *skb = txq->skbs[txq->q.read_ptr];
/* can be called from irqs-disabled context */
if (skb) {
dev_kfree_skb_any(skb);
- txq->txb[txq->q.read_ptr].skb = NULL;
+ txq->skbs[txq->q.read_ptr] = NULL;
}
}
}
@@ -3752,9 +4067,9 @@ il4965_hdl_alive(struct il_priv *il, struct il_rx_buf *rxb)
* This callback is provided in order to send a stats request.
*
* This timer function is continually reset to execute within
- * REG_RECALIB_PERIOD seconds since the last N_STATS
- * was received. We need to ensure we receive the stats in order
- * to update the temperature used for calibrating the TXPOWER.
+ * 60 seconds since the last N_STATS was received. We need to
+ * ensure we receive the stats in order to update the temperature
+ * used for calibrating the TXPOWER.
*/
static void
il4965_bg_stats_periodic(unsigned long data)
@@ -3804,7 +4119,7 @@ il4965_perform_ct_kill_task(struct il_priv *il)
_il_rd(il, CSR_UCODE_DRV_GP1);
spin_lock_irqsave(&il->reg_lock, flags);
- if (!_il_grab_nic_access(il))
+ if (likely(_il_grab_nic_access(il)))
_il_release_nic_access(il);
spin_unlock_irqrestore(&il->reg_lock, flags);
}
@@ -3842,17 +4157,17 @@ il4965_hdl_card_state(struct il_priv *il, struct il_rx_buf *rxb)
il4965_perform_ct_kill_task(il);
if (flags & HW_CARD_DISABLED)
- set_bit(S_RF_KILL_HW, &il->status);
+ set_bit(S_RFKILL, &il->status);
else
- clear_bit(S_RF_KILL_HW, &il->status);
+ clear_bit(S_RFKILL, &il->status);
if (!(flags & RXON_CARD_DISABLED))
il_scan_cancel(il);
- if ((test_bit(S_RF_KILL_HW, &status) !=
- test_bit(S_RF_KILL_HW, &il->status)))
+ if ((test_bit(S_RFKILL, &status) !=
+ test_bit(S_RFKILL, &il->status)))
wiphy_rfkill_set_hw_state(il->hw->wiphy,
- test_bit(S_RF_KILL_HW, &il->status));
+ test_bit(S_RFKILL, &il->status));
else
wake_up(&il->wait_command_queue);
}
@@ -3894,10 +4209,11 @@ il4965_setup_handlers(struct il_priv *il)
/* Rx handlers */
il->handlers[N_RX_PHY] = il4965_hdl_rx_phy;
il->handlers[N_RX_MPDU] = il4965_hdl_rx;
+ il->handlers[N_RX] = il4965_hdl_rx;
/* block ack */
il->handlers[N_COMPRESSED_BA] = il4965_hdl_compressed_ba;
- /* Set up hardware specific Rx handlers */
- il->cfg->ops->lib->handler_setup(il);
+ /* Tx response */
+ il->handlers[C_TX] = il4965_hdl_tx;
}
/**
@@ -3957,17 +4273,7 @@ il4965_rx_handle(struct il_priv *il)
len = le32_to_cpu(pkt->len_n_flags) & IL_RX_FRAME_SIZE_MSK;
len += sizeof(u32); /* account for status word */
- /* Reclaim a command buffer only if this packet is a response
- * to a (driver-originated) command.
- * If the packet (e.g. Rx frame) originated from uCode,
- * there is no command buffer to reclaim.
- * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
- * but apparently a few don't get set; catch them here. */
- reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
- (pkt->hdr.cmd != N_RX_PHY) && (pkt->hdr.cmd != N_RX) &&
- (pkt->hdr.cmd != N_RX_MPDU) &&
- (pkt->hdr.cmd != N_COMPRESSED_BA) &&
- (pkt->hdr.cmd != N_STATS) && (pkt->hdr.cmd != C_TX);
+ reclaim = il_need_reclaim(il, pkt);
/* Based on type of command response or notification,
* handle those that need handling via function in
@@ -4009,8 +4315,16 @@ il4965_rx_handle(struct il_priv *il)
pci_map_page(il->pci_dev, rxb->page, 0,
PAGE_SIZE << il->hw_params.
rx_page_order, PCI_DMA_FROMDEVICE);
- list_add_tail(&rxb->list, &rxq->rx_free);
- rxq->free_count++;
+
+ if (unlikely(pci_dma_mapping_error(il->pci_dev,
+ rxb->page_dma))) {
+ __il_free_pages(il, rxb->page);
+ rxb->page = NULL;
+ list_add_tail(&rxb->list, &rxq->rx_used);
+ } else {
+ list_add_tail(&rxb->list, &rxq->rx_free);
+ rxq->free_count++;
+ }
} else
list_add_tail(&rxb->list, &rxq->rx_used);
@@ -4127,9 +4441,8 @@ il4965_irq_tasklet(struct il_priv *il)
/* HW RF KILL switch toggled */
if (inta & CSR_INT_BIT_RF_KILL) {
int hw_rf_kill = 0;
- if (!
- (_il_rd(il, CSR_GP_CNTRL) &
- CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
+
+ if (!(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
hw_rf_kill = 1;
IL_WARN("RF_KILL bit toggled to %s.\n",
@@ -4142,13 +4455,13 @@ il4965_irq_tasklet(struct il_priv *il)
* is killed. Hence update the killswitch state here. The
* rfkill handler will care about restarting if needed.
*/
- if (!test_bit(S_ALIVE, &il->status)) {
- if (hw_rf_kill)
- set_bit(S_RF_KILL_HW, &il->status);
- else
- clear_bit(S_RF_KILL_HW, &il->status);
- wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill);
+ if (hw_rf_kill) {
+ set_bit(S_RFKILL, &il->status);
+ } else {
+ clear_bit(S_RFKILL, &il->status);
+ il_force_reset(il, true);
}
+ wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill);
handled |= CSR_INT_BIT_RF_KILL;
}
@@ -4267,14 +4580,12 @@ il4965_store_debug_level(struct device *d, struct device_attribute *attr,
unsigned long val;
int ret;
- ret = strict_strtoul(buf, 0, &val);
+ ret = kstrtoul(buf, 0, &val);
if (ret)
IL_ERR("%s is not in hex or decimal form.\n", buf);
- else {
+ else
il->debug_level = val;
- if (il_alloc_traffic_mem(il))
- IL_ERR("Not enough memory to generate traffic log\n");
- }
+
return strnlen(buf, count);
}
@@ -4316,7 +4627,7 @@ il4965_store_tx_power(struct device *d, struct device_attribute *attr,
unsigned long val;
int ret;
- ret = strict_strtoul(buf, 10, &val);
+ ret = kstrtoul(buf, 10, &val);
if (ret)
IL_INFO("%s is not in decimal form.\n", buf);
else {
@@ -4799,7 +5110,7 @@ il4965_dump_nic_error_log(struct il_priv *il)
else
base = le32_to_cpu(il->card_alive.error_event_table_ptr);
- if (!il->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
+ if (!il->ops->is_valid_rtc_data_addr(base)) {
IL_ERR("Not valid error log pointer 0x%08X for %s uCode\n",
base, (il->ucode_type == UCODE_INIT) ? "Init" : "RT");
return;
@@ -4979,7 +5290,6 @@ static void
il4965_alive_start(struct il_priv *il)
{
int ret = 0;
- struct il_rxon_context *ctx = &il->ctx;
D_INFO("Runtime Alive received.\n");
@@ -5019,18 +5329,21 @@ il4965_alive_start(struct il_priv *il)
il->active_rate = RATES_MASK;
- if (il_is_associated_ctx(ctx)) {
+ il_power_update_mode(il, true);
+ D_INFO("Updated power mode\n");
+
+ if (il_is_associated(il)) {
struct il_rxon_cmd *active_rxon =
- (struct il_rxon_cmd *)&ctx->active;
+ (struct il_rxon_cmd *)&il->active;
/* apply any changes in staging */
- ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
} else {
/* Initialize our rx_config data */
- il_connection_init_rx_config(il, &il->ctx);
+ il_connection_init_rx_config(il);
- if (il->cfg->ops->hcmd->set_rxon_chain)
- il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
+ if (il->ops->set_rxon_chain)
+ il->ops->set_rxon_chain(il);
}
/* Configure bluetooth coexistence if enabled */
@@ -5041,7 +5354,7 @@ il4965_alive_start(struct il_priv *il)
set_bit(S_READY, &il->status);
/* Configure the adapter for unassociated operation */
- il_commit_rxon(il, ctx);
+ il_commit_rxon(il);
/* At this point, the NIC is initialized and operational */
il4965_rf_kill_ct_config(il);
@@ -5049,9 +5362,6 @@ il4965_alive_start(struct il_priv *il)
D_INFO("ALIVE processing complete.\n");
wake_up(&il->wait_command_queue);
- il_power_update_mode(il, true);
- D_INFO("Updated power mode\n");
-
return;
restart:
@@ -5076,7 +5386,21 @@ __il4965_down(struct il_priv *il)
* to prevent rearm timer */
del_timer_sync(&il->watchdog);
- il_clear_ucode_stations(il, NULL);
+ il_clear_ucode_stations(il);
+
+ /* FIXME: race conditions ? */
+ spin_lock_irq(&il->sta_lock);
+ /*
+ * Remove all key information that is not stored as part
+ * of station information since mac80211 may not have had
+ * a chance to remove all the keys. When device is
+ * reconfigured by mac80211 after an error all keys will
+ * be reconfigured.
+ */
+ memset(il->_4965.wep_keys, 0, sizeof(il->_4965.wep_keys));
+ il->_4965.key_mapping_keys = 0;
+ spin_unlock_irq(&il->sta_lock);
+
il_dealloc_bcast_stations(il);
il_clear_driver_stations(il);
@@ -5104,12 +5428,8 @@ __il4965_down(struct il_priv *il)
* clear all bits but the RF Kill bit and return */
if (!il_is_init(il)) {
il->status =
- test_bit(S_RF_KILL_HW,
- &il->
- status) << S_RF_KILL_HW |
- test_bit(S_GEO_CONFIGURED,
- &il->
- status) << S_GEO_CONFIGURED |
+ test_bit(S_RFKILL, &il->status) << S_RFKILL |
+ test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED |
test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;
goto exit;
}
@@ -5117,28 +5437,32 @@ __il4965_down(struct il_priv *il)
/* ...otherwise clear out all the status bits but the RF Kill
* bit and continue taking the NIC down. */
il->status &=
- test_bit(S_RF_KILL_HW,
- &il->status) << S_RF_KILL_HW | test_bit(S_GEO_CONFIGURED,
- &il->
- status) <<
- S_GEO_CONFIGURED | test_bit(S_FW_ERROR,
- &il->
- status) << S_FW_ERROR |
+ test_bit(S_RFKILL, &il->status) << S_RFKILL |
+ test_bit(S_GEO_CONFIGURED, &il->status) << S_GEO_CONFIGURED |
+ test_bit(S_FW_ERROR, &il->status) << S_FW_ERROR |
test_bit(S_EXIT_PENDING, &il->status) << S_EXIT_PENDING;
+ /*
+ * We disabled and synchronized interrupt, and priv->mutex is taken, so
+ * here is the only thread which will program device registers, but
+ * still have lockdep assertions, so we are taking reg_lock.
+ */
+ spin_lock_irq(&il->reg_lock);
+ /* FIXME: il_grab_nic_access if rfkill is off ? */
+
il4965_txq_ctx_stop(il);
il4965_rxq_stop(il);
-
/* Power-down device's busmaster DMA clocks */
- il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
+ _il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
udelay(5);
-
/* Make sure (redundant) we've released our request to stay awake */
- il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-
+ _il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
/* Stop the device, and put it in low power state */
- il_apm_stop(il);
+ _il_apm_stop(il);
+ spin_unlock_irq(&il->reg_lock);
+
+ il4965_txq_ctx_unmap(il);
exit:
memset(&il->card_alive, 0, sizeof(struct il_alive_resp));
@@ -5159,40 +5483,36 @@ il4965_down(struct il_priv *il)
il4965_cancel_deferred_work(il);
}
-#define HW_READY_TIMEOUT (50)
-static int
+static void
il4965_set_hw_ready(struct il_priv *il)
{
- int ret = 0;
+ int ret;
il_set_bit(il, CSR_HW_IF_CONFIG_REG,
CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
/* See if we got it */
- ret =
- _il_poll_bit(il, CSR_HW_IF_CONFIG_REG,
- CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
- CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, HW_READY_TIMEOUT);
- if (ret != -ETIMEDOUT)
+ ret = _il_poll_bit(il, CSR_HW_IF_CONFIG_REG,
+ CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
+ CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
+ 100);
+ if (ret >= 0)
il->hw_ready = true;
- else
- il->hw_ready = false;
- D_INFO("hardware %s\n", (il->hw_ready == 1) ? "ready" : "not ready");
- return ret;
+ D_INFO("hardware %s ready\n", (il->hw_ready) ? "" : "not");
}
-static int
+static void
il4965_prepare_card_hw(struct il_priv *il)
{
- int ret = 0;
+ int ret;
- D_INFO("il4965_prepare_card_hw enter\n");
+ il->hw_ready = false;
- ret = il4965_set_hw_ready(il);
+ il4965_set_hw_ready(il);
if (il->hw_ready)
- return ret;
+ return;
/* If HW is not ready, prepare the conditions to check again */
il_set_bit(il, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_PREPARE);
@@ -5205,8 +5525,6 @@ il4965_prepare_card_hw(struct il_priv *il)
/* HW should be ready by now, check again. */
if (ret != -ETIMEDOUT)
il4965_set_hw_ready(il);
-
- return ret;
}
#define MAX_HW_RESTARTS 5
@@ -5227,29 +5545,26 @@ __il4965_up(struct il_priv *il)
return -EIO;
}
- ret = il4965_alloc_bcast_station(il, &il->ctx);
+ ret = il4965_alloc_bcast_station(il);
if (ret) {
il_dealloc_bcast_stations(il);
return ret;
}
il4965_prepare_card_hw(il);
-
if (!il->hw_ready) {
- IL_WARN("Exit HW not ready\n");
+ IL_ERR("HW not ready\n");
return -EIO;
}
/* If platform's RF_KILL switch is NOT set to KILL */
if (_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
- clear_bit(S_RF_KILL_HW, &il->status);
- else
- set_bit(S_RF_KILL_HW, &il->status);
-
- if (il_is_rfkill(il)) {
+ clear_bit(S_RFKILL, &il->status);
+ else {
+ set_bit(S_RFKILL, &il->status);
wiphy_rfkill_set_hw_state(il->hw->wiphy, true);
- il_enable_interrupts(il);
+ il_enable_rfkill_int(il);
IL_WARN("Radio disabled by HW RF Kill switch\n");
return 0;
}
@@ -5288,7 +5603,7 @@ __il4965_up(struct il_priv *il)
/* load bootstrap state machine,
* load bootstrap program into processor's memory,
* prepare to load the "initialize" uCode */
- ret = il->cfg->ops->lib->load_ucode(il);
+ ret = il->ops->load_ucode(il);
if (ret) {
IL_ERR("Unable to set up bootstrap uCode: %d\n", ret);
@@ -5329,7 +5644,7 @@ il4965_bg_init_alive_start(struct work_struct *data)
if (test_bit(S_EXIT_PENDING, &il->status))
goto out;
- il->cfg->ops->lib->init_alive_start(il);
+ il->ops->init_alive_start(il);
out:
mutex_unlock(&il->mutex);
}
@@ -5381,7 +5696,6 @@ il4965_bg_restart(struct work_struct *data)
if (test_and_clear_bit(S_FW_ERROR, &il->status)) {
mutex_lock(&il->mutex);
- il->ctx.vif = NULL;
il->is_open = 0;
__il4965_down(il);
@@ -5439,9 +5753,9 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length)
/* Tell mac80211 our characteristics */
hw->flags =
IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_AMPDU_AGGREGATION |
- IEEE80211_HW_NEED_DTIM_PERIOD | IEEE80211_HW_SPECTRUM_MGMT |
- IEEE80211_HW_REPORTS_TX_ACK_STATUS;
-
+ IEEE80211_HW_NEED_DTIM_BEFORE_ASSOC | IEEE80211_HW_SPECTRUM_MGMT |
+ IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
if (il->cfg->sku & IL_SKU_N)
hw->flags |=
IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
@@ -5450,11 +5764,12 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length)
hw->sta_data_size = sizeof(struct il_station_priv);
hw->vif_data_size = sizeof(struct il_vif_priv);
- hw->wiphy->interface_modes |= il->ctx.interface_modes;
- hw->wiphy->interface_modes |= il->ctx.exclusive_interface_modes;
+ hw->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
- hw->wiphy->flags |=
- WIPHY_FLAG_CUSTOM_REGULATORY | WIPHY_FLAG_DISABLE_BEACON_HINTS;
+ hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+ hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
+ REGULATORY_DISABLE_BEACON_HINTS;
/*
* For now, disable PS by default because it affects
@@ -5557,7 +5872,9 @@ il4965_mac_stop(struct ieee80211_hw *hw)
}
void
-il4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+il4965_mac_tx(struct ieee80211_hw *hw,
+ struct ieee80211_tx_control *control,
+ struct sk_buff *skb)
{
struct il_priv *il = hw->priv;
@@ -5566,7 +5883,7 @@ il4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
D_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
- if (il4965_tx_skb(il, skb))
+ if (il4965_tx_skb(il, control->sta, skb))
dev_kfree_skb_any(skb);
D_MACDUMP("leave\n");
@@ -5578,12 +5895,10 @@ il4965_mac_update_tkip_key(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u32 iv32, u16 * phase1key)
{
struct il_priv *il = hw->priv;
- struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
D_MAC80211("enter\n");
- il4965_update_tkip_key(il, vif_priv->ctx, keyconf, sta, iv32,
- phase1key);
+ il4965_update_tkip_key(il, keyconf, sta, iv32, phase1key);
D_MAC80211("leave\n");
}
@@ -5594,8 +5909,6 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct ieee80211_key_conf *key)
{
struct il_priv *il = hw->priv;
- struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
- struct il_rxon_context *ctx = vif_priv->ctx;
int ret;
u8 sta_id;
bool is_default_wep_key = false;
@@ -5607,7 +5920,17 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return -EOPNOTSUPP;
}
- sta_id = il_sta_id_or_broadcast(il, vif_priv->ctx, sta);
+ /*
+ * To support IBSS RSN, don't program group keys in IBSS, the
+ * hardware will then not attempt to decrypt the frames.
+ */
+ if (vif->type == NL80211_IFTYPE_ADHOC &&
+ !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+ D_MAC80211("leave - ad-hoc group key\n");
+ return -EOPNOTSUPP;
+ }
+
+ sta_id = il_sta_id_or_broadcast(il, sta);
if (sta_id == IL_INVALID_STATION)
return -EINVAL;
@@ -5623,7 +5946,7 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
key->cipher == WLAN_CIPHER_SUITE_WEP104) && !sta) {
if (cmd == SET_KEY)
- is_default_wep_key = !ctx->key_mapping_keys;
+ is_default_wep_key = !il->_4965.key_mapping_keys;
else
is_default_wep_key =
(key->hw_key_idx == HW_KEY_DEFAULT);
@@ -5632,20 +5955,17 @@ il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
switch (cmd) {
case SET_KEY:
if (is_default_wep_key)
- ret =
- il4965_set_default_wep_key(il, vif_priv->ctx, key);
+ ret = il4965_set_default_wep_key(il, key);
else
- ret =
- il4965_set_dynamic_key(il, vif_priv->ctx, key,
- sta_id);
+ ret = il4965_set_dynamic_key(il, key, sta_id);
D_MAC80211("enable hwcrypto key\n");
break;
case DISABLE_KEY:
if (is_default_wep_key)
- ret = il4965_remove_default_wep_key(il, ctx, key);
+ ret = il4965_remove_default_wep_key(il, key);
else
- ret = il4965_remove_dynamic_key(il, ctx, key, sta_id);
+ ret = il4965_remove_dynamic_key(il, key, sta_id);
D_MAC80211("disable hwcrypto key\n");
break;
@@ -5690,7 +6010,9 @@ il4965_mac_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
D_HT("start Tx\n");
ret = il4965_tx_agg_start(il, vif, sta, tid, ssn);
break;
- case IEEE80211_AMPDU_TX_STOP:
+ case IEEE80211_AMPDU_TX_STOP_CONT:
+ case IEEE80211_AMPDU_TX_STOP_FLUSH:
+ case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
D_HT("stop Tx\n");
ret = il4965_tx_agg_stop(il, vif, sta, tid);
if (test_bit(S_EXIT_PENDING, &il->status))
@@ -5711,7 +6033,6 @@ il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
{
struct il_priv *il = hw->priv;
struct il_station_priv *sta_priv = (void *)sta->drv_priv;
- struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
bool is_ap = vif->type == NL80211_IFTYPE_STATION;
int ret;
u8 sta_id;
@@ -5724,8 +6045,7 @@ il4965_mac_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
atomic_set(&sta_priv->pending_frames, 0);
ret =
- il_add_station_common(il, vif_priv->ctx, sta->addr, is_ap, sta,
- &sta_id);
+ il_add_station_common(il, sta->addr, is_ap, sta, &sta_id);
if (ret) {
IL_ERR("Unable to add station %pM (%d)\n", sta->addr, ret);
/* Should we return success if return code is EEXIST ? */
@@ -5750,10 +6070,8 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw,
struct il_priv *il = hw->priv;
const struct il_channel_info *ch_info;
struct ieee80211_conf *conf = &hw->conf;
- struct ieee80211_channel *channel = ch_switch->channel;
+ struct ieee80211_channel *channel = ch_switch->chandef.chan;
struct il_ht_config *ht_conf = &il->current_ht_config;
-
- struct il_rxon_context *ctx = &il->ctx;
u16 ch;
D_MAC80211("enter\n");
@@ -5768,14 +6086,14 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw,
test_bit(S_CHANNEL_SWITCH_PENDING, &il->status))
goto out;
- if (!il_is_associated_ctx(ctx))
+ if (!il_is_associated(il))
goto out;
- if (!il->cfg->ops->lib->set_channel_switch)
+ if (!il->ops->set_channel_switch)
goto out;
ch = channel->hw_value;
- if (le16_to_cpu(ctx->active.channel) == ch)
+ if (le16_to_cpu(il->active.channel) == ch)
goto out;
ch_info = il_get_channel_info(il, channel->band, ch);
@@ -5789,30 +6107,28 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw,
il->current_ht_config.smps = conf->smps_mode;
/* Configure HT40 channels */
- ctx->ht.enabled = conf_is_ht(conf);
- if (ctx->ht.enabled) {
- if (conf_is_ht40_minus(conf)) {
- ctx->ht.extension_chan_offset =
- IEEE80211_HT_PARAM_CHA_SEC_BELOW;
- ctx->ht.is_40mhz = true;
- } else if (conf_is_ht40_plus(conf)) {
- ctx->ht.extension_chan_offset =
- IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
- ctx->ht.is_40mhz = true;
- } else {
- ctx->ht.extension_chan_offset =
- IEEE80211_HT_PARAM_CHA_SEC_NONE;
- ctx->ht.is_40mhz = false;
- }
- } else
- ctx->ht.is_40mhz = false;
+ switch (cfg80211_get_chandef_type(&ch_switch->chandef)) {
+ case NL80211_CHAN_NO_HT:
+ case NL80211_CHAN_HT20:
+ il->ht.is_40mhz = false;
+ il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
+ break;
+ case NL80211_CHAN_HT40MINUS:
+ il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+ il->ht.is_40mhz = true;
+ break;
+ case NL80211_CHAN_HT40PLUS:
+ il->ht.extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+ il->ht.is_40mhz = true;
+ break;
+ }
- if ((le16_to_cpu(ctx->staging.channel) != ch))
- ctx->staging.flags = 0;
+ if ((le16_to_cpu(il->staging.channel) != ch))
+ il->staging.flags = 0;
- il_set_rxon_channel(il, channel, ctx);
+ il_set_rxon_channel(il, channel);
il_set_rxon_ht(il, ht_conf);
- il_set_flags_for_band(il, ctx, channel->band, ctx->vif);
+ il_set_flags_for_band(il, channel->band, il->vif);
spin_unlock_irq(&il->lock);
@@ -5823,10 +6139,10 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw,
*/
set_bit(S_CHANNEL_SWITCH_PENDING, &il->status);
il->switch_channel = cpu_to_le16(ch);
- if (il->cfg->ops->lib->set_channel_switch(il, ch_switch)) {
+ if (il->ops->set_channel_switch(il, ch_switch)) {
clear_bit(S_CHANNEL_SWITCH_PENDING, &il->status);
il->switch_channel = 0;
- ieee80211_chswitch_done(ctx->vif, false);
+ ieee80211_chswitch_done(il->vif, false);
}
out:
@@ -5860,8 +6176,8 @@ il4965_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
mutex_lock(&il->mutex);
- il->ctx.staging.filter_flags &= ~filter_nand;
- il->ctx.staging.filter_flags |= filter_or;
+ il->staging.filter_flags &= ~filter_nand;
+ il->staging.filter_flags |= filter_or;
/*
* Not committing directly because hardware can perform a scan,
@@ -5906,7 +6222,7 @@ il4965_bg_txpower_work(struct work_struct *work)
/* Regardless of if we are associated, we must reconfigure the
* TX power since frames can be sent on non-radar channels while
* not associated */
- il->cfg->ops->lib->send_tx_power(il);
+ il->ops->send_tx_power(il);
/* Update last_temperature to keep is_calib_needed from running
* when it isn't needed... */
@@ -6012,6 +6328,29 @@ il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq,
scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
}
+static const struct ieee80211_ops il4965_mac_ops = {
+ .tx = il4965_mac_tx,
+ .start = il4965_mac_start,
+ .stop = il4965_mac_stop,
+ .add_interface = il_mac_add_interface,
+ .remove_interface = il_mac_remove_interface,
+ .change_interface = il_mac_change_interface,
+ .config = il_mac_config,
+ .configure_filter = il4965_configure_filter,
+ .set_key = il4965_mac_set_key,
+ .update_tkip_key = il4965_mac_update_tkip_key,
+ .conf_tx = il_mac_conf_tx,
+ .reset_tsf = il_mac_reset_tsf,
+ .bss_info_changed = il_mac_bss_info_changed,
+ .ampdu_action = il4965_mac_ampdu_action,
+ .hw_scan = il_mac_hw_scan,
+ .sta_add = il4965_mac_sta_add,
+ .sta_remove = il_mac_sta_remove,
+ .channel_switch = il4965_mac_channel_switch,
+ .tx_last_beacon = il_mac_tx_last_beacon,
+ .flush = il_mac_flush,
+};
+
static int
il4965_init_drv(struct il_priv *il)
{
@@ -6036,8 +6375,8 @@ il4965_init_drv(struct il_priv *il)
il->force_reset.reset_duration = IL_DELAY_NEXT_FORCE_FW_RELOAD;
/* Choose which receivers/antennas to use */
- if (il->cfg->ops->hcmd->set_rxon_chain)
- il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx);
+ if (il->ops->set_rxon_chain)
+ il->ops->set_rxon_chain(il);
il_init_scan_params(il);
@@ -6065,7 +6404,6 @@ err:
static void
il4965_uninit_drv(struct il_priv *il)
{
- il4965_calib_free_results(il);
il_free_geos(il);
il_free_channel_map(il);
kfree(il->scan_cmd);
@@ -6080,9 +6418,37 @@ il4965_hw_detect(struct il_priv *il)
D_INFO("HW Revision ID = 0x%X\n", il->rev_id);
}
-static int
+static struct il_sensitivity_ranges il4965_sensitivity = {
+ .min_nrg_cck = 97,
+ .max_nrg_cck = 0, /* not used, set to 0 */
+
+ .auto_corr_min_ofdm = 85,
+ .auto_corr_min_ofdm_mrc = 170,
+ .auto_corr_min_ofdm_x1 = 105,
+ .auto_corr_min_ofdm_mrc_x1 = 220,
+
+ .auto_corr_max_ofdm = 120,
+ .auto_corr_max_ofdm_mrc = 210,
+ .auto_corr_max_ofdm_x1 = 140,
+ .auto_corr_max_ofdm_mrc_x1 = 270,
+
+ .auto_corr_min_cck = 125,
+ .auto_corr_max_cck = 200,
+ .auto_corr_min_cck_mrc = 200,
+ .auto_corr_max_cck_mrc = 400,
+
+ .nrg_th_cck = 100,
+ .nrg_th_ofdm = 100,
+
+ .barker_corr_th_min = 190,
+ .barker_corr_th_min_mrc = 390,
+ .nrg_th_cca = 62,
+};
+
+static void
il4965_set_hw_params(struct il_priv *il)
{
+ il->hw_params.bcast_id = IL4965_BROADCAST_ID;
il->hw_params.max_rxq_size = RX_QUEUE_SIZE;
il->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
if (il->cfg->mod_params->amsdu_size_8K)
@@ -6095,20 +6461,37 @@ il4965_set_hw_params(struct il_priv *il)
if (il->cfg->mod_params->disable_11n)
il->cfg->sku &= ~IL_SKU_N;
- /* Device-specific setup */
- return il->cfg->ops->lib->set_hw_params(il);
-}
+ if (il->cfg->mod_params->num_of_queues >= IL_MIN_NUM_QUEUES &&
+ il->cfg->mod_params->num_of_queues <= IL49_NUM_QUEUES)
+ il->cfg->num_of_queues =
+ il->cfg->mod_params->num_of_queues;
-static const u8 il4965_bss_ac_to_fifo[] = {
- IL_TX_FIFO_VO,
- IL_TX_FIFO_VI,
- IL_TX_FIFO_BE,
- IL_TX_FIFO_BK,
-};
+ il->hw_params.max_txq_num = il->cfg->num_of_queues;
+ il->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
+ il->hw_params.scd_bc_tbls_size =
+ il->cfg->num_of_queues *
+ sizeof(struct il4965_scd_bc_tbl);
-static const u8 il4965_bss_ac_to_queue[] = {
- 0, 1, 2, 3,
-};
+ il->hw_params.tfd_size = sizeof(struct il_tfd);
+ il->hw_params.max_stations = IL4965_STATION_COUNT;
+ il->hw_params.max_data_size = IL49_RTC_DATA_SIZE;
+ il->hw_params.max_inst_size = IL49_RTC_INST_SIZE;
+ il->hw_params.max_bsm_size = BSM_SRAM_SIZE;
+ il->hw_params.ht40_channel = BIT(IEEE80211_BAND_5GHZ);
+
+ il->hw_params.rx_wrt_ptr_reg = FH49_RSCSR_CHNL0_WPTR;
+
+ il->hw_params.tx_chains_num = il4965_num_of_ant(il->cfg->valid_tx_ant);
+ il->hw_params.rx_chains_num = il4965_num_of_ant(il->cfg->valid_rx_ant);
+ il->hw_params.valid_tx_ant = il->cfg->valid_tx_ant;
+ il->hw_params.valid_rx_ant = il->cfg->valid_rx_ant;
+
+ il->hw_params.ct_kill_threshold =
+ CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY);
+
+ il->hw_params.sens = &il4965_sensitivity;
+ il->hw_params.beacon_time_tsf_bits = IL4965_EXT_BEACON_TIME_POS;
+}
static int
il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
@@ -6124,43 +6507,24 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
* 1. Allocating HW data
************************/
- hw = il_alloc_all(cfg);
+ hw = ieee80211_alloc_hw(sizeof(struct il_priv), &il4965_mac_ops);
if (!hw) {
err = -ENOMEM;
goto out;
}
il = hw->priv;
- /* At this point both hw and il are allocated. */
-
- il->ctx.ctxid = 0;
-
- il->ctx.always_active = true;
- il->ctx.is_active = true;
- il->ctx.rxon_cmd = C_RXON;
- il->ctx.rxon_timing_cmd = C_RXON_TIMING;
- il->ctx.rxon_assoc_cmd = C_RXON_ASSOC;
- il->ctx.qos_cmd = C_QOS_PARAM;
- il->ctx.ap_sta_id = IL_AP_ID;
- il->ctx.wep_key_cmd = C_WEPKEY;
- il->ctx.ac_to_fifo = il4965_bss_ac_to_fifo;
- il->ctx.ac_to_queue = il4965_bss_ac_to_queue;
- il->ctx.exclusive_interface_modes = BIT(NL80211_IFTYPE_ADHOC);
- il->ctx.interface_modes = BIT(NL80211_IFTYPE_STATION);
- il->ctx.ap_devtype = RXON_DEV_TYPE_AP;
- il->ctx.ibss_devtype = RXON_DEV_TYPE_IBSS;
- il->ctx.station_devtype = RXON_DEV_TYPE_ESS;
- il->ctx.unused_devtype = RXON_DEV_TYPE_ESS;
-
+ il->hw = hw;
SET_IEEE80211_DEV(hw, &pdev->dev);
D_INFO("*** LOAD DRIVER ***\n");
il->cfg = cfg;
+ il->ops = &il4965_ops;
+#ifdef CONFIG_IWLEGACY_DEBUGFS
+ il->debugfs_ops = &il4965_debugfs_ops;
+#endif
il->pci_dev = pdev;
il->inta_mask = CSR_INI_SET_MASK;
- if (il_alloc_traffic_mem(il))
- IL_ERR("Not enough memory to generate traffic log\n");
-
/**************************
* 2. Initializing PCI bus
**************************/
@@ -6199,7 +6563,7 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/***********************
* 3. Read REV register
***********************/
- il->hw_base = pci_iomap(pdev, 0, 0);
+ il->hw_base = pci_ioremap_bar(pdev, 0);
if (!il->hw_base) {
err = -ENODEV;
goto out_pci_release_regions;
@@ -6232,6 +6596,7 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
il4965_prepare_card_hw(il);
if (!il->hw_ready) {
IL_WARN("Failed, HW not ready\n");
+ err = -EIO;
goto out_iounmap;
}
@@ -6248,9 +6613,6 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err)
goto out_free_eeprom;
- if (err)
- goto out_free_eeprom;
-
/* extract MAC Address */
il4965_eeprom_get_mac(il, il->addresses[0].addr);
D_INFO("MAC address: %pM\n", il->addresses[0].addr);
@@ -6260,10 +6622,7 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/************************
* 5. Setup HW constants
************************/
- if (il4965_set_hw_params(il)) {
- IL_ERR("failed to set hw parameters\n");
- goto out_free_eeprom;
- }
+ il4965_set_hw_params(il);
/*******************
* 6. Setup il
@@ -6307,12 +6666,12 @@ il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* If platform's RF_KILL switch is NOT set to KILL */
if (_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
- clear_bit(S_RF_KILL_HW, &il->status);
+ clear_bit(S_RFKILL, &il->status);
else
- set_bit(S_RF_KILL_HW, &il->status);
+ set_bit(S_RFKILL, &il->status);
wiphy_rfkill_set_hw_state(il->hw->wiphy,
- test_bit(S_RF_KILL_HW, &il->status));
+ test_bit(S_RFKILL, &il->status));
il_power_initialize(il);
@@ -6334,20 +6693,18 @@ out_disable_msi:
out_free_eeprom:
il_eeprom_free(il);
out_iounmap:
- pci_iounmap(pdev, il->hw_base);
+ 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);
out_ieee80211_free_hw:
- il_free_traffic_mem(il);
ieee80211_free_hw(il->hw);
out:
return err;
}
-static void __devexit
+static void
il4965_pci_remove(struct pci_dev *pdev)
{
struct il_priv *il = pci_get_drvdata(pdev);
@@ -6412,14 +6769,12 @@ il4965_pci_remove(struct pci_dev *pdev)
* until now... */
destroy_workqueue(il->workqueue);
il->workqueue = NULL;
- il_free_traffic_mem(il);
free_irq(il->pci_dev->irq, il);
pci_disable_msi(il->pci_dev);
- pci_iounmap(pdev, il->hw_base);
+ iounmap(il->hw_base);
pci_release_regions(pdev);
pci_disable_device(pdev);
- pci_set_drvdata(pdev, NULL);
il4965_uninit_drv(il);
@@ -6456,7 +6811,7 @@ static struct pci_driver il4965_driver = {
.name = DRV_NAME,
.id_table = il4965_hw_card_ids,
.probe = il4965_pci_probe,
- .remove = __devexit_p(il4965_pci_remove),
+ .remove = il4965_pci_remove,
.driver.pm = IL_LEGACY_PM_OPS,
};
@@ -6510,6 +6865,6 @@ module_param_named(11n_disable, il4965_mod_params.disable_11n, int, S_IRUGO);
MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
module_param_named(amsdu_size_8K, il4965_mod_params.amsdu_size_8K, int,
S_IRUGO);
-MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
+MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size (default 0 [disabled])");
module_param_named(fw_restart, il4965_mod_params.restart_fw, int, S_IRUGO);
MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
diff --git a/drivers/net/wireless/iwlegacy/4965-rs.c b/drivers/net/wireless/iwlegacy/4965-rs.c
index 467d0cb14ec..eaaeea19d8c 100644
--- a/drivers/net/wireless/iwlegacy/4965-rs.c
+++ b/drivers/net/wireless/iwlegacy/4965-rs.c
@@ -24,7 +24,6 @@
*
*****************************************************************************/
#include <linux/kernel.h>
-#include <linux/init.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <net/mac80211.h>
@@ -641,13 +640,10 @@ il4965_rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
* there are no non-GF stations present in the BSS.
*/
static bool
-il4965_rs_use_green(struct ieee80211_sta *sta)
+il4965_rs_use_green(struct il_priv *il, struct ieee80211_sta *sta)
{
- struct il_station_priv *sta_priv = (void *)sta->drv_priv;
- struct il_rxon_context *ctx = sta_priv->common.ctx;
-
return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
- !(ctx->ht.non_gf_sta_present);
+ !il->ht.non_gf_sta_present;
}
/**
@@ -823,8 +819,6 @@ il4965_rs_tx_status(void *il_r, struct ieee80211_supported_band *sband,
u32 tx_rate;
struct il_scale_tbl_info tbl_type;
struct il_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
- struct il_station_priv *sta_priv = (void *)sta->drv_priv;
- struct il_rxon_context *ctx = sta_priv->common.ctx;
D_RATE("get frame ack response, update rate scale win\n");
@@ -878,7 +872,7 @@ il4965_rs_tx_status(void *il_r, struct ieee80211_supported_band *sband,
tbl_type.is_SGI != !!(mac_flags & IEEE80211_TX_RC_SHORT_GI) ||
tbl_type.is_ht40 != !!(mac_flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ||
tbl_type.is_dup != !!(mac_flags & IEEE80211_TX_RC_DUP_DATA) ||
- tbl_type.ant_type != info->antenna_sel_tx ||
+ tbl_type.ant_type != info->status.antenna ||
!!(tx_rate & RATE_MCS_HT_MSK) != !!(mac_flags & IEEE80211_TX_RC_MCS)
|| !!(tx_rate & RATE_MCS_GF_MSK) !=
!!(mac_flags & IEEE80211_TX_RC_GREEN_FIELD) || rs_idx != mac_idx) {
@@ -892,7 +886,7 @@ il4965_rs_tx_status(void *il_r, struct ieee80211_supported_band *sband,
lq_sta->missed_rate_counter++;
if (lq_sta->missed_rate_counter > IL_MISSED_RATE_MAX) {
lq_sta->missed_rate_counter = 0;
- il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_ASYNC, false);
+ il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false);
}
/* Regardless, ignore this status info for outdated rate */
return;
@@ -1184,14 +1178,11 @@ il4965_rs_switch_to_mimo2(struct il_priv *il, struct il_lq_sta *lq_sta,
u16 rate_mask;
s32 rate;
s8 is_green = lq_sta->is_green;
- struct il_station_priv *sta_priv = (void *)sta->drv_priv;
- struct il_rxon_context *ctx = sta_priv->common.ctx;
if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
return -1;
- if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2) ==
- WLAN_HT_CAP_SM_PS_STATIC)
+ if (sta->smps_mode == IEEE80211_SMPS_STATIC)
return -1;
/* Need both Tx chains/antennas to support MIMO */
@@ -1206,7 +1197,7 @@ il4965_rs_switch_to_mimo2(struct il_priv *il, struct il_lq_sta *lq_sta,
tbl->max_search = IL_MAX_SEARCH;
rate_mask = lq_sta->active_mimo2_rate;
- if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap))
+ if (il_is_ht40_tx_allowed(il, &sta->ht_cap))
tbl->is_ht40 = 1;
else
tbl->is_ht40 = 0;
@@ -1240,8 +1231,6 @@ il4965_rs_switch_to_siso(struct il_priv *il, struct il_lq_sta *lq_sta,
u16 rate_mask;
u8 is_green = lq_sta->is_green;
s32 rate;
- struct il_station_priv *sta_priv = (void *)sta->drv_priv;
- struct il_rxon_context *ctx = sta_priv->common.ctx;
if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
return -1;
@@ -1254,7 +1243,7 @@ il4965_rs_switch_to_siso(struct il_priv *il, struct il_lq_sta *lq_sta,
tbl->max_search = IL_MAX_SEARCH;
rate_mask = lq_sta->active_siso_rate;
- if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap))
+ if (il_is_ht40_tx_allowed(il, &sta->ht_cap))
tbl->is_ht40 = 1;
else
tbl->is_ht40 = 0;
@@ -1733,8 +1722,7 @@ il4965_rs_stay_in_table(struct il_lq_sta *lq_sta, bool force_search)
* setup rate table in uCode
*/
static void
-il4965_rs_update_rate_tbl(struct il_priv *il, struct il_rxon_context *ctx,
- struct il_lq_sta *lq_sta,
+il4965_rs_update_rate_tbl(struct il_priv *il, struct il_lq_sta *lq_sta,
struct il_scale_tbl_info *tbl, int idx, u8 is_green)
{
u32 rate;
@@ -1742,7 +1730,7 @@ il4965_rs_update_rate_tbl(struct il_priv *il, struct il_rxon_context *ctx,
/* Update uCode's rate table. */
rate = il4965_rate_n_flags_from_tbl(il, tbl, idx, is_green);
il4965_rs_fill_link_cmd(il, lq_sta, rate);
- il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_ASYNC, false);
+ il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false);
}
/*
@@ -1778,8 +1766,6 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb,
s32 sr;
u8 tid = MAX_TID_COUNT;
struct il_tid_data *tid_data;
- struct il_station_priv *sta_priv = (void *)sta->drv_priv;
- struct il_rxon_context *ctx = sta_priv->common.ctx;
D_RATE("rate scale calculate new rate for skb\n");
@@ -1815,7 +1801,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb,
if (is_legacy(tbl->lq_type))
lq_sta->is_green = 0;
else
- lq_sta->is_green = il4965_rs_use_green(sta);
+ lq_sta->is_green = il4965_rs_use_green(il, sta);
is_green = lq_sta->is_green;
/* current tx rate */
@@ -1854,7 +1840,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb,
tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
/* get "active" rate info */
idx = il4965_hwrate_to_plcp_idx(tbl->current_rate);
- il4965_rs_update_rate_tbl(il, ctx, lq_sta, tbl, idx,
+ il4965_rs_update_rate_tbl(il, lq_sta, tbl, idx,
is_green);
}
return;
@@ -2057,8 +2043,7 @@ il4965_rs_rate_scale_perform(struct il_priv *il, struct sk_buff *skb,
lq_update:
/* Replace uCode's rate table for the destination station. */
if (update_lq)
- il4965_rs_update_rate_tbl(il, ctx, lq_sta, tbl, idx,
- is_green);
+ il4965_rs_update_rate_tbl(il, lq_sta, tbl, idx, is_green);
/* Should we stay with this modulation mode,
* or search for a new one? */
@@ -2098,7 +2083,7 @@ lq_update:
D_RATE("Switch current mcs: %X idx: %d\n",
tbl->current_rate, idx);
il4965_rs_fill_link_cmd(il, lq_sta, tbl->current_rate);
- il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_ASYNC, false);
+ il_send_lq_cmd(il, &lq_sta->lq, CMD_ASYNC, false);
} else
done_search = 1;
}
@@ -2166,17 +2151,16 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf,
int rate_idx;
int i;
u32 rate;
- u8 use_green = il4965_rs_use_green(sta);
+ u8 use_green;
u8 active_tbl = 0;
u8 valid_tx_ant;
struct il_station_priv *sta_priv;
- struct il_rxon_context *ctx;
if (!sta || !lq_sta)
return;
+ use_green = il4965_rs_use_green(il, sta);
sta_priv = (void *)sta->drv_priv;
- ctx = sta_priv->common.ctx;
i = lq_sta->last_txrate_idx;
@@ -2208,7 +2192,7 @@ il4965_rs_initialize_lq(struct il_priv *il, struct ieee80211_conf *conf,
il4965_rs_set_expected_tpt_table(lq_sta, tbl);
il4965_rs_fill_link_cmd(NULL, lq_sta, rate);
il->stations[lq_sta->lq.sta_id].lq = &lq_sta->lq;
- il_send_lq_cmd(il, ctx, &lq_sta->lq, CMD_SYNC, true);
+ il_send_lq_cmd(il, &lq_sta->lq, CMD_SYNC, true);
}
static void
@@ -2283,7 +2267,7 @@ il4965_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta,
info->control.rates[0].flags = 0;
}
info->control.rates[0].idx = rate_idx;
-
+ info->control.rates[0].count = 1;
}
static void *
@@ -2315,7 +2299,7 @@ il4965_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id)
sta_priv = (struct il_station_priv *)sta->drv_priv;
lq_sta = &sta_priv->lq_sta;
- sband = hw->wiphy->bands[conf->channel->band];
+ sband = hw->wiphy->bands[conf->chandef.chan->band];
lq_sta->lq.sta_id = sta_id;
@@ -2341,7 +2325,7 @@ il4965_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id)
lq_sta->is_dup = 0;
lq_sta->max_rate_idx = -1;
lq_sta->missed_rate_counter = IL_MISSED_RATE_MAX;
- lq_sta->is_green = il4965_rs_use_green(sta);
+ lq_sta->is_green = il4965_rs_use_green(il, sta);
lq_sta->active_legacy_rate = il->active_rate & ~(0x1000);
lq_sta->band = il->band;
/*
@@ -2533,12 +2517,6 @@ il4965_rs_free_sta(void *il_r, struct ieee80211_sta *sta, void *il_sta)
}
#ifdef CONFIG_MAC80211_DEBUGFS
-static int
-il4965_open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
static void
il4965_rs_dbgfs_set_mcs(struct il_lq_sta *lq_sta, u32 * rate_n_flags, int idx)
@@ -2579,9 +2557,6 @@ il4965_rs_sta_dbgfs_scale_table_write(struct file *file,
char buf[64];
size_t buf_size;
u32 parsed_rate;
- struct il_station_priv *sta_priv =
- container_of(lq_sta, struct il_station_priv, lq_sta);
- struct il_rxon_context *ctx = sta_priv->common.ctx;
il = lq_sta->drv;
memset(buf, 0, sizeof(buf));
@@ -2603,7 +2578,7 @@ il4965_rs_sta_dbgfs_scale_table_write(struct file *file,
if (lq_sta->dbg_fixed_rate) {
il4965_rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
- il_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC, false);
+ il_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC, false);
}
return count;
@@ -2713,7 +2688,7 @@ il4965_rs_sta_dbgfs_scale_table_read(struct file *file, char __user *user_buf,
static const struct file_operations rs_sta_dbgfs_scale_table_ops = {
.write = il4965_rs_sta_dbgfs_scale_table_write,
.read = il4965_rs_sta_dbgfs_scale_table_read,
- .open = il4965_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -2758,7 +2733,7 @@ il4965_rs_sta_dbgfs_stats_table_read(struct file *file, char __user *user_buf,
static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
.read = il4965_rs_sta_dbgfs_stats_table_read,
- .open = il4965_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -2786,7 +2761,7 @@ il4965_rs_sta_dbgfs_rate_scale_data_read(struct file *file,
static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
.read = il4965_rs_sta_dbgfs_rate_scale_data_read,
- .open = il4965_open_file_generic,
+ .open = simple_open,
.llseek = default_llseek,
};
@@ -2827,12 +2802,12 @@ il4965_rs_remove_debugfs(void *il, void *il_sta)
*/
static void
il4965_rs_rate_init_stub(void *il_r, struct ieee80211_supported_band *sband,
+ struct cfg80211_chan_def *chandef,
struct ieee80211_sta *sta, void *il_sta)
{
}
-static struct rate_control_ops rs_4965_ops = {
- .module = NULL,
+static const struct rate_control_ops rs_4965_ops = {
.name = IL4965_RS_NAME,
.tx_status = il4965_rs_tx_status,
.get_rate = il4965_rs_get_rate,
diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c
index cacbc03880b..fe47db9c20c 100644
--- a/drivers/net/wireless/iwlegacy/4965.c
+++ b/drivers/net/wireless/iwlegacy/4965.c
@@ -26,7 +26,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/init.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
@@ -264,10 +263,6 @@ il4965_led_enable(struct il_priv *il)
_il_wr(il, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
}
-const struct il_led_ops il4965_led_ops = {
- .cmd = il4965_send_led_cmd,
-};
-
static int il4965_send_tx_power(struct il_priv *il);
static int il4965_hw_get_temperature(struct il_priv *il);
@@ -508,7 +503,7 @@ iw4965_is_ht40_channel(__le32 rxon_flags)
chan_mod == CHANNEL_MODE_MIXED);
}
-static void
+void
il4965_nic_config(struct il_priv *il)
{
unsigned long flags;
@@ -569,82 +564,6 @@ il4965_chain_noise_reset(struct il_priv *il)
}
}
-static struct il_sensitivity_ranges il4965_sensitivity = {
- .min_nrg_cck = 97,
- .max_nrg_cck = 0, /* not used, set to 0 */
-
- .auto_corr_min_ofdm = 85,
- .auto_corr_min_ofdm_mrc = 170,
- .auto_corr_min_ofdm_x1 = 105,
- .auto_corr_min_ofdm_mrc_x1 = 220,
-
- .auto_corr_max_ofdm = 120,
- .auto_corr_max_ofdm_mrc = 210,
- .auto_corr_max_ofdm_x1 = 140,
- .auto_corr_max_ofdm_mrc_x1 = 270,
-
- .auto_corr_min_cck = 125,
- .auto_corr_max_cck = 200,
- .auto_corr_min_cck_mrc = 200,
- .auto_corr_max_cck_mrc = 400,
-
- .nrg_th_cck = 100,
- .nrg_th_ofdm = 100,
-
- .barker_corr_th_min = 190,
- .barker_corr_th_min_mrc = 390,
- .nrg_th_cca = 62,
-};
-
-static void
-il4965_set_ct_threshold(struct il_priv *il)
-{
- /* want Kelvin */
- il->hw_params.ct_kill_threshold =
- CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY);
-}
-
-/**
- * il4965_hw_set_hw_params
- *
- * Called when initializing driver
- */
-static int
-il4965_hw_set_hw_params(struct il_priv *il)
-{
- if (il->cfg->mod_params->num_of_queues >= IL_MIN_NUM_QUEUES &&
- il->cfg->mod_params->num_of_queues <= IL49_NUM_QUEUES)
- il->cfg->base_params->num_of_queues =
- il->cfg->mod_params->num_of_queues;
-
- il->hw_params.max_txq_num = il->cfg->base_params->num_of_queues;
- il->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
- il->hw_params.scd_bc_tbls_size =
- il->cfg->base_params->num_of_queues *
- sizeof(struct il4965_scd_bc_tbl);
- il->hw_params.tfd_size = sizeof(struct il_tfd);
- il->hw_params.max_stations = IL4965_STATION_COUNT;
- il->ctx.bcast_sta_id = IL4965_BROADCAST_ID;
- il->hw_params.max_data_size = IL49_RTC_DATA_SIZE;
- il->hw_params.max_inst_size = IL49_RTC_INST_SIZE;
- il->hw_params.max_bsm_size = BSM_SRAM_SIZE;
- il->hw_params.ht40_channel = BIT(IEEE80211_BAND_5GHZ);
-
- il->hw_params.rx_wrt_ptr_reg = FH49_RSCSR_CHNL0_WPTR;
-
- il->hw_params.tx_chains_num = il4965_num_of_ant(il->cfg->valid_tx_ant);
- il->hw_params.rx_chains_num = il4965_num_of_ant(il->cfg->valid_rx_ant);
- il->hw_params.valid_tx_ant = il->cfg->valid_tx_ant;
- il->hw_params.valid_rx_ant = il->cfg->valid_rx_ant;
-
- il4965_set_ct_threshold(il);
-
- il->hw_params.sens = &il4965_sensitivity;
- il->hw_params.beacon_time_tsf_bits = IL4965_EXT_BEACON_TIME_POS;
-
- return 0;
-}
-
static s32
il4965_math_div_round(s32 num, s32 denom, s32 * res)
{
@@ -1342,7 +1261,6 @@ il4965_send_tx_power(struct il_priv *il)
u8 band = 0;
bool is_ht40 = false;
u8 ctrl_chan_high = 0;
- struct il_rxon_context *ctx = &il->ctx;
if (WARN_ONCE
(test_bit(S_SCAN_HW, &il->status),
@@ -1351,16 +1269,16 @@ il4965_send_tx_power(struct il_priv *il)
band = il->band == IEEE80211_BAND_2GHZ;
- is_ht40 = iw4965_is_ht40_channel(ctx->active.flags);
+ is_ht40 = iw4965_is_ht40_channel(il->active.flags);
- if (is_ht40 && (ctx->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
+ if (is_ht40 && (il->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
ctrl_chan_high = 1;
cmd.band = band;
- cmd.channel = ctx->active.channel;
+ cmd.channel = il->active.channel;
ret =
- il4965_fill_txpower_tbl(il, band, le16_to_cpu(ctx->active.channel),
+ il4965_fill_txpower_tbl(il, band, le16_to_cpu(il->active.channel),
is_ht40, ctrl_chan_high, &cmd.tx_power);
if (ret)
goto out;
@@ -1372,12 +1290,12 @@ out:
}
static int
-il4965_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_send_rxon_assoc(struct il_priv *il)
{
int ret = 0;
struct il4965_rxon_assoc_cmd rxon_assoc;
- const struct il_rxon_cmd *rxon1 = &ctx->staging;
- const struct il_rxon_cmd *rxon2 = &ctx->active;
+ const struct il_rxon_cmd *rxon1 = &il->staging;
+ const struct il_rxon_cmd *rxon2 = &il->active;
if (rxon1->flags == rxon2->flags &&
rxon1->filter_flags == rxon2->filter_flags &&
@@ -1392,16 +1310,16 @@ il4965_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
return 0;
}
- rxon_assoc.flags = ctx->staging.flags;
- rxon_assoc.filter_flags = ctx->staging.filter_flags;
- rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
- rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
+ rxon_assoc.flags = il->staging.flags;
+ rxon_assoc.filter_flags = il->staging.filter_flags;
+ rxon_assoc.ofdm_basic_rates = il->staging.ofdm_basic_rates;
+ rxon_assoc.cck_basic_rates = il->staging.cck_basic_rates;
rxon_assoc.reserved = 0;
rxon_assoc.ofdm_ht_single_stream_basic_rates =
- ctx->staging.ofdm_ht_single_stream_basic_rates;
+ il->staging.ofdm_ht_single_stream_basic_rates;
rxon_assoc.ofdm_ht_dual_stream_basic_rates =
- ctx->staging.ofdm_ht_dual_stream_basic_rates;
- rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
+ il->staging.ofdm_ht_dual_stream_basic_rates;
+ rxon_assoc.rx_chain_select_flags = il->staging.rx_chain;
ret =
il_send_cmd_pdu_async(il, C_RXON_ASSOC, sizeof(rxon_assoc),
@@ -1411,23 +1329,20 @@ il4965_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
}
static int
-il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
+il4965_commit_rxon(struct il_priv *il)
{
/* cast away the const for active_rxon in this function */
- struct il_rxon_cmd *active_rxon = (void *)&ctx->active;
+ struct il_rxon_cmd *active_rxon = (void *)&il->active;
int ret;
- bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
+ bool new_assoc = !!(il->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
if (!il_is_alive(il))
return -EBUSY;
- if (!ctx->is_active)
- return 0;
-
/* always get timestamp with Rx frame */
- ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
+ il->staging.flags |= RXON_FLG_TSF2HOST_MSK;
- ret = il_check_rxon_cmd(il, ctx);
+ ret = il_check_rxon_cmd(il);
if (ret) {
IL_ERR("Invalid RXON configuration. Not committing.\n");
return -EINVAL;
@@ -1438,7 +1353,7 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
* abort any previous channel switch if still in process
*/
if (test_bit(S_CHANNEL_SWITCH_PENDING, &il->status) &&
- il->switch_channel != ctx->staging.channel) {
+ il->switch_channel != il->staging.channel) {
D_11H("abort channel switch on %d\n",
le16_to_cpu(il->switch_channel));
il_chswitch_done(il, false);
@@ -1447,15 +1362,15 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
/* If we don't need to send a full RXON, we can use
* il_rxon_assoc_cmd which is used to reconfigure filter
* and other flags for the current radio configuration. */
- if (!il_full_rxon_required(il, ctx)) {
- ret = il_send_rxon_assoc(il, ctx);
+ if (!il_full_rxon_required(il)) {
+ ret = il_send_rxon_assoc(il);
if (ret) {
IL_ERR("Error setting RXON_ASSOC (%d)\n", ret);
return ret;
}
- memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
- il_print_rx_config_cmd(il, ctx);
+ memcpy(active_rxon, &il->staging, sizeof(*active_rxon));
+ il_print_rx_config_cmd(il);
/*
* We do not commit tx power settings while channel changing,
* do it now if tx power changed.
@@ -1468,12 +1383,12 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
* an RXON_ASSOC and the new config wants the associated mask enabled,
* we must clear the associated from the active configuration
* before we apply the new config */
- if (il_is_associated_ctx(ctx) && new_assoc) {
+ if (il_is_associated(il) && new_assoc) {
D_INFO("Toggling associated bit on current RXON\n");
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
ret =
- il_send_cmd_pdu(il, ctx->rxon_cmd,
+ il_send_cmd_pdu(il, C_RXON,
sizeof(struct il_rxon_cmd), active_rxon);
/* If the mask clearing failed then we set
@@ -1483,9 +1398,9 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
IL_ERR("Error clearing ASSOC_MSK (%d)\n", ret);
return ret;
}
- il_clear_ucode_stations(il, ctx);
- il_restore_stations(il, ctx);
- ret = il4965_restore_default_wep_keys(il, ctx);
+ il_clear_ucode_stations(il);
+ il_restore_stations(il);
+ ret = il4965_restore_default_wep_keys(il);
if (ret) {
IL_ERR("Failed to restore WEP keys (%d)\n", ret);
return ret;
@@ -1494,9 +1409,9 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
D_INFO("Sending RXON\n" "* with%s RXON_FILTER_ASSOC_MSK\n"
"* channel = %d\n" "* bssid = %pM\n", (new_assoc ? "" : "out"),
- le16_to_cpu(ctx->staging.channel), ctx->staging.bssid_addr);
+ le16_to_cpu(il->staging.channel), il->staging.bssid_addr);
- il_set_rxon_hwcrypto(il, ctx, !il->cfg->mod_params->sw_crypto);
+ il_set_rxon_hwcrypto(il, !il->cfg->mod_params->sw_crypto);
/* Apply the new configuration
* RXON unassoc clears the station table in uCode so restoration of
@@ -1504,17 +1419,17 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
*/
if (!new_assoc) {
ret =
- il_send_cmd_pdu(il, ctx->rxon_cmd,
- sizeof(struct il_rxon_cmd), &ctx->staging);
+ il_send_cmd_pdu(il, C_RXON,
+ sizeof(struct il_rxon_cmd), &il->staging);
if (ret) {
IL_ERR("Error setting new RXON (%d)\n", ret);
return ret;
}
D_INFO("Return from !new_assoc RXON.\n");
- memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
- il_clear_ucode_stations(il, ctx);
- il_restore_stations(il, ctx);
- ret = il4965_restore_default_wep_keys(il, ctx);
+ memcpy(active_rxon, &il->staging, sizeof(*active_rxon));
+ il_clear_ucode_stations(il);
+ il_restore_stations(il);
+ ret = il4965_restore_default_wep_keys(il);
if (ret) {
IL_ERR("Failed to restore WEP keys (%d)\n", ret);
return ret;
@@ -1526,15 +1441,15 @@ il4965_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
* RXON assoc doesn't clear the station table in uCode,
*/
ret =
- il_send_cmd_pdu(il, ctx->rxon_cmd,
- sizeof(struct il_rxon_cmd), &ctx->staging);
+ il_send_cmd_pdu(il, C_RXON,
+ sizeof(struct il_rxon_cmd), &il->staging);
if (ret) {
IL_ERR("Error setting new RXON (%d)\n", ret);
return ret;
}
- memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
+ memcpy(active_rxon, &il->staging, sizeof(*active_rxon));
}
- il_print_rx_config_cmd(il, ctx);
+ il_print_rx_config_cmd(il);
il4965_init_sensitivity(il);
@@ -1553,7 +1468,6 @@ static int
il4965_hw_channel_switch(struct il_priv *il,
struct ieee80211_channel_switch *ch_switch)
{
- struct il_rxon_context *ctx = &il->ctx;
int rc;
u8 band = 0;
bool is_ht40 = false;
@@ -1564,21 +1478,24 @@ il4965_hw_channel_switch(struct il_priv *il,
u16 ch;
u32 tsf_low;
u8 switch_count;
- u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
- struct ieee80211_vif *vif = ctx->vif;
- band = il->band == IEEE80211_BAND_2GHZ;
+ u16 beacon_interval = le16_to_cpu(il->timing.beacon_interval);
+ struct ieee80211_vif *vif = il->vif;
+ band = (il->band == IEEE80211_BAND_2GHZ);
- is_ht40 = iw4965_is_ht40_channel(ctx->staging.flags);
+ if (WARN_ON_ONCE(vif == NULL))
+ return -EIO;
+
+ is_ht40 = iw4965_is_ht40_channel(il->staging.flags);
- if (is_ht40 && (ctx->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
+ if (is_ht40 && (il->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
ctrl_chan_high = 1;
cmd.band = band;
cmd.expect_beacon = 0;
- ch = ch_switch->channel->hw_value;
+ ch = ch_switch->chandef.chan->hw_value;
cmd.channel = cpu_to_le16(ch);
- cmd.rxon_flags = ctx->staging.flags;
- cmd.rxon_filter_flags = ctx->staging.filter_flags;
+ cmd.rxon_flags = il->staging.flags;
+ cmd.rxon_filter_flags = il->staging.filter_flags;
switch_count = ch_switch->count;
tsf_low = ch_switch->timestamp & 0x0ffffffff;
/*
@@ -1611,7 +1528,7 @@ il4965_hw_channel_switch(struct il_priv *il,
cmd.expect_beacon = il_is_channel_radar(ch_info);
else {
IL_ERR("invalid channel switch from %u to %u\n",
- ctx->active.channel, ch);
+ il->active.channel, ch);
return -EFAULT;
}
@@ -1756,7 +1673,7 @@ il4965_is_temp_calib_needed(struct il_priv *il)
return 1;
}
-static void
+void
il4965_temperature_calib(struct il_priv *il)
{
s32 temp;
@@ -1815,340 +1732,21 @@ il4965_build_addsta_hcmd(const struct il_addsta_cmd *cmd, u8 * data)
return (u16) sizeof(struct il4965_addsta_cmd);
}
-static inline u32
-il4965_get_scd_ssn(struct il4965_tx_resp *tx_resp)
-{
- return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN;
-}
-
-static inline u32
-il4965_tx_status_to_mac80211(u32 status)
-{
- status &= TX_STATUS_MSK;
-
- switch (status) {
- case TX_STATUS_SUCCESS:
- case TX_STATUS_DIRECT_DONE:
- return IEEE80211_TX_STAT_ACK;
- case TX_STATUS_FAIL_DEST_PS:
- return IEEE80211_TX_STAT_TX_FILTERED;
- default:
- return 0;
- }
-}
-
-static inline bool
-il4965_is_tx_success(u32 status)
-{
- status &= TX_STATUS_MSK;
- return (status == TX_STATUS_SUCCESS || status == TX_STATUS_DIRECT_DONE);
-}
-
-/**
- * il4965_tx_status_reply_tx - Handle Tx response for frames in aggregation queue
- */
-static int
-il4965_tx_status_reply_tx(struct il_priv *il, struct il_ht_agg *agg,
- struct il4965_tx_resp *tx_resp, int txq_id,
- u16 start_idx)
-{
- u16 status;
- struct agg_tx_status *frame_status = tx_resp->u.agg_status;
- struct ieee80211_tx_info *info = NULL;
- struct ieee80211_hdr *hdr = NULL;
- u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
- int i, sh, idx;
- u16 seq;
- if (agg->wait_for_ba)
- D_TX_REPLY("got tx response w/o block-ack\n");
-
- agg->frame_count = tx_resp->frame_count;
- agg->start_idx = start_idx;
- agg->rate_n_flags = rate_n_flags;
- agg->bitmap = 0;
-
- /* num frames attempted by Tx command */
- if (agg->frame_count == 1) {
- /* Only one frame was attempted; no block-ack will arrive */
- status = le16_to_cpu(frame_status[0].status);
- idx = start_idx;
-
- D_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n",
- agg->frame_count, agg->start_idx, idx);
-
- info = IEEE80211_SKB_CB(il->txq[txq_id].txb[idx].skb);
- info->status.rates[0].count = tx_resp->failure_frame + 1;
- info->flags &= ~IEEE80211_TX_CTL_AMPDU;
- info->flags |= il4965_tx_status_to_mac80211(status);
- il4965_hwrate_to_tx_control(il, rate_n_flags, info);
-
- D_TX_REPLY("1 Frame 0x%x failure :%d\n", status & 0xff,
- tx_resp->failure_frame);
- D_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags);
-
- agg->wait_for_ba = 0;
- } else {
- /* Two or more frames were attempted; expect block-ack */
- u64 bitmap = 0;
- int start = agg->start_idx;
-
- /* Construct bit-map of pending frames within Tx win */
- for (i = 0; i < agg->frame_count; i++) {
- u16 sc;
- status = le16_to_cpu(frame_status[i].status);
- seq = le16_to_cpu(frame_status[i].sequence);
- idx = SEQ_TO_IDX(seq);
- txq_id = SEQ_TO_QUEUE(seq);
-
- if (status &
- (AGG_TX_STATE_FEW_BYTES_MSK |
- AGG_TX_STATE_ABORT_MSK))
- continue;
-
- D_TX_REPLY("FrameCnt = %d, txq_id=%d idx=%d\n",
- agg->frame_count, txq_id, idx);
-
- hdr = il_tx_queue_get_hdr(il, txq_id, idx);
- if (!hdr) {
- IL_ERR("BUG_ON idx doesn't point to valid skb"
- " idx=%d, txq_id=%d\n", idx, txq_id);
- return -1;
- }
-
- sc = le16_to_cpu(hdr->seq_ctrl);
- if (idx != (SEQ_TO_SN(sc) & 0xff)) {
- IL_ERR("BUG_ON idx doesn't match seq control"
- " idx=%d, seq_idx=%d, seq=%d\n", idx,
- SEQ_TO_SN(sc), hdr->seq_ctrl);
- return -1;
- }
-
- D_TX_REPLY("AGG Frame i=%d idx %d seq=%d\n", i, idx,
- SEQ_TO_SN(sc));
-
- sh = idx - start;
- if (sh > 64) {
- sh = (start - idx) + 0xff;
- bitmap = bitmap << sh;
- sh = 0;
- start = idx;
- } else if (sh < -64)
- sh = 0xff - (start - idx);
- else if (sh < 0) {
- sh = start - idx;
- start = idx;
- bitmap = bitmap << sh;
- sh = 0;
- }
- bitmap |= 1ULL << sh;
- D_TX_REPLY("start=%d bitmap=0x%llx\n", start,
- (unsigned long long)bitmap);
- }
-
- agg->bitmap = bitmap;
- agg->start_idx = start;
- D_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n",
- agg->frame_count, agg->start_idx,
- (unsigned long long)agg->bitmap);
-
- if (bitmap)
- agg->wait_for_ba = 1;
- }
- return 0;
-}
-
-static u8
-il4965_find_station(struct il_priv *il, const u8 * addr)
-{
- int i;
- int start = 0;
- int ret = IL_INVALID_STATION;
- unsigned long flags;
-
- if ((il->iw_mode == NL80211_IFTYPE_ADHOC))
- start = IL_STA_ID;
-
- if (is_broadcast_ether_addr(addr))
- return il->ctx.bcast_sta_id;
-
- spin_lock_irqsave(&il->sta_lock, flags);
- for (i = start; i < il->hw_params.max_stations; i++)
- if (il->stations[i].used &&
- (!compare_ether_addr(il->stations[i].sta.sta.addr, addr))) {
- ret = i;
- goto out;
- }
-
- D_ASSOC("can not find STA %pM total %d\n", addr, il->num_stations);
-
-out:
- /*
- * It may be possible that more commands interacting with stations
- * arrive before we completed processing the adding of
- * station
- */
- if (ret != IL_INVALID_STATION &&
- (!(il->stations[ret].used & IL_STA_UCODE_ACTIVE) ||
- ((il->stations[ret].used & IL_STA_UCODE_ACTIVE) &&
- (il->stations[ret].used & IL_STA_UCODE_INPROGRESS)))) {
- IL_ERR("Requested station info for sta %d before ready.\n",
- ret);
- ret = IL_INVALID_STATION;
- }
- spin_unlock_irqrestore(&il->sta_lock, flags);
- return ret;
-}
-
-static int
-il4965_get_ra_sta_id(struct il_priv *il, struct ieee80211_hdr *hdr)
-{
- if (il->iw_mode == NL80211_IFTYPE_STATION) {
- return IL_AP_ID;
- } else {
- u8 *da = ieee80211_get_DA(hdr);
- return il4965_find_station(il, da);
- }
-}
-
-/**
- * il4965_hdl_tx - Handle standard (non-aggregation) Tx response
- */
-static void
-il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)
-{
- struct il_rx_pkt *pkt = rxb_addr(rxb);
- u16 sequence = le16_to_cpu(pkt->hdr.sequence);
- int txq_id = SEQ_TO_QUEUE(sequence);
- int idx = SEQ_TO_IDX(sequence);
- struct il_tx_queue *txq = &il->txq[txq_id];
- struct ieee80211_hdr *hdr;
- struct ieee80211_tx_info *info;
- struct il4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
- u32 status = le32_to_cpu(tx_resp->u.status);
- int uninitialized_var(tid);
- int sta_id;
- int freed;
- u8 *qc = NULL;
- unsigned long flags;
-
- if (idx >= txq->q.n_bd || il_queue_used(&txq->q, idx) == 0) {
- IL_ERR("Read idx for DMA queue txq_id (%d) idx %d "
- "is out of range [0-%d] %d %d\n", txq_id, idx,
- txq->q.n_bd, txq->q.write_ptr, txq->q.read_ptr);
- return;
- }
-
- txq->time_stamp = jiffies;
- info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
- memset(&info->status, 0, sizeof(info->status));
-
- hdr = il_tx_queue_get_hdr(il, txq_id, idx);
- if (ieee80211_is_data_qos(hdr->frame_control)) {
- qc = ieee80211_get_qos_ctl(hdr);
- tid = qc[0] & 0xf;
- }
-
- sta_id = il4965_get_ra_sta_id(il, hdr);
- if (txq->sched_retry && unlikely(sta_id == IL_INVALID_STATION)) {
- IL_ERR("Station not known\n");
- return;
- }
-
- spin_lock_irqsave(&il->sta_lock, flags);
- if (txq->sched_retry) {
- const u32 scd_ssn = il4965_get_scd_ssn(tx_resp);
- struct il_ht_agg *agg = NULL;
- WARN_ON(!qc);
-
- agg = &il->stations[sta_id].tid[tid].agg;
-
- il4965_tx_status_reply_tx(il, agg, tx_resp, txq_id, idx);
-
- /* check if BAR is needed */
- if ((tx_resp->frame_count == 1) &&
- !il4965_is_tx_success(status))
- info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
-
- if (txq->q.read_ptr != (scd_ssn & 0xff)) {
- idx = il_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
- D_TX_REPLY("Retry scheduler reclaim scd_ssn "
- "%d idx %d\n", scd_ssn, idx);
- freed = il4965_tx_queue_reclaim(il, txq_id, idx);
- if (qc)
- il4965_free_tfds_in_queue(il, sta_id, tid,
- freed);
-
- if (il->mac80211_registered &&
- il_queue_space(&txq->q) > txq->q.low_mark &&
- agg->state != IL_EMPTYING_HW_QUEUE_DELBA)
- il_wake_queue(il, txq);
- }
- } else {
- info->status.rates[0].count = tx_resp->failure_frame + 1;
- info->flags |= il4965_tx_status_to_mac80211(status);
- il4965_hwrate_to_tx_control(il,
- le32_to_cpu(tx_resp->rate_n_flags),
- info);
-
- D_TX_REPLY("TXQ %d status %s (0x%08x) "
- "rate_n_flags 0x%x retries %d\n", txq_id,
- il4965_get_tx_fail_reason(status), status,
- le32_to_cpu(tx_resp->rate_n_flags),
- tx_resp->failure_frame);
-
- freed = il4965_tx_queue_reclaim(il, txq_id, idx);
- if (qc && likely(sta_id != IL_INVALID_STATION))
- il4965_free_tfds_in_queue(il, sta_id, tid, freed);
- else if (sta_id == IL_INVALID_STATION)
- D_TX_REPLY("Station not known\n");
-
- if (il->mac80211_registered &&
- il_queue_space(&txq->q) > txq->q.low_mark)
- il_wake_queue(il, txq);
- }
- if (qc && likely(sta_id != IL_INVALID_STATION))
- il4965_txq_check_empty(il, sta_id, tid, txq_id);
-
- il4965_check_abort_status(il, tx_resp->frame_count, status);
-
- spin_unlock_irqrestore(&il->sta_lock, flags);
-}
-
-/* Set up 4965-specific Rx frame reply handlers */
-static void
-il4965_handler_setup(struct il_priv *il)
-{
- /* Legacy Rx frames */
- il->handlers[N_RX] = il4965_hdl_rx;
- /* Tx response */
- il->handlers[C_TX] = il4965_hdl_tx;
-}
-
-static struct il_hcmd_ops il4965_hcmd = {
- .rxon_assoc = il4965_send_rxon_assoc,
- .commit_rxon = il4965_commit_rxon,
- .set_rxon_chain = il4965_set_rxon_chain,
-};
-
static void
il4965_post_scan(struct il_priv *il)
{
- struct il_rxon_context *ctx = &il->ctx;
-
/*
* Since setting the RXON may have been deferred while
* performing the scan, fire one off if needed
*/
- if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
- il_commit_rxon(il, ctx);
+ if (memcmp(&il->staging, &il->active, sizeof(il->staging)))
+ il_commit_rxon(il);
}
static void
il4965_post_associate(struct il_priv *il)
{
- struct il_rxon_context *ctx = &il->ctx;
- struct ieee80211_vif *vif = ctx->vif;
- struct ieee80211_conf *conf = NULL;
+ struct ieee80211_vif *vif = il->vif;
int ret = 0;
if (!vif || !il->is_open)
@@ -2159,43 +1757,41 @@ il4965_post_associate(struct il_priv *il)
il_scan_cancel_timeout(il, 200);
- conf = &il->hw->conf;
+ il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ il_commit_rxon(il);
- ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- il_commit_rxon(il, ctx);
-
- ret = il_send_rxon_timing(il, ctx);
+ ret = il_send_rxon_timing(il);
if (ret)
IL_WARN("RXON timing - " "Attempting to continue.\n");
- ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
il_set_rxon_ht(il, &il->current_ht_config);
- if (il->cfg->ops->hcmd->set_rxon_chain)
- il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
+ if (il->ops->set_rxon_chain)
+ il->ops->set_rxon_chain(il);
- ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
+ il->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
D_ASSOC("assoc id %d beacon interval %d\n", vif->bss_conf.aid,
vif->bss_conf.beacon_int);
if (vif->bss_conf.use_short_preamble)
- ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
- ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
+ if (il->staging.flags & RXON_FLG_BAND_24G_MSK) {
if (vif->bss_conf.use_short_slot)
- ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
- ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
}
- il_commit_rxon(il, ctx);
+ il_commit_rxon(il);
D_ASSOC("Associated as %d to: %pM\n", vif->bss_conf.aid,
- ctx->active.bssid_addr);
+ il->active.bssid_addr);
switch (vif->type) {
case NL80211_IFTYPE_STATION:
@@ -2223,8 +1819,7 @@ il4965_post_associate(struct il_priv *il)
static void
il4965_config_ap(struct il_priv *il)
{
- struct il_rxon_context *ctx = &il->ctx;
- struct ieee80211_vif *vif = ctx->vif;
+ struct ieee80211_vif *vif = il->vif;
int ret = 0;
lockdep_assert_held(&il->mutex);
@@ -2233,14 +1828,14 @@ il4965_config_ap(struct il_priv *il)
return;
/* The following should be done only at AP bring up */
- if (!il_is_associated_ctx(ctx)) {
+ if (!il_is_associated(il)) {
/* RXON - unassoc (to set timing command) */
- ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- il_commit_rxon(il, ctx);
+ il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ il_commit_rxon(il);
/* RXON Timing */
- ret = il_send_rxon_timing(il, ctx);
+ ret = il_send_rxon_timing(il);
if (ret)
IL_WARN("RXON timing failed - "
"Attempting to continue.\n");
@@ -2248,133 +1843,63 @@ il4965_config_ap(struct il_priv *il)
/* AP has all antennas */
il->chain_noise_data.active_chains = il->hw_params.valid_rx_ant;
il_set_rxon_ht(il, &il->current_ht_config);
- if (il->cfg->ops->hcmd->set_rxon_chain)
- il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
+ if (il->ops->set_rxon_chain)
+ il->ops->set_rxon_chain(il);
- ctx->staging.assoc_id = 0;
+ il->staging.assoc_id = 0;
if (vif->bss_conf.use_short_preamble)
- ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
- ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
- if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
+ if (il->staging.flags & RXON_FLG_BAND_24G_MSK) {
if (vif->bss_conf.use_short_slot)
- ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
- ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
}
/* need to send beacon cmd before committing assoc RXON! */
il4965_send_beacon_cmd(il);
/* restore RXON assoc */
- ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
- il_commit_rxon(il, ctx);
+ il->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
+ il_commit_rxon(il);
}
il4965_send_beacon_cmd(il);
}
-static struct il_hcmd_utils_ops il4965_hcmd_utils = {
- .get_hcmd_size = il4965_get_hcmd_size,
- .build_addsta_hcmd = il4965_build_addsta_hcmd,
- .request_scan = il4965_request_scan,
- .post_scan = il4965_post_scan,
-};
-
-static struct il_lib_ops il4965_lib = {
- .set_hw_params = il4965_hw_set_hw_params,
+const struct il_ops il4965_ops = {
.txq_update_byte_cnt_tbl = il4965_txq_update_byte_cnt_tbl,
.txq_attach_buf_to_tfd = il4965_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = il4965_hw_txq_free_tfd,
.txq_init = il4965_hw_tx_queue_init,
- .handler_setup = il4965_handler_setup,
.is_valid_rtc_data_addr = il4965_hw_valid_rtc_data_addr,
.init_alive_start = il4965_init_alive_start,
.load_ucode = il4965_load_bsm,
.dump_nic_error_log = il4965_dump_nic_error_log,
.dump_fh = il4965_dump_fh,
.set_channel_switch = il4965_hw_channel_switch,
- .apm_ops = {
- .init = il_apm_init,
- .config = il4965_nic_config,
- },
- .eeprom_ops = {
- .regulatory_bands = {
- EEPROM_REGULATORY_BAND_1_CHANNELS,
- EEPROM_REGULATORY_BAND_2_CHANNELS,
- EEPROM_REGULATORY_BAND_3_CHANNELS,
- EEPROM_REGULATORY_BAND_4_CHANNELS,
- EEPROM_REGULATORY_BAND_5_CHANNELS,
- EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS,
- EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS},
- .acquire_semaphore = il4965_eeprom_acquire_semaphore,
- .release_semaphore = il4965_eeprom_release_semaphore,
- },
+ .apm_init = il_apm_init,
.send_tx_power = il4965_send_tx_power,
.update_chain_flags = il4965_update_chain_flags,
- .temp_ops = {
- .temperature = il4965_temperature_calib,
- },
-#ifdef CONFIG_IWLEGACY_DEBUGFS
- .debugfs_ops = {
- .rx_stats_read = il4965_ucode_rx_stats_read,
- .tx_stats_read = il4965_ucode_tx_stats_read,
- .general_stats_read = il4965_ucode_general_stats_read,
- },
-#endif
-};
+ .eeprom_acquire_semaphore = il4965_eeprom_acquire_semaphore,
+ .eeprom_release_semaphore = il4965_eeprom_release_semaphore,
+
+ .rxon_assoc = il4965_send_rxon_assoc,
+ .commit_rxon = il4965_commit_rxon,
+ .set_rxon_chain = il4965_set_rxon_chain,
+
+ .get_hcmd_size = il4965_get_hcmd_size,
+ .build_addsta_hcmd = il4965_build_addsta_hcmd,
+ .request_scan = il4965_request_scan,
+ .post_scan = il4965_post_scan,
-static const struct il_legacy_ops il4965_legacy_ops = {
.post_associate = il4965_post_associate,
.config_ap = il4965_config_ap,
.manage_ibss_station = il4965_manage_ibss_station,
.update_bcast_stations = il4965_update_bcast_stations,
-};
-struct ieee80211_ops il4965_hw_ops = {
- .tx = il4965_mac_tx,
- .start = il4965_mac_start,
- .stop = il4965_mac_stop,
- .add_interface = il_mac_add_interface,
- .remove_interface = il_mac_remove_interface,
- .change_interface = il_mac_change_interface,
- .config = il_mac_config,
- .configure_filter = il4965_configure_filter,
- .set_key = il4965_mac_set_key,
- .update_tkip_key = il4965_mac_update_tkip_key,
- .conf_tx = il_mac_conf_tx,
- .reset_tsf = il_mac_reset_tsf,
- .bss_info_changed = il_mac_bss_info_changed,
- .ampdu_action = il4965_mac_ampdu_action,
- .hw_scan = il_mac_hw_scan,
- .sta_add = il4965_mac_sta_add,
- .sta_remove = il_mac_sta_remove,
- .channel_switch = il4965_mac_channel_switch,
- .tx_last_beacon = il_mac_tx_last_beacon,
-};
-
-static const struct il_ops il4965_ops = {
- .lib = &il4965_lib,
- .hcmd = &il4965_hcmd,
- .utils = &il4965_hcmd_utils,
- .led = &il4965_led_ops,
- .legacy = &il4965_legacy_ops,
- .ieee80211_ops = &il4965_hw_ops,
-};
-
-static struct il_base_params il4965_base_params = {
- .eeprom_size = IL4965_EEPROM_IMG_SIZE,
- .num_of_queues = IL49_NUM_QUEUES,
- .num_of_ampdu_queues = IL49_NUM_AMPDU_QUEUES,
- .pll_cfg_val = 0,
- .set_l0s = true,
- .use_bsm = true,
- .led_compensation = 61,
- .chain_noise_num_beacons = IL4965_CAL_NUM_BEACONS,
- .wd_timeout = IL_DEF_WD_TIMEOUT,
- .temperature_kelvin = true,
- .ucode_tracing = true,
- .sensitivity_calib_by_driver = true,
- .chain_noise_calib_by_driver = true,
+ .send_led_cmd = il4965_send_led_cmd,
};
struct il_cfg il4965_cfg = {
@@ -2387,15 +1912,38 @@ struct il_cfg il4965_cfg = {
.valid_rx_ant = ANT_ABC,
.eeprom_ver = EEPROM_4965_EEPROM_VERSION,
.eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
- .ops = &il4965_ops,
.mod_params = &il4965_mod_params,
- .base_params = &il4965_base_params,
.led_mode = IL_LED_BLINK,
/*
* Force use of chains B and C for scan RX on 5 GHz band
* because the device has off-channel reception on chain A.
*/
.scan_rx_antennas[IEEE80211_BAND_5GHZ] = ANT_BC,
+
+ .eeprom_size = IL4965_EEPROM_IMG_SIZE,
+ .num_of_queues = IL49_NUM_QUEUES,
+ .num_of_ampdu_queues = IL49_NUM_AMPDU_QUEUES,
+ .pll_cfg_val = 0,
+ .set_l0s = true,
+ .use_bsm = true,
+ .led_compensation = 61,
+ .chain_noise_num_beacons = IL4965_CAL_NUM_BEACONS,
+ .wd_timeout = IL_DEF_WD_TIMEOUT,
+ .temperature_kelvin = true,
+ .ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
+
+ .regulatory_bands = {
+ EEPROM_REGULATORY_BAND_1_CHANNELS,
+ EEPROM_REGULATORY_BAND_2_CHANNELS,
+ EEPROM_REGULATORY_BAND_3_CHANNELS,
+ EEPROM_REGULATORY_BAND_4_CHANNELS,
+ EEPROM_REGULATORY_BAND_5_CHANNELS,
+ EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS,
+ EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS
+ },
+
};
/* Module firmware */
diff --git a/drivers/net/wireless/iwlegacy/4965.h b/drivers/net/wireless/iwlegacy/4965.h
index f280e0161b1..337dfcf3bbd 100644
--- a/drivers/net/wireless/iwlegacy/4965.h
+++ b/drivers/net/wireless/iwlegacy/4965.h
@@ -38,17 +38,16 @@ struct il_rxon_context;
/* configuration for the _4965 devices */
extern struct il_cfg il4965_cfg;
+extern const struct il_ops il4965_ops;
extern struct il_mod_params il4965_mod_params;
-extern struct ieee80211_ops il4965_hw_ops;
-
/* tx queue */
void il4965_free_tfds_in_queue(struct il_priv *il, int sta_id, int tid,
int freed);
/* RXON */
-void il4965_set_rxon_chain(struct il_priv *il, struct il_rxon_context *ctx);
+void il4965_set_rxon_chain(struct il_priv *il);
/* uCode */
int il4965_verify_ucode(struct il_priv *il);
@@ -61,6 +60,8 @@ int il4965_rx_init(struct il_priv *il, struct il_rx_queue *rxq);
int il4965_hw_nic_init(struct il_priv *il);
int il4965_dump_fh(struct il_priv *il, char **buf, bool display);
+void il4965_nic_config(struct il_priv *il);
+
/* rx */
void il4965_rx_queue_restock(struct il_priv *il);
void il4965_rx_replenish(struct il_priv *il);
@@ -68,8 +69,6 @@ void il4965_rx_replenish_now(struct il_priv *il);
void il4965_rx_queue_free(struct il_priv *il, struct il_rx_queue *rxq);
int il4965_rxq_stop(struct il_priv *il);
int il4965_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band);
-void il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb);
-void il4965_hdl_rx_phy(struct il_priv *il, struct il_rx_buf *rxb);
void il4965_rx_handle(struct il_priv *il);
/* tx */
@@ -79,13 +78,14 @@ int il4965_hw_txq_attach_buf_to_tfd(struct il_priv *il, struct il_tx_queue *txq,
int il4965_hw_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq);
void il4965_hwrate_to_tx_control(struct il_priv *il, u32 rate_n_flags,
struct ieee80211_tx_info *info);
-int il4965_tx_skb(struct il_priv *il, struct sk_buff *skb);
+int il4965_tx_skb(struct il_priv *il,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb);
int il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid, u16 * ssn);
int il4965_tx_agg_stop(struct il_priv *il, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, u16 tid);
int il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id);
-void il4965_hdl_compressed_ba(struct il_priv *il, struct il_rx_buf *rxb);
int il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx);
void il4965_hw_txq_ctx_free(struct il_priv *il);
int il4965_txq_ctx_alloc(struct il_priv *il);
@@ -107,12 +107,6 @@ void il4965_set_wr_ptrs(struct il_priv *il, int txq_id, u32 idx);
void il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq,
int tx_fifo_id, int scd_retry);
-/* rx */
-void il4965_hdl_missed_beacon(struct il_priv *il, struct il_rx_buf *rxb);
-bool il4965_good_plcp_health(struct il_priv *il, struct il_rx_pkt *pkt);
-void il4965_hdl_stats(struct il_priv *il, struct il_rx_buf *rxb);
-void il4965_hdl_c_stats(struct il_priv *il, struct il_rx_buf *rxb);
-
/* scan */
int il4965_request_scan(struct il_priv *il, struct ieee80211_vif *vif);
@@ -134,21 +128,18 @@ il4965_get_tx_fail_reason(u32 status)
#endif
/* station management */
-int il4965_alloc_bcast_station(struct il_priv *il, struct il_rxon_context *ctx);
-int il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx,
- const u8 *addr, u8 *sta_id_r);
+int il4965_alloc_bcast_station(struct il_priv *il);
+int il4965_add_bssid_station(struct il_priv *il, const u8 *addr, u8 *sta_id_r);
int il4965_remove_default_wep_key(struct il_priv *il,
- struct il_rxon_context *ctx,
struct ieee80211_key_conf *key);
-int il4965_set_default_wep_key(struct il_priv *il, struct il_rxon_context *ctx,
+int il4965_set_default_wep_key(struct il_priv *il,
struct ieee80211_key_conf *key);
-int il4965_restore_default_wep_keys(struct il_priv *il,
- struct il_rxon_context *ctx);
-int il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
+int il4965_restore_default_wep_keys(struct il_priv *il);
+int il4965_set_dynamic_key(struct il_priv *il,
struct ieee80211_key_conf *key, u8 sta_id);
-int il4965_remove_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
+int il4965_remove_dynamic_key(struct il_priv *il,
struct ieee80211_key_conf *key, u8 sta_id);
-void il4965_update_tkip_key(struct il_priv *il, struct il_rxon_context *ctx,
+void il4965_update_tkip_key(struct il_priv *il,
struct ieee80211_key_conf *keyconf,
struct ieee80211_sta *sta, u32 iv32,
u16 *phase1key);
@@ -174,7 +165,9 @@ void il4965_eeprom_release_semaphore(struct il_priv *il);
int il4965_eeprom_check_version(struct il_priv *il);
/* mac80211 handlers (for 4965) */
-void il4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
+void il4965_mac_tx(struct ieee80211_hw *hw,
+ struct ieee80211_tx_control *control,
+ struct sk_buff *skb);
int il4965_mac_start(struct ieee80211_hw *hw);
void il4965_mac_stop(struct ieee80211_hw *hw);
void il4965_configure_filter(struct ieee80211_hw *hw,
@@ -279,6 +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);
/********************* END TEMPERATURE ***************************************/
/********************* START TXPOWER *****************************************/
@@ -923,10 +917,6 @@ struct il4965_scd_bc_tbl {
/* PCI registers */
#define PCI_CFG_RETRY_TIMEOUT 0x041
-/* PCI register values */
-#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01
-#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02
-
#define IL4965_DEFAULT_TX_RETRY 15
/* EEPROM */
@@ -937,17 +927,10 @@ void il4965_chain_noise_calibration(struct il_priv *il, void *stat_resp);
void il4965_sensitivity_calibration(struct il_priv *il, void *resp);
void il4965_init_sensitivity(struct il_priv *il);
void il4965_reset_run_time_calib(struct il_priv *il);
-void il4965_calib_free_results(struct il_priv *il);
/* Debug */
#ifdef CONFIG_IWLEGACY_DEBUGFS
-ssize_t il4965_ucode_rx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-ssize_t il4965_ucode_tx_stats_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos);
-ssize_t il4965_ucode_general_stats_read(struct file *file,
- char __user *user_buf, size_t count,
- loff_t *ppos);
+extern const struct il_debugfs_ops il4965_debugfs_ops;
#endif
/****************************/
diff --git a/drivers/net/wireless/iwlegacy/Kconfig b/drivers/net/wireless/iwlegacy/Kconfig
index 05bd375cb84..fb919727b8b 100644
--- a/drivers/net/wireless/iwlegacy/Kconfig
+++ b/drivers/net/wireless/iwlegacy/Kconfig
@@ -6,45 +6,6 @@ config IWLEGACY
select LEDS_TRIGGERS
select MAC80211_LEDS
-menu "Debugging Options"
- depends on IWLEGACY
-
-config IWLEGACY_DEBUG
- bool "Enable full debugging output in iwlegacy (iwl 3945/4965) drivers"
- depends on IWLEGACY
- ---help---
- This option will enable debug tracing output for the iwlegacy
- drivers.
-
- This will result in the kernel module being ~100k larger. You can
- control which debug output is sent to the kernel log by setting the
- value in
-
- /sys/class/net/wlan0/device/debug_level
-
- This entry will only exist if this option is enabled.
-
- To set a value, simply echo an 8-byte hex value to the same file:
-
- % echo 0x43fff > /sys/class/net/wlan0/device/debug_level
-
- You can find the list of debug mask values in:
- drivers/net/wireless/iwlegacy/common.h
-
- If this is your first time using this driver, you should say Y here
- as the debug information can assist others in helping you resolve
- any problems you may encounter.
-
-config IWLEGACY_DEBUGFS
- bool "iwlegacy (iwl 3945/4965) debugfs support"
- depends on IWLEGACY && MAC80211_DEBUGFS
- ---help---
- Enable creation of debugfs files for the iwlegacy drivers. This
- is a low-impact option that allows getting insight into the
- driver's state at runtime.
-
-endmenu
-
config IWL4965
tristate "Intel Wireless WiFi 4965AGN (iwl4965)"
depends on PCI && MAC80211
@@ -98,3 +59,42 @@ config IWL3945
inserted in and removed from the running kernel whenever you want),
say M here and read <file:Documentation/kbuild/modules.txt>. The
module will be called iwl3945.
+
+menu "iwl3945 / iwl4965 Debugging Options"
+ depends on IWLEGACY
+
+config IWLEGACY_DEBUG
+ bool "Enable full debugging output in iwlegacy (iwl 3945/4965) drivers"
+ depends on IWLEGACY
+ ---help---
+ This option will enable debug tracing output for the iwlegacy
+ drivers.
+
+ This will result in the kernel module being ~100k larger. You can
+ control which debug output is sent to the kernel log by setting the
+ value in
+
+ /sys/class/net/wlan0/device/debug_level
+
+ This entry will only exist if this option is enabled.
+
+ To set a value, simply echo an 8-byte hex value to the same file:
+
+ % echo 0x43fff > /sys/class/net/wlan0/device/debug_level
+
+ You can find the list of debug mask values in:
+ drivers/net/wireless/iwlegacy/common.h
+
+ If this is your first time using this driver, you should say Y here
+ as the debug information can assist others in helping you resolve
+ any problems you may encounter.
+
+config IWLEGACY_DEBUGFS
+ bool "iwlegacy (iwl 3945/4965) debugfs support"
+ depends on IWLEGACY && MAC80211_DEBUGFS
+ ---help---
+ Enable creation of debugfs files for the iwlegacy drivers. This
+ is a low-impact option that allows getting insight into the
+ driver's state at runtime.
+
+endmenu
diff --git a/drivers/net/wireless/iwlegacy/commands.h b/drivers/net/wireless/iwlegacy/commands.h
index 25dd7d28d02..dd744135c95 100644
--- a/drivers/net/wireless/iwlegacy/commands.h
+++ b/drivers/net/wireless/iwlegacy/commands.h
@@ -1134,8 +1134,9 @@ struct il_wep_cmd {
#define RX_RES_PHY_FLAGS_MOD_CCK_MSK cpu_to_le16(1 << 1)
#define RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK cpu_to_le16(1 << 2)
#define RX_RES_PHY_FLAGS_NARROW_BAND_MSK cpu_to_le16(1 << 3)
-#define RX_RES_PHY_FLAGS_ANTENNA_MSK 0xf0
+#define RX_RES_PHY_FLAGS_ANTENNA_MSK 0x70
#define RX_RES_PHY_FLAGS_ANTENNA_POS 4
+#define RX_RES_PHY_FLAGS_AGG_MSK cpu_to_le16(1 << 7)
#define RX_RES_STATUS_SEC_TYPE_MSK (0x7 << 8)
#define RX_RES_STATUS_SEC_TYPE_NONE (0x0 << 8)
@@ -1347,14 +1348,6 @@ struct il_rx_mpdu_res_start {
#define TX_CMD_SEC_KEY128 0x08
/*
- * security overhead sizes
- */
-#define WEP_IV_LEN 4
-#define WEP_ICV_LEN 4
-#define CCMP_MIC_LEN 8
-#define TKIP_ICV_LEN 4
-
-/*
* C_TX = 0x1c (command)
*/
@@ -2277,7 +2270,8 @@ struct il_spectrum_notification {
*/
#define IL_POWER_VEC_SIZE 5
-#define IL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0))
+#define IL_POWER_DRIVER_ALLOW_SLEEP_MSK cpu_to_le16(BIT(0))
+#define IL_POWER_SLEEP_OVER_DTIM_MSK cpu_to_le16(BIT(2))
#define IL_POWER_PCI_PM_MSK cpu_to_le16(BIT(3))
struct il3945_powertable_cmd {
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index 36454d0bbee..ecc674627e6 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -33,7 +33,6 @@
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/lockdep.h>
-#include <linux/init.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
@@ -81,7 +80,7 @@ il_clear_bit(struct il_priv *p, u32 r, u32 m)
}
EXPORT_SYMBOL(il_clear_bit);
-int
+bool
_il_grab_nic_access(struct il_priv *il)
{
int ret;
@@ -111,14 +110,15 @@ _il_grab_nic_access(struct il_priv *il)
_il_poll_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
(CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
- if (ret < 0) {
+ if (unlikely(ret < 0)) {
val = _il_rd(il, CSR_GP_CNTRL);
- IL_ERR("MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
+ WARN_ONCE(1, "Timeout waiting for ucode processor access "
+ "(CSR_GP_CNTRL 0x%08x)\n", val);
_il_wr(il, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
- return -EIO;
+ return false;
}
- return 0;
+ return true;
}
EXPORT_SYMBOL_GPL(_il_grab_nic_access);
@@ -160,7 +160,7 @@ il_wr_prph(struct il_priv *il, u32 addr, u32 val)
unsigned long reg_flags;
spin_lock_irqsave(&il->reg_lock, reg_flags);
- if (!_il_grab_nic_access(il)) {
+ if (likely(_il_grab_nic_access(il))) {
_il_wr_prph(il, addr, val);
_il_release_nic_access(il);
}
@@ -178,7 +178,6 @@ il_read_targ_mem(struct il_priv *il, u32 addr)
_il_grab_nic_access(il);
_il_wr(il, HBUS_TARG_MEM_RADDR, addr);
- rmb();
value = _il_rd(il, HBUS_TARG_MEM_RDAT);
_il_release_nic_access(il);
@@ -193,9 +192,8 @@ il_write_targ_mem(struct il_priv *il, u32 addr, u32 val)
unsigned long reg_flags;
spin_lock_irqsave(&il->reg_lock, reg_flags);
- if (!_il_grab_nic_access(il)) {
+ if (likely(_il_grab_nic_access(il))) {
_il_wr(il, HBUS_TARG_MEM_WADDR, addr);
- wmb();
_il_wr(il, HBUS_TARG_MEM_WDAT, val);
_il_release_nic_access(il);
}
@@ -351,7 +349,7 @@ il_send_cmd_sync(struct il_priv *il, struct il_host_cmd *cmd)
}
}
- if (test_bit(S_RF_KILL_HW, &il->status)) {
+ if (test_bit(S_RFKILL, &il->status)) {
IL_ERR("Command %s aborted: RF KILL Switch\n",
il_get_cmd_string(cmd->id));
ret = -ECANCELED;
@@ -512,15 +510,15 @@ il_led_cmd(struct il_priv *il, unsigned long on, unsigned long off)
}
D_LED("Led blink time compensation=%u\n",
- il->cfg->base_params->led_compensation);
+ il->cfg->led_compensation);
led_cmd.on =
il_blink_compensation(il, on,
- il->cfg->base_params->led_compensation);
+ il->cfg->led_compensation);
led_cmd.off =
il_blink_compensation(il, off,
- il->cfg->base_params->led_compensation);
+ il->cfg->led_compensation);
- ret = il->cfg->ops->led->cmd(il, &led_cmd);
+ ret = il->ops->send_led_cmd(il, &led_cmd);
if (!ret) {
il->blink_on = on;
il->blink_off = off;
@@ -691,7 +689,7 @@ il_eeprom_verify_signature(struct il_priv *il)
const u8 *
il_eeprom_query_addr(const struct il_priv *il, size_t offset)
{
- BUG_ON(offset >= il->cfg->base_params->eeprom_size);
+ BUG_ON(offset >= il->cfg->eeprom_size);
return &il->eeprom[offset];
}
EXPORT_SYMBOL(il_eeprom_query_addr);
@@ -722,7 +720,7 @@ il_eeprom_init(struct il_priv *il)
u16 addr;
/* allocate eeprom */
- sz = il->cfg->base_params->eeprom_size;
+ sz = il->cfg->eeprom_size;
D_EEPROM("NVM size = %d\n", sz);
il->eeprom = kzalloc(sz, GFP_KERNEL);
if (!il->eeprom) {
@@ -731,7 +729,7 @@ il_eeprom_init(struct il_priv *il)
}
e = (__le16 *) il->eeprom;
- il->cfg->ops->lib->apm_ops.init(il);
+ il->ops->apm_init(il);
ret = il_eeprom_verify_signature(il);
if (ret < 0) {
@@ -741,7 +739,7 @@ il_eeprom_init(struct il_priv *il)
}
/* Make sure driver (instead of uCode) is allowed to read EEPROM */
- ret = il->cfg->ops->lib->eeprom_ops.acquire_semaphore(il);
+ ret = il->ops->eeprom_acquire_semaphore(il);
if (ret < 0) {
IL_ERR("Failed to acquire EEPROM semaphore.\n");
ret = -ENOENT;
@@ -773,7 +771,7 @@ il_eeprom_init(struct il_priv *il)
ret = 0;
done:
- il->cfg->ops->lib->eeprom_ops.release_semaphore(il);
+ il->ops->eeprom_release_semaphore(il);
err:
if (ret)
@@ -799,8 +797,8 @@ il_init_band_reference(const struct il_priv *il, int eep_band,
const struct il_eeprom_channel **eeprom_ch_info,
const u8 **eeprom_ch_idx)
{
- u32 offset =
- il->cfg->ops->lib->eeprom_ops.regulatory_bands[eep_band - 1];
+ u32 offset = il->cfg->regulatory_bands[eep_band - 1];
+
switch (eep_band) {
case 1: /* 2.4GHz band */
*eeprom_ch_count = ARRAY_SIZE(il_eeprom_band_1);
@@ -1001,10 +999,8 @@ il_init_channel_map(struct il_priv *il)
}
/* Check if we do have HT40 channels */
- if (il->cfg->ops->lib->eeprom_ops.regulatory_bands[5] ==
- EEPROM_REGULATORY_BAND_NO_HT40 &&
- il->cfg->ops->lib->eeprom_ops.regulatory_bands[6] ==
- EEPROM_REGULATORY_BAND_NO_HT40)
+ if (il->cfg->regulatory_bands[5] == EEPROM_REGULATORY_BAND_NO_HT40 &&
+ il->cfg->regulatory_bands[6] == EEPROM_REGULATORY_BAND_NO_HT40)
return 0;
/* Two additional EEPROM bands for 2.4 and 5 GHz HT40 channels */
@@ -1082,29 +1078,82 @@ EXPORT_SYMBOL(il_get_channel_info);
* Setting power level allows the card to go to sleep when not busy.
*
* We calculate a sleep command based on the required latency, which
- * we get from mac80211. In order to handle thermal throttling, we can
- * also use pre-defined power levels.
- */
-
-/*
- * This defines the old power levels. They are still used by default
- * (level 1) and for thermal throttle (levels 3 through 5)
+ * we get from mac80211.
*/
-struct il_power_vec_entry {
- struct il_powertable_cmd cmd;
- u8 no_dtim; /* number of skip dtim */
-};
+#define SLP_VEC(X0, X1, X2, X3, X4) { \
+ cpu_to_le32(X0), \
+ cpu_to_le32(X1), \
+ cpu_to_le32(X2), \
+ cpu_to_le32(X3), \
+ cpu_to_le32(X4) \
+}
static void
-il_power_sleep_cam_cmd(struct il_priv *il, struct il_powertable_cmd *cmd)
+il_build_powertable_cmd(struct il_priv *il, struct il_powertable_cmd *cmd)
{
+ const __le32 interval[3][IL_POWER_VEC_SIZE] = {
+ SLP_VEC(2, 2, 4, 6, 0xFF),
+ SLP_VEC(2, 4, 7, 10, 10),
+ SLP_VEC(4, 7, 10, 10, 0xFF)
+ };
+ int i, dtim_period, no_dtim;
+ u32 max_sleep;
+ bool skip;
+
memset(cmd, 0, sizeof(*cmd));
if (il->power_data.pci_pm)
cmd->flags |= IL_POWER_PCI_PM_MSK;
- D_POWER("Sleep command for CAM\n");
+ /* if no Power Save, we are done */
+ if (il->power_data.ps_disabled)
+ return;
+
+ cmd->flags = IL_POWER_DRIVER_ALLOW_SLEEP_MSK;
+ cmd->keep_alive_seconds = 0;
+ cmd->debug_flags = 0;
+ cmd->rx_data_timeout = cpu_to_le32(25 * 1024);
+ cmd->tx_data_timeout = cpu_to_le32(25 * 1024);
+ cmd->keep_alive_beacons = 0;
+
+ dtim_period = il->vif ? il->vif->bss_conf.dtim_period : 0;
+
+ if (dtim_period <= 2) {
+ memcpy(cmd->sleep_interval, interval[0], sizeof(interval[0]));
+ no_dtim = 2;
+ } else if (dtim_period <= 10) {
+ memcpy(cmd->sleep_interval, interval[1], sizeof(interval[1]));
+ no_dtim = 2;
+ } else {
+ memcpy(cmd->sleep_interval, interval[2], sizeof(interval[2]));
+ no_dtim = 0;
+ }
+
+ if (dtim_period == 0) {
+ dtim_period = 1;
+ skip = false;
+ } else {
+ skip = !!no_dtim;
+ }
+
+ if (skip) {
+ __le32 tmp = cmd->sleep_interval[IL_POWER_VEC_SIZE - 1];
+
+ max_sleep = le32_to_cpu(tmp);
+ if (max_sleep == 0xFF)
+ max_sleep = dtim_period * (skip + 1);
+ else if (max_sleep > dtim_period)
+ max_sleep = (max_sleep / dtim_period) * dtim_period;
+ cmd->flags |= IL_POWER_SLEEP_OVER_DTIM_MSK;
+ } else {
+ max_sleep = dtim_period;
+ cmd->flags &= ~IL_POWER_SLEEP_OVER_DTIM_MSK;
+ }
+
+ for (i = 0; i < IL_POWER_VEC_SIZE; i++)
+ if (le32_to_cpu(cmd->sleep_interval[i]) > max_sleep)
+ cmd->sleep_interval[i] = cpu_to_le32(max_sleep);
}
static int
@@ -1125,7 +1174,7 @@ il_set_power(struct il_priv *il, struct il_powertable_cmd *cmd)
sizeof(struct il_powertable_cmd), cmd);
}
-int
+static int
il_power_set_mode(struct il_priv *il, struct il_powertable_cmd *cmd, bool force)
{
int ret;
@@ -1158,9 +1207,9 @@ il_power_set_mode(struct il_priv *il, struct il_powertable_cmd *cmd, bool force)
if (!(cmd->flags & IL_POWER_DRIVER_ALLOW_SLEEP_MSK))
clear_bit(S_POWER_PMI, &il->status);
- if (il->cfg->ops->lib->update_chain_flags && update_chains)
- il->cfg->ops->lib->update_chain_flags(il);
- else if (il->cfg->ops->lib->update_chain_flags)
+ if (il->ops->update_chain_flags && update_chains)
+ il->ops->update_chain_flags(il);
+ else if (il->ops->update_chain_flags)
D_POWER("Cannot update the power, chain noise "
"calibration running: %d\n",
il->chain_noise_data.state);
@@ -1177,7 +1226,8 @@ il_power_update_mode(struct il_priv *il, bool force)
{
struct il_powertable_cmd cmd;
- il_power_sleep_cam_cmd(il, &cmd);
+ il_build_powertable_cmd(il, &cmd);
+
return il_power_set_mode(il, &cmd, force);
}
EXPORT_SYMBOL(il_power_update_mode);
@@ -1186,9 +1236,10 @@ EXPORT_SYMBOL(il_power_update_mode);
void
il_power_initialize(struct il_priv *il)
{
- u16 lctl = il_pcie_link_ctl(il);
+ u16 lctl;
- il->power_data.pci_pm = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN);
+ pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &lctl);
+ il->power_data.pci_pm = !(lctl & PCI_EXP_LNKCTL_ASPM_L0S);
il->power_data.debug_sleep_level_override = -1;
@@ -1425,7 +1476,7 @@ il_setup_rx_scan_handlers(struct il_priv *il)
}
EXPORT_SYMBOL(il_setup_rx_scan_handlers);
-inline u16
+u16
il_get_active_dwell_time(struct il_priv *il, enum ieee80211_band band,
u8 n_probes)
{
@@ -1442,7 +1493,6 @@ u16
il_get_passive_dwell_time(struct il_priv *il, enum ieee80211_band band,
struct ieee80211_vif *vif)
{
- struct il_rxon_context *ctx = &il->ctx;
u16 value;
u16 passive =
@@ -1457,7 +1507,7 @@ il_get_passive_dwell_time(struct il_priv *il, enum ieee80211_band band,
* dwell time to be 98% of the smallest beacon interval
* (minus 2 * channel tune time)
*/
- value = ctx->vif ? ctx->vif->bss_conf.beacon_int : 0;
+ value = il->vif ? il->vif->bss_conf.beacon_int : 0;
if (value > IL_PASSIVE_DWELL_BASE || !value)
value = IL_PASSIVE_DWELL_BASE;
value = (value * 98) / 100 - IL_CHANNEL_TUNE_TIME * 2;
@@ -1486,9 +1536,6 @@ il_scan_initiate(struct il_priv *il, struct ieee80211_vif *vif)
lockdep_assert_held(&il->mutex);
- if (WARN_ON(!il->cfg->ops->utils->request_scan))
- return -EOPNOTSUPP;
-
cancel_delayed_work(&il->scan_check);
if (!il_is_ready_rf(il)) {
@@ -1511,7 +1558,7 @@ il_scan_initiate(struct il_priv *il, struct ieee80211_vif *vif)
set_bit(S_SCANNING, &il->status);
il->scan_start = jiffies;
- ret = il->cfg->ops->utils->request_scan(il, vif);
+ ret = il->ops->request_scan(il, vif);
if (ret) {
clear_bit(S_SCANNING, &il->status);
return ret;
@@ -1530,12 +1577,13 @@ il_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct il_priv *il = hw->priv;
int ret;
- D_MAC80211("enter\n");
-
- if (req->n_channels == 0)
+ if (req->n_channels == 0) {
+ IL_ERR("Can not scan on no channels.\n");
return -EINVAL;
+ }
mutex_lock(&il->mutex);
+ D_MAC80211("enter\n");
if (test_bit(S_SCANNING, &il->status)) {
D_SCAN("Scan already in progress.\n");
@@ -1550,9 +1598,8 @@ il_mac_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
ret = il_scan_initiate(il, vif);
- D_MAC80211("leave\n");
-
out_unlock:
+ D_MAC80211("leave ret %d\n", ret);
mutex_unlock(&il->mutex);
return ret;
@@ -1593,9 +1640,9 @@ il_fill_probe_req(struct il_priv *il, struct ieee80211_mgmt *frame,
return 0;
frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
- memcpy(frame->da, il_bcast_addr, ETH_ALEN);
+ eth_broadcast_addr(frame->da);
memcpy(frame->sa, ta, ETH_ALEN);
- memcpy(frame->bssid, il_bcast_addr, ETH_ALEN);
+ eth_broadcast_addr(frame->bssid);
frame->seq_ctrl = 0;
len += 24;
@@ -1673,7 +1720,7 @@ out_settings:
il_power_set_mode(il, &il->power_data.sleep_cmd_next, false);
il_set_tx_power(il, il->tx_power_next, false);
- il->cfg->ops->utils->post_scan(il);
+ il->ops->post_scan(il);
out:
mutex_unlock(&il->mutex);
@@ -1815,7 +1862,7 @@ il_send_add_sta(struct il_priv *il, struct il_addsta_cmd *sta, u8 flags)
might_sleep();
}
- cmd.len = il->cfg->ops->utils->build_addsta_hcmd(sta, data);
+ cmd.len = il->ops->build_addsta_hcmd(sta, data);
ret = il_send_cmd(il, &cmd);
if (ret || (flags & CMD_ASYNC))
@@ -1832,37 +1879,34 @@ il_send_add_sta(struct il_priv *il, struct il_addsta_cmd *sta, u8 flags)
EXPORT_SYMBOL(il_send_add_sta);
static void
-il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta,
- struct il_rxon_context *ctx)
+il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta)
{
struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap;
__le32 sta_flags;
- u8 mimo_ps_mode;
if (!sta || !sta_ht_inf->ht_supported)
goto done;
- mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
D_ASSOC("spatial multiplexing power save mode: %s\n",
- (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ? "static" :
- (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ? "dynamic" :
+ (sta->smps_mode == IEEE80211_SMPS_STATIC) ? "static" :
+ (sta->smps_mode == IEEE80211_SMPS_DYNAMIC) ? "dynamic" :
"disabled");
sta_flags = il->stations[idx].sta.station_flags;
sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK);
- switch (mimo_ps_mode) {
- case WLAN_HT_CAP_SM_PS_STATIC:
+ switch (sta->smps_mode) {
+ case IEEE80211_SMPS_STATIC:
sta_flags |= STA_FLG_MIMO_DIS_MSK;
break;
- case WLAN_HT_CAP_SM_PS_DYNAMIC:
+ case IEEE80211_SMPS_DYNAMIC:
sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;
break;
- case WLAN_HT_CAP_SM_PS_DISABLED:
+ case IEEE80211_SMPS_OFF:
break;
default:
- IL_WARN("Invalid MIMO PS mode %d\n", mimo_ps_mode);
+ IL_WARN("Invalid MIMO PS mode %d\n", sta->smps_mode);
break;
}
@@ -1874,7 +1918,7 @@ il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta,
cpu_to_le32((u32) sta_ht_inf->
ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);
- if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap))
+ if (il_is_ht40_tx_allowed(il, &sta->ht_cap))
sta_flags |= STA_FLG_HT40_EN_MSK;
else
sta_flags &= ~STA_FLG_HT40_EN_MSK;
@@ -1890,8 +1934,8 @@ done:
* should be called with sta_lock held
*/
u8
-il_prep_station(struct il_priv *il, struct il_rxon_context *ctx,
- const u8 *addr, bool is_ap, struct ieee80211_sta *sta)
+il_prep_station(struct il_priv *il, const u8 *addr, bool is_ap,
+ struct ieee80211_sta *sta)
{
struct il_station_entry *station;
int i;
@@ -1899,13 +1943,13 @@ il_prep_station(struct il_priv *il, struct il_rxon_context *ctx,
u16 rate;
if (is_ap)
- sta_id = ctx->ap_sta_id;
+ sta_id = IL_AP_ID;
else if (is_broadcast_ether_addr(addr))
- sta_id = ctx->bcast_sta_id;
+ sta_id = il->hw_params.bcast_id;
else
for (i = IL_STA_ID; i < il->hw_params.max_stations; i++) {
- if (!compare_ether_addr
- (il->stations[i].sta.sta.addr, addr)) {
+ if (ether_addr_equal(il->stations[i].sta.sta.addr,
+ addr)) {
sta_id = i;
break;
}
@@ -1934,7 +1978,7 @@ il_prep_station(struct il_priv *il, struct il_rxon_context *ctx,
if ((il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE) &&
(il->stations[sta_id].used & IL_STA_UCODE_ACTIVE) &&
- !compare_ether_addr(il->stations[sta_id].sta.sta.addr, addr)) {
+ ether_addr_equal(il->stations[sta_id].sta.sta.addr, addr)) {
D_ASSOC("STA %d (%pM) already added, not adding again.\n",
sta_id, addr);
return sta_id;
@@ -1950,22 +1994,14 @@ il_prep_station(struct il_priv *il, struct il_rxon_context *ctx,
memcpy(station->sta.sta.addr, addr, ETH_ALEN);
station->sta.mode = 0;
station->sta.sta.sta_id = sta_id;
- station->sta.station_flags = ctx->station_flags;
- station->ctxid = ctx->ctxid;
-
- if (sta) {
- struct il_station_priv_common *sta_priv;
-
- sta_priv = (void *)sta->drv_priv;
- sta_priv->ctx = ctx;
- }
+ station->sta.station_flags = 0;
/*
* OK to call unconditionally, since local stations (IBSS BSSID
* STA and broadcast STA) pass in a NULL sta, and mac80211
* doesn't allow HT IBSS.
*/
- il_set_ht_add_station(il, sta_id, sta, ctx);
+ il_set_ht_add_station(il, sta_id, sta);
/* 3945 only */
rate = (il->band == IEEE80211_BAND_5GHZ) ? RATE_6M_PLCP : RATE_1M_PLCP;
@@ -1983,9 +2019,8 @@ EXPORT_SYMBOL_GPL(il_prep_station);
* il_add_station_common -
*/
int
-il_add_station_common(struct il_priv *il, struct il_rxon_context *ctx,
- const u8 *addr, bool is_ap, struct ieee80211_sta *sta,
- u8 *sta_id_r)
+il_add_station_common(struct il_priv *il, const u8 *addr, bool is_ap,
+ struct ieee80211_sta *sta, u8 *sta_id_r)
{
unsigned long flags_spin;
int ret = 0;
@@ -1994,7 +2029,7 @@ il_add_station_common(struct il_priv *il, struct il_rxon_context *ctx,
*sta_id_r = 0;
spin_lock_irqsave(&il->sta_lock, flags_spin);
- sta_id = il_prep_station(il, ctx, addr, is_ap, sta);
+ sta_id = il_prep_station(il, addr, is_ap, sta);
if (sta_id == IL_INVALID_STATION) {
IL_ERR("Unable to prepare station %pM for addition\n", addr);
spin_unlock_irqrestore(&il->sta_lock, flags_spin);
@@ -2181,7 +2216,7 @@ EXPORT_SYMBOL_GPL(il_remove_station);
* the ucode, e.g. unassociated RXON.
*/
void
-il_clear_ucode_stations(struct il_priv *il, struct il_rxon_context *ctx)
+il_clear_ucode_stations(struct il_priv *il)
{
int i;
unsigned long flags_spin;
@@ -2191,9 +2226,6 @@ il_clear_ucode_stations(struct il_priv *il, struct il_rxon_context *ctx)
spin_lock_irqsave(&il->sta_lock, flags_spin);
for (i = 0; i < il->hw_params.max_stations; i++) {
- if (ctx && ctx->ctxid != il->stations[i].ctxid)
- continue;
-
if (il->stations[i].used & IL_STA_UCODE_ACTIVE) {
D_INFO("Clearing ucode active for station %d\n", i);
il->stations[i].used &= ~IL_STA_UCODE_ACTIVE;
@@ -2216,7 +2248,7 @@ EXPORT_SYMBOL(il_clear_ucode_stations);
* Function sleeps.
*/
void
-il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx)
+il_restore_stations(struct il_priv *il)
{
struct il_addsta_cmd sta_cmd;
struct il_link_quality_cmd lq;
@@ -2234,8 +2266,6 @@ il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx)
D_ASSOC("Restoring all known stations ... start.\n");
spin_lock_irqsave(&il->sta_lock, flags_spin);
for (i = 0; i < il->hw_params.max_stations; i++) {
- if (ctx->ctxid != il->stations[i].ctxid)
- continue;
if ((il->stations[i].used & IL_STA_DRIVER_ACTIVE) &&
!(il->stations[i].used & IL_STA_UCODE_ACTIVE)) {
D_ASSOC("Restoring sta %pM\n",
@@ -2273,7 +2303,7 @@ il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx)
* current LQ command
*/
if (send_lq)
- il_send_lq_cmd(il, ctx, &lq, CMD_SYNC, true);
+ il_send_lq_cmd(il, &lq, CMD_SYNC, true);
spin_lock_irqsave(&il->sta_lock, flags_spin);
il->stations[i].used &= ~IL_STA_UCODE_INPROGRESS;
}
@@ -2353,15 +2383,14 @@ il_dump_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq)
* RXON flags are updated and when LQ command is updated.
*/
static bool
-il_is_lq_table_valid(struct il_priv *il, struct il_rxon_context *ctx,
- struct il_link_quality_cmd *lq)
+il_is_lq_table_valid(struct il_priv *il, struct il_link_quality_cmd *lq)
{
int i;
- if (ctx->ht.enabled)
+ if (il->ht.enabled)
return true;
- D_INFO("Channel %u is not an HT channel\n", ctx->active.channel);
+ D_INFO("Channel %u is not an HT channel\n", il->active.channel);
for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) {
D_INFO("idx %d of LQ expects HT channel\n", i);
@@ -2382,8 +2411,8 @@ il_is_lq_table_valid(struct il_priv *il, struct il_rxon_context *ctx,
* progress.
*/
int
-il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx,
- struct il_link_quality_cmd *lq, u8 flags, bool init)
+il_send_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq,
+ u8 flags, bool init)
{
int ret = 0;
unsigned long flags_spin;
@@ -2408,7 +2437,7 @@ il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx,
il_dump_lq_cmd(il, lq);
BUG_ON(init && (cmd.flags & CMD_ASYNC));
- if (il_is_lq_table_valid(il, ctx, lq))
+ if (il_is_lq_table_valid(il, lq))
ret = il_send_cmd(il, &cmd);
else
ret = -EINVAL;
@@ -2436,13 +2465,16 @@ il_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct il_station_priv_common *sta_common = (void *)sta->drv_priv;
int ret;
- D_INFO("received request to remove station %pM\n", sta->addr);
mutex_lock(&il->mutex);
- D_INFO("proceeding to remove station %pM\n", sta->addr);
+ D_MAC80211("enter station %pM\n", sta->addr);
+
ret = il_remove_station(il, sta_common->sta_id, sta->addr);
if (ret)
IL_ERR("Error removing station %pM\n", sta->addr);
+
+ D_MAC80211("leave ret %d\n", ret);
mutex_unlock(&il->mutex);
+
return ret;
}
EXPORT_SYMBOL(il_mac_sta_remove);
@@ -2587,15 +2619,13 @@ il_rx_queue_alloc(struct il_priv *il)
INIT_LIST_HEAD(&rxq->rx_used);
/* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
- rxq->bd =
- dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->bd_dma,
- GFP_KERNEL);
+ rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->bd_dma,
+ GFP_KERNEL);
if (!rxq->bd)
goto err_bd;
- rxq->rb_stts =
- dma_alloc_coherent(dev, sizeof(struct il_rb_status),
- &rxq->rb_stts_dma, GFP_KERNEL);
+ rxq->rb_stts = dma_alloc_coherent(dev, sizeof(struct il_rb_status),
+ &rxq->rb_stts_dma, GFP_KERNEL);
if (!rxq->rb_stts)
goto err_rb;
@@ -2648,7 +2678,7 @@ il_set_decrypted_flag(struct il_priv *il, struct ieee80211_hdr *hdr,
* All contexts have the same setting here due to it being
* a module parameter, so OK to check any context.
*/
- if (il->ctx.active.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
+ if (il->active.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK)
return 0;
if (!(fc & IEEE80211_FCTL_PROTECTED))
@@ -2739,7 +2769,7 @@ il_tx_queue_unmap(struct il_priv *il, int txq_id)
return;
while (q->write_ptr != q->read_ptr) {
- il->cfg->ops->lib->txq_free_tfd(il, txq);
+ il->ops->txq_free_tfd(il, txq);
q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd);
}
}
@@ -2772,8 +2802,8 @@ il_tx_queue_free(struct il_priv *il, int txq_id)
txq->tfds, txq->q.dma_addr);
/* De-alloc array of per-TFD driver data */
- kfree(txq->txb);
- txq->txb = NULL;
+ kfree(txq->skbs);
+ txq->skbs = NULL;
/* deallocate arrays */
kfree(txq->cmd);
@@ -2907,20 +2937,22 @@ EXPORT_SYMBOL(il_queue_space);
* il_queue_init - Initialize queue's high/low-water and read/write idxes
*/
static int
-il_queue_init(struct il_priv *il, struct il_queue *q, int count, int slots_num,
- u32 id)
+il_queue_init(struct il_priv *il, struct il_queue *q, int slots, u32 id)
{
- q->n_bd = count;
- q->n_win = slots_num;
- q->id = id;
+ /*
+ * TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
+ * il_queue_inc_wrap and il_queue_dec_wrap are broken.
+ */
+ BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
+ /* FIXME: remove q->n_bd */
+ q->n_bd = TFD_QUEUE_SIZE_MAX;
- /* count must be power-of-two size, otherwise il_queue_inc_wrap
- * and il_queue_dec_wrap are broken. */
- BUG_ON(!is_power_of_2(count));
+ q->n_win = slots;
+ q->id = id;
- /* slots_num must be power-of-two size, otherwise
+ /* slots_must be power-of-two size, otherwise
* il_get_cmd_idx is broken. */
- BUG_ON(!is_power_of_2(slots_num));
+ BUG_ON(!is_power_of_2(slots));
q->low_mark = q->n_win / 4;
if (q->low_mark < 4)
@@ -2947,32 +2979,29 @@ il_tx_queue_alloc(struct il_priv *il, struct il_tx_queue *txq, u32 id)
/* Driver ilate data, only for Tx (not command) queues,
* not shared with device. */
if (id != il->cmd_queue) {
- txq->txb = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(txq->txb[0]),
- GFP_KERNEL);
- if (!txq->txb) {
- IL_ERR("kmalloc for auxiliary BD "
- "structures failed\n");
+ txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(struct skb *),
+ GFP_KERNEL);
+ if (!txq->skbs) {
+ IL_ERR("Fail to alloc skbs\n");
goto error;
}
- } else {
- txq->txb = NULL;
- }
+ } else
+ txq->skbs = NULL;
/* Circular buffer of transmit frame descriptors (TFDs),
* shared with device */
txq->tfds =
dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr, GFP_KERNEL);
- if (!txq->tfds) {
- IL_ERR("pci_alloc_consistent(%zd) failed\n", tfd_sz);
+ if (!txq->tfds)
goto error;
- }
+
txq->q.id = id;
return 0;
error:
- kfree(txq->txb);
- txq->txb = NULL;
+ kfree(txq->skbs);
+ txq->skbs = NULL;
return -ENOMEM;
}
@@ -2981,12 +3010,11 @@ error:
* il_tx_queue_init - Allocate and initialize one tx/cmd queue
*/
int
-il_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq, int slots_num,
- u32 txq_id)
+il_tx_queue_init(struct il_priv *il, u32 txq_id)
{
- int i, len;
- int ret;
- int actual_slots = slots_num;
+ int i, len, ret;
+ int slots, actual_slots;
+ struct il_tx_queue *txq = &il->txq[txq_id];
/*
* Alloc buffer array for commands (Tx or other types of commands).
@@ -2996,8 +3024,13 @@ il_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq, int slots_num,
* For normal Tx queues (all other queues), no super-size command
* space is needed.
*/
- if (txq_id == il->cmd_queue)
- actual_slots++;
+ if (txq_id == il->cmd_queue) {
+ slots = TFD_CMD_SLOTS;
+ actual_slots = slots + 1;
+ } else {
+ slots = TFD_TX_CMD_SLOTS;
+ actual_slots = slots;
+ }
txq->meta =
kzalloc(sizeof(struct il_cmd_meta) * actual_slots, GFP_KERNEL);
@@ -3010,7 +3043,7 @@ il_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq, int slots_num,
len = sizeof(struct il_device_cmd);
for (i = 0; i < actual_slots; i++) {
/* only happens for cmd queue */
- if (i == slots_num)
+ if (i == slots)
len = IL_MAX_CMD_SIZE;
txq->cmd[i] = kmalloc(len, GFP_KERNEL);
@@ -3033,15 +3066,11 @@ il_tx_queue_init(struct il_priv *il, struct il_tx_queue *txq, int slots_num,
if (txq_id < 4)
il_set_swq_id(txq, txq_id, txq_id);
- /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
- * il_queue_inc_wrap and il_queue_dec_wrap are broken. */
- BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
-
/* Initialize queue's high/low-water marks, and head/tail idxes */
- il_queue_init(il, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
+ il_queue_init(il, &txq->q, slots, txq_id);
/* Tell device where to find queue */
- il->cfg->ops->lib->txq_init(il, txq);
+ il->ops->txq_init(il, txq);
return 0;
err:
@@ -3056,23 +3085,27 @@ out_free_arrays:
EXPORT_SYMBOL(il_tx_queue_init);
void
-il_tx_queue_reset(struct il_priv *il, struct il_tx_queue *txq, int slots_num,
- u32 txq_id)
+il_tx_queue_reset(struct il_priv *il, u32 txq_id)
{
- int actual_slots = slots_num;
+ int slots, actual_slots;
+ struct il_tx_queue *txq = &il->txq[txq_id];
- if (txq_id == il->cmd_queue)
- actual_slots++;
+ if (txq_id == il->cmd_queue) {
+ slots = TFD_CMD_SLOTS;
+ actual_slots = TFD_CMD_SLOTS + 1;
+ } else {
+ slots = TFD_TX_CMD_SLOTS;
+ actual_slots = TFD_TX_CMD_SLOTS;
+ }
memset(txq->meta, 0, sizeof(struct il_cmd_meta) * actual_slots);
-
txq->need_update = 0;
/* Initialize queue's high/low-water marks, and head/tail idxes */
- il_queue_init(il, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
+ il_queue_init(il, &txq->q, slots, txq_id);
/* Tell device where to find queue */
- il->cfg->ops->lib->txq_init(il, txq);
+ il->ops->txq_init(il, txq);
}
EXPORT_SYMBOL(il_tx_queue_reset);
@@ -3100,7 +3133,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
u32 idx;
u16 fix_size;
- cmd->len = il->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len);
+ cmd->len = il->ops->get_hcmd_size(cmd->id, cmd->len);
fix_size = (u16) (cmd->len + sizeof(out_cmd->hdr));
/* If any of the command structures end up being larger than
@@ -3177,25 +3210,31 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
idx, il->cmd_queue);
}
#endif
- txq->need_update = 1;
-
- if (il->cfg->ops->lib->txq_update_byte_cnt_tbl)
- /* Set up entry in queue's byte count circular buffer */
- il->cfg->ops->lib->txq_update_byte_cnt_tbl(il, txq, 0);
phys_addr =
pci_map_single(il->pci_dev, &out_cmd->hdr, fix_size,
PCI_DMA_BIDIRECTIONAL);
+ if (unlikely(pci_dma_mapping_error(il->pci_dev, phys_addr))) {
+ idx = -ENOMEM;
+ goto out;
+ }
dma_unmap_addr_set(out_meta, mapping, phys_addr);
dma_unmap_len_set(out_meta, len, fix_size);
- il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, fix_size,
- 1, U32_PAD(cmd->len));
+ txq->need_update = 1;
+
+ if (il->ops->txq_update_byte_cnt_tbl)
+ /* Set up entry in queue's byte count circular buffer */
+ il->ops->txq_update_byte_cnt_tbl(il, txq, 0);
+
+ il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, fix_size, 1,
+ U32_PAD(cmd->len));
/* Increment and update queue's write idx */
q->write_ptr = il_queue_inc_wrap(q->write_ptr, q->n_bd);
il_txq_update_write_ptr(il, txq);
+out:
spin_unlock_irqrestore(&il->hcmd_lock, flags);
return idx;
}
@@ -3332,30 +3371,6 @@ EXPORT_SYMBOL(il_debug_level);
const u8 il_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
EXPORT_SYMBOL(il_bcast_addr);
-/* This function both allocates and initializes hw and il. */
-struct ieee80211_hw *
-il_alloc_all(struct il_cfg *cfg)
-{
- struct il_priv *il;
- /* mac80211 allocates memory for this device instance, including
- * space for this driver's ilate structure */
- struct ieee80211_hw *hw;
-
- hw = ieee80211_alloc_hw(sizeof(struct il_priv),
- cfg->ops->ieee80211_ops);
- if (hw == NULL) {
- pr_err("%s: Can not allocate network device\n", cfg->name);
- goto out;
- }
-
- il = hw->priv;
- il->hw = hw;
-
-out:
- return hw;
-}
-EXPORT_SYMBOL(il_alloc_all);
-
#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
static void
@@ -3483,10 +3498,10 @@ il_init_geos(struct il_priv *il)
if (il_is_channel_valid(ch)) {
if (!(ch->flags & EEPROM_CHANNEL_IBSS))
- geo_ch->flags |= IEEE80211_CHAN_NO_IBSS;
+ geo_ch->flags |= IEEE80211_CHAN_NO_IR;
if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
- geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
+ geo_ch->flags |= IEEE80211_CHAN_NO_IR;
if (ch->flags & EEPROM_CHANNEL_RADAR)
geo_ch->flags |= IEEE80211_CHAN_RADAR;
@@ -3562,10 +3577,9 @@ il_is_channel_extension(struct il_priv *il, enum ieee80211_band band,
}
bool
-il_is_ht40_tx_allowed(struct il_priv *il, struct il_rxon_context *ctx,
- struct ieee80211_sta_ht_cap *ht_cap)
+il_is_ht40_tx_allowed(struct il_priv *il, struct ieee80211_sta_ht_cap *ht_cap)
{
- if (!ctx->ht.enabled || !ctx->ht.is_40mhz)
+ if (!il->ht.enabled || !il->ht.is_40mhz)
return false;
/*
@@ -3581,8 +3595,8 @@ il_is_ht40_tx_allowed(struct il_priv *il, struct il_rxon_context *ctx,
#endif
return il_is_channel_extension(il, il->band,
- le16_to_cpu(ctx->staging.channel),
- ctx->ht.extension_chan_offset);
+ le16_to_cpu(il->staging.channel),
+ il->ht.extension_chan_offset);
}
EXPORT_SYMBOL(il_is_ht40_tx_allowed);
@@ -3621,22 +3635,22 @@ il_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
}
int
-il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx)
+il_send_rxon_timing(struct il_priv *il)
{
u64 tsf;
s32 interval_tm, rem;
struct ieee80211_conf *conf = NULL;
u16 beacon_int;
- struct ieee80211_vif *vif = ctx->vif;
+ struct ieee80211_vif *vif = il->vif;
conf = &il->hw->conf;
lockdep_assert_held(&il->mutex);
- memset(&ctx->timing, 0, sizeof(struct il_rxon_time_cmd));
+ memset(&il->timing, 0, sizeof(struct il_rxon_time_cmd));
- ctx->timing.timestamp = cpu_to_le64(il->timestamp);
- ctx->timing.listen_interval = cpu_to_le16(conf->listen_interval);
+ il->timing.timestamp = cpu_to_le64(il->timestamp);
+ il->timing.listen_interval = cpu_to_le16(conf->listen_interval);
beacon_int = vif ? vif->bss_conf.beacon_int : 0;
@@ -3644,36 +3658,35 @@ il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx)
* TODO: For IBSS we need to get atim_win from mac80211,
* for now just always use 0
*/
- ctx->timing.atim_win = 0;
+ il->timing.atim_win = 0;
beacon_int =
il_adjust_beacon_interval(beacon_int,
il->hw_params.max_beacon_itrvl *
TIME_UNIT);
- ctx->timing.beacon_interval = cpu_to_le16(beacon_int);
+ il->timing.beacon_interval = cpu_to_le16(beacon_int);
tsf = il->timestamp; /* tsf is modifed by do_div: copy it */
interval_tm = beacon_int * TIME_UNIT;
rem = do_div(tsf, interval_tm);
- ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
+ il->timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
- ctx->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ? : 1) : 1;
+ il->timing.dtim_period = vif ? (vif->bss_conf.dtim_period ? : 1) : 1;
D_ASSOC("beacon interval %d beacon timer %d beacon tim %d\n",
- le16_to_cpu(ctx->timing.beacon_interval),
- le32_to_cpu(ctx->timing.beacon_init_val),
- le16_to_cpu(ctx->timing.atim_win));
+ le16_to_cpu(il->timing.beacon_interval),
+ le32_to_cpu(il->timing.beacon_init_val),
+ le16_to_cpu(il->timing.atim_win));
- return il_send_cmd_pdu(il, ctx->rxon_timing_cmd, sizeof(ctx->timing),
- &ctx->timing);
+ return il_send_cmd_pdu(il, C_RXON_TIMING, sizeof(il->timing),
+ &il->timing);
}
EXPORT_SYMBOL(il_send_rxon_timing);
void
-il_set_rxon_hwcrypto(struct il_priv *il, struct il_rxon_context *ctx,
- int hw_decrypt)
+il_set_rxon_hwcrypto(struct il_priv *il, int hw_decrypt)
{
- struct il_rxon_cmd *rxon = &ctx->staging;
+ struct il_rxon_cmd *rxon = &il->staging;
if (hw_decrypt)
rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
@@ -3685,9 +3698,9 @@ EXPORT_SYMBOL(il_set_rxon_hwcrypto);
/* validate RXON structure is valid */
int
-il_check_rxon_cmd(struct il_priv *il, struct il_rxon_context *ctx)
+il_check_rxon_cmd(struct il_priv *il)
{
- struct il_rxon_cmd *rxon = &ctx->staging;
+ struct il_rxon_cmd *rxon = &il->staging;
bool error = false;
if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
@@ -3765,10 +3778,10 @@ EXPORT_SYMBOL(il_check_rxon_cmd);
* a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
*/
int
-il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx)
+il_full_rxon_required(struct il_priv *il)
{
- const struct il_rxon_cmd *staging = &ctx->staging;
- const struct il_rxon_cmd *active = &ctx->active;
+ const struct il_rxon_cmd *staging = &il->staging;
+ const struct il_rxon_cmd *active = &il->active;
#define CHK(cond) \
if ((cond)) { \
@@ -3785,11 +3798,11 @@ il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx)
}
/* These items are only settable from the full RXON command */
- CHK(!il_is_associated_ctx(ctx));
- CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr));
- CHK(compare_ether_addr(staging->node_addr, active->node_addr));
- CHK(compare_ether_addr
- (staging->wlap_bssid_addr, active->wlap_bssid_addr));
+ CHK(!il_is_associated(il));
+ CHK(!ether_addr_equal_64bits(staging->bssid_addr, active->bssid_addr));
+ CHK(!ether_addr_equal_64bits(staging->node_addr, active->node_addr));
+ CHK(!ether_addr_equal_64bits(staging->wlap_bssid_addr,
+ active->wlap_bssid_addr));
CHK_NEQ(staging->dev_type, active->dev_type);
CHK_NEQ(staging->channel, active->channel);
CHK_NEQ(staging->air_propagation, active->air_propagation);
@@ -3819,13 +3832,13 @@ il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx)
EXPORT_SYMBOL(il_full_rxon_required);
u8
-il_get_lowest_plcp(struct il_priv *il, struct il_rxon_context *ctx)
+il_get_lowest_plcp(struct il_priv *il)
{
/*
* Assign the lowest rate -- should really get this from
* the beacon skb from mac80211.
*/
- if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK)
+ if (il->staging.flags & RXON_FLG_BAND_24G_MSK)
return RATE_1M_PLCP;
else
return RATE_6M_PLCP;
@@ -3833,12 +3846,11 @@ il_get_lowest_plcp(struct il_priv *il, struct il_rxon_context *ctx)
EXPORT_SYMBOL(il_get_lowest_plcp);
static void
-_il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf,
- struct il_rxon_context *ctx)
+_il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf)
{
- struct il_rxon_cmd *rxon = &ctx->staging;
+ struct il_rxon_cmd *rxon = &il->staging;
- if (!ctx->ht.enabled) {
+ if (!il->ht.enabled) {
rxon->flags &=
~(RXON_FLG_CHANNEL_MODE_MSK |
RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | RXON_FLG_HT40_PROT_MSK
@@ -3847,19 +3859,19 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf,
}
rxon->flags |=
- cpu_to_le32(ctx->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS);
+ cpu_to_le32(il->ht.protection << RXON_FLG_HT_OPERATING_MODE_POS);
/* Set up channel bandwidth:
* 20 MHz only, 20/40 mixed or pure 40 if ht40 ok */
/* clear the HT channel mode before set the mode */
rxon->flags &=
~(RXON_FLG_CHANNEL_MODE_MSK | RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
- if (il_is_ht40_tx_allowed(il, ctx, NULL)) {
+ if (il_is_ht40_tx_allowed(il, NULL)) {
/* pure ht40 */
- if (ctx->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
+ if (il->ht.protection == IEEE80211_HT_OP_MODE_PROTECTION_20MHZ) {
rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40;
/* Note: control channel is opposite of extension channel */
- switch (ctx->ht.extension_chan_offset) {
+ switch (il->ht.extension_chan_offset) {
case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
rxon->flags &=
~RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
@@ -3870,7 +3882,7 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf,
}
} else {
/* Note: control channel is opposite of extension channel */
- switch (ctx->ht.extension_chan_offset) {
+ switch (il->ht.extension_chan_offset) {
case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
rxon->flags &=
~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
@@ -3891,18 +3903,18 @@ _il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf,
rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY;
}
- if (il->cfg->ops->hcmd->set_rxon_chain)
- il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
+ if (il->ops->set_rxon_chain)
+ il->ops->set_rxon_chain(il);
D_ASSOC("rxon flags 0x%X operation mode :0x%X "
"extension channel offset 0x%x\n", le32_to_cpu(rxon->flags),
- ctx->ht.protection, ctx->ht.extension_chan_offset);
+ il->ht.protection, il->ht.extension_chan_offset);
}
void
il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf)
{
- _il_set_rxon_ht(il, ht_conf, &il->ctx);
+ _il_set_rxon_ht(il, ht_conf);
}
EXPORT_SYMBOL(il_set_rxon_ht);
@@ -3925,7 +3937,7 @@ il_get_single_channel_number(struct il_priv *il, enum ieee80211_band band)
for (i = min; i < max; i++) {
channel = il->channel_info[i].channel;
- if (channel == le16_to_cpu(il->ctx.staging.channel))
+ if (channel == le16_to_cpu(il->staging.channel))
continue;
ch_info = il_get_channel_info(il, band, channel);
@@ -3945,20 +3957,19 @@ EXPORT_SYMBOL(il_get_single_channel_number);
* in the staging RXON flag structure based on the ch->band
*/
int
-il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch,
- struct il_rxon_context *ctx)
+il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch)
{
enum ieee80211_band band = ch->band;
u16 channel = ch->hw_value;
- if (le16_to_cpu(ctx->staging.channel) == channel && il->band == band)
+ if (le16_to_cpu(il->staging.channel) == channel && il->band == band)
return 0;
- ctx->staging.channel = cpu_to_le16(channel);
+ il->staging.channel = cpu_to_le16(channel);
if (band == IEEE80211_BAND_5GHZ)
- ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK;
+ il->staging.flags &= ~RXON_FLG_BAND_24G_MSK;
else
- ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
+ il->staging.flags |= RXON_FLG_BAND_24G_MSK;
il->band = band;
@@ -3969,24 +3980,24 @@ il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch,
EXPORT_SYMBOL(il_set_rxon_channel);
void
-il_set_flags_for_band(struct il_priv *il, struct il_rxon_context *ctx,
- enum ieee80211_band band, struct ieee80211_vif *vif)
+il_set_flags_for_band(struct il_priv *il, enum ieee80211_band band,
+ struct ieee80211_vif *vif)
{
if (band == IEEE80211_BAND_5GHZ) {
- ctx->staging.flags &=
+ il->staging.flags &=
~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK |
RXON_FLG_CCK_MSK);
- ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
} else {
/* Copied from il_post_associate() */
if (vif && vif->bss_conf.use_short_slot)
- ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
+ il->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
- ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
+ il->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
- ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
- ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK;
- ctx->staging.flags &= ~RXON_FLG_CCK_MSK;
+ il->staging.flags |= RXON_FLG_BAND_24G_MSK;
+ il->staging.flags |= RXON_FLG_AUTO_DETECT_MSK;
+ il->staging.flags &= ~RXON_FLG_CCK_MSK;
}
}
EXPORT_SYMBOL(il_set_flags_for_band);
@@ -3995,69 +4006,64 @@ EXPORT_SYMBOL(il_set_flags_for_band);
* initialize rxon structure with default values from eeprom
*/
void
-il_connection_init_rx_config(struct il_priv *il, struct il_rxon_context *ctx)
+il_connection_init_rx_config(struct il_priv *il)
{
const struct il_channel_info *ch_info;
- memset(&ctx->staging, 0, sizeof(ctx->staging));
+ memset(&il->staging, 0, sizeof(il->staging));
- if (!ctx->vif) {
- ctx->staging.dev_type = ctx->unused_devtype;
- } else
- switch (ctx->vif->type) {
-
- case NL80211_IFTYPE_STATION:
- ctx->staging.dev_type = ctx->station_devtype;
- ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
- break;
-
- case NL80211_IFTYPE_ADHOC:
- ctx->staging.dev_type = ctx->ibss_devtype;
- ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
- ctx->staging.filter_flags =
- RXON_FILTER_BCON_AWARE_MSK |
- RXON_FILTER_ACCEPT_GRP_MSK;
- break;
-
- default:
- IL_ERR("Unsupported interface type %d\n",
- ctx->vif->type);
- break;
- }
+ switch (il->iw_mode) {
+ case NL80211_IFTYPE_UNSPECIFIED:
+ il->staging.dev_type = RXON_DEV_TYPE_ESS;
+ break;
+ case NL80211_IFTYPE_STATION:
+ il->staging.dev_type = RXON_DEV_TYPE_ESS;
+ il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ il->staging.dev_type = RXON_DEV_TYPE_IBSS;
+ il->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
+ il->staging.filter_flags =
+ RXON_FILTER_BCON_AWARE_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
+ break;
+ default:
+ IL_ERR("Unsupported interface type %d\n", il->vif->type);
+ return;
+ }
#if 0
/* TODO: Figure out when short_preamble would be set and cache from
* that */
if (!hw_to_local(il->hw)->short_preamble)
- ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
else
- ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
#endif
ch_info =
- il_get_channel_info(il, il->band, le16_to_cpu(ctx->active.channel));
+ il_get_channel_info(il, il->band, le16_to_cpu(il->active.channel));
if (!ch_info)
ch_info = &il->channel_info[0];
- ctx->staging.channel = cpu_to_le16(ch_info->channel);
+ il->staging.channel = cpu_to_le16(ch_info->channel);
il->band = ch_info->band;
- il_set_flags_for_band(il, ctx, il->band, ctx->vif);
+ il_set_flags_for_band(il, il->band, il->vif);
- ctx->staging.ofdm_basic_rates =
+ il->staging.ofdm_basic_rates =
(IL_OFDM_RATES_MASK >> IL_FIRST_OFDM_RATE) & 0xFF;
- ctx->staging.cck_basic_rates =
+ il->staging.cck_basic_rates =
(IL_CCK_RATES_MASK >> IL_FIRST_CCK_RATE) & 0xF;
/* clear both MIX and PURE40 mode flag */
- ctx->staging.flags &=
+ il->staging.flags &=
~(RXON_FLG_CHANNEL_MODE_MIXED | RXON_FLG_CHANNEL_MODE_PURE_40);
- if (ctx->vif)
- memcpy(ctx->staging.node_addr, ctx->vif->addr, ETH_ALEN);
+ if (il->vif)
+ memcpy(il->staging.node_addr, il->vif->addr, ETH_ALEN);
- ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff;
- ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff;
+ il->staging.ofdm_ht_single_stream_basic_rates = 0xff;
+ il->staging.ofdm_ht_dual_stream_basic_rates = 0xff;
}
EXPORT_SYMBOL(il_connection_init_rx_config);
@@ -4084,10 +4090,10 @@ il_set_rate(struct il_priv *il)
D_RATE("Set active_rate = %0x\n", il->active_rate);
- il->ctx.staging.cck_basic_rates =
+ il->staging.cck_basic_rates =
(IL_CCK_BASIC_RATES_MASK >> IL_FIRST_CCK_RATE) & 0xF;
- il->ctx.staging.ofdm_basic_rates =
+ il->staging.ofdm_basic_rates =
(IL_OFDM_BASIC_RATES_MASK >> IL_FIRST_OFDM_RATE) & 0xFF;
}
EXPORT_SYMBOL(il_set_rate);
@@ -4095,13 +4101,11 @@ EXPORT_SYMBOL(il_set_rate);
void
il_chswitch_done(struct il_priv *il, bool is_success)
{
- struct il_rxon_context *ctx = &il->ctx;
-
if (test_bit(S_EXIT_PENDING, &il->status))
return;
if (test_and_clear_bit(S_CHANNEL_SWITCH_PENDING, &il->status))
- ieee80211_chswitch_done(ctx->vif, is_success);
+ ieee80211_chswitch_done(il->vif, is_success);
}
EXPORT_SYMBOL(il_chswitch_done);
@@ -4110,16 +4114,14 @@ il_hdl_csa(struct il_priv *il, struct il_rx_buf *rxb)
{
struct il_rx_pkt *pkt = rxb_addr(rxb);
struct il_csa_notification *csa = &(pkt->u.csa_notif);
-
- struct il_rxon_context *ctx = &il->ctx;
- struct il_rxon_cmd *rxon = (void *)&ctx->active;
+ struct il_rxon_cmd *rxon = (void *)&il->active;
if (!test_bit(S_CHANNEL_SWITCH_PENDING, &il->status))
return;
if (!le32_to_cpu(csa->status) && csa->channel == il->switch_channel) {
rxon->channel = csa->channel;
- ctx->staging.channel = csa->channel;
+ il->staging.channel = csa->channel;
D_11H("CSA notif: channel %d\n", le16_to_cpu(csa->channel));
il_chswitch_done(il, true);
} else {
@@ -4132,9 +4134,9 @@ EXPORT_SYMBOL(il_hdl_csa);
#ifdef CONFIG_IWLEGACY_DEBUG
void
-il_print_rx_config_cmd(struct il_priv *il, struct il_rxon_context *ctx)
+il_print_rx_config_cmd(struct il_priv *il)
{
- struct il_rxon_cmd *rxon = &ctx->staging;
+ struct il_rxon_cmd *rxon = &il->staging;
D_RADIO("RX CONFIG:\n");
il_print_hex_dump(il, IL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
@@ -4164,12 +4166,12 @@ il_irq_handle_error(struct il_priv *il)
IL_ERR("Loaded firmware version: %s\n", il->hw->wiphy->fw_version);
- il->cfg->ops->lib->dump_nic_error_log(il);
- if (il->cfg->ops->lib->dump_fh)
- il->cfg->ops->lib->dump_fh(il, NULL, false);
+ il->ops->dump_nic_error_log(il);
+ if (il->ops->dump_fh)
+ il->ops->dump_fh(il, NULL, false);
#ifdef CONFIG_IWLEGACY_DEBUG
if (il_get_debug_level(il) & IL_DL_FW_ERRORS)
- il_print_rx_config_cmd(il, &il->ctx);
+ il_print_rx_config_cmd(il);
#endif
wake_up(&il->wait_command_queue);
@@ -4189,17 +4191,17 @@ il_irq_handle_error(struct il_priv *il)
EXPORT_SYMBOL(il_irq_handle_error);
static int
-il_apm_stop_master(struct il_priv *il)
+_il_apm_stop_master(struct il_priv *il)
{
int ret = 0;
/* stop device's busmaster DMA activity */
- il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
+ _il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
ret =
_il_poll_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED,
CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
- if (ret)
+ if (ret < 0)
IL_WARN("Master Disable Timed Out, 100 usec\n");
D_INFO("stop master\n");
@@ -4208,15 +4210,17 @@ il_apm_stop_master(struct il_priv *il)
}
void
-il_apm_stop(struct il_priv *il)
+_il_apm_stop(struct il_priv *il)
{
+ lockdep_assert_held(&il->reg_lock);
+
D_INFO("Stop card, put in low power state\n");
/* Stop device's DMA activity */
- il_apm_stop_master(il);
+ _il_apm_stop_master(il);
/* Reset the entire device */
- il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+ _il_set_bit(il, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
udelay(10);
@@ -4224,7 +4228,18 @@ il_apm_stop(struct il_priv *il)
* Clear "initialization complete" bit to move adapter from
* D0A* (powered-up Active) --> D0U* (Uninitialized) state.
*/
- il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+ _il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+}
+EXPORT_SYMBOL(_il_apm_stop);
+
+void
+il_apm_stop(struct il_priv *il)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&il->reg_lock, flags);
+ _il_apm_stop(il);
+ spin_unlock_irqrestore(&il->reg_lock, flags);
}
EXPORT_SYMBOL(il_apm_stop);
@@ -4276,10 +4291,9 @@ il_apm_init(struct il_priv *il)
* If not (unlikely), enable L0S, so there is at least some
* power savings, even without L1.
*/
- if (il->cfg->base_params->set_l0s) {
- lctl = il_pcie_link_ctl(il);
- if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
- PCI_CFG_LINK_CTRL_VAL_L1_EN) {
+ if (il->cfg->set_l0s) {
+ pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &lctl);
+ if (lctl & PCI_EXP_LNKCTL_ASPM_L1) {
/* L1-ASPM enabled; disable(!) L0S */
il_set_bit(il, CSR_GIO_REG,
CSR_GIO_REG_VAL_L0S_ENABLED);
@@ -4293,9 +4307,9 @@ il_apm_init(struct il_priv *il)
}
/* Configure analog phase-lock-loop before activating to D0A */
- if (il->cfg->base_params->pll_cfg_val)
+ if (il->cfg->pll_cfg_val)
il_set_bit(il, CSR_ANA_PLL_CFG,
- il->cfg->base_params->pll_cfg_val);
+ il->cfg->pll_cfg_val);
/*
* Set "initialization complete" bit to move adapter from
@@ -4325,7 +4339,7 @@ il_apm_init(struct il_priv *il)
* do not disable clocks. This preserves any hardware bits already
* set by default in "CLK_CTRL_REG" after reset.
*/
- if (il->cfg->base_params->use_bsm)
+ if (il->cfg->use_bsm)
il_wr_prph(il, APMG_CLK_EN_REG,
APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT);
else
@@ -4347,14 +4361,13 @@ il_set_tx_power(struct il_priv *il, s8 tx_power, bool force)
int ret;
s8 prev_tx_power;
bool defer;
- struct il_rxon_context *ctx = &il->ctx;
lockdep_assert_held(&il->mutex);
if (il->tx_power_user_lmt == tx_power && !force)
return 0;
- if (!il->cfg->ops->lib->send_tx_power)
+ if (!il->ops->send_tx_power)
return -EOPNOTSUPP;
/* 0 dBm mean 1 milliwatt */
@@ -4378,7 +4391,7 @@ il_set_tx_power(struct il_priv *il, s8 tx_power, bool force)
/* do not set tx power when scanning or channel changing */
defer = test_bit(S_SCANNING, &il->status) ||
- memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging));
+ memcmp(&il->active, &il->staging, sizeof(il->staging));
if (defer && !force) {
D_INFO("Deferring tx power set\n");
return 0;
@@ -4387,7 +4400,7 @@ il_set_tx_power(struct il_priv *il, s8 tx_power, bool force)
prev_tx_power = il->tx_power_user_lmt;
il->tx_power_user_lmt = tx_power;
- ret = il->cfg->ops->lib->send_tx_power(il);
+ ret = il->ops->send_tx_power(il);
/* if fail to set tx_power, restore the orig. tx power */
if (ret) {
@@ -4505,15 +4518,15 @@ il_mac_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
spin_lock_irqsave(&il->lock, flags);
- il->ctx.qos_data.def_qos_parm.ac[q].cw_min =
+ il->qos_data.def_qos_parm.ac[q].cw_min =
cpu_to_le16(params->cw_min);
- il->ctx.qos_data.def_qos_parm.ac[q].cw_max =
+ il->qos_data.def_qos_parm.ac[q].cw_max =
cpu_to_le16(params->cw_max);
- il->ctx.qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
- il->ctx.qos_data.def_qos_parm.ac[q].edca_txop =
+ il->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
+ il->qos_data.def_qos_parm.ac[q].edca_txop =
cpu_to_le16((params->txop * 32));
- il->ctx.qos_data.def_qos_parm.ac[q].reserved1 = 0;
+ il->qos_data.def_qos_parm.ac[q].reserved1 = 0;
spin_unlock_irqrestore(&il->lock, flags);
@@ -4526,60 +4539,37 @@ int
il_mac_tx_last_beacon(struct ieee80211_hw *hw)
{
struct il_priv *il = hw->priv;
+ int ret;
- return il->ibss_manager == IL_IBSS_MANAGER;
-}
-EXPORT_SYMBOL_GPL(il_mac_tx_last_beacon);
-
-static int
-il_set_mode(struct il_priv *il, struct il_rxon_context *ctx)
-{
- il_connection_init_rx_config(il, ctx);
+ D_MAC80211("enter\n");
- if (il->cfg->ops->hcmd->set_rxon_chain)
- il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
+ ret = (il->ibss_manager == IL_IBSS_MANAGER);
- return il_commit_rxon(il, ctx);
+ D_MAC80211("leave ret %d\n", ret);
+ return ret;
}
+EXPORT_SYMBOL_GPL(il_mac_tx_last_beacon);
static int
-il_setup_interface(struct il_priv *il, struct il_rxon_context *ctx)
+il_set_mode(struct il_priv *il)
{
- struct ieee80211_vif *vif = ctx->vif;
- int err;
-
- lockdep_assert_held(&il->mutex);
-
- /*
- * This variable will be correct only when there's just
- * a single context, but all code using it is for hardware
- * that supports only one context.
- */
- il->iw_mode = vif->type;
-
- ctx->is_active = true;
+ il_connection_init_rx_config(il);
- err = il_set_mode(il, ctx);
- if (err) {
- if (!ctx->always_active)
- ctx->is_active = false;
- return err;
- }
+ if (il->ops->set_rxon_chain)
+ il->ops->set_rxon_chain(il);
- return 0;
+ return il_commit_rxon(il);
}
int
il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
struct il_priv *il = hw->priv;
- struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
int err;
- u32 modes;
-
- D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr);
+ bool reset;
mutex_lock(&il->mutex);
+ D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr);
if (!il_is_ready_rf(il)) {
IL_WARN("Try to add interface when device not ready\n");
@@ -4587,42 +4577,39 @@ il_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
goto out;
}
- /* check if busy context is exclusive */
- if (il->ctx.vif &&
- (il->ctx.exclusive_interface_modes & BIT(il->ctx.vif->type))) {
- err = -EINVAL;
- goto out;
- }
-
- modes = il->ctx.interface_modes | il->ctx.exclusive_interface_modes;
- if (!(modes & BIT(vif->type))) {
+ /*
+ * We do not support multiple virtual interfaces, but on hardware reset
+ * we have to add the same interface again.
+ */
+ reset = (il->vif == vif);
+ if (il->vif && !reset) {
err = -EOPNOTSUPP;
goto out;
}
- vif_priv->ctx = &il->ctx;
- il->ctx.vif = vif;
+ il->vif = vif;
+ il->iw_mode = vif->type;
- err = il_setup_interface(il, &il->ctx);
+ err = il_set_mode(il);
if (err) {
- il->ctx.vif = NULL;
- il->iw_mode = NL80211_IFTYPE_STATION;
+ IL_WARN("Fail to set mode %d\n", vif->type);
+ if (!reset) {
+ il->vif = NULL;
+ il->iw_mode = NL80211_IFTYPE_STATION;
+ }
}
out:
+ D_MAC80211("leave err %d\n", err);
mutex_unlock(&il->mutex);
- D_MAC80211("leave\n");
return err;
}
EXPORT_SYMBOL(il_mac_add_interface);
static void
-il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif,
- bool mode_change)
+il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif)
{
- struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
-
lockdep_assert_held(&il->mutex);
if (il->scan_vif == vif) {
@@ -4630,33 +4617,25 @@ il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif,
il_force_scan_end(il);
}
- if (!mode_change) {
- il_set_mode(il, ctx);
- if (!ctx->always_active)
- ctx->is_active = false;
- }
+ il_set_mode(il);
}
void
il_mac_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
struct il_priv *il = hw->priv;
- struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
-
- D_MAC80211("enter\n");
mutex_lock(&il->mutex);
+ D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr);
- WARN_ON(ctx->vif != vif);
- ctx->vif = NULL;
-
- il_teardown_interface(il, vif, false);
-
+ WARN_ON(il->vif != vif);
+ il->vif = NULL;
+ il->iw_mode = NL80211_IFTYPE_UNSPECIFIED;
+ il_teardown_interface(il, vif);
memset(il->bssid, 0, ETH_ALEN);
- mutex_unlock(&il->mutex);
D_MAC80211("leave\n");
-
+ mutex_unlock(&il->mutex);
}
EXPORT_SYMBOL(il_mac_remove_interface);
@@ -4666,7 +4645,7 @@ il_alloc_txq_mem(struct il_priv *il)
if (!il->txq)
il->txq =
kzalloc(sizeof(struct il_tx_queue) *
- il->cfg->base_params->num_of_queues, GFP_KERNEL);
+ il->cfg->num_of_queues, GFP_KERNEL);
if (!il->txq) {
IL_ERR("Not enough memory for txq\n");
return -ENOMEM;
@@ -4676,259 +4655,12 @@ il_alloc_txq_mem(struct il_priv *il)
EXPORT_SYMBOL(il_alloc_txq_mem);
void
-il_txq_mem(struct il_priv *il)
+il_free_txq_mem(struct il_priv *il)
{
kfree(il->txq);
il->txq = NULL;
}
-EXPORT_SYMBOL(il_txq_mem);
-
-#ifdef CONFIG_IWLEGACY_DEBUGFS
-
-#define IL_TRAFFIC_DUMP_SIZE (IL_TRAFFIC_ENTRY_SIZE * IL_TRAFFIC_ENTRIES)
-
-void
-il_reset_traffic_log(struct il_priv *il)
-{
- il->tx_traffic_idx = 0;
- il->rx_traffic_idx = 0;
- if (il->tx_traffic)
- memset(il->tx_traffic, 0, IL_TRAFFIC_DUMP_SIZE);
- if (il->rx_traffic)
- memset(il->rx_traffic, 0, IL_TRAFFIC_DUMP_SIZE);
-}
-
-int
-il_alloc_traffic_mem(struct il_priv *il)
-{
- u32 traffic_size = IL_TRAFFIC_DUMP_SIZE;
-
- if (il_debug_level & IL_DL_TX) {
- if (!il->tx_traffic) {
- il->tx_traffic = kzalloc(traffic_size, GFP_KERNEL);
- if (!il->tx_traffic)
- return -ENOMEM;
- }
- }
- if (il_debug_level & IL_DL_RX) {
- if (!il->rx_traffic) {
- il->rx_traffic = kzalloc(traffic_size, GFP_KERNEL);
- if (!il->rx_traffic)
- return -ENOMEM;
- }
- }
- il_reset_traffic_log(il);
- return 0;
-}
-EXPORT_SYMBOL(il_alloc_traffic_mem);
-
-void
-il_free_traffic_mem(struct il_priv *il)
-{
- kfree(il->tx_traffic);
- il->tx_traffic = NULL;
-
- kfree(il->rx_traffic);
- il->rx_traffic = NULL;
-}
-EXPORT_SYMBOL(il_free_traffic_mem);
-
-void
-il_dbg_log_tx_data_frame(struct il_priv *il, u16 length,
- struct ieee80211_hdr *header)
-{
- __le16 fc;
- u16 len;
-
- if (likely(!(il_debug_level & IL_DL_TX)))
- return;
-
- if (!il->tx_traffic)
- return;
-
- fc = header->frame_control;
- if (ieee80211_is_data(fc)) {
- len =
- (length >
- IL_TRAFFIC_ENTRY_SIZE) ? IL_TRAFFIC_ENTRY_SIZE : length;
- memcpy((il->tx_traffic +
- (il->tx_traffic_idx * IL_TRAFFIC_ENTRY_SIZE)), header,
- len);
- il->tx_traffic_idx =
- (il->tx_traffic_idx + 1) % IL_TRAFFIC_ENTRIES;
- }
-}
-EXPORT_SYMBOL(il_dbg_log_tx_data_frame);
-
-void
-il_dbg_log_rx_data_frame(struct il_priv *il, u16 length,
- struct ieee80211_hdr *header)
-{
- __le16 fc;
- u16 len;
-
- if (likely(!(il_debug_level & IL_DL_RX)))
- return;
-
- if (!il->rx_traffic)
- return;
-
- fc = header->frame_control;
- if (ieee80211_is_data(fc)) {
- len =
- (length >
- IL_TRAFFIC_ENTRY_SIZE) ? IL_TRAFFIC_ENTRY_SIZE : length;
- memcpy((il->rx_traffic +
- (il->rx_traffic_idx * IL_TRAFFIC_ENTRY_SIZE)), header,
- len);
- il->rx_traffic_idx =
- (il->rx_traffic_idx + 1) % IL_TRAFFIC_ENTRIES;
- }
-}
-EXPORT_SYMBOL(il_dbg_log_rx_data_frame);
-
-const char *
-il_get_mgmt_string(int cmd)
-{
- switch (cmd) {
- IL_CMD(MANAGEMENT_ASSOC_REQ);
- IL_CMD(MANAGEMENT_ASSOC_RESP);
- IL_CMD(MANAGEMENT_REASSOC_REQ);
- IL_CMD(MANAGEMENT_REASSOC_RESP);
- IL_CMD(MANAGEMENT_PROBE_REQ);
- IL_CMD(MANAGEMENT_PROBE_RESP);
- IL_CMD(MANAGEMENT_BEACON);
- IL_CMD(MANAGEMENT_ATIM);
- IL_CMD(MANAGEMENT_DISASSOC);
- IL_CMD(MANAGEMENT_AUTH);
- IL_CMD(MANAGEMENT_DEAUTH);
- IL_CMD(MANAGEMENT_ACTION);
- default:
- return "UNKNOWN";
-
- }
-}
-
-const char *
-il_get_ctrl_string(int cmd)
-{
- switch (cmd) {
- IL_CMD(CONTROL_BACK_REQ);
- IL_CMD(CONTROL_BACK);
- IL_CMD(CONTROL_PSPOLL);
- IL_CMD(CONTROL_RTS);
- IL_CMD(CONTROL_CTS);
- IL_CMD(CONTROL_ACK);
- IL_CMD(CONTROL_CFEND);
- IL_CMD(CONTROL_CFENDACK);
- default:
- return "UNKNOWN";
-
- }
-}
-
-void
-il_clear_traffic_stats(struct il_priv *il)
-{
- memset(&il->tx_stats, 0, sizeof(struct traffic_stats));
- memset(&il->rx_stats, 0, sizeof(struct traffic_stats));
-}
-
-/*
- * if CONFIG_IWLEGACY_DEBUGFS defined,
- * il_update_stats function will
- * record all the MGMT, CTRL and DATA pkt for both TX and Rx pass
- * Use debugFs to display the rx/rx_stats
- * if CONFIG_IWLEGACY_DEBUGFS not being defined, then no MGMT and CTRL
- * information will be recorded, but DATA pkt still will be recorded
- * for the reason of il_led.c need to control the led blinking based on
- * number of tx and rx data.
- *
- */
-void
-il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len)
-{
- struct traffic_stats *stats;
-
- if (is_tx)
- stats = &il->tx_stats;
- else
- stats = &il->rx_stats;
-
- if (ieee80211_is_mgmt(fc)) {
- switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
- case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
- stats->mgmt[MANAGEMENT_ASSOC_REQ]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
- stats->mgmt[MANAGEMENT_ASSOC_RESP]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
- stats->mgmt[MANAGEMENT_REASSOC_REQ]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
- stats->mgmt[MANAGEMENT_REASSOC_RESP]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ):
- stats->mgmt[MANAGEMENT_PROBE_REQ]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
- stats->mgmt[MANAGEMENT_PROBE_RESP]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_BEACON):
- stats->mgmt[MANAGEMENT_BEACON]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_ATIM):
- stats->mgmt[MANAGEMENT_ATIM]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
- stats->mgmt[MANAGEMENT_DISASSOC]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_AUTH):
- stats->mgmt[MANAGEMENT_AUTH]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
- stats->mgmt[MANAGEMENT_DEAUTH]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_ACTION):
- stats->mgmt[MANAGEMENT_ACTION]++;
- break;
- }
- } else if (ieee80211_is_ctl(fc)) {
- switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
- case cpu_to_le16(IEEE80211_STYPE_BACK_REQ):
- stats->ctrl[CONTROL_BACK_REQ]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_BACK):
- stats->ctrl[CONTROL_BACK]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_PSPOLL):
- stats->ctrl[CONTROL_PSPOLL]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_RTS):
- stats->ctrl[CONTROL_RTS]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_CTS):
- stats->ctrl[CONTROL_CTS]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_ACK):
- stats->ctrl[CONTROL_ACK]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_CFEND):
- stats->ctrl[CONTROL_CFEND]++;
- break;
- case cpu_to_le16(IEEE80211_STYPE_CFENDACK):
- stats->ctrl[CONTROL_CFENDACK]++;
- break;
- }
- } else {
- /* data */
- stats->data_cnt++;
- stats->data_bytes += len;
- }
-}
-EXPORT_SYMBOL(il_update_stats);
-#endif
+EXPORT_SYMBOL(il_free_txq_mem);
int
il_force_reset(struct il_priv *il, bool external)
@@ -4981,21 +4713,25 @@ il_force_reset(struct il_priv *il, bool external)
return 0;
}
+EXPORT_SYMBOL(il_force_reset);
int
il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
enum nl80211_iftype newtype, bool newp2p)
{
struct il_priv *il = hw->priv;
- struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
- u32 modes;
int err;
- newtype = ieee80211_iftype_p2p(newtype, newp2p);
-
mutex_lock(&il->mutex);
+ D_MAC80211("enter: type %d, addr %pM newtype %d newp2p %d\n",
+ vif->type, vif->addr, newtype, newp2p);
- if (!ctx->vif || !il_is_ready_rf(il)) {
+ if (newp2p) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ if (!il->vif || !il_is_ready_rf(il)) {
/*
* Huh? But wait ... this can maybe happen when
* we're in the middle of a firmware restart!
@@ -5004,39 +4740,57 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
goto out;
}
- modes = ctx->interface_modes | ctx->exclusive_interface_modes;
- if (!(modes & BIT(newtype))) {
- err = -EOPNOTSUPP;
- goto out;
- }
-
- if ((il->ctx.exclusive_interface_modes & BIT(il->ctx.vif->type)) ||
- (il->ctx.exclusive_interface_modes & BIT(newtype))) {
- err = -EINVAL;
- goto out;
- }
-
/* success */
- il_teardown_interface(il, vif, true);
vif->type = newtype;
- vif->p2p = newp2p;
- err = il_setup_interface(il, ctx);
- WARN_ON(err);
- /*
- * We've switched internally, but submitting to the
- * device may have failed for some reason. Mask this
- * error, because otherwise mac80211 will not switch
- * (and set the interface type back) and we'll be
- * out of sync with it.
- */
+ vif->p2p = false;
+ il->iw_mode = newtype;
+ il_teardown_interface(il, vif);
err = 0;
out:
+ D_MAC80211("leave err %d\n", err);
mutex_unlock(&il->mutex);
+
return err;
}
EXPORT_SYMBOL(il_mac_change_interface);
+void il_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ u32 queues, bool drop)
+{
+ struct il_priv *il = hw->priv;
+ unsigned long timeout = jiffies + msecs_to_jiffies(500);
+ int i;
+
+ mutex_lock(&il->mutex);
+ D_MAC80211("enter\n");
+
+ if (il->txq == NULL)
+ goto out;
+
+ for (i = 0; i < il->hw_params.max_txq_num; i++) {
+ struct il_queue *q;
+
+ if (i == il->cmd_queue)
+ continue;
+
+ q = &il->txq[i].q;
+ if (q->read_ptr == q->write_ptr)
+ continue;
+
+ if (time_after(jiffies, timeout)) {
+ IL_ERR("Failed to flush queue %d\n", q->id);
+ break;
+ }
+
+ msleep(20);
+ }
+out:
+ D_MAC80211("leave\n");
+ mutex_unlock(&il->mutex);
+}
+EXPORT_SYMBOL(il_mac_flush);
+
/*
* On every watchdog tick we check (latest) time stamp. If it does not
* change during timeout period and queue is not empty we reset firmware.
@@ -5047,20 +4801,21 @@ il_check_stuck_queue(struct il_priv *il, int cnt)
struct il_tx_queue *txq = &il->txq[cnt];
struct il_queue *q = &txq->q;
unsigned long timeout;
+ unsigned long now = jiffies;
int ret;
if (q->read_ptr == q->write_ptr) {
- txq->time_stamp = jiffies;
+ txq->time_stamp = now;
return 0;
}
timeout =
txq->time_stamp +
- msecs_to_jiffies(il->cfg->base_params->wd_timeout);
+ msecs_to_jiffies(il->cfg->wd_timeout);
- if (time_after(jiffies, timeout)) {
+ if (time_after(now, timeout)) {
IL_ERR("Queue %d stuck for %u ms.\n", q->id,
- il->cfg->base_params->wd_timeout);
+ jiffies_to_msecs(now - txq->time_stamp));
ret = il_force_reset(il, false);
return (ret == -EAGAIN) ? 0 : 1;
}
@@ -5088,7 +4843,7 @@ il_bg_watchdog(unsigned long data)
if (test_bit(S_EXIT_PENDING, &il->status))
return;
- timeout = il->cfg->base_params->wd_timeout;
+ timeout = il->cfg->wd_timeout;
if (timeout == 0)
return;
@@ -5097,14 +4852,12 @@ il_bg_watchdog(unsigned long data)
return;
/* monitor and check for other stuck queues */
- if (il_is_any_associated(il)) {
- for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
- /* skip as we already checked the command queue */
- if (cnt == il->cmd_queue)
- continue;
- if (il_check_stuck_queue(il, cnt))
- return;
- }
+ for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
+ /* skip as we already checked the command queue */
+ if (cnt == il->cmd_queue)
+ continue;
+ if (il_check_stuck_queue(il, cnt))
+ return;
}
mod_timer(&il->watchdog,
@@ -5115,7 +4868,7 @@ EXPORT_SYMBOL(il_bg_watchdog);
void
il_setup_watchdog(struct il_priv *il)
{
- unsigned int timeout = il->cfg->base_params->wd_timeout;
+ unsigned int timeout = il->cfg->wd_timeout;
if (timeout)
mod_timer(&il->watchdog,
@@ -5189,9 +4942,9 @@ il_add_beacon_time(struct il_priv *il, u32 base, u32 addon,
}
EXPORT_SYMBOL(il_add_beacon_time);
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
-int
+static int
il_pci_suspend(struct device *device)
{
struct pci_dev *pdev = to_pci_dev(device);
@@ -5208,9 +4961,8 @@ il_pci_suspend(struct device *device)
return 0;
}
-EXPORT_SYMBOL(il_pci_suspend);
-int
+static int
il_pci_resume(struct device *device)
{
struct pci_dev *pdev = to_pci_dev(device);
@@ -5229,51 +4981,40 @@ il_pci_resume(struct device *device)
hw_rfkill = true;
if (hw_rfkill)
- set_bit(S_RF_KILL_HW, &il->status);
+ set_bit(S_RFKILL, &il->status);
else
- clear_bit(S_RF_KILL_HW, &il->status);
+ clear_bit(S_RFKILL, &il->status);
wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rfkill);
return 0;
}
-EXPORT_SYMBOL(il_pci_resume);
-const struct dev_pm_ops il_pm_ops = {
- .suspend = il_pci_suspend,
- .resume = il_pci_resume,
- .freeze = il_pci_suspend,
- .thaw = il_pci_resume,
- .poweroff = il_pci_suspend,
- .restore = il_pci_resume,
-};
+SIMPLE_DEV_PM_OPS(il_pm_ops, il_pci_suspend, il_pci_resume);
EXPORT_SYMBOL(il_pm_ops);
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
static void
-il_update_qos(struct il_priv *il, struct il_rxon_context *ctx)
+il_update_qos(struct il_priv *il)
{
if (test_bit(S_EXIT_PENDING, &il->status))
return;
- if (!ctx->is_active)
- return;
+ il->qos_data.def_qos_parm.qos_flags = 0;
- ctx->qos_data.def_qos_parm.qos_flags = 0;
-
- if (ctx->qos_data.qos_active)
- ctx->qos_data.def_qos_parm.qos_flags |=
+ if (il->qos_data.qos_active)
+ il->qos_data.def_qos_parm.qos_flags |=
QOS_PARAM_FLG_UPDATE_EDCA_MSK;
- if (ctx->ht.enabled)
- ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
+ if (il->ht.enabled)
+ il->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
D_QOS("send QoS cmd with Qos active=%d FLAGS=0x%X\n",
- ctx->qos_data.qos_active, ctx->qos_data.def_qos_parm.qos_flags);
+ il->qos_data.qos_active, il->qos_data.def_qos_parm.qos_flags);
- il_send_cmd_pdu_async(il, ctx->qos_cmd, sizeof(struct il_qosparam_cmd),
- &ctx->qos_data.def_qos_parm, NULL);
+ il_send_cmd_pdu_async(il, C_QOS_PARAM, sizeof(struct il_qosparam_cmd),
+ &il->qos_data.def_qos_parm, NULL);
}
/**
@@ -5285,21 +5026,16 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed)
struct il_priv *il = hw->priv;
const struct il_channel_info *ch_info;
struct ieee80211_conf *conf = &hw->conf;
- struct ieee80211_channel *channel = conf->channel;
+ struct ieee80211_channel *channel = conf->chandef.chan;
struct il_ht_config *ht_conf = &il->current_ht_config;
- struct il_rxon_context *ctx = &il->ctx;
unsigned long flags = 0;
int ret = 0;
u16 ch;
int scan_active = 0;
bool ht_changed = false;
- if (WARN_ON(!il->cfg->ops->legacy))
- return -EOPNOTSUPP;
-
mutex_lock(&il->mutex);
-
- D_MAC80211("enter to channel %d changed 0x%X\n", channel->hw_value,
+ D_MAC80211("enter: channel %d changed 0x%X\n", channel->hw_value,
changed);
if (unlikely(test_bit(S_SCANNING, &il->status))) {
@@ -5319,8 +5055,8 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed)
* set up the SM PS mode to OFF if an HT channel is
* configured.
*/
- if (il->cfg->ops->hcmd->set_rxon_chain)
- il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx);
+ if (il->ops->set_rxon_chain)
+ il->ops->set_rxon_chain(il);
}
/* during scanning mac80211 will delay channel setting until
@@ -5349,48 +5085,48 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed)
spin_lock_irqsave(&il->lock, flags);
/* Configure HT40 channels */
- if (ctx->ht.enabled != conf_is_ht(conf)) {
- ctx->ht.enabled = conf_is_ht(conf);
+ if (il->ht.enabled != conf_is_ht(conf)) {
+ il->ht.enabled = conf_is_ht(conf);
ht_changed = true;
}
- if (ctx->ht.enabled) {
+ if (il->ht.enabled) {
if (conf_is_ht40_minus(conf)) {
- ctx->ht.extension_chan_offset =
+ il->ht.extension_chan_offset =
IEEE80211_HT_PARAM_CHA_SEC_BELOW;
- ctx->ht.is_40mhz = true;
+ il->ht.is_40mhz = true;
} else if (conf_is_ht40_plus(conf)) {
- ctx->ht.extension_chan_offset =
+ il->ht.extension_chan_offset =
IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
- ctx->ht.is_40mhz = true;
+ il->ht.is_40mhz = true;
} else {
- ctx->ht.extension_chan_offset =
+ il->ht.extension_chan_offset =
IEEE80211_HT_PARAM_CHA_SEC_NONE;
- ctx->ht.is_40mhz = false;
+ il->ht.is_40mhz = false;
}
} else
- ctx->ht.is_40mhz = false;
+ il->ht.is_40mhz = false;
/*
* Default to no protection. Protection mode will
* later be set from BSS config in il_ht_conf
*/
- ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
+ il->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
/* if we are switching from ht to 2.4 clear flags
* from any ht related info since 2.4 does not
* support ht */
- if ((le16_to_cpu(ctx->staging.channel) != ch))
- ctx->staging.flags = 0;
+ if ((le16_to_cpu(il->staging.channel) != ch))
+ il->staging.flags = 0;
- il_set_rxon_channel(il, channel, ctx);
+ il_set_rxon_channel(il, channel);
il_set_rxon_ht(il, ht_conf);
- il_set_flags_for_band(il, ctx, channel->band, ctx->vif);
+ il_set_flags_for_band(il, channel->band, il->vif);
spin_unlock_irqrestore(&il->lock, flags);
- if (il->cfg->ops->legacy->update_bcast_stations)
- ret = il->cfg->ops->legacy->update_bcast_stations(il);
+ if (il->ops->update_bcast_stations)
+ ret = il->ops->update_bcast_stations(il);
set_ch_out:
/* The list of supported rates and rate mask can be different
@@ -5400,6 +5136,7 @@ set_ch_out:
}
if (changed & (IEEE80211_CONF_CHANGE_PS | IEEE80211_CONF_CHANGE_IDLE)) {
+ il->power_data.ps_disabled = !(conf->flags & IEEE80211_CONF_PS);
ret = il_power_update_mode(il, false);
if (ret)
D_MAC80211("Error setting sleep level\n");
@@ -5420,16 +5157,17 @@ set_ch_out:
if (scan_active)
goto out;
- if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)))
- il_commit_rxon(il, ctx);
+ if (memcmp(&il->active, &il->staging, sizeof(il->staging)))
+ il_commit_rxon(il);
else
D_INFO("Not re-sending same RXON configuration.\n");
if (ht_changed)
- il_update_qos(il, ctx);
+ il_update_qos(il);
out:
- D_MAC80211("leave\n");
+ D_MAC80211("leave ret %d\n", ret);
mutex_unlock(&il->mutex);
+
return ret;
}
EXPORT_SYMBOL(il_mac_config);
@@ -5439,26 +5177,18 @@ il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
struct il_priv *il = hw->priv;
unsigned long flags;
- struct il_rxon_context *ctx = &il->ctx;
-
- if (WARN_ON(!il->cfg->ops->legacy))
- return;
mutex_lock(&il->mutex);
- D_MAC80211("enter\n");
+ D_MAC80211("enter: type %d, addr %pM\n", vif->type, vif->addr);
spin_lock_irqsave(&il->lock, flags);
- memset(&il->current_ht_config, 0, sizeof(struct il_ht_config));
- spin_unlock_irqrestore(&il->lock, flags);
- spin_lock_irqsave(&il->lock, flags);
+ memset(&il->current_ht_config, 0, sizeof(struct il_ht_config));
/* new association get rid of ibss beacon skb */
if (il->beacon_skb)
dev_kfree_skb(il->beacon_skb);
-
il->beacon_skb = NULL;
-
il->timestamp = 0;
spin_unlock_irqrestore(&il->lock, flags);
@@ -5470,17 +5200,14 @@ il_mac_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
return;
}
- /* we are restarting association process
- * clear RXON_FILTER_ASSOC_MSK bit
- */
- ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- il_commit_rxon(il, ctx);
+ /* we are restarting association process */
+ il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ il_commit_rxon(il);
il_set_rate(il);
- mutex_unlock(&il->mutex);
-
D_MAC80211("leave\n");
+ mutex_unlock(&il->mutex);
}
EXPORT_SYMBOL(il_mac_reset_tsf);
@@ -5490,16 +5217,15 @@ il_ht_conf(struct il_priv *il, struct ieee80211_vif *vif)
struct il_ht_config *ht_conf = &il->current_ht_config;
struct ieee80211_sta *sta;
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
- struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
D_ASSOC("enter:\n");
- if (!ctx->ht.enabled)
+ if (!il->ht.enabled)
return;
- ctx->ht.protection =
+ il->ht.protection =
bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
- ctx->ht.non_gf_sta_present =
+ il->ht.non_gf_sta_present =
!!(bss_conf->
ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
@@ -5548,16 +5274,14 @@ il_ht_conf(struct il_priv *il, struct ieee80211_vif *vif)
static inline void
il_set_no_assoc(struct il_priv *il, struct ieee80211_vif *vif)
{
- struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
-
/*
* inform the ucode that there is no longer an
* association and that no more packets should be
* sent
*/
- ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- ctx->staging.assoc_id = 0;
- il_commit_rxon(il, ctx);
+ il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+ il->staging.assoc_id = 0;
+ il_commit_rxon(il);
}
static void
@@ -5575,8 +5299,8 @@ il_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
lockdep_assert_held(&il->mutex);
- if (!il->beacon_ctx) {
- IL_ERR("update beacon but no beacon context!\n");
+ if (!il->beacon_enabled) {
+ IL_ERR("update beacon with no beaconing enabled\n");
dev_kfree_skb(skb);
return;
}
@@ -5599,7 +5323,7 @@ il_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
return;
}
- il->cfg->ops->legacy->post_associate(il);
+ il->ops->post_associate(il);
}
void
@@ -5607,17 +5331,13 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf, u32 changes)
{
struct il_priv *il = hw->priv;
- struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif);
int ret;
- if (WARN_ON(!il->cfg->ops->legacy))
- return;
-
- D_MAC80211("changes = 0x%X\n", changes);
-
mutex_lock(&il->mutex);
+ D_MAC80211("enter: changes 0x%x\n", changes);
if (!il_is_alive(il)) {
+ D_MAC80211("leave - not alive\n");
mutex_unlock(&il->mutex);
return;
}
@@ -5626,49 +5346,49 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
unsigned long flags;
spin_lock_irqsave(&il->lock, flags);
- ctx->qos_data.qos_active = bss_conf->qos;
- il_update_qos(il, ctx);
+ il->qos_data.qos_active = bss_conf->qos;
+ il_update_qos(il);
spin_unlock_irqrestore(&il->lock, flags);
}
if (changes & BSS_CHANGED_BEACON_ENABLED) {
- /*
- * the add_interface code must make sure we only ever
- * have a single interface that could be beaconing at
- * any time.
- */
+ /* FIXME: can we remove beacon_enabled ? */
if (vif->bss_conf.enable_beacon)
- il->beacon_ctx = ctx;
+ il->beacon_enabled = true;
else
- il->beacon_ctx = NULL;
+ il->beacon_enabled = false;
}
if (changes & BSS_CHANGED_BSSID) {
D_MAC80211("BSSID %pM\n", bss_conf->bssid);
/*
- * If there is currently a HW scan going on in the
- * background then we need to cancel it else the RXON
- * below/in post_associate will fail.
+ * On passive channel we wait with blocked queues to see if
+ * there is traffic on that channel. If no frame will be
+ * received (what is very unlikely since scan detects AP on
+ * that channel, but theoretically possible), mac80211 associate
+ * procedure will time out and mac80211 will call us with NULL
+ * bssid. We have to unblock queues on such condition.
+ */
+ if (is_zero_ether_addr(bss_conf->bssid))
+ il_wake_queues_by_reason(il, IL_STOP_REASON_PASSIVE);
+
+ /*
+ * If there is currently a HW scan going on in the background,
+ * then we need to cancel it, otherwise sometimes we are not
+ * able to authenticate (FIXME: why ?)
*/
if (il_scan_cancel_timeout(il, 100)) {
- IL_WARN("Aborted scan still in progress after 100ms\n");
- D_MAC80211("leaving - scan abort failed.\n");
+ D_MAC80211("leave - scan abort failed\n");
mutex_unlock(&il->mutex);
return;
}
/* mac80211 only sets assoc when in STATION mode */
- if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
- memcpy(ctx->staging.bssid_addr, bss_conf->bssid,
- ETH_ALEN);
-
- /* currently needed in a few places */
- memcpy(il->bssid, bss_conf->bssid, ETH_ALEN);
- } else {
- ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
- }
+ memcpy(il->staging.bssid_addr, bss_conf->bssid, ETH_ALEN);
+ /* FIXME: currently needed in a few places */
+ memcpy(il->bssid, bss_conf->bssid, ETH_ALEN);
}
/*
@@ -5682,21 +5402,21 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
if (changes & BSS_CHANGED_ERP_PREAMBLE) {
D_MAC80211("ERP_PREAMBLE %d\n", bss_conf->use_short_preamble);
if (bss_conf->use_short_preamble)
- ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
+ il->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
- ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+ il->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
}
if (changes & BSS_CHANGED_ERP_CTS_PROT) {
D_MAC80211("ERP_CTS %d\n", bss_conf->use_cts_prot);
if (bss_conf->use_cts_prot && il->band != IEEE80211_BAND_5GHZ)
- ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
+ il->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
else
- ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
+ il->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
if (bss_conf->use_cts_prot)
- ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
+ il->staging.flags |= RXON_FLG_SELF_CTS_EN;
else
- ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
+ il->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
}
if (changes & BSS_CHANGED_BASIC_RATES) {
@@ -5706,12 +5426,12 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
* like this here:
*
if (A-band)
- ctx->staging.ofdm_basic_rates =
+ il->staging.ofdm_basic_rates =
bss_conf->basic_rates;
else
- ctx->staging.ofdm_basic_rates =
+ il->staging.ofdm_basic_rates =
bss_conf->basic_rates >> 4;
- ctx->staging.cck_basic_rates =
+ il->staging.cck_basic_rates =
bss_conf->basic_rates & 0xF;
*/
}
@@ -5719,55 +5439,52 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
if (changes & BSS_CHANGED_HT) {
il_ht_conf(il, vif);
- if (il->cfg->ops->hcmd->set_rxon_chain)
- il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
+ if (il->ops->set_rxon_chain)
+ il->ops->set_rxon_chain(il);
}
if (changes & BSS_CHANGED_ASSOC) {
D_MAC80211("ASSOC %d\n", bss_conf->assoc);
if (bss_conf->assoc) {
- il->timestamp = bss_conf->timestamp;
+ il->timestamp = bss_conf->sync_tsf;
if (!il_is_rfkill(il))
- il->cfg->ops->legacy->post_associate(il);
+ il->ops->post_associate(il);
} else
il_set_no_assoc(il, vif);
}
- if (changes && il_is_associated_ctx(ctx) && bss_conf->aid) {
+ if (changes && il_is_associated(il) && bss_conf->aid) {
D_MAC80211("Changes (%#x) while associated\n", changes);
- ret = il_send_rxon_assoc(il, ctx);
+ ret = il_send_rxon_assoc(il);
if (!ret) {
/* Sync active_rxon with latest change. */
- memcpy((void *)&ctx->active, &ctx->staging,
+ memcpy((void *)&il->active, &il->staging,
sizeof(struct il_rxon_cmd));
}
}
if (changes & BSS_CHANGED_BEACON_ENABLED) {
if (vif->bss_conf.enable_beacon) {
- memcpy(ctx->staging.bssid_addr, bss_conf->bssid,
+ memcpy(il->staging.bssid_addr, bss_conf->bssid,
ETH_ALEN);
memcpy(il->bssid, bss_conf->bssid, ETH_ALEN);
- il->cfg->ops->legacy->config_ap(il);
+ il->ops->config_ap(il);
} else
il_set_no_assoc(il, vif);
}
if (changes & BSS_CHANGED_IBSS) {
- ret =
- il->cfg->ops->legacy->manage_ibss_station(il, vif,
- bss_conf->
- ibss_joined);
+ ret = il->ops->manage_ibss_station(il, vif,
+ bss_conf->ibss_joined);
if (ret)
IL_ERR("failed to %s IBSS station %pM\n",
bss_conf->ibss_joined ? "add" : "remove",
bss_conf->bssid);
}
- mutex_unlock(&il->mutex);
-
D_MAC80211("leave\n");
+ mutex_unlock(&il->mutex);
}
EXPORT_SYMBOL(il_mac_bss_info_changed);
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index abfa388588b..ea5c0f863c4 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -143,12 +143,6 @@ struct il_queue {
* space less than this */
};
-/* One for each TFD */
-struct il_tx_info {
- struct sk_buff *skb;
- struct il_rxon_context *ctx;
-};
-
/**
* struct il_tx_queue - Tx Queue for DMA
* @q: generic Rx/Tx queue descriptor
@@ -156,7 +150,7 @@ struct il_tx_info {
* @cmd: array of command/TX buffer pointers
* @meta: array of meta data for each command/tx buffer
* @dma_addr_cmd: physical address of cmd/tx buffer array
- * @txb: array of per-TFD driver data
+ * @skbs: array of per-TFD socket buffer pointers
* @time_stamp: time (in jiffies) of last read_ptr change
* @need_update: indicates need to update read/write idx
* @sched_retry: indicates queue is high-throughput aggregation (HT AGG) enabled
@@ -172,7 +166,7 @@ struct il_tx_queue {
void *tfds;
struct il_device_cmd **cmd;
struct il_cmd_meta *meta;
- struct il_tx_info *txb;
+ struct sk_buff **skbs;
unsigned long time_stamp;
u8 need_update;
u8 sched_retry;
@@ -431,12 +425,6 @@ struct il_eeprom_calib_info {
#define EEPROM_REGULATORY_BAND_NO_HT40 (0)
-struct il_eeprom_ops {
- const u32 regulatory_bands[7];
- int (*acquire_semaphore) (struct il_priv *il);
- void (*release_semaphore) (struct il_priv *il);
-};
-
int il_eeprom_init(struct il_priv *il);
void il_eeprom_free(struct il_priv *il);
const u8 *il_eeprom_query_addr(const struct il_priv *il, size_t offset);
@@ -553,10 +541,6 @@ struct il_frame {
struct list_head list;
};
-#define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
-#define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
-#define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
-
enum {
CMD_SYNC = 0,
CMD_SIZE_NORMAL = 0,
@@ -735,13 +719,12 @@ struct il_qos_info {
struct il_station_entry {
struct il_addsta_cmd sta;
struct il_tid_data tid[MAX_TID_COUNT];
- u8 used, ctxid;
+ u8 used;
struct il_hw_key keyinfo;
struct il_link_quality_cmd *lq;
};
struct il_station_priv_common {
- struct il_rxon_context *ctx;
u8 sta_id;
};
@@ -752,7 +735,6 @@ struct il_station_priv_common {
* space for us to put data into.
*/
struct il_vif_priv {
- struct il_rxon_context *ctx;
u8 ibss_bssid_sta_id;
};
@@ -816,6 +798,7 @@ struct il_sensitivity_ranges {
/**
* struct il_hw_params
+ * @bcast_id: f/w broadcast station ID
* @max_txq_num: Max # Tx queues supported
* @dma_chnl_num: Number of Tx DMA/FIFO channels
* @scd_bc_tbls_size: size of scheduler byte count tables
@@ -836,6 +819,7 @@ struct il_sensitivity_ranges {
* @struct il_sensitivity_ranges: range of sensitivity values
*/
struct il_hw_params {
+ u8 bcast_id;
u8 max_txq_num;
u8 dma_chnl_num;
u16 scd_bc_tbls_size;
@@ -874,9 +858,9 @@ struct il_hw_params {
* il4965_mac_ <-- mac80211 callback
*
****************************************************************************/
-extern void il4965_update_chain_flags(struct il_priv *il);
+void il4965_update_chain_flags(struct il_priv *il);
extern const u8 il_bcast_addr[ETH_ALEN];
-extern int il_queue_space(const struct il_queue *q);
+int il_queue_space(const struct il_queue *q);
static inline int
il_queue_used(const struct il_queue *q, int i)
{
@@ -968,26 +952,6 @@ enum il4965_chain_noise_state {
IL_CHAIN_NOISE_DONE,
};
-enum il4965_calib_enabled_state {
- IL_CALIB_DISABLED = 0, /* must be 0 */
- IL_CALIB_ENABLED = 1,
-};
-
-/*
- * enum il_calib
- * defines the order in which results of initial calibrations
- * should be sent to the runtime uCode
- */
-enum il_calib {
- IL_CALIB_MAX,
-};
-
-/* Opaque calibration results */
-struct il_calib_result {
- void *buf;
- size_t buf_len;
-};
-
enum ucode_type {
UCODE_NONE = 0,
UCODE_INIT,
@@ -1152,55 +1116,6 @@ struct il_force_reset {
struct il_rxon_context {
struct ieee80211_vif *vif;
-
- const u8 *ac_to_fifo;
- const u8 *ac_to_queue;
- u8 mcast_queue;
-
- /*
- * We could use the vif to indicate active, but we
- * also need it to be active during disabling when
- * we already removed the vif for type setting.
- */
- bool always_active, is_active;
-
- bool ht_need_multiple_chains;
-
- int ctxid;
-
- u32 interface_modes, exclusive_interface_modes;
- u8 unused_devtype, ap_devtype, ibss_devtype, station_devtype;
-
- /*
- * We declare this const so it can only be
- * changed via explicit cast within the
- * routines that actually update the physical
- * hardware.
- */
- const struct il_rxon_cmd active;
- struct il_rxon_cmd staging;
-
- struct il_rxon_time_cmd timing;
-
- struct il_qos_info qos_data;
-
- u8 bcast_sta_id, ap_sta_id;
-
- u8 rxon_cmd, rxon_assoc_cmd, rxon_timing_cmd;
- u8 qos_cmd;
- u8 wep_key_cmd;
-
- struct il_wep_key wep_keys[WEP_KEYS_MAX];
- u8 key_mapping_keys;
-
- __le32 station_flags;
-
- struct {
- bool non_gf_sta_present;
- u8 protection;
- bool enabled, is_40mhz;
- u8 extension_chan_offset;
- } ht;
};
struct il_power_mgr {
@@ -1208,15 +1123,19 @@ struct il_power_mgr {
struct il_powertable_cmd sleep_cmd_next;
int debug_sleep_level_override;
bool pci_pm;
+ bool ps_disabled;
};
struct il_priv {
-
- /* ieee device used by generic ieee processing code */
struct ieee80211_hw *hw;
struct ieee80211_channel *ieee_channels;
struct ieee80211_rate *ieee_rates;
+
struct il_cfg *cfg;
+ const struct il_ops *ops;
+#ifdef CONFIG_IWLEGACY_DEBUGFS
+ const struct il_debugfs_ops *debugfs_ops;
+#endif
/* temporary frame storage list */
struct list_head free_frames;
@@ -1253,9 +1172,6 @@ struct il_priv {
s32 temperature; /* degrees Kelvin */
s32 last_temperature;
- /* init calibration results */
- struct il_calib_result calib_results[IL_CALIB_MAX];
-
/* Scan related variables */
unsigned long scan_start;
unsigned long scan_start_tsf;
@@ -1304,7 +1220,28 @@ struct il_priv {
u8 ucode_write_complete; /* the image write is complete */
char firmware_name[25];
- struct il_rxon_context ctx;
+ struct ieee80211_vif *vif;
+
+ struct il_qos_info qos_data;
+
+ struct {
+ bool enabled;
+ bool is_40mhz;
+ bool non_gf_sta_present;
+ u8 protection;
+ u8 extension_chan_offset;
+ } ht;
+
+ /*
+ * We declare this const so it can only be
+ * changed via explicit cast within the
+ * routines that actually update the physical
+ * hardware.
+ */
+ const struct il_rxon_cmd active;
+ struct il_rxon_cmd staging;
+
+ struct il_rxon_time_cmd timing;
__le16 switch_channel;
@@ -1363,6 +1300,8 @@ struct il_priv {
/* queue refcounts */
#define IL_MAX_HW_QUEUES 32
unsigned long queue_stopped[BITS_TO_LONGS(IL_MAX_HW_QUEUES)];
+#define IL_STOP_REASON_PASSIVE 0
+ unsigned long stop_reason;
/* for each AC */
atomic_t queue_stop_count[4];
@@ -1416,6 +1355,7 @@ struct il_priv {
struct {
struct il_rx_phy_res last_phy_res;
bool last_phy_res_valid;
+ u32 ampdu_ref;
struct completion firmware_loading_complete;
@@ -1427,6 +1367,9 @@ struct il_priv {
u8 phy_calib_chain_noise_reset_cmd;
u8 phy_calib_chain_noise_gain_cmd;
+ u8 key_mapping_keys;
+ struct il_wep_key wep_keys[WEP_KEYS_MAX];
+
struct il_notif_stats stats;
#ifdef CONFIG_IWLEGACY_DEBUGFS
struct il_notif_stats accum_stats;
@@ -1449,7 +1392,7 @@ struct il_priv {
struct work_struct rx_replenish;
struct work_struct abort_scan;
- struct il_rxon_context *beacon_ctx;
+ bool beacon_enabled;
struct sk_buff *beacon_skb;
struct work_struct tx_flush;
@@ -1507,30 +1450,10 @@ il_txq_ctx_deactivate(struct il_priv *il, int txq_id)
clear_bit(txq_id, &il->txq_ctx_active_msk);
}
-static inline struct ieee80211_hdr *
-il_tx_queue_get_hdr(struct il_priv *il, int txq_id, int idx)
-{
- if (il->txq[txq_id].txb[idx].skb)
- return (struct ieee80211_hdr *)il->txq[txq_id].txb[idx].skb->
- data;
- return NULL;
-}
-
-static inline struct il_rxon_context *
-il_rxon_ctx_from_vif(struct ieee80211_vif *vif)
-{
- struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
-
- return vif_priv->ctx;
-}
-
-#define for_each_context(il, _ctx) \
- for (_ctx = &il->ctx; _ctx == &il->ctx; _ctx++)
-
static inline int
il_is_associated(struct il_priv *il)
{
- return (il->ctx.active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
+ return (il->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
}
static inline int
@@ -1540,12 +1463,6 @@ il_is_any_associated(struct il_priv *il)
}
static inline int
-il_is_associated_ctx(struct il_rxon_context *ctx)
-{
- return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
-}
-
-static inline int
il_is_channel_valid(const struct il_channel_info *ch_info)
{
if (ch_info == NULL)
@@ -1613,25 +1530,6 @@ il_free_pages(struct il_priv *il, unsigned long page)
#define IL_RX_BUF_SIZE_4K (4 * 1024)
#define IL_RX_BUF_SIZE_8K (8 * 1024)
-struct il_hcmd_ops {
- int (*rxon_assoc) (struct il_priv *il, struct il_rxon_context *ctx);
- int (*commit_rxon) (struct il_priv *il, struct il_rxon_context *ctx);
- void (*set_rxon_chain) (struct il_priv *il,
- struct il_rxon_context *ctx);
-};
-
-struct il_hcmd_utils_ops {
- u16(*get_hcmd_size) (u8 cmd_id, u16 len);
- u16(*build_addsta_hcmd) (const struct il_addsta_cmd *cmd, u8 *data);
- int (*request_scan) (struct il_priv *il, struct ieee80211_vif *vif);
- void (*post_scan) (struct il_priv *il);
-};
-
-struct il_apm_ops {
- int (*init) (struct il_priv *il);
- void (*config) (struct il_priv *il);
-};
-
#ifdef CONFIG_IWLEGACY_DEBUGFS
struct il_debugfs_ops {
ssize_t(*rx_stats_read) (struct file *file, char __user *user_buf,
@@ -1644,13 +1542,7 @@ struct il_debugfs_ops {
};
#endif
-struct il_temp_ops {
- void (*temperature) (struct il_priv *il);
-};
-
-struct il_lib_ops {
- /* set hw dependent parameters */
- int (*set_hw_params) (struct il_priv *il);
+struct il_ops {
/* Handling TX */
void (*txq_update_byte_cnt_tbl) (struct il_priv *il,
struct il_tx_queue *txq,
@@ -1660,8 +1552,6 @@ struct il_lib_ops {
u16 len, u8 reset, u8 pad);
void (*txq_free_tfd) (struct il_priv *il, struct il_tx_queue *txq);
int (*txq_init) (struct il_priv *il, struct il_tx_queue *txq);
- /* setup Rx handler */
- void (*handler_setup) (struct il_priv *il);
/* alive notification after init uCode load */
void (*init_alive_start) (struct il_priv *il);
/* check validity of rtc data address */
@@ -1674,45 +1564,33 @@ struct il_lib_ops {
int (*set_channel_switch) (struct il_priv *il,
struct ieee80211_channel_switch *ch_switch);
/* power management */
- struct il_apm_ops apm_ops;
+ int (*apm_init) (struct il_priv *il);
- /* power */
+ /* tx power */
int (*send_tx_power) (struct il_priv *il);
void (*update_chain_flags) (struct il_priv *il);
/* eeprom operations */
- struct il_eeprom_ops eeprom_ops;
+ int (*eeprom_acquire_semaphore) (struct il_priv *il);
+ void (*eeprom_release_semaphore) (struct il_priv *il);
- /* temperature */
- struct il_temp_ops temp_ops;
+ int (*rxon_assoc) (struct il_priv *il);
+ int (*commit_rxon) (struct il_priv *il);
+ void (*set_rxon_chain) (struct il_priv *il);
-#ifdef CONFIG_IWLEGACY_DEBUGFS
- struct il_debugfs_ops debugfs_ops;
-#endif
-
-};
-
-struct il_led_ops {
- int (*cmd) (struct il_priv *il, struct il_led_cmd *led_cmd);
-};
+ u16(*get_hcmd_size) (u8 cmd_id, u16 len);
+ u16(*build_addsta_hcmd) (const struct il_addsta_cmd *cmd, u8 *data);
-struct il_legacy_ops {
+ int (*request_scan) (struct il_priv *il, struct ieee80211_vif *vif);
+ void (*post_scan) (struct il_priv *il);
void (*post_associate) (struct il_priv *il);
void (*config_ap) (struct il_priv *il);
/* station management */
int (*update_bcast_stations) (struct il_priv *il);
int (*manage_ibss_station) (struct il_priv *il,
struct ieee80211_vif *vif, bool add);
-};
-struct il_ops {
- const struct il_lib_ops *lib;
- const struct il_hcmd_ops *hcmd;
- const struct il_hcmd_utils_ops *utils;
- const struct il_led_ops *led;
- const struct il_nic_ops *nic;
- const struct il_legacy_ops *legacy;
- const struct ieee80211_ops *ieee80211_ops;
+ int (*send_led_cmd) (struct il_priv *il, struct il_led_cmd *led_cmd);
};
struct il_mod_params {
@@ -1720,42 +1598,11 @@ struct il_mod_params {
int disable_hw_scan; /* def: 0 = use h/w scan */
int num_of_queues; /* def: HW dependent */
int disable_11n; /* def: 0 = 11n capabilities enabled */
- int amsdu_size_8K; /* def: 1 = enable 8K amsdu size */
+ int amsdu_size_8K; /* def: 0 = disable 8K amsdu size */
int antenna; /* def: 0 = both antennas (use diversity) */
int restart_fw; /* def: 1 = restart firmware */
};
-/*
- * @led_compensation: compensate on the led on/off time per HW according
- * to the deviation to achieve the desired led frequency.
- * The detail algorithm is described in common.c
- * @chain_noise_num_beacons: number of beacons used to compute chain noise
- * @wd_timeout: TX queues watchdog timeout
- * @temperature_kelvin: temperature report by uCode in kelvin
- * @ucode_tracing: support ucode continuous tracing
- * @sensitivity_calib_by_driver: driver has the capability to perform
- * sensitivity calibration operation
- * @chain_noise_calib_by_driver: driver has the capability to perform
- * chain noise calibration operation
- */
-struct il_base_params {
- int eeprom_size;
- int num_of_queues; /* def: HW dependent */
- int num_of_ampdu_queues; /* def: HW dependent */
- /* for il_apm_init() */
- u32 pll_cfg_val;
- bool set_l0s;
- bool use_bsm;
-
- u16 led_compensation;
- int chain_noise_num_beacons;
- unsigned int wd_timeout;
- bool temperature_kelvin;
- const bool ucode_tracing;
- const bool sensitivity_calib_by_driver;
- const bool chain_noise_calib_by_driver;
-};
-
#define IL_LED_SOLID 11
#define IL_DEF_LED_INTRVL cpu_to_le32(1000)
@@ -1821,7 +1668,6 @@ struct il_cfg {
unsigned int sku;
u16 eeprom_ver;
u16 eeprom_calib_ver;
- const struct il_ops *ops;
/* module based parameters which can be set from modprobe cmd */
const struct il_mod_params *mod_params;
/* params not likely to change within a device family */
@@ -1829,31 +1675,45 @@ struct il_cfg {
/* params likely to change within a device family */
u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
enum il_led_mode led_mode;
+
+ int eeprom_size;
+ int num_of_queues; /* def: HW dependent */
+ int num_of_ampdu_queues; /* def: HW dependent */
+ /* for il_apm_init() */
+ u32 pll_cfg_val;
+ bool set_l0s;
+ bool use_bsm;
+
+ u16 led_compensation;
+ int chain_noise_num_beacons;
+ unsigned int wd_timeout;
+ bool temperature_kelvin;
+ const bool ucode_tracing;
+ const bool sensitivity_calib_by_driver;
+ const bool chain_noise_calib_by_driver;
+
+ const u32 regulatory_bands[7];
};
/***************************
* L i b *
***************************/
-struct ieee80211_hw *il_alloc_all(struct il_cfg *cfg);
int il_mac_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u16 queue, const struct ieee80211_tx_queue_params *params);
int il_mac_tx_last_beacon(struct ieee80211_hw *hw);
-void il_set_rxon_hwcrypto(struct il_priv *il, struct il_rxon_context *ctx,
- int hw_decrypt);
-int il_check_rxon_cmd(struct il_priv *il, struct il_rxon_context *ctx);
-int il_full_rxon_required(struct il_priv *il, struct il_rxon_context *ctx);
-int il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch,
- struct il_rxon_context *ctx);
-void il_set_flags_for_band(struct il_priv *il, struct il_rxon_context *ctx,
- enum ieee80211_band band, struct ieee80211_vif *vif);
+void il_set_rxon_hwcrypto(struct il_priv *il, int hw_decrypt);
+int il_check_rxon_cmd(struct il_priv *il);
+int il_full_rxon_required(struct il_priv *il);
+int il_set_rxon_channel(struct il_priv *il, struct ieee80211_channel *ch);
+void il_set_flags_for_band(struct il_priv *il, enum ieee80211_band band,
+ struct ieee80211_vif *vif);
u8 il_get_single_channel_number(struct il_priv *il, enum ieee80211_band band);
void il_set_rxon_ht(struct il_priv *il, struct il_ht_config *ht_conf);
-bool il_is_ht40_tx_allowed(struct il_priv *il, struct il_rxon_context *ctx,
+bool il_is_ht40_tx_allowed(struct il_priv *il,
struct ieee80211_sta_ht_cap *ht_cap);
-void il_connection_init_rx_config(struct il_priv *il,
- struct il_rxon_context *ctx);
+void il_connection_init_rx_config(struct il_priv *il);
void il_set_rate(struct il_priv *il);
int il_set_decrypted_flag(struct il_priv *il, struct ieee80211_hdr *hdr,
u32 decrypt_res, struct ieee80211_rx_status *stats);
@@ -1863,61 +1723,27 @@ void il_mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
enum nl80211_iftype newtype, bool newp2p);
+void il_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ u32 queues, bool drop);
int il_alloc_txq_mem(struct il_priv *il);
-void il_txq_mem(struct il_priv *il);
+void il_free_txq_mem(struct il_priv *il);
#ifdef CONFIG_IWLEGACY_DEBUGFS
-int il_alloc_traffic_mem(struct il_priv *il);
-void il_free_traffic_mem(struct il_priv *il);
-void il_reset_traffic_log(struct il_priv *il);
-void il_dbg_log_tx_data_frame(struct il_priv *il, u16 length,
- struct ieee80211_hdr *header);
-void il_dbg_log_rx_data_frame(struct il_priv *il, u16 length,
- struct ieee80211_hdr *header);
-const char *il_get_mgmt_string(int cmd);
-const char *il_get_ctrl_string(int cmd);
-void il_clear_traffic_stats(struct il_priv *il);
void il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len);
#else
-static inline int
-il_alloc_traffic_mem(struct il_priv *il)
-{
- return 0;
-}
-
-static inline void
-il_free_traffic_mem(struct il_priv *il)
-{
-}
-
-static inline void
-il_reset_traffic_log(struct il_priv *il)
-{
-}
-
-static inline void
-il_dbg_log_tx_data_frame(struct il_priv *il, u16 length,
- struct ieee80211_hdr *header)
-{
-}
-
-static inline void
-il_dbg_log_rx_data_frame(struct il_priv *il, u16 length,
- struct ieee80211_hdr *header)
-{
-}
-
static inline void
il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len)
{
}
#endif
+
/*****************************************************
- * RX handlers.
- * **************************************************/
+ * Handlers
+ ***************************************************/
void il_hdl_pm_sleep(struct il_priv *il, struct il_rx_buf *rxb);
void il_hdl_pm_debug_stats(struct il_priv *il, struct il_rx_buf *rxb);
void il_hdl_error(struct il_priv *il, struct il_rx_buf *rxb);
+void il_hdl_csa(struct il_priv *il, struct il_rx_buf *rxb);
/*****************************************************
* RX
@@ -1928,22 +1754,17 @@ int il_rx_queue_alloc(struct il_priv *il);
void il_rx_queue_update_write_ptr(struct il_priv *il, struct il_rx_queue *q);
int il_rx_queue_space(const struct il_rx_queue *q);
void il_tx_cmd_complete(struct il_priv *il, struct il_rx_buf *rxb);
-/* Handlers */
+
void il_hdl_spectrum_measurement(struct il_priv *il, struct il_rx_buf *rxb);
void il_recover_from_stats(struct il_priv *il, struct il_rx_pkt *pkt);
void il_chswitch_done(struct il_priv *il, bool is_success);
-void il_hdl_csa(struct il_priv *il, struct il_rx_buf *rxb);
-
-/* TX helpers */
/*****************************************************
* 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, struct il_tx_queue *txq, int slots_num,
- u32 txq_id);
-void il_tx_queue_reset(struct il_priv *il, struct il_tx_queue *txq,
- int slots_num, u32 txq_id);
+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);
@@ -1956,7 +1777,7 @@ int il_set_tx_power(struct il_priv *il, s8 tx_power, bool force);
* Rate
******************************************************************************/
-u8 il_get_lowest_plcp(struct il_priv *il, struct il_rxon_context *ctx);
+u8 il_get_lowest_plcp(struct il_priv *il);
/*******************************************************************************
* Scanning
@@ -2010,43 +1831,31 @@ int il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd);
* PCI *
*****************************************************/
-static inline u16
-il_pcie_link_ctl(struct il_priv *il)
-{
- int pos;
- u16 pci_lnk_ctl;
- pos = pci_pcie_cap(il->pci_dev);
- pci_read_config_word(il->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
- return pci_lnk_ctl;
-}
-
void il_bg_watchdog(unsigned long data);
u32 il_usecs_to_beacons(struct il_priv *il, u32 usec, u32 beacon_interval);
__le32 il_add_beacon_time(struct il_priv *il, u32 base, u32 addon,
u32 beacon_interval);
-#ifdef CONFIG_PM
-int il_pci_suspend(struct device *device);
-int il_pci_resume(struct device *device);
+#ifdef CONFIG_PM_SLEEP
extern const struct dev_pm_ops il_pm_ops;
#define IL_LEGACY_PM_OPS (&il_pm_ops)
-#else /* !CONFIG_PM */
+#else /* !CONFIG_PM_SLEEP */
#define IL_LEGACY_PM_OPS NULL
-#endif /* !CONFIG_PM */
+#endif /* !CONFIG_PM_SLEEP */
/*****************************************************
* Error Handling Debugging
******************************************************/
void il4965_dump_nic_error_log(struct il_priv *il);
#ifdef CONFIG_IWLEGACY_DEBUG
-void il_print_rx_config_cmd(struct il_priv *il, struct il_rxon_context *ctx);
+void il_print_rx_config_cmd(struct il_priv *il);
#else
static inline void
-il_print_rx_config_cmd(struct il_priv *il, struct il_rxon_context *ctx)
+il_print_rx_config_cmd(struct il_priv *il)
{
}
#endif
@@ -2064,7 +1873,7 @@ void il_free_geos(struct il_priv *il);
#define S_HCMD_ACTIVE 0 /* host command in progress */
/* 1 is unused (used to be S_HCMD_SYNC_ACTIVE) */
#define S_INT_ENABLED 2
-#define S_RF_KILL_HW 3
+#define S_RFKILL 3
#define S_CT_KILL 4
#define S_INIT 5
#define S_ALIVE 6
@@ -2103,15 +1912,9 @@ il_is_init(struct il_priv *il)
}
static inline int
-il_is_rfkill_hw(struct il_priv *il)
-{
- return test_bit(S_RF_KILL_HW, &il->status);
-}
-
-static inline int
il_is_rfkill(struct il_priv *il)
{
- return il_is_rfkill_hw(il);
+ return test_bit(S_RFKILL, &il->status);
}
static inline int
@@ -2130,22 +1933,25 @@ il_is_ready_rf(struct il_priv *il)
return il_is_ready(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);
+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);
+
int il_apm_init(struct il_priv *il);
-int il_send_rxon_timing(struct il_priv *il, struct il_rxon_context *ctx);
+int il_send_rxon_timing(struct il_priv *il);
+
static inline int
-il_send_rxon_assoc(struct il_priv *il, struct il_rxon_context *ctx)
+il_send_rxon_assoc(struct il_priv *il)
{
- return il->cfg->ops->hcmd->rxon_assoc(il, ctx);
+ return il->ops->rxon_assoc(il);
}
static inline int
-il_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx)
+il_commit_rxon(struct il_priv *il)
{
- return il->cfg->ops->hcmd->commit_rxon(il, ctx);
+ return il->ops->commit_rxon(il);
}
static inline const struct ieee80211_supported_band *
@@ -2164,33 +1970,47 @@ void il_tx_cmd_protection(struct il_priv *il, struct ieee80211_tx_info *info,
irqreturn_t il_isr(int irq, void *data);
-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 int _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);
+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);
+
+static inline bool il_need_reclaim(struct il_priv *il, struct il_rx_pkt *pkt)
+{
+ /* Reclaim a command buffer only if this packet is a response
+ * to a (driver-originated) command. If the packet (e.g. Rx frame)
+ * originated from uCode, there is no command buffer to reclaim.
+ * Ucode should set SEQ_RX_FRAME bit if ucode-originated, but
+ * apparently a few don't get set; catch them here.
+ */
+ return !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
+ pkt->hdr.cmd != N_STATS && pkt->hdr.cmd != C_TX &&
+ pkt->hdr.cmd != N_RX_PHY && pkt->hdr.cmd != N_RX &&
+ pkt->hdr.cmd != N_RX_MPDU && pkt->hdr.cmd != N_COMPRESSED_BA;
+}
static inline void
_il_write8(struct il_priv *il, u32 ofs, u8 val)
{
- iowrite8(val, il->hw_base + ofs);
+ writeb(val, il->hw_base + ofs);
}
#define il_write8(il, ofs, val) _il_write8(il, ofs, val)
static inline void
_il_wr(struct il_priv *il, u32 ofs, u32 val)
{
- iowrite32(val, il->hw_base + ofs);
+ writel(val, il->hw_base + ofs);
}
static inline u32
_il_rd(struct il_priv *il, u32 ofs)
{
- return ioread32(il->hw_base + ofs);
+ return readl(il->hw_base + ofs);
}
static inline void
@@ -2209,6 +2029,13 @@ static inline void
_il_release_nic_access(struct il_priv *il)
{
_il_clear_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+ /*
+ * In above we are reading CSR_GP_CNTRL register, what will flush any
+ * previous writes, but still want write, which clear MAC_ACCESS_REQ
+ * bit, be performed on PCI bus before any other writes scheduled on
+ * different CPUs (after we drop reg_lock).
+ */
+ mmiowb();
}
static inline u32
@@ -2231,7 +2058,7 @@ il_wr(struct il_priv *il, u32 reg, u32 value)
unsigned long reg_flags;
spin_lock_irqsave(&il->reg_lock, reg_flags);
- if (!_il_grab_nic_access(il)) {
+ if (likely(_il_grab_nic_access(il))) {
_il_wr(il, reg, value);
_il_release_nic_access(il);
}
@@ -2242,7 +2069,6 @@ static inline u32
_il_rd_prph(struct il_priv *il, u32 reg)
{
_il_wr(il, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
- rmb();
return _il_rd(il, HBUS_TARG_PRPH_RDAT);
}
@@ -2250,7 +2076,6 @@ static inline void
_il_wr_prph(struct il_priv *il, u32 addr, u32 val)
{
_il_wr(il, HBUS_TARG_PRPH_WADDR, ((addr & 0x0000FFFF) | (3 << 24)));
- wmb();
_il_wr(il, HBUS_TARG_PRPH_WDAT, val);
}
@@ -2260,9 +2085,10 @@ il_set_bits_prph(struct il_priv *il, u32 reg, u32 mask)
unsigned long reg_flags;
spin_lock_irqsave(&il->reg_lock, reg_flags);
- _il_grab_nic_access(il);
- _il_wr_prph(il, reg, (_il_rd_prph(il, reg) | mask));
- _il_release_nic_access(il);
+ if (likely(_il_grab_nic_access(il))) {
+ _il_wr_prph(il, reg, (_il_rd_prph(il, reg) | mask));
+ _il_release_nic_access(il);
+ }
spin_unlock_irqrestore(&il->reg_lock, reg_flags);
}
@@ -2272,9 +2098,10 @@ il_set_bits_mask_prph(struct il_priv *il, u32 reg, u32 bits, u32 mask)
unsigned long reg_flags;
spin_lock_irqsave(&il->reg_lock, reg_flags);
- _il_grab_nic_access(il);
- _il_wr_prph(il, reg, ((_il_rd_prph(il, reg) & mask) | bits));
- _il_release_nic_access(il);
+ if (likely(_il_grab_nic_access(il))) {
+ _il_wr_prph(il, reg, ((_il_rd_prph(il, reg) & mask) | bits));
+ _il_release_nic_access(il);
+ }
spin_unlock_irqrestore(&il->reg_lock, reg_flags);
}
@@ -2285,10 +2112,11 @@ il_clear_bits_prph(struct il_priv *il, u32 reg, u32 mask)
u32 val;
spin_lock_irqsave(&il->reg_lock, reg_flags);
- _il_grab_nic_access(il);
- val = _il_rd_prph(il, reg);
- _il_wr_prph(il, reg, (val & ~mask));
- _il_release_nic_access(il);
+ if (likely(_il_grab_nic_access(il))) {
+ val = _il_rd_prph(il, reg);
+ _il_wr_prph(il, reg, (val & ~mask));
+ _il_release_nic_access(il);
+ }
spin_unlock_irqrestore(&il->reg_lock, reg_flags);
}
@@ -2303,23 +2131,22 @@ il_clear_bits_prph(struct il_priv *il, u32 reg, u32 mask)
(this is for the IBSS BSSID stations) */
#define IL_STA_BCAST BIT(4) /* this station is the special bcast station */
-void il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx);
-void il_clear_ucode_stations(struct il_priv *il, struct il_rxon_context *ctx);
+void il_restore_stations(struct il_priv *il);
+void il_clear_ucode_stations(struct il_priv *il);
void il_dealloc_bcast_stations(struct il_priv *il);
int il_get_free_ucode_key_idx(struct il_priv *il);
int il_send_add_sta(struct il_priv *il, struct il_addsta_cmd *sta, u8 flags);
-int il_add_station_common(struct il_priv *il, struct il_rxon_context *ctx,
- const u8 *addr, bool is_ap,
+int il_add_station_common(struct il_priv *il, const u8 *addr, bool is_ap,
struct ieee80211_sta *sta, u8 *sta_id_r);
int il_remove_station(struct il_priv *il, const u8 sta_id, const u8 * addr);
int il_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
-u8 il_prep_station(struct il_priv *il, struct il_rxon_context *ctx,
- const u8 *addr, bool is_ap, struct ieee80211_sta *sta);
+u8 il_prep_station(struct il_priv *il, const u8 *addr, bool is_ap,
+ struct ieee80211_sta *sta);
-int il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx,
- struct il_link_quality_cmd *lq, u8 flags, bool init);
+int il_send_lq_cmd(struct il_priv *il, struct il_link_quality_cmd *lq,
+ u8 flags, bool init);
/**
* il_clear_driver_stations - clear knowledge of all stations from driver
@@ -2334,24 +2161,11 @@ static inline void
il_clear_driver_stations(struct il_priv *il)
{
unsigned long flags;
- struct il_rxon_context *ctx = &il->ctx;
spin_lock_irqsave(&il->sta_lock, flags);
memset(il->stations, 0, sizeof(il->stations));
il->num_stations = 0;
-
il->ucode_key_table = 0;
-
- /*
- * Remove all key information that is not stored as part
- * of station information since mac80211 may not have had
- * a chance to remove all the keys. When device is
- * reconfigured by mac80211 after an error all keys will
- * be reconfigured.
- */
- memset(ctx->wep_keys, 0, sizeof(ctx->wep_keys));
- ctx->key_mapping_keys = 0;
-
spin_unlock_irqrestore(&il->sta_lock, flags);
}
@@ -2376,13 +2190,12 @@ il_sta_id(struct ieee80211_sta *sta)
* inline wraps that pattern.
*/
static inline int
-il_sta_id_or_broadcast(struct il_priv *il, struct il_rxon_context *context,
- struct ieee80211_sta *sta)
+il_sta_id_or_broadcast(struct il_priv *il, struct ieee80211_sta *sta)
{
int sta_id;
if (!sta)
- return context->bcast_sta_id;
+ return il->hw_params.bcast_id;
sta_id = il_sta_id(sta);
@@ -2436,9 +2249,8 @@ il_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc)
return -EINVAL;
}
- desc->v_addr =
- dma_alloc_coherent(&pci_dev->dev, desc->len, &desc->p_addr,
- GFP_KERNEL);
+ desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len,
+ &desc->p_addr, GFP_KERNEL);
return (desc->v_addr != NULL) ? 0 : -ENOMEM;
}
@@ -2463,6 +2275,19 @@ il_set_swq_id(struct il_tx_queue *txq, u8 ac, u8 hwq)
}
static inline void
+_il_wake_queue(struct il_priv *il, u8 ac)
+{
+ if (atomic_dec_return(&il->queue_stop_count[ac]) <= 0)
+ ieee80211_wake_queue(il->hw, ac);
+}
+
+static inline void
+_il_stop_queue(struct il_priv *il, u8 ac)
+{
+ if (atomic_inc_return(&il->queue_stop_count[ac]) > 0)
+ ieee80211_stop_queue(il->hw, ac);
+}
+static inline void
il_wake_queue(struct il_priv *il, struct il_tx_queue *txq)
{
u8 queue = txq->swq_id;
@@ -2470,8 +2295,7 @@ il_wake_queue(struct il_priv *il, struct il_tx_queue *txq)
u8 hwq = (queue >> 2) & 0x1f;
if (test_and_clear_bit(hwq, il->queue_stopped))
- if (atomic_dec_return(&il->queue_stop_count[ac]) <= 0)
- ieee80211_wake_queue(il->hw, ac);
+ _il_wake_queue(il, ac);
}
static inline void
@@ -2482,8 +2306,27 @@ il_stop_queue(struct il_priv *il, struct il_tx_queue *txq)
u8 hwq = (queue >> 2) & 0x1f;
if (!test_and_set_bit(hwq, il->queue_stopped))
- if (atomic_inc_return(&il->queue_stop_count[ac]) > 0)
- ieee80211_stop_queue(il->hw, ac);
+ _il_stop_queue(il, ac);
+}
+
+static inline void
+il_wake_queues_by_reason(struct il_priv *il, int reason)
+{
+ u8 ac;
+
+ if (test_and_clear_bit(reason, &il->stop_reason))
+ for (ac = 0; ac < 4; ac++)
+ _il_wake_queue(il, ac);
+}
+
+static inline void
+il_stop_queues_by_reason(struct il_priv *il, int reason)
+{
+ u8 ac;
+
+ if (!test_and_set_bit(reason, &il->stop_reason))
+ for (ac = 0; ac < 4; ac++)
+ _il_stop_queue(il, ac);
}
#ifdef ieee80211_stop_queue
@@ -2565,10 +2408,10 @@ struct il_rb_status {
__le32 __unused; /* 3945 only */
} __packed;
-#define TFD_QUEUE_SIZE_MAX (256)
-#define TFD_QUEUE_SIZE_BC_DUP (64)
+#define TFD_QUEUE_SIZE_MAX 256
+#define TFD_QUEUE_SIZE_BC_DUP 64
#define TFD_QUEUE_BC_SIZE (TFD_QUEUE_SIZE_MAX + TFD_QUEUE_SIZE_BC_DUP)
-#define IL_TX_DMA_MASK DMA_BIT_MASK(36)
+#define IL_TX_DMA_MASK DMA_BIT_MASK(36)
#define IL_NUM_OF_TBS 20
static inline u8
@@ -2629,10 +2472,6 @@ struct il_tfd {
/* PCI registers */
#define PCI_CFG_RETRY_TIMEOUT 0x041
-/* PCI register values */
-#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01
-#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02
-
struct il_rate_info {
u8 plcp; /* uCode API: RATE_6M_PLCP, etc. */
u8 plcp_siso; /* uCode API: RATE_SISO_6M_PLCP, etc. */
@@ -3045,13 +2884,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
*/
-extern void il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
+void il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
/* Initialize station's rate scaling information after adding station */
-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);
+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);
/**
* il_rate_control_register - Register the rate control algorithm callbacks
@@ -3063,8 +2902,8 @@ extern void il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta,
* ieee80211_register_hw
*
*/
-extern int il4965_rate_control_register(void);
-extern int il3945_rate_control_register(void);
+int il4965_rate_control_register(void);
+int il3945_rate_control_register(void);
/**
* il_rate_control_unregister - Unregister the rate control callbacks
@@ -3072,11 +2911,11 @@ extern int il3945_rate_control_register(void);
* This should be called after calling ieee80211_unregister_hw, but before
* the driver is unloaded.
*/
-extern void il4965_rate_control_unregister(void);
-extern void il3945_rate_control_unregister(void);
+void il4965_rate_control_unregister(void);
+void il3945_rate_control_unregister(void);
-extern int il_power_update_mode(struct il_priv *il, bool force);
-extern void il_power_initialize(struct il_priv *il);
+int il_power_update_mode(struct il_priv *il, bool force);
+void il_power_initialize(struct il_priv *il);
extern u32 il_debug_level;
@@ -3114,9 +2953,8 @@ do { \
#define IL_DBG(level, fmt, args...) \
do { \
if (il_get_debug_level(il) & level) \
- dev_printk(KERN_ERR, &il->hw->wiphy->dev, \
- "%c %s " fmt, in_interrupt() ? 'I' : 'U', \
- __func__ , ## args); \
+ dev_err(&il->hw->wiphy->dev, "%c %s " fmt, \
+ in_interrupt() ? 'I' : 'U', __func__ , ##args); \
} while (0)
#define il_print_hex_dump(il, level, p, len) \
diff --git a/drivers/net/wireless/iwlegacy/debug.c b/drivers/net/wireless/iwlegacy/debug.c
index b1b8926a9c7..34401015319 100644
--- a/drivers/net/wireless/iwlegacy/debug.c
+++ b/drivers/net/wireless/iwlegacy/debug.c
@@ -31,6 +31,101 @@
#include "common.h"
+static void
+il_clear_traffic_stats(struct il_priv *il)
+{
+ memset(&il->tx_stats, 0, sizeof(struct traffic_stats));
+ memset(&il->rx_stats, 0, sizeof(struct traffic_stats));
+}
+
+/*
+ * il_update_stats function record all the MGMT, CTRL and DATA pkt for
+ * both TX and Rx . Use debugfs to display the rx/rx_stats
+ */
+void
+il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len)
+{
+ struct traffic_stats *stats;
+
+ if (is_tx)
+ stats = &il->tx_stats;
+ else
+ stats = &il->rx_stats;
+
+ if (ieee80211_is_mgmt(fc)) {
+ switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
+ case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):
+ stats->mgmt[MANAGEMENT_ASSOC_REQ]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
+ stats->mgmt[MANAGEMENT_ASSOC_RESP]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):
+ stats->mgmt[MANAGEMENT_REASSOC_REQ]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
+ stats->mgmt[MANAGEMENT_REASSOC_RESP]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ):
+ stats->mgmt[MANAGEMENT_PROBE_REQ]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):
+ stats->mgmt[MANAGEMENT_PROBE_RESP]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_BEACON):
+ stats->mgmt[MANAGEMENT_BEACON]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_ATIM):
+ stats->mgmt[MANAGEMENT_ATIM]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
+ stats->mgmt[MANAGEMENT_DISASSOC]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_AUTH):
+ stats->mgmt[MANAGEMENT_AUTH]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
+ stats->mgmt[MANAGEMENT_DEAUTH]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_ACTION):
+ stats->mgmt[MANAGEMENT_ACTION]++;
+ break;
+ }
+ } else if (ieee80211_is_ctl(fc)) {
+ switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {
+ case cpu_to_le16(IEEE80211_STYPE_BACK_REQ):
+ stats->ctrl[CONTROL_BACK_REQ]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_BACK):
+ stats->ctrl[CONTROL_BACK]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_PSPOLL):
+ stats->ctrl[CONTROL_PSPOLL]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_RTS):
+ stats->ctrl[CONTROL_RTS]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_CTS):
+ stats->ctrl[CONTROL_CTS]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_ACK):
+ stats->ctrl[CONTROL_ACK]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_CFEND):
+ stats->ctrl[CONTROL_CFEND]++;
+ break;
+ case cpu_to_le16(IEEE80211_STYPE_CFENDACK):
+ stats->ctrl[CONTROL_CFENDACK]++;
+ break;
+ }
+ } else {
+ /* data */
+ stats->data_cnt++;
+ stats->data_bytes += len;
+ }
+}
+EXPORT_SYMBOL(il_update_stats);
+
/* create and remove of files */
#define DEBUGFS_ADD_FILE(name, parent, mode) do { \
if (!debugfs_create_file(#name, mode, parent, il, \
@@ -65,18 +160,12 @@ static ssize_t il_dbgfs_##name##_write(struct file *file, \
const char __user *user_buf, \
size_t count, loff_t *ppos);
-static int
-il_dbgfs_open_file_generic(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
#define DEBUGFS_READ_FILE_OPS(name) \
DEBUGFS_READ_FUNC(name); \
static const struct file_operations il_dbgfs_##name##_ops = { \
.read = il_dbgfs_##name##_read, \
- .open = il_dbgfs_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
@@ -84,7 +173,7 @@ static const struct file_operations il_dbgfs_##name##_ops = { \
DEBUGFS_WRITE_FUNC(name); \
static const struct file_operations il_dbgfs_##name##_ops = { \
.write = il_dbgfs_##name##_write, \
- .open = il_dbgfs_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
@@ -94,10 +183,50 @@ static const struct file_operations il_dbgfs_##name##_ops = { \
static const struct file_operations il_dbgfs_##name##_ops = { \
.write = il_dbgfs_##name##_write, \
.read = il_dbgfs_##name##_read, \
- .open = il_dbgfs_open_file_generic, \
+ .open = simple_open, \
.llseek = generic_file_llseek, \
};
+static const char *
+il_get_mgmt_string(int cmd)
+{
+ switch (cmd) {
+ IL_CMD(MANAGEMENT_ASSOC_REQ);
+ IL_CMD(MANAGEMENT_ASSOC_RESP);
+ IL_CMD(MANAGEMENT_REASSOC_REQ);
+ IL_CMD(MANAGEMENT_REASSOC_RESP);
+ IL_CMD(MANAGEMENT_PROBE_REQ);
+ IL_CMD(MANAGEMENT_PROBE_RESP);
+ IL_CMD(MANAGEMENT_BEACON);
+ IL_CMD(MANAGEMENT_ATIM);
+ IL_CMD(MANAGEMENT_DISASSOC);
+ IL_CMD(MANAGEMENT_AUTH);
+ IL_CMD(MANAGEMENT_DEAUTH);
+ IL_CMD(MANAGEMENT_ACTION);
+ default:
+ return "UNKNOWN";
+
+ }
+}
+
+static const char *
+il_get_ctrl_string(int cmd)
+{
+ switch (cmd) {
+ IL_CMD(CONTROL_BACK_REQ);
+ IL_CMD(CONTROL_BACK);
+ IL_CMD(CONTROL_PSPOLL);
+ IL_CMD(CONTROL_RTS);
+ IL_CMD(CONTROL_CTS);
+ IL_CMD(CONTROL_ACK);
+ IL_CMD(CONTROL_CFEND);
+ IL_CMD(CONTROL_CFENDACK);
+ default:
+ return "UNKNOWN";
+
+ }
+}
+
static ssize_t
il_dbgfs_tx_stats_read(struct file *file, char __user *user_buf, size_t count,
loff_t *ppos)
@@ -361,7 +490,7 @@ il_dbgfs_nvm_read(struct file *file, char __user *user_buf, size_t count,
const u8 *ptr;
char *buf;
u16 eeprom_ver;
- size_t eeprom_len = il->cfg->base_params->eeprom_size;
+ size_t eeprom_len = il->cfg->eeprom_size;
buf_size = 4 * eeprom_len + 256;
if (eeprom_len % 16) {
@@ -438,12 +567,12 @@ il_dbgfs_channels_read(struct file *file, char __user *user_buf, size_t count,
flags & IEEE80211_CHAN_RADAR ?
" (IEEE 802.11h required)" : "",
((channels[i].
- flags & IEEE80211_CHAN_NO_IBSS) ||
+ flags & IEEE80211_CHAN_NO_IR) ||
(channels[i].
flags & IEEE80211_CHAN_RADAR)) ? "" :
", IBSS",
channels[i].
- flags & IEEE80211_CHAN_PASSIVE_SCAN ?
+ flags & IEEE80211_CHAN_NO_IR ?
"passive only" : "active/passive");
}
supp_band = il_get_hw_mode(il, IEEE80211_BAND_5GHZ);
@@ -465,12 +594,12 @@ il_dbgfs_channels_read(struct file *file, char __user *user_buf, size_t count,
flags & IEEE80211_CHAN_RADAR ?
" (IEEE 802.11h required)" : "",
((channels[i].
- flags & IEEE80211_CHAN_NO_IBSS) ||
+ flags & IEEE80211_CHAN_NO_IR) ||
(channels[i].
flags & IEEE80211_CHAN_RADAR)) ? "" :
", IBSS",
channels[i].
- flags & IEEE80211_CHAN_PASSIVE_SCAN ?
+ flags & IEEE80211_CHAN_NO_IR ?
"passive only" : "active/passive");
}
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
@@ -495,8 +624,8 @@ il_dbgfs_status_read(struct file *file, char __user *user_buf, size_t count,
scnprintf(buf + pos, bufsz - pos, "S_INT_ENABLED:\t %d\n",
test_bit(S_INT_ENABLED, &il->status));
pos +=
- scnprintf(buf + pos, bufsz - pos, "S_RF_KILL_HW:\t %d\n",
- test_bit(S_RF_KILL_HW, &il->status));
+ scnprintf(buf + pos, bufsz - pos, "S_RFKILL:\t %d\n",
+ test_bit(S_RFKILL, &il->status));
pos +=
scnprintf(buf + pos, bufsz - pos, "S_CT_KILL:\t\t %d\n",
test_bit(S_CT_KILL, &il->status));
@@ -644,12 +773,10 @@ il_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count,
loff_t *ppos)
{
struct il_priv *il = file->private_data;
- struct il_rxon_context *ctx = &il->ctx;
int pos = 0, i;
char buf[256];
const size_t bufsz = sizeof(buf);
- pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n", ctx->ctxid);
for (i = 0; i < AC_NUM; i++) {
pos +=
scnprintf(buf + pos, bufsz - pos,
@@ -657,10 +784,10 @@ il_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count,
pos +=
scnprintf(buf + pos, bufsz - pos,
"AC[%d]\t%u\t%u\t%u\t%u\n", i,
- ctx->qos_data.def_qos_parm.ac[i].cw_min,
- ctx->qos_data.def_qos_parm.ac[i].cw_max,
- ctx->qos_data.def_qos_parm.ac[i].aifsn,
- ctx->qos_data.def_qos_parm.ac[i].edca_txop);
+ il->qos_data.def_qos_parm.ac[i].cw_min,
+ il->qos_data.def_qos_parm.ac[i].cw_max,
+ il->qos_data.def_qos_parm.ac[i].aifsn,
+ il->qos_data.def_qos_parm.ac[i].edca_txop);
}
return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
@@ -717,112 +844,6 @@ DEBUGFS_READ_FILE_OPS(qos);
DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
static ssize_t
-il_dbgfs_traffic_log_read(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct il_priv *il = file->private_data;
- int pos = 0, ofs = 0;
- int cnt = 0, entry;
- struct il_tx_queue *txq;
- struct il_queue *q;
- struct il_rx_queue *rxq = &il->rxq;
- char *buf;
- int bufsz =
- ((IL_TRAFFIC_ENTRIES * IL_TRAFFIC_ENTRY_SIZE * 64) * 2) +
- (il->cfg->base_params->num_of_queues * 32 * 8) + 400;
- const u8 *ptr;
- ssize_t ret;
-
- if (!il->txq) {
- IL_ERR("txq not ready\n");
- return -EAGAIN;
- }
- buf = kzalloc(bufsz, GFP_KERNEL);
- if (!buf) {
- IL_ERR("Can not allocate buffer\n");
- return -ENOMEM;
- }
- pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n");
- for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {
- txq = &il->txq[cnt];
- q = &txq->q;
- pos +=
- scnprintf(buf + pos, bufsz - pos,
- "q[%d]: read_ptr: %u, write_ptr: %u\n", cnt,
- q->read_ptr, q->write_ptr);
- }
- if (il->tx_traffic && (il_debug_level & IL_DL_TX)) {
- ptr = il->tx_traffic;
- pos +=
- scnprintf(buf + pos, bufsz - pos, "Tx Traffic idx: %u\n",
- il->tx_traffic_idx);
- for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
- for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16;
- entry++, ofs += 16) {
- pos +=
- scnprintf(buf + pos, bufsz - pos, "0x%.4x ",
- ofs);
- hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
- buf + pos, bufsz - pos, 0);
- pos += strlen(buf + pos);
- if (bufsz - pos > 0)
- buf[pos++] = '\n';
- }
- }
- }
-
- pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n");
- pos +=
- scnprintf(buf + pos, bufsz - pos, "read: %u, write: %u\n",
- rxq->read, rxq->write);
-
- if (il->rx_traffic && (il_debug_level & IL_DL_RX)) {
- ptr = il->rx_traffic;
- pos +=
- scnprintf(buf + pos, bufsz - pos, "Rx Traffic idx: %u\n",
- il->rx_traffic_idx);
- for (cnt = 0, ofs = 0; cnt < IL_TRAFFIC_ENTRIES; cnt++) {
- for (entry = 0; entry < IL_TRAFFIC_ENTRY_SIZE / 16;
- entry++, ofs += 16) {
- pos +=
- scnprintf(buf + pos, bufsz - pos, "0x%.4x ",
- ofs);
- hex_dump_to_buffer(ptr + ofs, 16, 16, 2,
- buf + pos, bufsz - pos, 0);
- pos += strlen(buf + pos);
- if (bufsz - pos > 0)
- buf[pos++] = '\n';
- }
- }
- }
-
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
- kfree(buf);
- return ret;
-}
-
-static ssize_t
-il_dbgfs_traffic_log_write(struct file *file, const char __user *user_buf,
- size_t count, loff_t *ppos)
-{
- struct il_priv *il = file->private_data;
- char buf[8];
- int buf_size;
- int traffic_log;
-
- memset(buf, 0, sizeof(buf));
- buf_size = min(count, sizeof(buf) - 1);
- if (copy_from_user(buf, user_buf, buf_size))
- return -EFAULT;
- if (sscanf(buf, "%d", &traffic_log) != 1)
- return -EFAULT;
- if (traffic_log == 0)
- il_reset_traffic_log(il);
-
- return count;
-}
-
-static ssize_t
il_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count,
loff_t *ppos)
{
@@ -835,7 +856,7 @@ il_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count,
int cnt;
int ret;
const size_t bufsz =
- sizeof(char) * 64 * il->cfg->base_params->num_of_queues;
+ sizeof(char) * 64 * il->cfg->num_of_queues;
if (!il->txq) {
IL_ERR("txq not ready\n");
@@ -903,8 +924,8 @@ il_dbgfs_ucode_rx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct il_priv *il = file->private_data;
- return il->cfg->ops->lib->debugfs_ops.rx_stats_read(file, user_buf,
- count, ppos);
+
+ return il->debugfs_ops->rx_stats_read(file, user_buf, count, ppos);
}
static ssize_t
@@ -912,8 +933,8 @@ il_dbgfs_ucode_tx_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct il_priv *il = file->private_data;
- return il->cfg->ops->lib->debugfs_ops.tx_stats_read(file, user_buf,
- count, ppos);
+
+ return il->debugfs_ops->tx_stats_read(file, user_buf, count, ppos);
}
static ssize_t
@@ -921,8 +942,8 @@ il_dbgfs_ucode_general_stats_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct il_priv *il = file->private_data;
- return il->cfg->ops->lib->debugfs_ops.general_stats_read(file, user_buf,
- count, ppos);
+
+ return il->debugfs_ops->general_stats_read(file, user_buf, count, ppos);
}
static ssize_t
@@ -1153,7 +1174,7 @@ il_dbgfs_rxon_flags_read(struct file *file, char __user *user_buf,
int len = 0;
char buf[20];
- len = sprintf(buf, "0x%04X\n", le32_to_cpu(il->ctx.active.flags));
+ len = sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.flags));
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
@@ -1167,7 +1188,7 @@ il_dbgfs_rxon_filter_flags_read(struct file *file, char __user *user_buf,
char buf[20];
len =
- sprintf(buf, "0x%04X\n", le32_to_cpu(il->ctx.active.filter_flags));
+ sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.filter_flags));
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
}
@@ -1180,8 +1201,8 @@ il_dbgfs_fh_reg_read(struct file *file, char __user *user_buf, size_t count,
int pos = 0;
ssize_t ret = -EFAULT;
- if (il->cfg->ops->lib->dump_fh) {
- ret = pos = il->cfg->ops->lib->dump_fh(il, &buf, true);
+ if (il->ops->dump_fh) {
+ ret = pos = il->ops->dump_fh(il, &buf, true);
if (buf) {
ret =
simple_read_from_buffer(user_buf, count, ppos, buf,
@@ -1298,14 +1319,13 @@ il_dbgfs_wd_timeout_write(struct file *file, const char __user *user_buf,
if (timeout < 0 || timeout > IL_MAX_WD_TIMEOUT)
timeout = IL_DEF_WD_TIMEOUT;
- il->cfg->base_params->wd_timeout = timeout;
+ il->cfg->wd_timeout = timeout;
il_setup_watchdog(il);
return count;
}
DEBUGFS_READ_FILE_OPS(rx_stats);
DEBUGFS_READ_FILE_OPS(tx_stats);
-DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
DEBUGFS_READ_FILE_OPS(rx_queue);
DEBUGFS_READ_FILE_OPS(tx_queue);
DEBUGFS_READ_FILE_OPS(ucode_rx_stats);
@@ -1359,7 +1379,6 @@ il_dbgfs_register(struct il_priv *il, const char *name)
DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(rx_stats, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(tx_stats, dir_debug, S_IRUSR);
- DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
@@ -1372,17 +1391,17 @@ il_dbgfs_register(struct il_priv *il, const char *name)
DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);
- if (il->cfg->base_params->sensitivity_calib_by_driver)
+ if (il->cfg->sensitivity_calib_by_driver)
DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
- if (il->cfg->base_params->chain_noise_calib_by_driver)
+ if (il->cfg->chain_noise_calib_by_driver)
DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
- if (il->cfg->base_params->sensitivity_calib_by_driver)
+ if (il->cfg->sensitivity_calib_by_driver)
DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
&il->disable_sens_cal);
- if (il->cfg->base_params->chain_noise_calib_by_driver)
+ if (il->cfg->chain_noise_calib_by_driver)
DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
&il->disable_chain_noise_cal);
DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, &il->disable_tx_power_cal);