aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlegacy/4965.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlegacy/4965.c')
-rw-r--r--drivers/net/wireless/iwlegacy/4965.c698
1 files changed, 125 insertions, 573 deletions
diff --git a/drivers/net/wireless/iwlegacy/4965.c b/drivers/net/wireless/iwlegacy/4965.c
index cacbc03880b0..5db11714e047 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 */