diff options
Diffstat (limited to 'drivers/net/wireless/iwlegacy')
-rw-r--r-- | drivers/net/wireless/iwlegacy/3945-debug.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/3945-mac.c | 288 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/3945-rs.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/3945.c | 235 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/3945.h | 14 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/4965-calib.c | 36 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/4965-debug.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/4965-mac.c | 1058 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/4965-rs.c | 48 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/4965.c | 698 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/4965.h | 43 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/Kconfig | 78 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/common.c | 1112 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/common.h | 471 | ||||
-rw-r--r-- | drivers/net/wireless/iwlegacy/debug.c | 291 |
15 files changed, 1800 insertions, 2591 deletions
diff --git a/drivers/net/wireless/iwlegacy/3945-debug.c b/drivers/net/wireless/iwlegacy/3945-debug.c index 5e1a19fd354..f767dd106b0 100644 --- a/drivers/net/wireless/iwlegacy/3945-debug.c +++ b/drivers/net/wireless/iwlegacy/3945-debug.c @@ -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 54b2d391e91..0c120939016 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); @@ -512,7 +512,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, info->control.sta); if (sta_id == IL_INVALID_STATION) { D_DROP("Dropping - INVALID STATION: %pM\n", hdr->addr1); goto drop; @@ -538,10 +538,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]; @@ -576,7 +573,6 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb) len = (u16) skb->len; tx_cmd->len = cpu_to_le16(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; @@ -619,8 +615,7 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb) /* 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); + il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1, 0); /* Set up TFD's 2nd entry to point directly to remainder of skb, * if any (802.11 null frames have no payload). */ @@ -629,8 +624,8 @@ il3945_tx_skb(struct il_priv *il, struct sk_buff *skb) phys_addr = pci_map_single(il->pci_dev, skb->data + hdr_len, len, PCI_DMA_TODEVICE); - il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq, phys_addr, - len, 0, U32_PAD(len)); + il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, len, 0, + U32_PAD(len)); } /* Tell device the write idx *just past* this latest filled TFD */ @@ -672,15 +667,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 +687,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 +809,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); } @@ -2150,7 +2142,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 +2166,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 +2178,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 +2197,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 +2212,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 +2244,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 +2272,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 +2281,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 +2331,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,9 +2371,9 @@ __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); + set_bit(S_RFKILL, &il->status); IL_WARN("Radio disabled by HW RF Kill switch\n"); return -ENODEV; } @@ -2414,7 +2405,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 +2413,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); @@ -2475,7 +2466,7 @@ il3945_bg_alive_start(struct work_struct *data) container_of(data, struct il_priv, alive_start.work); mutex_lock(&il->mutex); - if (test_bit(S_EXIT_PENDING, &il->status)) + if (test_bit(S_EXIT_PENDING, &il->status) || il->txq == NULL) goto out; il3945_alive_start(il); @@ -2494,15 +2485,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 +2593,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 +2655,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 +2673,8 @@ 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; + /* FIXME: vif can be dereferenced */ + il->vif = NULL; il->is_open = 0; mutex_unlock(&il->mutex); il3945_down(il); @@ -2722,13 +2712,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 +2726,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 +2763,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 +2782,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. */ @@ -2891,8 +2879,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 +2889,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 +2940,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 +2977,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 +2993,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 +3021,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 +3040,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, @@ -3112,11 +3100,9 @@ il3945_store_debug_level(struct device *d, struct device_attribute *attr, ret = strict_strtoul(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 +3156,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 +3166,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 +3191,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 +3200,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 +3260,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), }; @@ -3474,7 +3455,7 @@ static struct attribute_group il3945_attribute_group = { .attrs = il3945_sysfs_entries, }; -struct ieee80211_ops il3945_hw_ops = { +struct ieee80211_ops il3945_mac_ops = { .tx = il3945_mac_tx, .start = il3945_mac_start, .stop = il3945_mac_stop, @@ -3567,7 +3548,8 @@ il3945_setup_mac(struct il_priv *il) /* Tell mac80211 our characteristics */ hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SPECTRUM_MGMT; - hw->wiphy->interface_modes = il->ctx.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 | @@ -3614,50 +3596,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 +3655,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 +3669,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); @@ -3773,8 +3740,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,14 +3780,13 @@ 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; @@ -3889,12 +3854,11 @@ 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); diff --git a/drivers/net/wireless/iwlegacy/3945-rs.c b/drivers/net/wireless/iwlegacy/3945-rs.c index d7a83f22919..70bee1a4d87 100644 --- a/drivers/net/wireless/iwlegacy/3945-rs.c +++ b/drivers/net/wireless/iwlegacy/3945-rs.c @@ -342,7 +342,7 @@ 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; @@ -927,8 +927,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 +943,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 diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index 1489b1573a6..c5b1d199e0b 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c @@ -57,10 +57,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 +289,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 && @@ -336,7 +332,7 @@ il3945_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb) } 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 */ @@ -577,8 +573,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 +654,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 +790,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 +826,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 +842,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 +947,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 +1002,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 +1011,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 +1373,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 +1382,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 +1600,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 +1647,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 +1658,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 +1669,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 +1699,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 +1720,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 +1729,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 +1761,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 +1771,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 +1786,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 +1799,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 @@ -1870,11 +1855,12 @@ il3945_bg_reg_txpower_periodic(struct work_struct *work) struct il_priv *il = container_of(work, struct il_priv, _3945.thermal_periodic.work); - if (test_bit(S_EXIT_PENDING, &il->status)) - return; - mutex_lock(&il->mutex); + if (test_bit(S_EXIT_PENDING, &il->status) || il->txq == NULL) + goto out; + il3945_reg_txpower_periodic(il); +out: mutex_unlock(&il->mutex); } @@ -2185,12 +2171,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; @@ -2258,7 +2246,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; @@ -2266,7 +2253,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; @@ -2396,15 +2383,16 @@ il3945_hw_set_hw_params(struct il_priv *il) 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; @@ -2425,7 +2413,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 = @@ -2632,76 +2620,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 = { @@ -2711,10 +2654,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 = { @@ -2724,10 +2683,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..1d45075e0d5 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 @@ -249,7 +251,7 @@ 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); -extern int il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx); +extern int il3945_commit_rxon(struct il_priv *il); /** * il3945_hw_find_station - Find station id for a given BSSID @@ -261,8 +263,6 @@ extern int il3945_commit_rxon(struct il_priv *il, struct il_rxon_context *ctx); */ extern u8 il3945_hw_find_station(struct il_priv *il, const u8 * bssid); -extern struct ieee80211_ops il3945_hw_ops; - 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); @@ -595,13 +595,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..c8153fc64f7 100644 --- a/drivers/net/wireless/iwlegacy/4965-debug.c +++ b/drivers/net/wireless/iwlegacy/4965-debug.c @@ -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..7b54dbb338b 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c @@ -199,18 +199,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) { @@ -445,11 +441,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; } @@ -692,7 +692,6 @@ il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb) /* 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); @@ -843,7 +842,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 +857,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 +915,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 +1029,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 +1122,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 +1158,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 || @@ -1348,12 +1342,11 @@ il4965_accumulative_stats(struct il_priv *il, __le32 * stats) } #endif -#define REG_RECALIB_PERIOD (60) - 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,20 +1367,21 @@ 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 @@ -1457,10 +1451,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; @@ -1639,7 +1640,6 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) 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 +1655,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 +1676,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, info->control.sta); if (sta_id == IL_INVALID_STATION) { D_DROP("Dropping - INVALID STATION: %pM\n", hdr->addr1); @@ -1696,7 +1693,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 +1706,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 +1752,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]; @@ -1798,7 +1784,6 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) /* 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); @@ -1828,8 +1813,7 @@ il4965_tx_skb(struct il_priv *il, struct sk_buff *skb) 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); + il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, 1, 0); if (!ieee80211_has_morefrags(hdr->frame_control)) { txq->need_update = 1; @@ -1845,8 +1829,8 @@ 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); + il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, secondlen, + 0, 0); } scratch_phys = @@ -1866,9 +1850,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); @@ -1957,7 +1939,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 +1952,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 +1989,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 +2010,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) +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 +2043,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 +2140,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 +2207,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; @@ -2290,11 +2268,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 +2301,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 +2376,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); @@ -2410,11 +2386,11 @@ il4965_txq_check_empty(struct il_priv *il, int sta_id, u8 tid, int txq_id) 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); + 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 +2398,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 +2407,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 +2425,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 +2440,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 +2454,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 +2529,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 +2540,308 @@ 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 && + (!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); + } +} + +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; + } +} + +/** + * 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 != (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; +} + +/** + * 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; + } + + 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 */ @@ -2771,8 +3047,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 +3057,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 +3078,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 +3090,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 +3110,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 +3136,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 +3213,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 +3250,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 +3262,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 +3298,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 +3308,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 +3342,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 +3355,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 +3373,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 +3386,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); @@ -3167,28 +3437,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 +3480,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 +3520,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 +3546,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 +3646,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 +3761,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 +3781,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 +3792,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 +3915,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 +4020,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 +4072,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 +4110,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 +4162,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; } /** @@ -4127,9 +4396,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", @@ -4144,9 +4412,9 @@ il4965_irq_tasklet(struct il_priv *il) */ if (!test_bit(S_ALIVE, &il->status)) { if (hw_rf_kill) - 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_rf_kill); } @@ -4270,11 +4538,9 @@ il4965_store_debug_level(struct device *d, struct device_attribute *attr, ret = strict_strtoul(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); } @@ -4799,7 +5065,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 +5245,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 +5284,18 @@ il4965_alive_start(struct il_priv *il) il->active_rate = RATES_MASK; - if (il_is_associated_ctx(ctx)) { + 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 +5306,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); @@ -5076,7 +5341,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 +5383,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 +5392,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 +5438,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 +5480,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 +5500,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 +5558,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 +5599,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 +5651,8 @@ 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; + /* FIXME: do we dereference vif without mutex locked ? */ + il->vif = NULL; il->is_open = 0; __il4965_down(il); @@ -5450,8 +5721,8 @@ 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; @@ -5578,12 +5849,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 +5863,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 +5874,7 @@ 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); + sta_id = il_sta_id_or_broadcast(il, sta); if (sta_id == IL_INVALID_STATION) return -EINVAL; @@ -5623,7 +5890,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 +5899,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; @@ -5711,7 +5975,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 +5987,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 ? */ @@ -5752,8 +6014,6 @@ il4965_mac_channel_switch(struct ieee80211_hw *hw, struct ieee80211_conf *conf = &hw->conf; struct ieee80211_channel *channel = ch_switch->channel; 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 +6028,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 +6049,30 @@ 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) { + il->ht.enabled = conf_is_ht(conf); + 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; - 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 +6083,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 +6120,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 +6166,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 +6272,28 @@ il4965_tx_queue_set_status(struct il_priv *il, struct il_tx_queue *txq, scd_retry ? "BA" : "AC", txq_id, tx_fifo_id); } +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, +}; + static int il4965_init_drv(struct il_priv *il) { @@ -6036,8 +6318,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 +6347,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 +6361,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 +6404,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 +6450,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 +6506,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; @@ -6260,10 +6567,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 +6611,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,14 +6638,13 @@ 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; @@ -6412,11 +6715,10 @@ 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); diff --git a/drivers/net/wireless/iwlegacy/4965-rs.c b/drivers/net/wireless/iwlegacy/4965-rs.c index 467d0cb14ec..d7e2856e41d 100644 --- a/drivers/net/wireless/iwlegacy/4965-rs.c +++ b/drivers/net/wireless/iwlegacy/4965-rs.c @@ -641,13 +641,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 +820,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"); @@ -892,7 +887,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,8 +1179,6 @@ 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; @@ -1206,7 +1199,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 +1233,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 +1245,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 +1724,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 +1732,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 +1768,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 +1803,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 +1842,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 +2045,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 +2085,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 +2153,15 @@ 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 = il4965_rs_use_green(il, sta); u8 active_tbl = 0; u8 valid_tx_ant; struct il_station_priv *sta_priv; - struct il_rxon_context *ctx; if (!sta || !lq_sta) return; sta_priv = (void *)sta->drv_priv; - ctx = sta_priv->common.ctx; i = lq_sta->last_txrate_idx; @@ -2208,7 +2193,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 @@ -2341,7 +2326,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; /* @@ -2579,9 +2564,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 +2585,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; diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c index cacbc03880b..5db11714e04 100644 --- a/drivers/net/wireless/iwlegacy/4965.c +++ b/drivers/net/wireless/iwlegacy/4965.c @@ -264,10 +264,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 +504,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 +565,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 +1262,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 +1270,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 +1291,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 +1311,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 +1330,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 +1354,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 +1363,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 +1384,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 +1399,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 +1410,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 +1420,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 +1442,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 +1469,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 +1479,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); + + if (WARN_ON_ONCE(vif == NULL)) + return -EIO; - is_ht40 = iw4965_is_ht40_channel(ctx->staging.flags); + 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; 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 +1529,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 +1674,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,339 +1733,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_vif *vif = il->vif; struct ieee80211_conf *conf = NULL; int ret = 0; @@ -2161,41 +1761,41 @@ il4965_post_associate(struct il_priv *il) conf = &il->hw->conf; - 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); - 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 +1823,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 +1832,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 +1847,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 +1916,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..1db677689cf 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 */ @@ -85,7 +84,6 @@ int il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif, 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 +105,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 +126,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); @@ -279,6 +268,7 @@ il4965_hw_valid_rtc_data_addr(u32 addr) ((t) < IL_TX_POWER_TEMPERATURE_MIN || \ (t) > IL_TX_POWER_TEMPERATURE_MAX) +extern void il4965_temperature_calib(struct il_priv *il); /********************* END TEMPERATURE ***************************************/ /********************* START TXPOWER *****************************************/ @@ -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/common.c b/drivers/net/wireless/iwlegacy/common.c index 36454d0bbee..e5ac04739bc 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -81,7 +81,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 +111,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 +161,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 +179,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 +193,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 +350,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 +511,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 +690,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 +721,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 +730,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 +740,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 +772,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 +798,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 +1000,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 */ @@ -1158,9 +1155,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); @@ -1442,7 +1439,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 +1453,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 +1482,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 +1504,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 +1523,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 +1544,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; @@ -1673,7 +1666,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 +1808,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,8 +1825,7 @@ 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; @@ -1874,7 +1866,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 +1882,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,9 +1891,9 @@ 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 @@ -1950,22 +1942,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 +1967,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 +1977,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 +2164,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 +2174,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 +2196,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 +2214,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 +2251,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 +2331,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 +2359,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 +2385,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 +2413,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); @@ -2648,7 +2628,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 +2719,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 +2752,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 +2887,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,23 +2929,21 @@ 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); + IL_ERR("Fail to alloc TFDs\n"); goto error; } txq->q.id = id; @@ -2971,8 +2951,8 @@ il_tx_queue_alloc(struct il_priv *il, struct il_tx_queue *txq, u32 id) return 0; error: - kfree(txq->txb); - txq->txb = NULL; + kfree(txq->skbs); + txq->skbs = NULL; return -ENOMEM; } @@ -2981,12 +2961,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 +2975,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 +2994,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 +3017,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 +3036,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 +3084,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 @@ -3179,9 +3163,9 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd) #endif txq->need_update = 1; - if (il->cfg->ops->lib->txq_update_byte_cnt_tbl) + if (il->ops->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); + il->ops->txq_update_byte_cnt_tbl(il, txq, 0); phys_addr = pci_map_single(il->pci_dev, &out_cmd->hdr, fix_size, @@ -3189,8 +3173,8 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd) 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)); + 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); @@ -3332,30 +3316,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 @@ -3562,10 +3522,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 +3540,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 +3580,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 +3603,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 +3643,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 +3723,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,7 +3743,7 @@ 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(!il_is_associated(il)); CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr)); CHK(compare_ether_addr(staging->node_addr, active->node_addr)); CHK(compare_ether_addr @@ -3819,13 +3777,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 +3791,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 +3804,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 +3827,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 +3848,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 +3882,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 +3902,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 +3925,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 +3951,60 @@ 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)); - - 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; - } + memset(&il->staging, 0, sizeof(il->staging)); + + if (!il->vif) { + il->staging.dev_type = RXON_DEV_TYPE_ESS; + } else if (il->vif->type == NL80211_IFTYPE_STATION) { + il->staging.dev_type = RXON_DEV_TYPE_ESS; + il->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; + } else if (il->vif->type == 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; + } else { + 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 +4031,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 +4042,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 +4055,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 +4075,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 +4107,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 +4132,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 +4151,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 +4169,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,7 +4232,7 @@ 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) { + if (il->cfg->set_l0s) { lctl = il_pcie_link_ctl(il); if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN) { @@ -4293,9 +4249,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 +4281,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 +4303,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 +4333,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 +4342,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 +4460,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 +4481,36 @@ 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; + il_connection_init_rx_config(il); - lockdep_assert_held(&il->mutex); + if (il->ops->set_rxon_chain) + il->ops->set_rxon_chain(il); - /* - * 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; - - err = il_set_mode(il, ctx); - if (err) { - if (!ctx->always_active) - ctx->is_active = false; - return err; - } - - 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); 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,32 +4518,24 @@ 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))) { + if (il->vif) { 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->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); @@ -4621,8 +4544,6 @@ static void il_teardown_interface(struct il_priv *il, struct ieee80211_vif *vif, bool mode_change) { - struct il_rxon_context *ctx = il_rxon_ctx_from_vif(vif); - lockdep_assert_held(&il->mutex); if (il->scan_vif == vif) { @@ -4630,33 +4551,27 @@ 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; - } + if (!mode_change) + 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; + WARN_ON(il->vif != vif); + il->vif = NULL; il_teardown_interface(il, vif, false); - 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 +4581,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 +4591,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) @@ -4987,15 +4655,18 @@ 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,23 +4675,11 @@ 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); + vif->p2p = false; + err = il_set_mode(il); WARN_ON(err); /* * We've switched internally, but submitting to the @@ -5032,7 +4691,9 @@ il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, err = 0; out: + D_MAC80211("leave err %d\n", err); mutex_unlock(&il->mutex); + return err; } EXPORT_SYMBOL(il_mac_change_interface); @@ -5056,11 +4717,11 @@ il_check_stuck_queue(struct il_priv *il, int cnt) 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)) { IL_ERR("Queue %d stuck for %u ms.\n", q->id, - il->cfg->base_params->wd_timeout); + il->cfg->wd_timeout); ret = il_force_reset(il, false); return (ret == -EAGAIN) ? 0 : 1; } @@ -5088,7 +4749,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; @@ -5115,7 +4776,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, @@ -5229,9 +4890,9 @@ 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); @@ -5252,28 +4913,25 @@ EXPORT_SYMBOL(il_pm_ops); #endif /* CONFIG_PM */ 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; - - ctx->qos_data.def_qos_parm.qos_flags = 0; + il->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); } /** @@ -5287,19 +4945,14 @@ il_mac_config(struct ieee80211_hw *hw, u32 changed) struct ieee80211_conf *conf = &hw->conf; struct ieee80211_channel *channel = conf->channel; 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 +4972,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 +5002,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 @@ -5420,16 +5073,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 +5093,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 +5116,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 +5133,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 +5190,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 +5215,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 +5239,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 +5247,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,21 +5262,17 @@ 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) { @@ -5652,23 +5284,20 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, * below/in post_associate will fail. */ 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, + memcpy(il->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; - } - + } else + il->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; } /* @@ -5682,21 +5311,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 +5335,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 +5348,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->last_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..5f5017767b9 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); @@ -735,13 +723,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 +739,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 +802,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 +823,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; @@ -968,26 +956,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 +1120,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 { @@ -1211,12 +1130,15 @@ struct il_power_mgr { }; 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 +1175,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 +1223,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; @@ -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; - -#ifdef CONFIG_IWLEGACY_DEBUGFS - struct il_debugfs_ops debugfs_ops; -#endif + int (*rxon_assoc) (struct il_priv *il); + int (*commit_rxon) (struct il_priv *il); + void (*set_rxon_chain) (struct il_priv *il); -}; - -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 { @@ -1725,37 +1603,6 @@ struct il_mod_params { 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); @@ -1864,60 +1724,24 @@ void il_mac_remove_interface(struct ieee80211_hw *hw, int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum nl80211_iftype newtype, bool newp2p); 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); +extern 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,25 +1752,20 @@ 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); -void il_tx_queue_unmap(struct il_priv *il, int txq_id); -void il_tx_queue_free(struct il_priv *il, int txq_id); -void il_setup_watchdog(struct il_priv *il); +extern void il_txq_update_write_ptr(struct il_priv *il, struct il_tx_queue *txq); +extern int il_tx_queue_init(struct il_priv *il, u32 txq_id); +extern void il_tx_queue_reset(struct il_priv *il, u32 txq_id); +extern void il_tx_queue_unmap(struct il_priv *il, int txq_id); +extern void il_tx_queue_free(struct il_priv *il, int txq_id); +extern void il_setup_watchdog(struct il_priv *il); /***************************************************** * TX power ****************************************************/ @@ -1956,7 +1775,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 @@ -2043,10 +1862,10 @@ extern const struct dev_pm_ops il_pm_ops; ******************************************************/ 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 +1883,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 +1922,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 @@ -2132,20 +1945,23 @@ il_is_ready_rf(struct il_priv *il) extern void il_send_bt_config(struct il_priv *il); extern int il_send_stats_request(struct il_priv *il, u8 flags, bool clear); -void il_apm_stop(struct il_priv *il); +extern void il_apm_stop(struct il_priv *il); +extern void _il_apm_stop(struct il_priv *il); + int il_apm_init(struct il_priv *il); -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 * @@ -2166,7 +1982,7 @@ 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 bool _il_grab_nic_access(struct il_priv *il); extern int _il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout); extern int il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout); extern u32 il_rd_prph(struct il_priv *il, u32 reg); @@ -2177,20 +1993,20 @@ extern void il_write_targ_mem(struct il_priv *il, u32 addr, u32 val); static inline void _il_write8(struct il_priv *il, u32 ofs, u8 val) { - 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 +2025,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 +2054,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 +2065,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 +2072,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 +2081,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 +2094,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 +2108,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 +2127,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 +2157,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 +2186,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); @@ -2565,10 +2374,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 diff --git a/drivers/net/wireless/iwlegacy/debug.c b/drivers/net/wireless/iwlegacy/debug.c index b1b8926a9c7..229849150aa 100644 --- a/drivers/net/wireless/iwlegacy/debug.c +++ b/drivers/net/wireless/iwlegacy/debug.c @@ -31,6 +31,101 @@ #include "common.h" +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, \ @@ -98,6 +193,46 @@ static const struct file_operations il_dbgfs_##name##_ops = { \ .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 +496,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) { @@ -495,8 +630,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 +779,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 +790,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 +850,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 +862,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 +930,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 +939,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 +948,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 +1180,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 +1194,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 +1207,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 +1325,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 +1385,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 +1397,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); |