Commit 8bd413e6 authored by Johannes Berg's avatar Johannes Berg Committed by Wey-Yi Guy

iwlwifi: move virtual interface pointer into context

iwlwifi occasionally needs to find the virtual
interface pointer to give it to mac80211, but right
now it only keeps one. Move it into the context so
that we can keep one pointer each.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
parent c90cbbbd
...@@ -932,7 +932,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) ...@@ -932,7 +932,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
rcu_read_lock(); rcu_read_lock();
sta = ieee80211_find_sta(priv->vif, sta = ieee80211_find_sta(priv->contexts[IWL_RXON_CTX_BSS].vif,
priv->stations[sta_id].sta.sta.addr); priv->stations[sta_id].sta.sta.addr);
if (!sta) { if (!sta) {
IWL_DEBUG_RATE(priv, "Unable to find station to initialize rate scaling.\n"); IWL_DEBUG_RATE(priv, "Unable to find station to initialize rate scaling.\n");
......
...@@ -1462,7 +1462,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, ...@@ -1462,7 +1462,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
u32 tsf_low; u32 tsf_low;
u8 switch_count; u8 switch_count;
u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
struct ieee80211_vif *vif = priv->vif; struct ieee80211_vif *vif = ctx->vif;
band = priv->band == IEEE80211_BAND_2GHZ; band = priv->band == IEEE80211_BAND_2GHZ;
is_ht40 = is_ht40_channel(ctx->staging.flags); is_ht40 = is_ht40_channel(ctx->staging.flags);
......
...@@ -287,7 +287,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, ...@@ -287,7 +287,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
u32 tsf_low; u32 tsf_low;
u8 switch_count; u8 switch_count;
u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
struct ieee80211_vif *vif = priv->vif; struct ieee80211_vif *vif = ctx->vif;
struct iwl_host_cmd hcmd = { struct iwl_host_cmd hcmd = {
.id = REPLY_CHANNEL_SWITCH, .id = REPLY_CHANNEL_SWITCH,
.len = sizeof(cmd), .len = sizeof(cmd),
......
...@@ -210,7 +210,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, ...@@ -210,7 +210,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
u32 tsf_low; u32 tsf_low;
u8 switch_count; u8 switch_count;
u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
struct ieee80211_vif *vif = priv->vif; struct ieee80211_vif *vif = ctx->vif;
struct iwl_host_cmd hcmd = { struct iwl_host_cmd hcmd = {
.id = REPLY_CHANNEL_SWITCH, .id = REPLY_CHANNEL_SWITCH,
.len = sizeof(cmd), .len = sizeof(cmd),
......
...@@ -1720,6 +1720,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) ...@@ -1720,6 +1720,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
{ {
struct iwl_priv *priv = struct iwl_priv *priv =
container_of(work, struct iwl_priv, bt_traffic_change_work); container_of(work, struct iwl_priv, bt_traffic_change_work);
struct iwl_rxon_context *ctx;
int smps_request = -1; int smps_request = -1;
IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n", IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n",
...@@ -1747,9 +1748,12 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) ...@@ -1747,9 +1748,12 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
if (priv->cfg->ops->lib->update_chain_flags) if (priv->cfg->ops->lib->update_chain_flags)
priv->cfg->ops->lib->update_chain_flags(priv); priv->cfg->ops->lib->update_chain_flags(priv);
if (smps_request != -1 && if (smps_request != -1) {
priv->vif && priv->vif->type == NL80211_IFTYPE_STATION) for_each_context(priv, ctx) {
ieee80211_request_smps(priv->vif, smps_request); if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION)
ieee80211_request_smps(ctx->vif, smps_request);
}
}
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
} }
......
...@@ -1120,6 +1120,9 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, ...@@ -1120,6 +1120,9 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
struct iwl_queue *q = &priv->txq[txq_id].q; struct iwl_queue *q = &priv->txq[txq_id].q;
u8 *addr = priv->stations[sta_id].sta.sta.addr; u8 *addr = priv->stations[sta_id].sta.sta.addr;
struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid];
struct iwl_rxon_context *ctx;
ctx = &priv->contexts[priv->stations[sta_id].ctxid];
lockdep_assert_held(&priv->sta_lock); lockdep_assert_held(&priv->sta_lock);
...@@ -1135,7 +1138,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, ...@@ -1135,7 +1138,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
ssn, tx_fifo); ssn, tx_fifo);
tid_data->agg.state = IWL_AGG_OFF; tid_data->agg.state = IWL_AGG_OFF;
ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, addr, tid); ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
} }
break; break;
case IWL_EMPTYING_HW_QUEUE_ADDBA: case IWL_EMPTYING_HW_QUEUE_ADDBA:
...@@ -1143,7 +1146,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, ...@@ -1143,7 +1146,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
if (tid_data->tfds_in_queue == 0) { if (tid_data->tfds_in_queue == 0) {
IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n"); IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n");
tid_data->agg.state = IWL_AGG_ON; tid_data->agg.state = IWL_AGG_ON;
ieee80211_start_tx_ba_cb_irqsafe(priv->vif, addr, tid); ieee80211_start_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
} }
break; break;
} }
...@@ -1151,14 +1154,14 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv, ...@@ -1151,14 +1154,14 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
return 0; return 0;
} }
static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb) static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info)
{ {
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx_info->skb->data;
struct ieee80211_sta *sta; struct ieee80211_sta *sta;
struct iwl_station_priv *sta_priv; struct iwl_station_priv *sta_priv;
rcu_read_lock(); rcu_read_lock();
sta = ieee80211_find_sta(priv->vif, hdr->addr1); sta = ieee80211_find_sta(tx_info->ctx->vif, hdr->addr1);
if (sta) { if (sta) {
sta_priv = (void *)sta->drv_priv; sta_priv = (void *)sta->drv_priv;
/* avoid atomic ops if this isn't a client */ /* avoid atomic ops if this isn't a client */
...@@ -1168,7 +1171,7 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb) ...@@ -1168,7 +1171,7 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb)
} }
rcu_read_unlock(); rcu_read_unlock();
ieee80211_tx_status_irqsafe(priv->hw, skb); ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb);
} }
int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
...@@ -1191,7 +1194,7 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) ...@@ -1191,7 +1194,7 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
tx_info = &txq->txb[txq->q.read_ptr]; tx_info = &txq->txb[txq->q.read_ptr];
iwlagn_tx_status(priv, tx_info->skb); iwlagn_tx_status(priv, tx_info);
hdr = (struct ieee80211_hdr *)tx_info->skb->data; hdr = (struct ieee80211_hdr *)tx_info->skb->data;
if (hdr && ieee80211_is_data_qos(hdr->frame_control)) if (hdr && ieee80211_is_data_qos(hdr->frame_control))
......
...@@ -603,7 +603,9 @@ static void iwl_bg_beacon_update(struct work_struct *work) ...@@ -603,7 +603,9 @@ static void iwl_bg_beacon_update(struct work_struct *work)
struct sk_buff *beacon; struct sk_buff *beacon;
/* Pull updated AP beacon from mac80211. will fail if not in AP mode */ /* Pull updated AP beacon from mac80211. will fail if not in AP mode */
beacon = ieee80211_beacon_get(priv->hw, priv->vif); #warning "introduce and use beacon context"
beacon = ieee80211_beacon_get(priv->hw,
priv->contexts[IWL_RXON_CTX_BSS].vif);
if (!beacon) { if (!beacon) {
IWL_ERR(priv, "update beacon failed\n"); IWL_ERR(priv, "update beacon failed\n");
...@@ -3154,13 +3156,15 @@ static void iwl_bg_restart(struct work_struct *data) ...@@ -3154,13 +3156,15 @@ static void iwl_bg_restart(struct work_struct *data)
return; return;
if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
struct iwl_rxon_context *ctx;
bool bt_sco, bt_full_concurrent; bool bt_sco, bt_full_concurrent;
u8 bt_ci_compliance; u8 bt_ci_compliance;
u8 bt_load; u8 bt_load;
u8 bt_status; u8 bt_status;
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
priv->vif = NULL; for_each_context(priv, ctx)
ctx->vif = NULL;
priv->is_open = 0; priv->is_open = 0;
/* /*
...@@ -3838,7 +3842,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw, ...@@ -3838,7 +3842,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
iwl_set_rxon_channel(priv, channel, ctx); iwl_set_rxon_channel(priv, channel, ctx);
iwl_set_rxon_ht(priv, ht_conf); iwl_set_rxon_ht(priv, ht_conf);
iwl_set_flags_for_band(priv, ctx, channel->band, iwl_set_flags_for_band(priv, ctx, channel->band,
priv->vif); ctx->vif);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
iwl_set_rate(priv); iwl_set_rate(priv);
...@@ -3855,7 +3859,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw, ...@@ -3855,7 +3859,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
out_exit: out_exit:
if (!priv->switch_rxon.switch_in_progress) if (!priv->switch_rxon.switch_in_progress)
ieee80211_chswitch_done(priv->vif, false); ieee80211_chswitch_done(ctx->vif, false);
IWL_DEBUG_MAC80211(priv, "leave\n"); IWL_DEBUG_MAC80211(priv, "leave\n");
} }
......
...@@ -1133,11 +1133,17 @@ EXPORT_SYMBOL(iwl_set_rate); ...@@ -1133,11 +1133,17 @@ EXPORT_SYMBOL(iwl_set_rate);
void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) void iwl_chswitch_done(struct iwl_priv *priv, bool is_success)
{ {
/*
* MULTI-FIXME
* See iwl_mac_channel_switch.
*/
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return; return;
if (priv->switch_rxon.switch_in_progress) { if (priv->switch_rxon.switch_in_progress) {
ieee80211_chswitch_done(priv->vif, is_success); ieee80211_chswitch_done(ctx->vif, is_success);
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
priv->switch_rxon.switch_in_progress = false; priv->switch_rxon.switch_in_progress = false;
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
...@@ -1149,9 +1155,11 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) ...@@ -1149,9 +1155,11 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
{ {
struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_rx_packet *pkt = rxb_addr(rxb);
struct iwl_csa_notification *csa = &(pkt->u.csa_notif); struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
#if !TODO /*
* MULTI-FIXME
* See iwl_mac_channel_switch.
*/
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
#endif
struct iwl_rxon_cmd *rxon = (void *)&ctx->active; struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
if (priv->switch_rxon.switch_in_progress) { if (priv->switch_rxon.switch_in_progress) {
...@@ -1735,7 +1743,9 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -1735,7 +1743,9 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
IWL_DEBUG_MAC80211(priv, "leave\n"); IWL_DEBUG_MAC80211(priv, "leave\n");
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
priv->cfg->ops->lib->post_associate(priv, priv->vif); #warning "use beacon context?"
priv->cfg->ops->lib->post_associate(
priv, priv->contexts[IWL_RXON_CTX_BSS].vif);
return 0; return 0;
} }
...@@ -1927,6 +1937,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ...@@ -1927,6 +1937,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{ {
struct iwl_priv *priv = hw->priv; struct iwl_priv *priv = hw->priv;
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
struct iwl_rxon_context *ctx;
int err = 0; int err = 0;
IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
...@@ -1934,20 +1945,23 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ...@@ -1934,20 +1945,23 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
vif_priv->ctx = &priv->contexts[IWL_RXON_CTX_BSS]; /* For now always use this context. */
ctx = &priv->contexts[IWL_RXON_CTX_BSS];
vif_priv->ctx = ctx;
if (WARN_ON(!iwl_is_ready_rf(priv))) { if (WARN_ON(!iwl_is_ready_rf(priv))) {
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
if (priv->vif) { if (ctx->vif) {
IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n"); IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
goto out; goto out;
} }
priv->vif = vif; ctx->vif = vif;
priv->iw_mode = vif->type; priv->iw_mode = vif->type;
err = iwl_set_mode(priv, vif); err = iwl_set_mode(priv, vif);
...@@ -1967,7 +1981,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ...@@ -1967,7 +1981,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
goto out; goto out;
out_err: out_err:
priv->vif = NULL; ctx->vif = NULL;
priv->iw_mode = NL80211_IFTYPE_STATION; priv->iw_mode = NL80211_IFTYPE_STATION;
out: out:
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
...@@ -1993,15 +2007,12 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, ...@@ -1993,15 +2007,12 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwlcore_commit_rxon(priv, ctx); iwlcore_commit_rxon(priv, ctx);
} }
if (priv->vif == vif) {
priv->vif = NULL;
if (priv->scan_vif == vif) { if (priv->scan_vif == vif) {
scan_completed = true; scan_completed = true;
priv->scan_vif = NULL; priv->scan_vif = NULL;
priv->scan_request = NULL; priv->scan_request = NULL;
} }
memset(priv->bssid, 0, ETH_ALEN);
}
/* /*
* When removing the IBSS interface, overwrite the * When removing the IBSS interface, overwrite the
...@@ -2013,6 +2024,9 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, ...@@ -2013,6 +2024,9 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
if (vif->type == NL80211_IFTYPE_ADHOC) if (vif->type == NL80211_IFTYPE_ADHOC)
priv->bt_traffic_load = priv->notif_bt_traffic_load; priv->bt_traffic_load = priv->notif_bt_traffic_load;
WARN_ON(ctx->vif != vif);
ctx->vif = NULL;
memset(priv->bssid, 0, ETH_ALEN);
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
if (scan_completed) if (scan_completed)
...@@ -2117,7 +2131,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed) ...@@ -2117,7 +2131,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
iwl_set_rxon_ht(priv, ht_conf); iwl_set_rxon_ht(priv, ht_conf);
iwl_set_flags_for_band(priv, ctx, channel->band, iwl_set_flags_for_band(priv, ctx, channel->band,
priv->vif); ctx->vif);
} }
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
......
...@@ -1114,6 +1114,7 @@ enum iwl_rxon_context_id { ...@@ -1114,6 +1114,7 @@ enum iwl_rxon_context_id {
}; };
struct iwl_rxon_context { struct iwl_rxon_context {
struct ieee80211_vif *vif;
enum iwl_rxon_context_id ctxid; enum iwl_rxon_context_id ctxid;
/* /*
* We declare this const so it can only be * We declare this const so it can only be
...@@ -1321,7 +1322,6 @@ struct iwl_priv { ...@@ -1321,7 +1322,6 @@ struct iwl_priv {
/* Last Rx'd beacon timestamp */ /* Last Rx'd beacon timestamp */
u64 timestamp; u64 timestamp;
struct ieee80211_vif *vif;
union { union {
#if defined(CONFIG_IWL3945) || defined(CONFIG_IWL3945_MODULE) #if defined(CONFIG_IWL3945) || defined(CONFIG_IWL3945_MODULE)
......
...@@ -802,7 +802,8 @@ static void iwl3945_bg_beacon_update(struct work_struct *work) ...@@ -802,7 +802,8 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
struct sk_buff *beacon; struct sk_buff *beacon;
/* Pull updated AP beacon from mac80211. will fail if not in AP mode */ /* Pull updated AP beacon from mac80211. will fail if not in AP mode */
beacon = ieee80211_beacon_get(priv->hw, priv->vif); beacon = ieee80211_beacon_get(priv->hw,
priv->contexts[IWL_RXON_CTX_BSS].vif);
if (!beacon) { if (!beacon) {
IWL_ERR(priv, "update beacon failed\n"); IWL_ERR(priv, "update beacon failed\n");
...@@ -3048,8 +3049,10 @@ static void iwl3945_bg_restart(struct work_struct *data) ...@@ -3048,8 +3049,10 @@ static void iwl3945_bg_restart(struct work_struct *data)
return; return;
if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
struct iwl_rxon_context *ctx;
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
priv->vif = NULL; for_each_context(priv, ctx)
ctx->vif = NULL;
priv->is_open = 0; priv->is_open = 0;
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
iwl3945_down(priv); iwl3945_down(priv);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment