Skip to content

Commit

Permalink
iwlwifi: move virtual interface pointer into context
Browse files Browse the repository at this point in the history
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: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
  • Loading branch information
Johannes Berg authored and Wey-Yi Guy committed Aug 27, 2010
1 parent c90cbbb commit 8bd413e
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 38 deletions.
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/iwl-3945-rs.c
Original file line number Diff line number Diff line change
Expand Up @@ -932,7 +932,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)

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);
if (!sta) {
IWL_DEBUG_RATE(priv, "Unable to find station to initialize rate scaling.\n");
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/iwl-4965.c
Original file line number Diff line number Diff line change
Expand Up @@ -1462,7 +1462,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
u32 tsf_low;
u8 switch_count;
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;

is_ht40 = is_ht40_channel(ctx->staging.flags);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/iwl-5000.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
u32 tsf_low;
u8 switch_count;
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 = {
.id = REPLY_CHANNEL_SWITCH,
.len = sizeof(cmd),
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/iwl-6000.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
u32 tsf_low;
u8 switch_count;
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 = {
.id = REPLY_CHANNEL_SWITCH,
.len = sizeof(cmd),
Expand Down
10 changes: 7 additions & 3 deletions drivers/net/wireless/iwlwifi/iwl-agn-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1720,6 +1720,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
{
struct iwl_priv *priv =
container_of(work, struct iwl_priv, bt_traffic_change_work);
struct iwl_rxon_context *ctx;
int smps_request = -1;

IWL_DEBUG_INFO(priv, "BT traffic load changes: %d\n",
Expand Down Expand Up @@ -1747,9 +1748,12 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
if (priv->cfg->ops->lib->update_chain_flags)
priv->cfg->ops->lib->update_chain_flags(priv);

if (smps_request != -1 &&
priv->vif && priv->vif->type == NL80211_IFTYPE_STATION)
ieee80211_request_smps(priv->vif, smps_request);
if (smps_request != -1) {
for_each_context(priv, ctx) {
if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION)
ieee80211_request_smps(ctx->vif, smps_request);
}
}

mutex_unlock(&priv->mutex);
}
Expand Down
17 changes: 10 additions & 7 deletions drivers/net/wireless/iwlwifi/iwl-agn-tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1120,6 +1120,9 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
struct iwl_queue *q = &priv->txq[txq_id].q;
u8 *addr = priv->stations[sta_id].sta.sta.addr;
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);

Expand All @@ -1135,30 +1138,30 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
ssn, tx_fifo);
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;
case IWL_EMPTYING_HW_QUEUE_ADDBA:
/* We are reclaiming the last packet of the queue */
if (tid_data->tfds_in_queue == 0) {
IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n");
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;
}

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 iwl_station_priv *sta_priv;

rcu_read_lock();
sta = ieee80211_find_sta(priv->vif, hdr->addr1);
sta = ieee80211_find_sta(tx_info->ctx->vif, hdr->addr1);
if (sta) {
sta_priv = (void *)sta->drv_priv;
/* avoid atomic ops if this isn't a client */
Expand All @@ -1168,7 +1171,7 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb)
}
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)
Expand All @@ -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)) {

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;
if (hdr && ieee80211_is_data_qos(hdr->frame_control))
Expand Down
12 changes: 8 additions & 4 deletions drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,9 @@ static void iwl_bg_beacon_update(struct work_struct *work)
struct sk_buff *beacon;

/* 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) {
IWL_ERR(priv, "update beacon failed\n");
Expand Down Expand Up @@ -3154,13 +3156,15 @@ static void iwl_bg_restart(struct work_struct *data)
return;

if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
struct iwl_rxon_context *ctx;
bool bt_sco, bt_full_concurrent;
u8 bt_ci_compliance;
u8 bt_load;
u8 bt_status;

mutex_lock(&priv->mutex);
priv->vif = NULL;
for_each_context(priv, ctx)
ctx->vif = NULL;
priv->is_open = 0;

/*
Expand Down Expand Up @@ -3838,7 +3842,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
iwl_set_rxon_channel(priv, channel, ctx);
iwl_set_rxon_ht(priv, ht_conf);
iwl_set_flags_for_band(priv, ctx, channel->band,
priv->vif);
ctx->vif);
spin_unlock_irqrestore(&priv->lock, flags);

iwl_set_rate(priv);
Expand All @@ -3855,7 +3859,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
mutex_unlock(&priv->mutex);
out_exit:
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");
}

Expand Down
48 changes: 31 additions & 17 deletions drivers/net/wireless/iwlwifi/iwl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1133,11 +1133,17 @@ EXPORT_SYMBOL(iwl_set_rate);

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))
return;

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);
priv->switch_rxon.switch_in_progress = false;
mutex_unlock(&priv->mutex);
Expand All @@ -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_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];
#endif
struct iwl_rxon_cmd *rxon = (void *)&ctx->active;

if (priv->switch_rxon.switch_in_progress) {
Expand Down Expand Up @@ -1735,7 +1743,9 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
IWL_DEBUG_MAC80211(priv, "leave\n");
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;
}
Expand Down Expand Up @@ -1927,27 +1937,31 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
struct iwl_priv *priv = hw->priv;
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
struct iwl_rxon_context *ctx;
int err = 0;

IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
vif->type, vif->addr);

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))) {
err = -EINVAL;
goto out;
}

if (priv->vif) {
if (ctx->vif) {
IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
err = -EOPNOTSUPP;
goto out;
}

priv->vif = vif;
ctx->vif = vif;
priv->iw_mode = vif->type;

err = iwl_set_mode(priv, vif);
Expand All @@ -1967,7 +1981,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
goto out;

out_err:
priv->vif = NULL;
ctx->vif = NULL;
priv->iw_mode = NL80211_IFTYPE_STATION;
out:
mutex_unlock(&priv->mutex);
Expand All @@ -1993,14 +2007,11 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwlcore_commit_rxon(priv, ctx);
}
if (priv->vif == vif) {
priv->vif = NULL;
if (priv->scan_vif == vif) {
scan_completed = true;
priv->scan_vif = NULL;
priv->scan_request = NULL;
}
memset(priv->bssid, 0, ETH_ALEN);

if (priv->scan_vif == vif) {
scan_completed = true;
priv->scan_vif = NULL;
priv->scan_request = NULL;
}

/*
Expand All @@ -2013,6 +2024,9 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
if (vif->type == NL80211_IFTYPE_ADHOC)
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);

if (scan_completed)
Expand Down Expand Up @@ -2117,7 +2131,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
iwl_set_rxon_ht(priv, ht_conf);

iwl_set_flags_for_band(priv, ctx, channel->band,
priv->vif);
ctx->vif);
}

spin_unlock_irqrestore(&priv->lock, flags);
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/iwl-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,7 @@ enum iwl_rxon_context_id {
};

struct iwl_rxon_context {
struct ieee80211_vif *vif;
enum iwl_rxon_context_id ctxid;
/*
* We declare this const so it can only be
Expand Down Expand Up @@ -1321,7 +1322,6 @@ struct iwl_priv {

/* Last Rx'd beacon timestamp */
u64 timestamp;
struct ieee80211_vif *vif;

union {
#if defined(CONFIG_IWL3945) || defined(CONFIG_IWL3945_MODULE)
Expand Down
7 changes: 5 additions & 2 deletions drivers/net/wireless/iwlwifi/iwl3945-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,8 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
struct sk_buff *beacon;

/* 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) {
IWL_ERR(priv, "update beacon failed\n");
Expand Down Expand Up @@ -3048,8 +3049,10 @@ static void iwl3945_bg_restart(struct work_struct *data)
return;

if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
struct iwl_rxon_context *ctx;
mutex_lock(&priv->mutex);
priv->vif = NULL;
for_each_context(priv, ctx)
ctx->vif = NULL;
priv->is_open = 0;
mutex_unlock(&priv->mutex);
iwl3945_down(priv);
Expand Down

0 comments on commit 8bd413e

Please sign in to comment.