]> rtime.felk.cvut.cz Git - lisovros/linux_canprio.git/commitdiff
Merge branch 'master' of git://github.com/padovan/bluetooth-next
authorJohn W. Linville <linville@tuxdriver.com>
Tue, 27 Sep 2011 18:15:00 +0000 (14:15 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 27 Sep 2011 18:15:00 +0000 (14:15 -0400)
23 files changed:
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn-tx.c
drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-led.c
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/iwlwifi/iwl-scan.c
drivers/net/wireless/iwlwifi/iwl-shared.h
drivers/net/wireless/iwlwifi/iwl-sta.c
drivers/net/wireless/iwlwifi/iwl-sta.h
drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h
drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c
drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
drivers/net/wireless/iwlwifi/iwl-trans.h
drivers/net/wireless/mwifiex/sta_ioctl.c
drivers/nfc/Kconfig
net/mac80211/iface.c
net/mac80211/mesh_plink.c

index e8b324c84da8e4aeff107a0cad5e92179b617235..d30714be515b38249028337f59d6238b7deff305 100644 (file)
@@ -190,433 +190,6 @@ int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band)
        return -1;
 }
 
-static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
-                                          struct ieee80211_vif *vif,
-                                          enum ieee80211_band band,
-                                          struct iwl_scan_channel *scan_ch)
-{
-       const struct ieee80211_supported_band *sband;
-       u16 passive_dwell = 0;
-       u16 active_dwell = 0;
-       int added = 0;
-       u16 channel = 0;
-
-       sband = iwl_get_hw_mode(priv, band);
-       if (!sband) {
-               IWL_ERR(priv, "invalid band\n");
-               return added;
-       }
-
-       active_dwell = iwl_get_active_dwell_time(priv, band, 0);
-       passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);
-
-       if (passive_dwell <= active_dwell)
-               passive_dwell = active_dwell + 1;
-
-       channel = iwl_get_single_channel_number(priv, band);
-       if (channel) {
-               scan_ch->channel = cpu_to_le16(channel);
-               scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
-               scan_ch->active_dwell = cpu_to_le16(active_dwell);
-               scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
-               /* Set txpower levels to defaults */
-               scan_ch->dsp_atten = 110;
-               if (band == IEEE80211_BAND_5GHZ)
-                       scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
-               else
-                       scan_ch->tx_gain = ((1 << 5) | (5 << 3));
-               added++;
-       } else
-               IWL_ERR(priv, "no valid channel found\n");
-       return added;
-}
-
-static int iwl_get_channels_for_scan(struct iwl_priv *priv,
-                                    struct ieee80211_vif *vif,
-                                    enum ieee80211_band band,
-                                    u8 is_active, u8 n_probes,
-                                    struct iwl_scan_channel *scan_ch)
-{
-       struct ieee80211_channel *chan;
-       const struct ieee80211_supported_band *sband;
-       const struct iwl_channel_info *ch_info;
-       u16 passive_dwell = 0;
-       u16 active_dwell = 0;
-       int added, i;
-       u16 channel;
-
-       sband = iwl_get_hw_mode(priv, band);
-       if (!sband)
-               return 0;
-
-       active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
-       passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);
-
-       if (passive_dwell <= active_dwell)
-               passive_dwell = active_dwell + 1;
-
-       for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) {
-               chan = priv->scan_request->channels[i];
-
-               if (chan->band != band)
-                       continue;
-
-               channel = chan->hw_value;
-               scan_ch->channel = cpu_to_le16(channel);
-
-               ch_info = iwl_get_channel_info(priv, band, channel);
-               if (!is_channel_valid(ch_info)) {
-                       IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n",
-                                       channel);
-                       continue;
-               }
-
-               if (!is_active || is_channel_passive(ch_info) ||
-                   (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
-                       scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
-               else
-                       scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
-
-               if (n_probes)
-                       scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
-
-               scan_ch->active_dwell = cpu_to_le16(active_dwell);
-               scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
-
-               /* Set txpower levels to defaults */
-               scan_ch->dsp_atten = 110;
-
-               /* NOTE: if we were doing 6Mb OFDM for scans we'd use
-                * power level:
-                * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
-                */
-               if (band == IEEE80211_BAND_5GHZ)
-                       scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
-               else
-                       scan_ch->tx_gain = ((1 << 5) | (5 << 3));
-
-               IWL_DEBUG_SCAN(priv, "Scanning ch=%d prob=0x%X [%s %d]\n",
-                              channel, le32_to_cpu(scan_ch->type),
-                              (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
-                               "ACTIVE" : "PASSIVE",
-                              (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
-                              active_dwell : passive_dwell);
-
-               scan_ch++;
-               added++;
-       }
-
-       IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added);
-       return added;
-}
-
-int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
-{
-       struct iwl_host_cmd cmd = {
-               .id = REPLY_SCAN_CMD,
-               .len = { sizeof(struct iwl_scan_cmd), },
-               .flags = CMD_SYNC,
-       };
-       struct iwl_scan_cmd *scan;
-       struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
-       u32 rate_flags = 0;
-       u16 cmd_len;
-       u16 rx_chain = 0;
-       enum ieee80211_band band;
-       u8 n_probes = 0;
-       u8 rx_ant = hw_params(priv).valid_rx_ant;
-       u8 rate;
-       bool is_active = false;
-       int  chan_mod;
-       u8 active_chains;
-       u8 scan_tx_antennas = hw_params(priv).valid_tx_ant;
-       int ret;
-
-       lockdep_assert_held(&priv->shrd->mutex);
-
-       if (vif)
-               ctx = iwl_rxon_ctx_from_vif(vif);
-
-       if (!priv->scan_cmd) {
-               priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) +
-                                        IWL_MAX_SCAN_SIZE, GFP_KERNEL);
-               if (!priv->scan_cmd) {
-                       IWL_DEBUG_SCAN(priv,
-                                      "fail to allocate memory for scan\n");
-                       return -ENOMEM;
-               }
-       }
-       scan = priv->scan_cmd;
-       memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);
-
-       scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
-       scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
-
-       if (priv->scan_type != IWL_SCAN_ROC &&
-           iwl_is_any_associated(priv)) {
-               u16 interval = 0;
-               u32 extra;
-               u32 suspend_time = 100;
-               u32 scan_suspend_time = 100;
-
-               IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
-               switch (priv->scan_type) {
-               case IWL_SCAN_ROC:
-                       WARN_ON(1);
-                       break;
-               case IWL_SCAN_RADIO_RESET:
-                       interval = 0;
-                       break;
-               case IWL_SCAN_NORMAL:
-                       interval = vif->bss_conf.beacon_int;
-                       break;
-               }
-
-               scan->suspend_time = 0;
-               scan->max_out_time = cpu_to_le32(200 * 1024);
-               if (!interval)
-                       interval = suspend_time;
-
-               extra = (suspend_time / interval) << 22;
-               scan_suspend_time = (extra |
-                   ((suspend_time % interval) * 1024));
-               scan->suspend_time = cpu_to_le32(scan_suspend_time);
-               IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
-                              scan_suspend_time, interval);
-       } else if (priv->scan_type == IWL_SCAN_ROC) {
-               scan->suspend_time = 0;
-               scan->max_out_time = 0;
-               scan->quiet_time = 0;
-               scan->quiet_plcp_th = 0;
-       }
-
-       switch (priv->scan_type) {
-       case IWL_SCAN_RADIO_RESET:
-               IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
-               break;
-       case IWL_SCAN_NORMAL:
-               if (priv->scan_request->n_ssids) {
-                       int i, p = 0;
-                       IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
-                       for (i = 0; i < priv->scan_request->n_ssids; i++) {
-                               /* always does wildcard anyway */
-                               if (!priv->scan_request->ssids[i].ssid_len)
-                                       continue;
-                               scan->direct_scan[p].id = WLAN_EID_SSID;
-                               scan->direct_scan[p].len =
-                                       priv->scan_request->ssids[i].ssid_len;
-                               memcpy(scan->direct_scan[p].ssid,
-                                      priv->scan_request->ssids[i].ssid,
-                                      priv->scan_request->ssids[i].ssid_len);
-                               n_probes++;
-                               p++;
-                       }
-                       is_active = true;
-               } else
-                       IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
-               break;
-       case IWL_SCAN_ROC:
-               IWL_DEBUG_SCAN(priv, "Start ROC scan.\n");
-               break;
-       }
-
-       scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
-       scan->tx_cmd.sta_id = ctx->bcast_sta_id;
-       scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
-
-       switch (priv->scan_band) {
-       case IEEE80211_BAND_2GHZ:
-               scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
-               chan_mod = le32_to_cpu(
-                       priv->contexts[IWL_RXON_CTX_BSS].active.flags &
-                                               RXON_FLG_CHANNEL_MODE_MSK)
-                                      >> RXON_FLG_CHANNEL_MODE_POS;
-               if (chan_mod == CHANNEL_MODE_PURE_40) {
-                       rate = IWL_RATE_6M_PLCP;
-               } else {
-                       rate = IWL_RATE_1M_PLCP;
-                       rate_flags = RATE_MCS_CCK_MSK;
-               }
-               /*
-                * Internal scans are passive, so we can indiscriminately set
-                * the BT ignore flag on 2.4 GHz since it applies to TX only.
-                */
-               if (priv->cfg->bt_params &&
-                   priv->cfg->bt_params->advanced_bt_coexist)
-                       scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT;
-               break;
-       case IEEE80211_BAND_5GHZ:
-               rate = IWL_RATE_6M_PLCP;
-               break;
-       default:
-               IWL_WARN(priv, "Invalid scan band\n");
-               return -EIO;
-       }
-
-       /*
-        * If active scanning is requested but a certain channel is
-        * marked passive, we can do active scanning if we detect
-        * transmissions.
-        *
-        * There is an issue with some firmware versions that triggers
-        * a sysassert on a "good CRC threshold" of zero (== disabled),
-        * on a radar channel even though this means that we should NOT
-        * send probes.
-        *
-        * The "good CRC threshold" is the number of frames that we
-        * need to receive during our dwell time on a channel before
-        * sending out probes -- setting this to a huge value will
-        * mean we never reach it, but at the same time work around
-        * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
-        * here instead of IWL_GOOD_CRC_TH_DISABLED.
-        *
-        * This was fixed in later versions along with some other
-        * scan changes, and the threshold behaves as a flag in those
-        * versions.
-        */
-       if (priv->new_scan_threshold_behaviour)
-               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
-                                               IWL_GOOD_CRC_TH_DISABLED;
-       else
-               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
-                                               IWL_GOOD_CRC_TH_NEVER;
-
-       band = priv->scan_band;
-
-       if (priv->cfg->scan_rx_antennas[band])
-               rx_ant = priv->cfg->scan_rx_antennas[band];
-
-       if (band == IEEE80211_BAND_2GHZ &&
-           priv->cfg->bt_params &&
-           priv->cfg->bt_params->advanced_bt_coexist) {
-               /* transmit 2.4 GHz probes only on first antenna */
-               scan_tx_antennas = first_antenna(scan_tx_antennas);
-       }
-
-       priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band],
-                                                   scan_tx_antennas);
-       rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
-       scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
-
-       /* In power save mode use one chain, otherwise use all chains */
-       if (test_bit(STATUS_POWER_PMI, &priv->shrd->status)) {
-               /* rx_ant has been set to all valid chains previously */
-               active_chains = rx_ant &
-                               ((u8)(priv->chain_noise_data.active_chains));
-               if (!active_chains)
-                       active_chains = rx_ant;
-
-               IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n",
-                               priv->chain_noise_data.active_chains);
-
-               rx_ant = first_antenna(active_chains);
-       }
-       if (priv->cfg->bt_params &&
-           priv->cfg->bt_params->advanced_bt_coexist &&
-           priv->bt_full_concurrent) {
-               /* operated as 1x1 in full concurrency mode */
-               rx_ant = first_antenna(rx_ant);
-       }
-
-       /* MIMO is not used here, but value is required */
-       rx_chain |=
-               hw_params(priv).valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
-       rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
-       rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
-       rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
-       scan->rx_chain = cpu_to_le16(rx_chain);
-       switch (priv->scan_type) {
-       case IWL_SCAN_NORMAL:
-               cmd_len = iwl_fill_probe_req(priv,
-                                       (struct ieee80211_mgmt *)scan->data,
-                                       vif->addr,
-                                       priv->scan_request->ie,
-                                       priv->scan_request->ie_len,
-                                       IWL_MAX_SCAN_SIZE - sizeof(*scan));
-               break;
-       case IWL_SCAN_RADIO_RESET:
-       case IWL_SCAN_ROC:
-               /* use bcast addr, will not be transmitted but must be valid */
-               cmd_len = iwl_fill_probe_req(priv,
-                                       (struct ieee80211_mgmt *)scan->data,
-                                       iwl_bcast_addr, NULL, 0,
-                                       IWL_MAX_SCAN_SIZE - sizeof(*scan));
-               break;
-       default:
-               BUG();
-       }
-       scan->tx_cmd.len = cpu_to_le16(cmd_len);
-
-       scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
-                              RXON_FILTER_BCON_AWARE_MSK);
-
-       switch (priv->scan_type) {
-       case IWL_SCAN_RADIO_RESET:
-               scan->channel_count =
-                       iwl_get_single_channel_for_scan(priv, vif, band,
-                               (void *)&scan->data[cmd_len]);
-               break;
-       case IWL_SCAN_NORMAL:
-               scan->channel_count =
-                       iwl_get_channels_for_scan(priv, vif, band,
-                               is_active, n_probes,
-                               (void *)&scan->data[cmd_len]);
-               break;
-       case IWL_SCAN_ROC: {
-               struct iwl_scan_channel *scan_ch;
-
-               scan->channel_count = 1;
-
-               scan_ch = (void *)&scan->data[cmd_len];
-               scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
-               scan_ch->channel =
-                       cpu_to_le16(priv->hw_roc_channel->hw_value);
-               scan_ch->active_dwell =
-               scan_ch->passive_dwell =
-                       cpu_to_le16(priv->hw_roc_duration);
-
-               /* Set txpower levels to defaults */
-               scan_ch->dsp_atten = 110;
-
-               /* NOTE: if we were doing 6Mb OFDM for scans we'd use
-                * power level:
-                * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
-                */
-               if (priv->hw_roc_channel->band == IEEE80211_BAND_5GHZ)
-                       scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
-               else
-                       scan_ch->tx_gain = ((1 << 5) | (5 << 3));
-               }
-               break;
-       }
-
-       if (scan->channel_count == 0) {
-               IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
-               return -EIO;
-       }
-
-       cmd.len[0] += le16_to_cpu(scan->tx_cmd.len) +
-           scan->channel_count * sizeof(struct iwl_scan_channel);
-       cmd.data[0] = scan;
-       cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
-       scan->len = cpu_to_le16(cmd.len[0]);
-
-       /* set scan bit here for PAN params */
-       set_bit(STATUS_SCAN_HW, &priv->shrd->status);
-
-       ret = iwlagn_set_pan_params(priv);
-       if (ret)
-               return ret;
-
-       ret = iwl_trans_send_cmd(trans(priv), &cmd);
-       if (ret) {
-               clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
-               iwlagn_set_pan_params(priv);
-       }
-
-       return ret;
-}
-
 int iwlagn_manage_ibss_station(struct iwl_priv *priv,
                               struct ieee80211_vif *vif, bool add)
 {
@@ -1132,8 +705,9 @@ static void iwlagn_set_kill_msk(struct iwl_priv *priv,
        }
 }
 
-void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
-                                            struct iwl_rx_mem_buffer *rxb)
+int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
+                                 struct iwl_rx_mem_buffer *rxb,
+                                 struct iwl_device_cmd *cmd)
 {
        unsigned long flags;
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -1142,7 +716,7 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
 
        if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) {
                /* bt coex disabled */
-               return;
+               return 0;
        }
 
        IWL_DEBUG_COEX(priv, "BT Coex notification:\n");
@@ -1184,6 +758,7 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
        spin_lock_irqsave(&priv->shrd->lock, flags);
        priv->bt_ci_compliance = coex->bt_ci_compliance;
        spin_unlock_irqrestore(&priv->shrd->lock, flags);
+       return 0;
 }
 
 void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv)
index ffee15ba06a8a53abf6c051713d6950f4011cad2..c14f8d6fd7d8d36878f071ba907ebe0661f5c848 100644 (file)
@@ -346,7 +346,7 @@ static void rs_program_fix_rate(struct iwl_priv *priv,
 {
        struct iwl_station_priv *sta_priv =
                container_of(lq_sta, struct iwl_station_priv, lq_sta);
-       struct iwl_rxon_context *ctx = sta_priv->common.ctx;
+       struct iwl_rxon_context *ctx = sta_priv->ctx;
 
        lq_sta->active_legacy_rate = 0x0FFF;    /* 1 - 54 MBits, includes CCK */
        lq_sta->active_siso_rate   = 0x1FD0;    /* 6 - 60 MBits, no 9, no CCK */
@@ -710,7 +710,7 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
 static bool rs_use_green(struct ieee80211_sta *sta)
 {
        struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
-       struct iwl_rxon_context *ctx = sta_priv->common.ctx;
+       struct iwl_rxon_context *ctx = sta_priv->ctx;
 
        return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) &&
                !(ctx->ht.non_gf_sta_present);
@@ -917,7 +917,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
        struct iwl_scale_tbl_info tbl_type;
        struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
        struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
-       struct iwl_rxon_context *ctx = sta_priv->common.ctx;
+       struct iwl_rxon_context *ctx = sta_priv->ctx;
 
        IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
 
@@ -1283,7 +1283,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
        s32 rate;
        s8 is_green = lq_sta->is_green;
        struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
-       struct iwl_rxon_context *ctx = sta_priv->common.ctx;
+       struct iwl_rxon_context *ctx = sta_priv->ctx;
 
        if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
                return -1;
@@ -1339,7 +1339,7 @@ static int rs_switch_to_mimo3(struct iwl_priv *priv,
        s32 rate;
        s8 is_green = lq_sta->is_green;
        struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
-       struct iwl_rxon_context *ctx = sta_priv->common.ctx;
+       struct iwl_rxon_context *ctx = sta_priv->ctx;
 
        if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
                return -1;
@@ -1396,7 +1396,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
        u8 is_green = lq_sta->is_green;
        s32 rate;
        struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
-       struct iwl_rxon_context *ctx = sta_priv->common.ctx;
+       struct iwl_rxon_context *ctx = sta_priv->ctx;
 
        if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
                return -1;
@@ -2263,7 +2263,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
        u8 tid = IWL_MAX_TID_COUNT;
        struct iwl_tid_data *tid_data;
        struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
-       struct iwl_rxon_context *ctx = sta_priv->common.ctx;
+       struct iwl_rxon_context *ctx = sta_priv->ctx;
 
        IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n");
 
@@ -2706,7 +2706,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
                return;
 
        sta_priv = (void *)sta->drv_priv;
-       ctx = sta_priv->common.ctx;
+       ctx = sta_priv->ctx;
 
        i = lq_sta->last_txrate_idx;
 
index 459b82b8a2a7d0964ebfb8e8fe4f88bc5134e899..8c0f07f56149bf07ea2208e7dace8ad542baf7ef 100644 (file)
@@ -313,6 +313,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
                iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
        }
 
+       if (info->flags & IEEE80211_TX_CTL_AMPDU)
+               is_agg = true;
+
        /* irqs already disabled/saved above when locking priv->shrd->lock */
        spin_lock(&priv->shrd->sta_lock);
 
@@ -322,7 +325,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
                goto drop_unlock_sta;
 
        memset(dev_cmd, 0, sizeof(*dev_cmd));
-       tx_cmd = &dev_cmd->cmd.tx;
+       tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload;
 
        /* Copy MAC header from skb into command buffer */
        memcpy(tx_cmd->hdr, hdr, hdr_len);
@@ -736,7 +739,8 @@ static void iwl_check_abort_status(struct iwl_priv *priv,
        }
 }
 
-void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
+int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+                              struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        u16 sequence = le16_to_cpu(pkt->hdr.sequence);
@@ -824,6 +828,7 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
 
        iwl_check_abort_status(priv, tx_resp->frame_count, status);
        spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       return 0;
 }
 
 /**
@@ -832,8 +837,9 @@ void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
  * Handles block-acknowledge notification from device, which reports success
  * of frames sent via aggregation.
  */
-void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
-                                          struct iwl_rx_mem_buffer *rxb)
+int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
+                                  struct iwl_rx_mem_buffer *rxb,
+                                  struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
@@ -857,7 +863,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
        if (scd_flow >= hw_params(priv).max_txq_num) {
                IWL_ERR(priv,
                        "BUG_ON scd_flow is bigger than number of queues\n");
-               return;
+               return 0;
        }
 
        sta_id = ba_resp->sta_id;
@@ -877,14 +883,14 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
                        "BA scd_flow %d does not match txq_id %d\n",
                        scd_flow, agg->txq_id);
                spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
-               return;
+               return 0;
        }
 
        if (unlikely(!agg->wait_for_ba)) {
                if (unlikely(ba_resp->bitmap))
                        IWL_ERR(priv, "Received BA when not expected\n");
                spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
-               return;
+               return 0;
        }
 
        IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, "
@@ -955,4 +961,5 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
        }
 
        spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
+       return 0;
 }
index 634f18f6125a194a233edb581e2dd3b7a30ad6d9..b4e1e7c4c3148af02c1405bec1fe21003b2003d1 100644 (file)
@@ -228,8 +228,9 @@ static int iwlagn_send_calib_cfg(struct iwl_priv *priv)
        return iwl_trans_send_cmd(trans(priv), &cmd);
 }
 
-void iwlagn_rx_calib_result(struct iwl_priv *priv,
-                            struct iwl_rx_mem_buffer *rxb)
+int iwlagn_rx_calib_result(struct iwl_priv *priv,
+                           struct iwl_rx_mem_buffer *rxb,
+                           struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_calib_hdr *hdr = (struct iwl_calib_hdr *)pkt->u.raw;
@@ -262,9 +263,10 @@ void iwlagn_rx_calib_result(struct iwl_priv *priv,
        default:
                IWL_ERR(priv, "Unknown calibration notification %d\n",
                          hdr->op_code);
-               return;
+               return -1;
        }
        iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
+       return 0;
 }
 
 int iwlagn_init_alive_start(struct iwl_priv *priv)
index 6def1c2727757f6ccb2aa4c33b416681e84b21e7..baaf48616cc7afc11e4e9131e8ad2482f53f8996 100644 (file)
@@ -2513,7 +2513,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
        mutex_lock(&priv->shrd->mutex);
        IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n",
                        sta->addr);
-       sta_priv->common.sta_id = IWL_INVALID_STATION;
+       sta_priv->sta_id = IWL_INVALID_STATION;
 
        atomic_set(&sta_priv->pending_frames, 0);
        if (vif->type == NL80211_IFTYPE_AP)
@@ -2529,7 +2529,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
                return ret;
        }
 
-       sta_priv->common.sta_id = sta_id;
+       sta_priv->sta_id = sta_id;
 
        /* Initialize rate scaling */
        IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
@@ -2770,15 +2770,6 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw,
 
        mutex_lock(&priv->shrd->mutex);
 
-       /*
-        * TODO: Remove this hack! Firmware needs to be updated
-        * to allow longer off-channel periods in scanning for
-        * this use case, based on a flag (and we'll need an API
-        * flag in the firmware when it has that).
-        */
-       if (iwl_is_associated(priv, IWL_RXON_CTX_BSS) && duration > 80)
-               duration = 80;
-
        if (test_bit(STATUS_SCAN_HW, &priv->shrd->status)) {
                err = -EBUSY;
                goto out;
@@ -2787,6 +2778,7 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw,
        priv->hw_roc_channel = channel;
        priv->hw_roc_chantype = channel_type;
        priv->hw_roc_duration = duration;
+       priv->hw_roc_start_notified = false;
        cancel_delayed_work(&priv->hw_roc_disable_work);
 
        if (!ctx->is_active) {
index 4bc1f4669e5a1afe873bd6ba08e174c84970e6cc..2a297d1e6bc7b0db59051036590a421fe4ac7a27 100644 (file)
@@ -88,8 +88,9 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
                             u32 changes);
 
 /* uCode */
-void iwlagn_rx_calib_result(struct iwl_priv *priv,
-                        struct iwl_rx_mem_buffer *rxb);
+int iwlagn_rx_calib_result(struct iwl_priv *priv,
+                           struct iwl_rx_mem_buffer *rxb,
+                           struct iwl_device_cmd *cmd);
 int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
 void iwlagn_send_prio_tbl(struct iwl_priv *priv);
 int iwlagn_run_init_ucode(struct iwl_priv *priv);
@@ -116,9 +117,11 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
                        struct ieee80211_sta *sta, u16 tid, u16 *ssn);
 int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
                       struct ieee80211_sta *sta, u16 tid);
-void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
-                               struct iwl_rx_mem_buffer *rxb);
-void iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
+int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
+                                  struct iwl_rx_mem_buffer *rxb,
+                                  struct iwl_device_cmd *cmd);
+int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+                              struct iwl_device_cmd *cmd);
 
 static inline u32 iwl_tx_status_to_mac80211(u32 status)
 {
@@ -146,7 +149,6 @@ static inline bool iwl_is_tx_success(u32 status)
 u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx, u8 valid);
 
 /* scan */
-int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
 void iwlagn_post_scan(struct iwl_priv *priv);
 void iwlagn_disable_roc(struct iwl_priv *priv);
 
@@ -156,8 +158,9 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
 
 /* bt coex */
 void iwlagn_send_advance_bt_config(struct iwl_priv *priv);
-void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
-                                 struct iwl_rx_mem_buffer *rxb);
+int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
+                                 struct iwl_rx_mem_buffer *rxb,
+                                 struct iwl_device_cmd *cmd);
 void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv);
 void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv);
 void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv);
index 6d7ad45c6d6f9168d69e5486a554ef9423aadee2..74d4cff09faec02b3bb3bfed7c9d731d4f4d0e30 100644 (file)
@@ -330,12 +330,6 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external);
 u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
                       const u8 *ta, const u8 *ie, int ie_len, int left);
 void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
-u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
-                             enum ieee80211_band band,
-                             u8 n_probes);
-u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
-                              enum ieee80211_band band,
-                              struct ieee80211_vif *vif);
 void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
 void iwl_cancel_scan_deferred_work(struct iwl_priv *priv);
 int __must_check iwl_scan_initiate(struct iwl_priv *priv,
index f69e556bd3c2877fc46b5caceb345a71e69bb3d2..4ddaf2c63f50071c06f28a08452b1036f602ab24 100644 (file)
@@ -202,11 +202,6 @@ struct iwl_station_entry {
        struct iwl_link_quality_cmd *lq;
 };
 
-struct iwl_station_priv_common {
-       struct iwl_rxon_context *ctx;
-       u8 sta_id;
-};
-
 /*
  * iwl_station_priv: Driver's private station information
  *
@@ -215,12 +210,13 @@ struct iwl_station_priv_common {
  * space.
  */
 struct iwl_station_priv {
-       struct iwl_station_priv_common common;
+       struct iwl_rxon_context *ctx;
        struct iwl_lq_sta lq_sta;
        atomic_t pending_frames;
        bool client;
        bool asleep;
        u8 max_agg_bufsize;
+       u8 sta_id;
 };
 
 /**
@@ -845,8 +841,9 @@ struct iwl_priv {
 
        void (*pre_rx_handler)(struct iwl_priv *priv,
                               struct iwl_rx_mem_buffer *rxb);
-       void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
-                                      struct iwl_rx_mem_buffer *rxb);
+       int (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
+                                      struct iwl_rx_mem_buffer *rxb,
+                                      struct iwl_device_cmd *cmd);
 
        struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
 
@@ -1033,7 +1030,7 @@ struct iwl_priv {
        struct delayed_work hw_roc_disable_work;
        enum nl80211_channel_type hw_roc_chantype;
        int hw_roc_duration;
-       bool hw_roc_setup;
+       bool hw_roc_setup, hw_roc_start_notified;
 
        /* bt coex */
        u8 bt_enable_flag;
index 7dffed186f0a5f5abf21ee4090aa5b09b458e730..f149165e801075aca13d9865bfd9b2a35ec3368f 100644 (file)
@@ -104,7 +104,6 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
                .len = { sizeof(struct iwl_led_cmd), },
                .data = { led_cmd, },
                .flags = CMD_ASYNC,
-               .callback = NULL,
        };
        u32 reg;
 
index 2ee61031e207b8357e63f40eea6ce2a95f0eb4b4..bcd7f64683aa02c06ebd1af0e8650ef39d8fdd11 100644 (file)
@@ -130,8 +130,9 @@ const char *get_cmd_string(u8 cmd)
  *
  ******************************************************************************/
 
-static void iwl_rx_reply_error(struct iwl_priv *priv,
-                              struct iwl_rx_mem_buffer *rxb)
+static int iwl_rx_reply_error(struct iwl_priv *priv,
+                              struct iwl_rx_mem_buffer *rxb,
+                              struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
 
@@ -142,9 +143,11 @@ static void iwl_rx_reply_error(struct iwl_priv *priv,
                pkt->u.err_resp.cmd_id,
                le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
                le32_to_cpu(pkt->u.err_resp.error_info));
+       return 0;
 }
 
-static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
+static int iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+                              struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
@@ -156,7 +159,7 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
        struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
 
        if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->shrd->status))
-               return;
+               return 0;
 
        if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) {
                rxon->channel = csa->channel;
@@ -169,11 +172,13 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
                        le16_to_cpu(csa->channel));
                iwl_chswitch_done(priv, false);
        }
+       return 0;
 }
 
 
-static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
-                                         struct iwl_rx_mem_buffer *rxb)
+static int iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
+                                         struct iwl_rx_mem_buffer *rxb,
+                                         struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_spectrum_notification *report = &(pkt->u.spectrum_notif);
@@ -181,15 +186,17 @@ static void iwl_rx_spectrum_measure_notif(struct iwl_priv *priv,
        if (!report->state) {
                IWL_DEBUG_11H(priv,
                        "Spectrum Measure Notification: Start\n");
-               return;
+               return 0;
        }
 
        memcpy(&priv->measure_report, report, sizeof(*report));
        priv->measurement_status |= MEASUREMENT_READY;
+       return 0;
 }
 
-static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
-                                 struct iwl_rx_mem_buffer *rxb)
+static int iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
+                                 struct iwl_rx_mem_buffer *rxb,
+                                 struct iwl_device_cmd *cmd)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -197,10 +204,12 @@ static void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
        IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n",
                     sleep->pm_sleep_mode, sleep->pm_wakeup_src);
 #endif
+       return 0;
 }
 
-static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
-                                            struct iwl_rx_mem_buffer *rxb)
+static int iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
+                                            struct iwl_rx_mem_buffer *rxb,
+                                            struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        u32 __maybe_unused len =
@@ -209,10 +218,12 @@ static void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
                        "notification for %s:\n", len,
                        get_cmd_string(pkt->hdr.cmd));
        iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, len);
+       return 0;
 }
 
-static void iwl_rx_beacon_notif(struct iwl_priv *priv,
-                               struct iwl_rx_mem_buffer *rxb)
+static int iwl_rx_beacon_notif(struct iwl_priv *priv,
+                               struct iwl_rx_mem_buffer *rxb,
+                               struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwlagn_beacon_notif *beacon = (void *)pkt->u.raw;
@@ -233,6 +244,7 @@ static void iwl_rx_beacon_notif(struct iwl_priv *priv,
 
        if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
                queue_work(priv->shrd->workqueue, &priv->beacon_update);
+       return 0;
 }
 
 /* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */
@@ -475,8 +487,9 @@ iwl_accumulative_statistics(struct iwl_priv *priv,
 }
 #endif
 
-static void iwl_rx_statistics(struct iwl_priv *priv,
-                             struct iwl_rx_mem_buffer *rxb)
+static int iwl_rx_statistics(struct iwl_priv *priv,
+                             struct iwl_rx_mem_buffer *rxb,
+                             struct iwl_device_cmd *cmd)
 {
        unsigned long stamp = jiffies;
        const int reg_recalib_period = 60;
@@ -530,7 +543,7 @@ static void iwl_rx_statistics(struct iwl_priv *priv,
                WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n",
                          len, sizeof(struct iwl_bt_notif_statistics),
                          sizeof(struct iwl_notif_statistics));
-               return;
+               return 0;
        }
 
        change = common->temperature != priv->statistics.common.temperature ||
@@ -573,10 +586,12 @@ static void iwl_rx_statistics(struct iwl_priv *priv,
        }
        if (priv->cfg->lib->temperature && change)
                priv->cfg->lib->temperature(priv);
+       return 0;
 }
 
-static void iwl_rx_reply_statistics(struct iwl_priv *priv,
-                                   struct iwl_rx_mem_buffer *rxb)
+static int iwl_rx_reply_statistics(struct iwl_priv *priv,
+                                   struct iwl_rx_mem_buffer *rxb,
+                                   struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
 
@@ -591,13 +606,15 @@ static void iwl_rx_reply_statistics(struct iwl_priv *priv,
 #endif
                IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
        }
-       iwl_rx_statistics(priv, rxb);
+       iwl_rx_statistics(priv, rxb, cmd);
+       return 0;
 }
 
 /* Handle notification from uCode that card's power state is changing
  * due to software, hardware, or critical temperature RFKILL */
-static void iwl_rx_card_state_notif(struct iwl_priv *priv,
-                                   struct iwl_rx_mem_buffer *rxb)
+static int iwl_rx_card_state_notif(struct iwl_priv *priv,
+                                   struct iwl_rx_mem_buffer *rxb,
+                                   struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
@@ -645,10 +662,12 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
                        test_bit(STATUS_RF_KILL_HW, &priv->shrd->status));
        else
                wake_up(&priv->shrd->wait_command_queue);
+       return 0;
 }
 
-static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
-                                      struct iwl_rx_mem_buffer *rxb)
+static int iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
+                                      struct iwl_rx_mem_buffer *rxb,
+                                      struct iwl_device_cmd *cmd)
 
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -666,18 +685,21 @@ static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
                if (!test_bit(STATUS_SCANNING, &priv->shrd->status))
                        iwl_init_sensitivity(priv);
        }
+       return 0;
 }
 
 /* Cache phy data (Rx signal strength, etc) for HT frame (REPLY_RX_PHY_CMD).
  * This will be used later in iwl_rx_reply_rx() for REPLY_RX_MPDU_CMD. */
-static void iwl_rx_reply_rx_phy(struct iwl_priv *priv,
-                               struct iwl_rx_mem_buffer *rxb)
+static int iwl_rx_reply_rx_phy(struct iwl_priv *priv,
+                               struct iwl_rx_mem_buffer *rxb,
+                               struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
 
        priv->last_phy_res_valid = true;
        memcpy(&priv->last_phy_res, pkt->u.raw,
               sizeof(struct iwl_rx_phy_res));
+       return 0;
 }
 
 /*
@@ -892,8 +914,9 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv,
 
 /* Called for REPLY_RX (legacy ABG frames), or
  * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */
-static void iwl_rx_reply_rx(struct iwl_priv *priv,
-                           struct iwl_rx_mem_buffer *rxb)
+static int iwl_rx_reply_rx(struct iwl_priv *priv,
+                           struct iwl_rx_mem_buffer *rxb,
+                           struct iwl_device_cmd *cmd)
 {
        struct ieee80211_hdr *header;
        struct ieee80211_rx_status rx_status;
@@ -926,7 +949,7 @@ static void iwl_rx_reply_rx(struct iwl_priv *priv,
        } else {
                if (!priv->last_phy_res_valid) {
                        IWL_ERR(priv, "MPDU frame without cached PHY data\n");
-                       return;
+                       return 0;
                }
                phy_res = &priv->last_phy_res;
                amsdu = (struct iwl_rx_mpdu_res_start *)pkt->u.raw;
@@ -940,14 +963,14 @@ static void iwl_rx_reply_rx(struct iwl_priv *priv,
        if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
                IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d/n",
                                phy_res->cfg_phy_cnt);
-               return;
+               return 0;
        }
 
        if (!(rx_pkt_status & RX_RES_STATUS_NO_CRC32_ERROR) ||
            !(rx_pkt_status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
                IWL_DEBUG_RX(priv, "Bad CRC or FIFO: 0x%08X.\n",
                                le32_to_cpu(rx_pkt_status));
-               return;
+               return 0;
        }
 
        /* This will be used in several places later */
@@ -1008,6 +1031,7 @@ static void iwl_rx_reply_rx(struct iwl_priv *priv,
 
        iwl_pass_packet_to_mac80211(priv, header, len, ampdu_status,
                                    rxb, &rx_status);
+       return 0;
 }
 
 /**
@@ -1018,7 +1042,8 @@ static void iwl_rx_reply_rx(struct iwl_priv *priv,
  */
 void iwl_setup_rx_handlers(struct iwl_priv *priv)
 {
-       void (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
+       int (**handlers)(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+                              struct iwl_device_cmd *cmd);
 
        handlers = priv->rx_handlers;
 
@@ -1028,6 +1053,7 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
        handlers[PM_SLEEP_NOTIFICATION]         = iwl_rx_pm_sleep_notif;
        handlers[PM_DEBUG_STATISTIC_NOTIFIC]    = iwl_rx_pm_debug_statistics_notif;
        handlers[BEACON_NOTIFICATION]           = iwl_rx_beacon_notif;
+       handlers[REPLY_ADD_STA]                 = iwl_add_sta_callback;
 
        /*
         * The same handler is used for both the REPLY to a discrete
@@ -1065,9 +1091,11 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv)
 
 }
 
-void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
+int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+                    struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
+       int err = 0;
 
        /*
         * Do the notification wait before RX handlers so
@@ -1102,11 +1130,12 @@ void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
         *   rx_handlers table.  See iwl_setup_rx_handlers() */
        if (priv->rx_handlers[pkt->hdr.cmd]) {
                priv->rx_handlers_stats[pkt->hdr.cmd]++;
-               priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
+               err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd);
        } else {
                /* No handling needed */
                IWL_DEBUG_RX(priv,
                        "No handler needed for %s, 0x%02x\n",
                        get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
        }
+       return err;
 }
index fc5af3475392b7bf897844afe54f241b10def001..2b6db24daf70d6b04b5a6f5fb4e6925751942a39 100644 (file)
@@ -189,8 +189,9 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
 }
 
 /* Service response to REPLY_SCAN_CMD (0x80) */
-static void iwl_rx_reply_scan(struct iwl_priv *priv,
-                             struct iwl_rx_mem_buffer *rxb)
+static int iwl_rx_reply_scan(struct iwl_priv *priv,
+                             struct iwl_rx_mem_buffer *rxb,
+                             struct iwl_device_cmd *cmd)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -199,11 +200,13 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv,
 
        IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status);
 #endif
+       return 0;
 }
 
 /* Service SCAN_START_NOTIFICATION (0x82) */
-static void iwl_rx_scan_start_notif(struct iwl_priv *priv,
-                                   struct iwl_rx_mem_buffer *rxb)
+static int iwl_rx_scan_start_notif(struct iwl_priv *priv,
+                                   struct iwl_rx_mem_buffer *rxb,
+                                   struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_scanstart_notification *notif =
@@ -218,13 +221,19 @@ static void iwl_rx_scan_start_notif(struct iwl_priv *priv,
                       le32_to_cpu(notif->tsf_low),
                       notif->status, notif->beacon_timer);
 
-       if (priv->scan_type == IWL_SCAN_ROC)
+       if (priv->scan_type == IWL_SCAN_ROC &&
+           !priv->hw_roc_start_notified) {
                ieee80211_ready_on_channel(priv->hw);
+               priv->hw_roc_start_notified = true;
+       }
+
+       return 0;
 }
 
 /* Service SCAN_RESULTS_NOTIFICATION (0x83) */
-static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
-                                     struct iwl_rx_mem_buffer *rxb)
+static int iwl_rx_scan_results_notif(struct iwl_priv *priv,
+                                     struct iwl_rx_mem_buffer *rxb,
+                                     struct iwl_device_cmd *cmd)
 {
 #ifdef CONFIG_IWLWIFI_DEBUG
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
@@ -242,11 +251,13 @@ static void iwl_rx_scan_results_notif(struct iwl_priv *priv,
                       le32_to_cpu(notif->statistics[0]),
                       le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf);
 #endif
+       return 0;
 }
 
 /* Service SCAN_COMPLETE_NOTIFICATION (0x84) */
-static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
-                                      struct iwl_rx_mem_buffer *rxb)
+static int iwl_rx_scan_complete_notif(struct iwl_priv *priv,
+                                      struct iwl_rx_mem_buffer *rxb,
+                                      struct iwl_device_cmd *cmd)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw;
@@ -286,6 +297,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
                queue_work(priv->shrd->workqueue,
                           &priv->bt_traffic_change_work);
        }
+       return 0;
 }
 
 void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)
@@ -299,9 +311,8 @@ void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)
                                        iwl_rx_scan_complete_notif;
 }
 
-inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
-                                    enum ieee80211_band band,
-                                    u8 n_probes)
+static u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
+                                    enum ieee80211_band band, u8 n_probes)
 {
        if (band == IEEE80211_BAND_5GHZ)
                return IWL_ACTIVE_DWELL_TIME_52 +
@@ -311,35 +322,481 @@ inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
                        IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1);
 }
 
-u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
-                              enum ieee80211_band band,
-                              struct ieee80211_vif *vif)
+static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time)
 {
        struct iwl_rxon_context *ctx;
+
+       /*
+        * If we're associated, we clamp the dwell time 98%
+        * of the smallest beacon interval (minus 2 * channel
+        * tune time)
+        */
+       for_each_context(priv, ctx) {
+               u16 value;
+
+               if (!iwl_is_associated_ctx(ctx))
+                       continue;
+               value = ctx->beacon_int;
+               if (!value)
+                       value = IWL_PASSIVE_DWELL_BASE;
+               value = (value * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
+               dwell_time = min(value, dwell_time);
+       }
+
+       return dwell_time;
+}
+
+static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
+                                     enum ieee80211_band band)
+{
        u16 passive = (band == IEEE80211_BAND_2GHZ) ?
            IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
            IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
 
-       if (iwl_is_any_associated(priv)) {
+       return iwl_limit_dwell(priv, passive);
+}
+
+static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
+                                          struct ieee80211_vif *vif,
+                                          enum ieee80211_band band,
+                                          struct iwl_scan_channel *scan_ch)
+{
+       const struct ieee80211_supported_band *sband;
+       u16 passive_dwell = 0;
+       u16 active_dwell = 0;
+       int added = 0;
+       u16 channel = 0;
+
+       sband = iwl_get_hw_mode(priv, band);
+       if (!sband) {
+               IWL_ERR(priv, "invalid band\n");
+               return added;
+       }
+
+       active_dwell = iwl_get_active_dwell_time(priv, band, 0);
+       passive_dwell = iwl_get_passive_dwell_time(priv, band);
+
+       if (passive_dwell <= active_dwell)
+               passive_dwell = active_dwell + 1;
+
+       channel = iwl_get_single_channel_number(priv, band);
+       if (channel) {
+               scan_ch->channel = cpu_to_le16(channel);
+               scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
+               scan_ch->active_dwell = cpu_to_le16(active_dwell);
+               scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
+               /* Set txpower levels to defaults */
+               scan_ch->dsp_atten = 110;
+               if (band == IEEE80211_BAND_5GHZ)
+                       scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
+               else
+                       scan_ch->tx_gain = ((1 << 5) | (5 << 3));
+               added++;
+       } else
+               IWL_ERR(priv, "no valid channel found\n");
+       return added;
+}
+
+static int iwl_get_channels_for_scan(struct iwl_priv *priv,
+                                    struct ieee80211_vif *vif,
+                                    enum ieee80211_band band,
+                                    u8 is_active, u8 n_probes,
+                                    struct iwl_scan_channel *scan_ch)
+{
+       struct ieee80211_channel *chan;
+       const struct ieee80211_supported_band *sband;
+       const struct iwl_channel_info *ch_info;
+       u16 passive_dwell = 0;
+       u16 active_dwell = 0;
+       int added, i;
+       u16 channel;
+
+       sband = iwl_get_hw_mode(priv, band);
+       if (!sband)
+               return 0;
+
+       active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
+       passive_dwell = iwl_get_passive_dwell_time(priv, band);
+
+       if (passive_dwell <= active_dwell)
+               passive_dwell = active_dwell + 1;
+
+       for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) {
+               chan = priv->scan_request->channels[i];
+
+               if (chan->band != band)
+                       continue;
+
+               channel = chan->hw_value;
+               scan_ch->channel = cpu_to_le16(channel);
+
+               ch_info = iwl_get_channel_info(priv, band, channel);
+               if (!is_channel_valid(ch_info)) {
+                       IWL_DEBUG_SCAN(priv,
+                                      "Channel %d is INVALID for this band.\n",
+                                      channel);
+                       continue;
+               }
+
+               if (!is_active || is_channel_passive(ch_info) ||
+                   (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
+                       scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
+               else
+                       scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
+
+               if (n_probes)
+                       scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
+
+               scan_ch->active_dwell = cpu_to_le16(active_dwell);
+               scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
+
+               /* Set txpower levels to defaults */
+               scan_ch->dsp_atten = 110;
+
+               /* NOTE: if we were doing 6Mb OFDM for scans we'd use
+                * power level:
+                * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
+                */
+               if (band == IEEE80211_BAND_5GHZ)
+                       scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
+               else
+                       scan_ch->tx_gain = ((1 << 5) | (5 << 3));
+
+               IWL_DEBUG_SCAN(priv, "Scanning ch=%d prob=0x%X [%s %d]\n",
+                              channel, le32_to_cpu(scan_ch->type),
+                              (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
+                               "ACTIVE" : "PASSIVE",
+                              (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
+                              active_dwell : passive_dwell);
+
+               scan_ch++;
+               added++;
+       }
+
+       IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added);
+       return added;
+}
+
+static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
+{
+       struct iwl_host_cmd cmd = {
+               .id = REPLY_SCAN_CMD,
+               .len = { sizeof(struct iwl_scan_cmd), },
+               .flags = CMD_SYNC,
+       };
+       struct iwl_scan_cmd *scan;
+       struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
+       u32 rate_flags = 0;
+       u16 cmd_len;
+       u16 rx_chain = 0;
+       enum ieee80211_band band;
+       u8 n_probes = 0;
+       u8 rx_ant = hw_params(priv).valid_rx_ant;
+       u8 rate;
+       bool is_active = false;
+       int  chan_mod;
+       u8 active_chains;
+       u8 scan_tx_antennas = hw_params(priv).valid_tx_ant;
+       int ret;
+
+       lockdep_assert_held(&priv->shrd->mutex);
+
+       if (vif)
+               ctx = iwl_rxon_ctx_from_vif(vif);
+
+       if (!priv->scan_cmd) {
+               priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) +
+                                        IWL_MAX_SCAN_SIZE, GFP_KERNEL);
+               if (!priv->scan_cmd) {
+                       IWL_DEBUG_SCAN(priv,
+                                      "fail to allocate memory for scan\n");
+                       return -ENOMEM;
+               }
+       }
+       scan = priv->scan_cmd;
+       memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);
+
+       scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
+       scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
+
+       if (priv->scan_type != IWL_SCAN_ROC &&
+           iwl_is_any_associated(priv)) {
+               u16 interval = 0;
+               u32 extra;
+               u32 suspend_time = 100;
+               u32 scan_suspend_time = 100;
+
+               IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
+               switch (priv->scan_type) {
+               case IWL_SCAN_ROC:
+                       WARN_ON(1);
+                       break;
+               case IWL_SCAN_RADIO_RESET:
+                       interval = 0;
+                       break;
+               case IWL_SCAN_NORMAL:
+                       interval = vif->bss_conf.beacon_int;
+                       break;
+               }
+
+               scan->suspend_time = 0;
+               scan->max_out_time = cpu_to_le32(200 * 1024);
+               if (!interval)
+                       interval = suspend_time;
+
+               extra = (suspend_time / interval) << 22;
+               scan_suspend_time = (extra |
+                   ((suspend_time % interval) * 1024));
+               scan->suspend_time = cpu_to_le32(scan_suspend_time);
+               IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
+                              scan_suspend_time, interval);
+       } else if (priv->scan_type == IWL_SCAN_ROC) {
+               scan->suspend_time = 0;
+               scan->max_out_time = 0;
+               scan->quiet_time = 0;
+               scan->quiet_plcp_th = 0;
+       }
+
+       switch (priv->scan_type) {
+       case IWL_SCAN_RADIO_RESET:
+               IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
+               break;
+       case IWL_SCAN_NORMAL:
+               if (priv->scan_request->n_ssids) {
+                       int i, p = 0;
+                       IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
+                       for (i = 0; i < priv->scan_request->n_ssids; i++) {
+                               /* always does wildcard anyway */
+                               if (!priv->scan_request->ssids[i].ssid_len)
+                                       continue;
+                               scan->direct_scan[p].id = WLAN_EID_SSID;
+                               scan->direct_scan[p].len =
+                                       priv->scan_request->ssids[i].ssid_len;
+                               memcpy(scan->direct_scan[p].ssid,
+                                      priv->scan_request->ssids[i].ssid,
+                                      priv->scan_request->ssids[i].ssid_len);
+                               n_probes++;
+                               p++;
+                       }
+                       is_active = true;
+               } else
+                       IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
+               break;
+       case IWL_SCAN_ROC:
+               IWL_DEBUG_SCAN(priv, "Start ROC scan.\n");
+               break;
+       }
+
+       scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
+       scan->tx_cmd.sta_id = ctx->bcast_sta_id;
+       scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
+
+       switch (priv->scan_band) {
+       case IEEE80211_BAND_2GHZ:
+               scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
+               chan_mod = le32_to_cpu(
+                       priv->contexts[IWL_RXON_CTX_BSS].active.flags &
+                                               RXON_FLG_CHANNEL_MODE_MSK)
+                                      >> RXON_FLG_CHANNEL_MODE_POS;
+               if (chan_mod == CHANNEL_MODE_PURE_40) {
+                       rate = IWL_RATE_6M_PLCP;
+               } else {
+                       rate = IWL_RATE_1M_PLCP;
+                       rate_flags = RATE_MCS_CCK_MSK;
+               }
                /*
-                * If we're associated, we clamp the maximum passive
-                * dwell time to be 98% of the smallest beacon interval
-                * (minus 2 * channel tune time)
+                * Internal scans are passive, so we can indiscriminately set
+                * the BT ignore flag on 2.4 GHz since it applies to TX only.
                 */
-               for_each_context(priv, ctx) {
-                       u16 value;
-
-                       if (!iwl_is_associated_ctx(ctx))
-                               continue;
-                       value = ctx->vif ? ctx->vif->bss_conf.beacon_int : 0;
-                       if ((value > IWL_PASSIVE_DWELL_BASE) || !value)
-                               value = IWL_PASSIVE_DWELL_BASE;
-                       value = (value * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
-                       passive = min(value, passive);
+               if (priv->cfg->bt_params &&
+                   priv->cfg->bt_params->advanced_bt_coexist)
+                       scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT;
+               break;
+       case IEEE80211_BAND_5GHZ:
+               rate = IWL_RATE_6M_PLCP;
+               break;
+       default:
+               IWL_WARN(priv, "Invalid scan band\n");
+               return -EIO;
+       }
+
+       /*
+        * If active scanning is requested but a certain channel is
+        * marked passive, we can do active scanning if we detect
+        * transmissions.
+        *
+        * There is an issue with some firmware versions that triggers
+        * a sysassert on a "good CRC threshold" of zero (== disabled),
+        * on a radar channel even though this means that we should NOT
+        * send probes.
+        *
+        * The "good CRC threshold" is the number of frames that we
+        * need to receive during our dwell time on a channel before
+        * sending out probes -- setting this to a huge value will
+        * mean we never reach it, but at the same time work around
+        * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
+        * here instead of IWL_GOOD_CRC_TH_DISABLED.
+        *
+        * This was fixed in later versions along with some other
+        * scan changes, and the threshold behaves as a flag in those
+        * versions.
+        */
+       if (priv->new_scan_threshold_behaviour)
+               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+                                               IWL_GOOD_CRC_TH_DISABLED;
+       else
+               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+                                               IWL_GOOD_CRC_TH_NEVER;
+
+       band = priv->scan_band;
+
+       if (priv->cfg->scan_rx_antennas[band])
+               rx_ant = priv->cfg->scan_rx_antennas[band];
+
+       if (band == IEEE80211_BAND_2GHZ &&
+           priv->cfg->bt_params &&
+           priv->cfg->bt_params->advanced_bt_coexist) {
+               /* transmit 2.4 GHz probes only on first antenna */
+               scan_tx_antennas = first_antenna(scan_tx_antennas);
+       }
+
+       priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv,
+                                                   priv->scan_tx_ant[band],
+                                                   scan_tx_antennas);
+       rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
+       scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
+
+       /* In power save mode use one chain, otherwise use all chains */
+       if (test_bit(STATUS_POWER_PMI, &priv->shrd->status)) {
+               /* rx_ant has been set to all valid chains previously */
+               active_chains = rx_ant &
+                               ((u8)(priv->chain_noise_data.active_chains));
+               if (!active_chains)
+                       active_chains = rx_ant;
+
+               IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n",
+                               priv->chain_noise_data.active_chains);
+
+               rx_ant = first_antenna(active_chains);
+       }
+       if (priv->cfg->bt_params &&
+           priv->cfg->bt_params->advanced_bt_coexist &&
+           priv->bt_full_concurrent) {
+               /* operated as 1x1 in full concurrency mode */
+               rx_ant = first_antenna(rx_ant);
+       }
+
+       /* MIMO is not used here, but value is required */
+       rx_chain |=
+               hw_params(priv).valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
+       rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
+       rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
+       rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
+       scan->rx_chain = cpu_to_le16(rx_chain);
+       switch (priv->scan_type) {
+       case IWL_SCAN_NORMAL:
+               cmd_len = iwl_fill_probe_req(priv,
+                                       (struct ieee80211_mgmt *)scan->data,
+                                       vif->addr,
+                                       priv->scan_request->ie,
+                                       priv->scan_request->ie_len,
+                                       IWL_MAX_SCAN_SIZE - sizeof(*scan));
+               break;
+       case IWL_SCAN_RADIO_RESET:
+       case IWL_SCAN_ROC:
+               /* use bcast addr, will not be transmitted but must be valid */
+               cmd_len = iwl_fill_probe_req(priv,
+                                       (struct ieee80211_mgmt *)scan->data,
+                                       iwl_bcast_addr, NULL, 0,
+                                       IWL_MAX_SCAN_SIZE - sizeof(*scan));
+               break;
+       default:
+               BUG();
+       }
+       scan->tx_cmd.len = cpu_to_le16(cmd_len);
+
+       scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
+                              RXON_FILTER_BCON_AWARE_MSK);
+
+       switch (priv->scan_type) {
+       case IWL_SCAN_RADIO_RESET:
+               scan->channel_count =
+                       iwl_get_single_channel_for_scan(priv, vif, band,
+                               (void *)&scan->data[cmd_len]);
+               break;
+       case IWL_SCAN_NORMAL:
+               scan->channel_count =
+                       iwl_get_channels_for_scan(priv, vif, band,
+                               is_active, n_probes,
+                               (void *)&scan->data[cmd_len]);
+               break;
+       case IWL_SCAN_ROC: {
+               struct iwl_scan_channel *scan_ch;
+               int n_chan, i;
+               u16 dwell;
+
+               dwell = iwl_limit_dwell(priv, priv->hw_roc_duration);
+               n_chan = DIV_ROUND_UP(priv->hw_roc_duration, dwell);
+
+               scan->channel_count = n_chan;
+
+               scan_ch = (void *)&scan->data[cmd_len];
+
+               for (i = 0; i < n_chan; i++) {
+                       scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
+                       scan_ch->channel =
+                               cpu_to_le16(priv->hw_roc_channel->hw_value);
+
+                       if (i == n_chan - 1)
+                               dwell = priv->hw_roc_duration - i * dwell;
+
+                       scan_ch->active_dwell =
+                       scan_ch->passive_dwell = cpu_to_le16(dwell);
+
+                       /* Set txpower levels to defaults */
+                       scan_ch->dsp_atten = 110;
+
+                       /* NOTE: if we were doing 6Mb OFDM for scans we'd use
+                        * power level:
+                        * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
+                        */
+                       if (priv->hw_roc_channel->band == IEEE80211_BAND_5GHZ)
+                               scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
+                       else
+                               scan_ch->tx_gain = ((1 << 5) | (5 << 3));
+
+                       scan_ch++;
                }
+               }
+
+               break;
        }
 
-       return passive;
+       if (scan->channel_count == 0) {
+               IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
+               return -EIO;
+       }
+
+       cmd.len[0] += le16_to_cpu(scan->tx_cmd.len) +
+           scan->channel_count * sizeof(struct iwl_scan_channel);
+       cmd.data[0] = scan;
+       cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
+       scan->len = cpu_to_le16(cmd.len[0]);
+
+       /* set scan bit here for PAN params */
+       set_bit(STATUS_SCAN_HW, &priv->shrd->status);
+
+       ret = iwlagn_set_pan_params(priv);
+       if (ret)
+               return ret;
+
+       ret = iwl_trans_send_cmd(trans(priv), &cmd);
+       if (ret) {
+               clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
+               iwlagn_set_pan_params(priv);
+       }
+
+       return ret;
 }
 
 void iwl_init_scan_params(struct iwl_priv *priv)
index 40186a61f20a37ec72186b19ac59ae758605e83b..7abafe16de9a41527b4f2d6213938b26ad90c8cb 100644 (file)
@@ -423,8 +423,11 @@ enum iwl_rxon_context_id {
 int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops,
                struct iwl_cfg *cfg);
 void __devexit iwl_remove(struct iwl_priv * priv);
+struct iwl_device_cmd;
+int __must_check iwl_rx_dispatch(struct iwl_priv *priv,
+                                struct iwl_rx_mem_buffer *rxb,
+                                struct iwl_device_cmd *cmd);
 
-void iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
 int iwlagn_hw_valid_rtc_data_addr(u32 addr);
 void iwl_start_tx_ba_trans_ready(struct iwl_priv *priv,
                                 enum iwl_rxon_context_id ctx,
index e24135e7d37d78d45a2376e137da289ca614295b..580a4d702ff3c019ef7c84880ae080f272eae3eb 100644 (file)
@@ -59,8 +59,7 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
 
 static int iwl_process_add_sta_resp(struct iwl_priv *priv,
                                    struct iwl_addsta_cmd *addsta,
-                                   struct iwl_rx_packet *pkt,
-                                   bool sync)
+                                   struct iwl_rx_packet *pkt)
 {
        u8 sta_id = addsta->sta.sta_id;
        unsigned long flags;
@@ -123,15 +122,14 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv,
        return ret;
 }
 
-static void iwl_add_sta_callback(struct iwl_shared *shrd,
-                                struct iwl_device_cmd *cmd,
-                                struct iwl_rx_packet *pkt)
+int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+                              struct iwl_device_cmd *cmd)
 {
+       struct iwl_rx_packet *pkt = rxb_addr(rxb);
        struct iwl_addsta_cmd *addsta =
-               (struct iwl_addsta_cmd *)cmd->cmd.payload;
-
-       iwl_process_add_sta_resp(shrd->priv, addsta, pkt, false);
+               (struct iwl_addsta_cmd *) cmd->payload;
 
+       return iwl_process_add_sta_resp(priv, addsta, pkt);
 }
 
 static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
@@ -147,7 +145,6 @@ static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
 int iwl_send_add_sta(struct iwl_priv *priv,
                     struct iwl_addsta_cmd *sta, u8 flags)
 {
-       struct iwl_rx_packet *pkt = NULL;
        int ret = 0;
        u8 data[sizeof(*sta)];
        struct iwl_host_cmd cmd = {
@@ -160,9 +157,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
        IWL_DEBUG_INFO(priv, "Adding sta %u (%pM) %ssynchronously\n",
                       sta_id, sta->sta.addr, flags & CMD_ASYNC ?  "a" : "");
 
-       if (flags & CMD_ASYNC)
-               cmd.callback = iwl_add_sta_callback;
-       else {
+       if (!(flags & CMD_ASYNC)) {
                cmd.flags |= CMD_WANT_SKB;
                might_sleep();
        }
@@ -172,14 +167,16 @@ int iwl_send_add_sta(struct iwl_priv *priv,
 
        if (ret || (flags & CMD_ASYNC))
                return ret;
+       /*else the command was successfully sent in SYNC mode, need to free
+        * the reply page */
 
-       if (ret == 0) {
-               pkt = (struct iwl_rx_packet *)cmd.reply_page;
-               ret = iwl_process_add_sta_resp(priv, sta, pkt, true);
-       }
        iwl_free_pages(priv->shrd, cmd.reply_page);
 
-       return ret;
+       if (cmd.handler_status)
+               IWL_ERR(priv, "%s - error in the CMD response %d", __func__,
+                       cmd.handler_status);
+
+       return cmd.handler_status;
 }
 
 static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
@@ -305,7 +302,7 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
        station->ctxid = ctx->ctxid;
 
        if (sta) {
-               struct iwl_station_priv_common *sta_priv;
+               struct iwl_station_priv *sta_priv;
 
                sta_priv = (void *)sta->drv_priv;
                sta_priv->ctx = ctx;
@@ -821,7 +818,7 @@ int iwl_mac_sta_remove(struct ieee80211_hw *hw,
                       struct ieee80211_sta *sta)
 {
        struct iwl_priv *priv = hw->priv;
-       struct iwl_station_priv_common *sta_common = (void *)sta->drv_priv;
+       struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
        int ret;
 
        IWL_DEBUG_INFO(priv, "received request to remove station %pM\n",
@@ -829,7 +826,7 @@ int iwl_mac_sta_remove(struct ieee80211_hw *hw,
        mutex_lock(&priv->shrd->mutex);
        IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n",
                        sta->addr);
-       ret = iwl_remove_station(priv, sta_common->sta_id, sta->addr);
+       ret = iwl_remove_station(priv, sta_priv->sta_id, sta->addr);
        if (ret)
                IWL_ERR(priv, "Error removing station %pM\n",
                        sta->addr);
index 9641eb6b1d0afa435fed3803c6b95fbc289376cd..1bca0dabde8d1009309a3e662db95aebca3b3b8c 100644 (file)
@@ -61,6 +61,9 @@ u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
 int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
                    struct iwl_link_quality_cmd *lq, u8 flags, bool init);
 void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
+int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb,
+                              struct iwl_device_cmd *cmd);
+
 
 /**
  * iwl_clear_driver_stations - clear knowledge of all stations from driver
@@ -102,7 +105,7 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta)
        if (WARN_ON(!sta))
                return IWL_INVALID_STATION;
 
-       return ((struct iwl_station_priv_common *)sta->drv_priv)->sta_id;
+       return ((struct iwl_station_priv *)sta->drv_priv)->sta_id;
 }
 
 /**
index 49cd5a7682805ca88ebd17f072142ea7a25a51b3..2b6756e8b8f97578394bdfd2a473f8acd0bd95d6 100644 (file)
@@ -118,16 +118,6 @@ struct iwl_dma_ptr {
 struct iwl_cmd_meta {
        /* only for SYNC commands, iff the reply skb is wanted */
        struct iwl_host_cmd *source;
-       /*
-        * only for ASYNC commands
-        * (which is somewhat stupid -- look at iwl-sta.c for instance
-        * which duplicates a bunch of code because the callback isn't
-        * invoked for SYNC commands, if it were and its result passed
-        * through it would be simpler...)
-        */
-       void (*callback)(struct iwl_shared *shrd,
-                        struct iwl_device_cmd *cmd,
-                        struct iwl_rx_packet *pkt);
 
        u32 flags;
 
@@ -285,10 +275,8 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans,
                                 dma_addr_t addr, u16 len, u8 reset);
 int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id);
 int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
-int __must_check iwl_trans_pcie_send_cmd_pdu(struct iwl_trans *trans, u8 id,
-                       u32 flags, u16 len, const void *data);
 void iwl_tx_cmd_complete(struct iwl_trans *trans,
-                        struct iwl_rx_mem_buffer *rxb);
+                        struct iwl_rx_mem_buffer *rxb, int handler_status);
 void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans,
                                           struct iwl_tx_queue *txq,
                                           u16 byte_cnt);
index 6f3f07dd817da308e2fefe83634ab2f47449484d..3ef9eac02ff4753348eb2faf092aa38d6b2dddf2 100644 (file)
@@ -372,12 +372,15 @@ static void iwl_rx_handle(struct iwl_trans *trans)
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
        struct iwl_rx_queue *rxq = &trans_pcie->rxq;
+       struct iwl_tx_queue *txq = &trans_pcie->txq[trans->shrd->cmd_queue];
+       struct iwl_device_cmd *cmd;
        u32 r, i;
        int reclaim;
        unsigned long flags;
        u8 fill_rx = 0;
        u32 count = 8;
        int total_empty;
+       int index, cmd_index;
 
        /* uCode's read index (stored in shared DRAM) indicates the last Rx
         * buffer that the driver may process (last buffer filled by ucode). */
@@ -397,7 +400,7 @@ static void iwl_rx_handle(struct iwl_trans *trans)
                fill_rx = 1;
 
        while (i != r) {
-               int len;
+               int len, err;
                u16 txq_id, sequence;
 
                rxb = rxq->queue[i];
@@ -439,7 +442,13 @@ static void iwl_rx_handle(struct iwl_trans *trans)
                        (pkt->hdr.cmd != REPLY_TX);
 
                sequence = le16_to_cpu(pkt->hdr.sequence);
-               txq_id = SEQ_TO_QUEUE(le16_to_cpu(pkt->hdr.sequence));
+               index = SEQ_TO_INDEX(sequence);
+               cmd_index = get_cmd_index(&txq->q, index);
+
+               if (reclaim)
+                       cmd = txq->cmd[cmd_index];
+               else
+                       cmd = NULL;
 
                /* warn if this is cmd response / notification and the uCode
                 * didn't set the SEQ_RX_FRAME for a frame that is
@@ -449,7 +458,7 @@ static void iwl_rx_handle(struct iwl_trans *trans)
                     "reclaim is false, SEQ_RX_FRAME unset: %s\n",
                     get_cmd_string(pkt->hdr.cmd));
 
-               iwl_rx_dispatch(priv(trans), rxb);
+               err = iwl_rx_dispatch(priv(trans), rxb, cmd);
 
                /*
                 * XXX: After here, we should always check rxb->page
@@ -464,7 +473,7 @@ static void iwl_rx_handle(struct iwl_trans *trans)
                         * iwl_trans_send_cmd()
                         * as we reclaim the driver command queue */
                        if (rxb->page)
-                               iwl_tx_cmd_complete(trans, rxb);
+                               iwl_tx_cmd_complete(trans, rxb, err);
                        else
                                IWL_WARN(trans, "Claim null rxb?\n");
                }
index 031a291a13dce1bfb7a4a9dc260d2a987393543d..ee7059dcbbcb1a5bb142547b7ea70fabfd473d88 100644 (file)
@@ -59,13 +59,15 @@ void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans,
        u8 sta_id = 0;
        u16 len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
        __le16 bc_ent;
+       struct iwl_tx_cmd *tx_cmd =
+               (struct iwl_tx_cmd *) txq->cmd[txq->q.write_ptr]->payload;
 
        scd_bc_tbl = trans_pcie->scd_bc_tbls.addr;
 
        WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
 
-       sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
-       sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
+       sta_id = tx_cmd->sta_id;
+       sec_ctl = tx_cmd->sec_ctl;
 
        switch (sec_ctl & TX_CMD_SEC_MSK) {
        case TX_CMD_SEC_CCM:
@@ -353,11 +355,13 @@ static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_trans *trans,
        int read_ptr = txq->q.read_ptr;
        u8 sta_id = 0;
        __le16 bc_ent;
+       struct iwl_tx_cmd *tx_cmd =
+               (struct iwl_tx_cmd *) txq->cmd[txq->q.read_ptr]->payload;
 
        WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX);
 
        if (txq_id != trans->shrd->cmd_queue)
-               sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
+               sta_id = tx_cmd->sta_id;
 
        bc_ent = cpu_to_le16(1 | (sta_id << 12));
        scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
@@ -762,8 +766,6 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
        memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */
        if (cmd->flags & CMD_WANT_SKB)
                out_meta->source = cmd;
-       if (cmd->flags & CMD_ASYNC)
-               out_meta->callback = cmd->callback;
 
        /* set up the header */
 
@@ -775,7 +777,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
 
        /* and copy the data that needs to be copied */
 
-       cmd_dest = &out_cmd->cmd.payload[0];
+       cmd_dest = out_cmd->payload;
        for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
                if (!cmd->len[i])
                        continue;
@@ -894,12 +896,15 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id,
 /**
  * iwl_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
  * @rxb: Rx buffer to reclaim
+ * @handler_status: return value of the handler of the command
+ *     (put in setup_rx_handlers)
  *
  * If an Rx buffer has an async callback associated with it the callback
  * will be executed.  The attached skb (if present) will only be freed
  * if the callback returns 1
  */
-void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb)
+void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb,
+                        int handler_status)
 {
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
        u16 sequence = le16_to_cpu(pkt->hdr.sequence);
@@ -936,9 +941,9 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb)
        /* Input error checking is done when commands are added to queue. */
        if (meta->flags & CMD_WANT_SKB) {
                meta->source->reply_page = (unsigned long)rxb_addr(rxb);
+               meta->source->handler_status = handler_status;
                rxb->page = NULL;
-       } else if (meta->callback)
-               meta->callback(trans->shrd, cmd, pkt);
+       }
 
        spin_lock_irqsave(&trans->hcmd_lock, flags);
 
@@ -958,30 +963,6 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb)
 
 #define HOST_COMPLETE_TIMEOUT (2 * HZ)
 
-static void iwl_generic_cmd_callback(struct iwl_shared *shrd,
-                                    struct iwl_device_cmd *cmd,
-                                    struct iwl_rx_packet *pkt)
-{
-       if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
-               IWL_ERR(shrd->trans, "Bad return from %s (0x%08X)\n",
-                       get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
-               return;
-       }
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-       switch (cmd->hdr.cmd) {
-       case REPLY_TX_LINK_QUALITY_CMD:
-       case SENSITIVITY_CMD:
-               IWL_DEBUG_HC_DUMP(shrd->trans, "back from %s (0x%08X)\n",
-                               get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
-               break;
-       default:
-               IWL_DEBUG_HC(shrd->trans, "back from %s (0x%08X)\n",
-                               get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
-       }
-#endif
-}
-
 static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
 {
        int ret;
@@ -990,9 +971,6 @@ static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
        if (WARN_ON(cmd->flags & CMD_WANT_SKB))
                return -EINVAL;
 
-       /* Assign a generic callback if one is not provided */
-       if (!cmd->callback)
-               cmd->callback = iwl_generic_cmd_callback;
 
        if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status))
                return -EBUSY;
@@ -1014,10 +992,6 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
 
        lockdep_assert_held(&trans->shrd->mutex);
 
-        /* A synchronous command can not have a callback set. */
-       if (WARN_ON(cmd->callback))
-               return -EINVAL;
-
        IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n",
                        get_cmd_string(cmd->id));
 
index ca13eebbdb4f1213633b40049e02d6c6a69874e1..b78ac65b277941526018f640681623e8f10d2a26 100644 (file)
@@ -83,8 +83,6 @@ static int iwl_trans_rx_alloc(struct iwl_trans *trans)
        memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq));
 
        spin_lock_init(&rxq->lock);
-       INIT_LIST_HEAD(&rxq->rx_free);
-       INIT_LIST_HEAD(&rxq->rx_used);
 
        if (WARN_ON(rxq->bd || rxq->rb_stts))
                return -EINVAL;
@@ -1043,7 +1041,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
        struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct iwl_tx_cmd *tx_cmd = &dev_cmd->cmd.tx;
+       struct iwl_tx_cmd *tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload;
        struct iwl_cmd_meta *out_meta;
        struct iwl_tx_queue *txq;
        struct iwl_queue *q;
@@ -1096,8 +1094,8 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
                hdr->seq_ctrl |= cpu_to_le16(seq_number);
                seq_number += 0x10;
                /* aggregation is on for this <sta,tid> */
-               if (info->flags & IEEE80211_TX_CTL_AMPDU &&
-                   tid_data->agg.state == IWL_AGG_ON) {
+               if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+                       WARN_ON(tid_data->agg.state != IWL_AGG_ON);
                        txq_id = tid_data->agg.txq_id;
                        is_agg = true;
                }
index 5b6e6842d5fcc93eb8920ee25aebe565ce4bfd30..c5923125c3f96bb8fe7625e2b59e0ba1cde4b8d7 100644 (file)
@@ -97,15 +97,7 @@ enum {
  */
 struct iwl_device_cmd {
        struct iwl_cmd_header hdr;      /* uCode API */
-       union {
-               u32 flags;
-               u8 val8;
-               u16 val16;
-               u32 val32;
-               struct iwl_tx_cmd tx;
-               struct iwl6000_channel_switch_cmd chswitch;
-               u8 payload[DEF_CMD_PAYLOAD_SIZE];
-       } __packed cmd;
+       u8 payload[DEF_CMD_PAYLOAD_SIZE];
 } __packed;
 
 #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))
@@ -120,6 +112,8 @@ enum iwl_hcmd_dataflag {
  * struct iwl_host_cmd - Host command to the uCode
  * @data: array of chunks that composes the data of the host command
  * @reply_page: pointer to the page that holds the response to the host command
+ * @handler_status: return value of the handler of the command
+ *     (put in setup_rx_handlers) - valid for SYNC mode only
  * @callback:
  * @flags: can be CMD_* note CMD_WANT_SKB is incompatible withe CMD_ASYNC
  * @len: array of the lenths of the chunks in data
@@ -129,9 +123,8 @@ enum iwl_hcmd_dataflag {
 struct iwl_host_cmd {
        const void *data[IWL_MAX_CMD_TFDS];
        unsigned long reply_page;
-       void (*callback)(struct iwl_shared *shrd,
-                        struct iwl_device_cmd *cmd,
-                        struct iwl_rx_packet *pkt);
+       int handler_status;
+
        u32 flags;
        u16 len[IWL_MAX_CMD_TFDS];
        u8 dataflags[IWL_MAX_CMD_TFDS];
index eb569fa9adbaa5652da67ae297e9e6b8693c0684..1df5ef6b4953bc51b25c59c0e94183077daf5cd5 100644 (file)
@@ -203,6 +203,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
                beacon_ie = kmemdup(bss->information_elements,
                                        bss->len_beacon_ies, GFP_KERNEL);
                if (!beacon_ie) {
+                       kfree(bss_desc);
                        dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");
                        return -ENOMEM;
                }
@@ -867,10 +868,10 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
        ret = mwifiex_rate_ioctl_cfg(priv, rate);
 
        if (!ret) {
-               if (rate && rate->is_rate_auto)
+               if (rate->is_rate_auto)
                        rate->rate = mwifiex_index_to_data_rate(priv->tx_rate,
                                                        priv->tx_htinfo);
-               else if (rate)
+               else
                        rate->rate = priv->data_rate;
        } else {
                ret = -1;
index 8a56fd3da98953aab54673022f71967c6af18572..5af959274d4ef0c6ba4b355a49575604101db0d1 100644 (file)
@@ -29,7 +29,7 @@ config NFC_PN533
 
 config NFC_WILINK
        tristate "Texas Instruments NFC WiLink driver"
-       depends on TI_ST
+       depends on TI_ST && NFC_NCI
        help
          This enables the NFC driver for Texas Instrument's BT/FM/GPS/NFC
          combo devices. This makes use of shared transport line discipline
index eaa80a3d412b156d21804b3e0656d205b36fb1c0..4116a7542b6b51af584dad4c6a22e264caa6fa18 100644 (file)
@@ -460,17 +460,15 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
                synchronize_rcu();
                kfree(old_beacon);
 
-               /* free all potentially still buffered bcast frames */
-               while ((skb = skb_dequeue(&sdata->u.ap.ps_bc_buf))) {
-                       local->total_ps_buffered--;
-                       dev_kfree_skb(skb);
-               }
-
                /* down all dependent devices, that is VLANs */
                list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
                                         u.vlan.list)
                        dev_close(vlan->dev);
                WARN_ON(!list_empty(&sdata->u.ap.vlans));
+
+               /* free all potentially still buffered bcast frames */
+               local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps_bc_buf);
+               skb_queue_purge(&sdata->u.ap.ps_bc_buf);
        }
 
        if (going_down)
index 4396906175ae22c00d55978171b4040632d72011..1213a23ff0fa7e28cfb547bbbcb29855891974f2 100644 (file)
@@ -43,6 +43,10 @@ enum plink_event {
        CLS_IGNR
 };
 
+static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
+               enum ieee80211_self_protected_actioncode action,
+               u8 *da, __le16 llid, __le16 plid, __le16 reason);
+
 static inline
 void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
 {
@@ -133,6 +137,10 @@ void mesh_plink_deactivate(struct sta_info *sta)
 
        spin_lock_bh(&sta->lock);
        deactivated = __mesh_plink_deactivate(sta);
+       sta->reason = cpu_to_le16(WLAN_REASON_MESH_PEER_CANCELED);
+       mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CLOSE,
+                           sta->sta.addr, sta->llid, sta->plid,
+                           sta->reason);
        spin_unlock_bh(&sta->lock);
 
        if (deactivated)