summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-09-18 18:14:18 +0200
committerJohn W. Linville <linville@tuxdriver.com>2008-09-24 16:18:03 -0400
commit4b7679a561e552eeda1e3567119bef2bca99b66e (patch)
treeb5f2b45c9186eb954f9329322d07e277e669b422 /drivers/net/wireless/iwlwifi
parent2ff6a6d4e92270283432690adf53a7e5ab186d19 (diff)
mac80211: clean up rate control API
Long awaited, hard work. This patch totally cleans up the rate control API to remove the requirement to include internal headers outside of net/mac80211/. There's one internal use in the PID algorithm left for mesh networking, we'll have to figure out a way to clean that one up and decide how to do the peer link evaluation, possibly independent of the rate control algorithm or via new API. Additionally, ath9k is left using the cross-inclusion hack for now, we will add new API where necessary to make this work properly, but right now I'm not expert enough to do it. It's still off better than before. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c182
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c146
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c11
5 files changed, 104 insertions, 248 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index a279bf1dc9b0..6fc5e7361f26 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -36,8 +36,6 @@
#include <linux/workqueue.h>
-#include "../net/mac80211/rate.h"
-
#include "iwl-3945.h"
#define RS_NAME "iwl-3945-rs"
@@ -319,10 +317,10 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
}
}
-static void rs_rate_init(void *priv_rate, void *priv_sta,
- struct ieee80211_local *local, struct sta_info *sta)
+static void rs_rate_init(void *priv, struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta, void *priv_sta)
{
- struct iwl3945_rs_sta *rs_sta = (void *)sta->rate_ctrl_priv;
+ struct iwl3945_rs_sta *rs_sta = priv_sta;
int i;
IWL_DEBUG_RATE("enter\n");
@@ -333,22 +331,22 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
* after assoc.. */
for (i = IWL_RATE_COUNT - 1; i >= 0; i--) {
- if (sta->sta.supp_rates[local->hw.conf.channel->band] & (1 << i)) {
+ if (sta->supp_rates[sband->band] & (1 << i)) {
rs_sta->last_txrate_idx = i;
break;
}
}
/* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */
- if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ)
+ if (sband->band == IEEE80211_BAND_5GHZ)
rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
IWL_DEBUG_RATE("leave\n");
}
-static void *rs_alloc(struct ieee80211_local *local)
+static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
{
- return local->hw.priv;
+ return hw->priv;
}
/* rate scale requires free function to be implemented */
@@ -356,17 +354,24 @@ static void rs_free(void *priv)
{
return;
}
+
static void rs_clear(void *priv)
{
return;
}
-static void *rs_alloc_sta(void *priv, gfp_t gfp)
+static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
{
struct iwl3945_rs_sta *rs_sta;
+ struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
int i;
+ /*
+ * XXX: If it's using sta->drv_priv anyway, it might
+ * as well just put all the information there.
+ */
+
IWL_DEBUG_RATE("enter\n");
rs_sta = kzalloc(sizeof(struct iwl3945_rs_sta), gfp);
@@ -375,6 +380,8 @@ static void *rs_alloc_sta(void *priv, gfp_t gfp)
return NULL;
}
+ psta->rs_sta = rs_sta;
+
spin_lock_init(&rs_sta->lock);
rs_sta->start_rate = IWL_RATE_INVALID;
@@ -400,10 +407,14 @@ static void *rs_alloc_sta(void *priv, gfp_t gfp)
return rs_sta;
}
-static void rs_free_sta(void *priv, void *priv_sta)
+static void rs_free_sta(void *priv, struct ieee80211_sta *sta,
+ void *priv_sta)
{
+ struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
struct iwl3945_rs_sta *rs_sta = priv_sta;
+ psta->rs_sta = NULL;
+
IWL_DEBUG_RATE("enter\n");
del_timer_sync(&rs_sta->rate_scale_flush);
kfree(rs_sta);
@@ -445,26 +456,19 @@ static int rs_adjust_next_rate(struct iwl3945_priv *priv, int rate)
* NOTE: Uses iwl3945_priv->retry_rate for the # of retries attempted by
* the hardware for each rate.
*/
-static void rs_tx_status(void *priv_rate,
- struct net_device *dev,
+static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta, void *priv_sta,
struct sk_buff *skb)
{
u8 retries, current_count;
int scale_rate_index, first_index, last_index;
unsigned long flags;
- struct sta_info *sta;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate;
- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
- struct iwl3945_rs_sta *rs_sta;
- struct ieee80211_supported_band *sband;
+ struct iwl3945_rs_sta *rs_sta = priv_sta;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
IWL_DEBUG_RATE("enter\n");
- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
-
retries = info->status.retry_count;
first_index = sband->bitrates[info->tx_rate_idx].hw_value;
if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) {
@@ -472,17 +476,11 @@ static void rs_tx_status(void *priv_rate,
return;
}
- rcu_read_lock();
-
- sta = sta_info_get(local, hdr->addr1);
- if (!sta || !sta->rate_ctrl_priv) {
- rcu_read_unlock();
+ if (!priv_sta) {
IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
return;
}
- rs_sta = (void *)sta->rate_ctrl_priv;
-
rs_sta->tx_packets++;
scale_rate_index = first_index;
@@ -549,8 +547,6 @@ static void rs_tx_status(void *priv_rate,
spin_unlock_irqrestore(&rs_sta->lock, flags);
- rcu_read_unlock();
-
IWL_DEBUG_RATE("leave\n");
return;
@@ -634,16 +630,15 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
* rate table and must reference the driver allocated rate table
*
*/
-static void rs_get_rate(void *priv_rate, struct net_device *dev,
- struct ieee80211_supported_band *sband,
- struct sk_buff *skb,
- struct rate_selection *sel)
+static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta, void *priv_sta,
+ struct sk_buff *skb, struct rate_selection *sel)
{
u8 low = IWL_RATE_INVALID;
u8 high = IWL_RATE_INVALID;
u16 high_low;
int index;
- struct iwl3945_rs_sta *rs_sta;
+ struct iwl3945_rs_sta *rs_sta = priv_sta;
struct iwl3945_rate_scale_data *window = NULL;
int current_tpt = IWL_INV_TPT;
int low_tpt = IWL_INV_TPT;
@@ -651,34 +646,25 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
u32 fail_count;
s8 scale_action = 0;
unsigned long flags;
- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- struct sta_info *sta;
u16 fc, rate_mask;
- struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate;
+ struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r;
DECLARE_MAC_BUF(mac);
IWL_DEBUG_RATE("enter\n");
- rcu_read_lock();
-
- sta = sta_info_get(local, hdr->addr1);
-
/* Send management frames and broadcast/multicast data using lowest
* rate. */
fc = le16_to_cpu(hdr->frame_control);
if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
is_multicast_ether_addr(hdr->addr1) ||
- !sta || !sta->rate_ctrl_priv) {
+ !sta || !priv_sta) {
IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
- sel->rate_idx = rate_lowest_index(local, sband, sta);
- rcu_read_unlock();
+ sel->rate_idx = rate_lowest_index(sband, sta);
return;
}
- rs_sta = (void *)sta->rate_ctrl_priv;
-
- rate_mask = sta->sta.supp_rates[sband->band];
+ rate_mask = sta->supp_rates[sband->band];
index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1);
if (sband->band == IEEE80211_BAND_5GHZ)
@@ -811,8 +797,6 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
else
sel->rate_idx = rs_sta->last_txrate_idx;
- rcu_read_unlock();
-
IWL_DEBUG_RATE("leave: %d\n", index);
}
@@ -829,114 +813,28 @@ static struct rate_control_ops rs_ops = {
.free_sta = rs_free_sta,
};
-int iwl3945_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
-{
- struct ieee80211_local *local = hw_to_local(hw);
- struct iwl3945_priv *priv = hw->priv;
- struct iwl3945_rs_sta *rs_sta;
- struct sta_info *sta;
- unsigned long flags;
- int count = 0, i;
- u32 samples = 0, success = 0, good = 0;
- unsigned long now = jiffies;
- u32 max_time = 0;
-
- rcu_read_lock();
-
- sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr);
- if (!sta || !sta->rate_ctrl_priv) {
- if (sta)
- IWL_DEBUG_RATE("leave - no private rate data!\n");
- else
- IWL_DEBUG_RATE("leave - no station!\n");
- rcu_read_unlock();
- return sprintf(buf, "station %d not found\n", sta_id);
- }
-
- rs_sta = (void *)sta->rate_ctrl_priv;
- spin_lock_irqsave(&rs_sta->lock, flags);
- i = IWL_RATE_54M_INDEX;
- while (1) {
- u64 mask;
- int j;
-
- count +=
- sprintf(&buf[count], " %2dMbs: ", iwl3945_rates[i].ieee / 2);
-
- mask = (1ULL << (IWL_RATE_MAX_WINDOW - 1));
- for (j = 0; j < IWL_RATE_MAX_WINDOW; j++, mask >>= 1)
- buf[count++] =
- (rs_sta->win[i].data & mask) ? '1' : '0';
-
- samples += rs_sta->win[i].counter;
- good += rs_sta->win[i].success_counter;
- success += rs_sta->win[i].success_counter *
- iwl3945_rates[i].ieee;
-
- if (rs_sta->win[i].stamp) {
- int delta =
- jiffies_to_msecs(now - rs_sta->win[i].stamp);
-
- if (delta > max_time)
- max_time = delta;
-
- count += sprintf(&buf[count], "%5dms\n", delta);
- } else
- buf[count++] = '\n';
-
- j = iwl3945_get_prev_ieee_rate(i);
- if (j == i)
- break;
- i = j;
- }
- spin_unlock_irqrestore(&rs_sta->lock, flags);
- rcu_read_unlock();
-
- /* Display the average rate of all samples taken.
- *
- * NOTE: We multiple # of samples by 2 since the IEEE measurement
- * added from iwl3945_rates is actually 2X the rate */
- if (samples)
- count += sprintf(
- &buf[count],
- "\nAverage rate is %3d.%02dMbs over last %4dms\n"
- "%3d%% success (%d good packets over %d tries)\n",
- success / (2 * samples), (success * 5 / samples) % 10,
- max_time, good * 100 / samples, good, samples);
- else
- count += sprintf(&buf[count], "\nAverage rate: 0Mbs\n");
-
- return count;
-}
-
void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
{
struct iwl3945_priv *priv = hw->priv;
s32 rssi = 0;
unsigned long flags;
- struct ieee80211_local *local = hw_to_local(hw);
struct iwl3945_rs_sta *rs_sta;
- struct sta_info *sta;
+ struct ieee80211_sta *sta;
+ struct iwl3945_sta_priv *psta;
IWL_DEBUG_RATE("enter\n");
- if (!local->rate_ctrl->ops->name ||
- strcmp(local->rate_ctrl->ops->name, RS_NAME)) {
- IWL_WARNING("iwl-3945-rs not selected as rate control algo!\n");
- IWL_DEBUG_RATE("leave - mac80211 picked the wrong RC algo.\n");
- return;
- }
-
rcu_read_lock();
- sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr);
- if (!sta || !sta->rate_ctrl_priv) {
+ sta = ieee80211_find_sta(hw, priv->stations[sta_id].sta.sta.addr);
+ psta = (void *) sta->drv_priv;
+ if (!sta || !psta) {
IWL_DEBUG_RATE("leave - no private rate data!\n");
rcu_read_unlock();
return;
}
- rs_sta = (void *)sta->rate_ctrl_priv;
+ rs_sta = psta->rs_sta;
spin_lock_irqsave(&rs_sta->lock, flags);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
index f085d330bdcf..98b17ae6ef24 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h
@@ -176,15 +176,6 @@ static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
}
/**
- * iwl3945_fill_rs_info - Fill an output text buffer with the rate representation
- *
- * NOTE: This is provided as a quick mechanism for a user to visualize
- * the performance of the rate control algorithm and is not meant to be
- * parsed software.
- */
-extern int iwl3945_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
-
-/**
* iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
*
* The specific throughput table used is based on the type of network
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 2a4933b5fb64..bdd32475b99c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -73,6 +73,10 @@ extern struct pci_device_id iwl3945_hw_card_ids[];
extern int iwl3945_param_hwcrypto;
extern int iwl3945_param_queues_num;
+struct iwl3945_sta_priv {
+ struct iwl3945_rs_sta *rs_sta;
+};
+
enum iwl3945_antenna {
IWL_ANTENNA_DIVERSITY,
IWL_ANTENNA_MAIN,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 8b57b390c8ba..93944de923ca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -35,8 +35,6 @@
#include <linux/workqueue.h>
-#include "../net/mac80211/rate.h"
-
#include "iwl-dev.h"
#include "iwl-sta.h"
#include "iwl-core.h"
@@ -169,9 +167,9 @@ struct iwl_lq_sta {
};
static void rs_rate_scale_perform(struct iwl_priv *priv,
- struct net_device *dev,
struct ieee80211_hdr *hdr,
- struct sta_info *sta);
+ struct ieee80211_sta *sta,
+ struct iwl_lq_sta *lq_sta);
static void rs_fill_link_cmd(const struct iwl_priv *priv,
struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
@@ -357,20 +355,20 @@ static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
struct iwl_lq_sta *lq_data, u8 tid,
- struct sta_info *sta)
+ struct ieee80211_sta *sta)
{
DECLARE_MAC_BUF(mac);
if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {
IWL_DEBUG_HT("Starting Tx agg: STA: %s tid: %d\n",
- print_mac(mac, sta->sta.addr), tid);
- ieee80211_start_tx_ba_session(priv->hw, sta->sta.addr, tid);
+ print_mac(mac, sta->addr), tid);
+ ieee80211_start_tx_ba_session(priv->hw, sta->addr, tid);
}
}
static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
struct iwl_lq_sta *lq_data,
- struct sta_info *sta)
+ struct ieee80211_sta *sta)
{
if ((tid < TID_MAX_LOAD_COUNT))
rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
@@ -770,7 +768,8 @@ out:
/*
* mac80211 sends us Tx status
*/
-static void rs_tx_status(void *priv_rate, struct net_device *dev,
+static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta, void *priv_sta,
struct sk_buff *skb)
{
int status;
@@ -778,11 +777,9 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
int rs_index, index = 0;
struct iwl_lq_sta *lq_sta;
struct iwl_link_quality_cmd *table;
- struct sta_info *sta;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
- struct ieee80211_hw *hw = local_to_hw(local);
+ struct iwl_priv *priv = (struct iwl_priv *)priv_r;
+ struct ieee80211_hw *hw = priv->hw;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct iwl_rate_scale_data *window = NULL;
struct iwl_rate_scale_data *search_win = NULL;
@@ -808,15 +805,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
if (retries > 15)
retries = 15;
- rcu_read_lock();
-
- sta = sta_info_get(local, hdr->addr1);
-
- if (!sta || !sta->rate_ctrl_priv)
- goto out;
-
-
- lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
+ lq_sta = (struct iwl_lq_sta *)priv_sta;
if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
!lq_sta->ibss_sta_added)
@@ -962,9 +951,8 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
}
/* See if there's a better rate or modulation mode to try. */
- rs_rate_scale_perform(priv, dev, hdr, sta);
+ rs_rate_scale_perform(priv, hdr, sta, lq_sta);
out:
- rcu_read_unlock();
return;
}
@@ -1140,7 +1128,7 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,
static int rs_switch_to_mimo2(struct iwl_priv *priv,
struct iwl_lq_sta *lq_sta,
struct ieee80211_conf *conf,
- struct sta_info *sta,
+ struct ieee80211_sta *sta,
struct iwl_scale_tbl_info *tbl, int index)
{
u16 rate_mask;
@@ -1148,10 +1136,10 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
s8 is_green = lq_sta->is_green;
if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) ||
- !sta->sta.ht_info.ht_supported)
+ !sta->ht_info.ht_supported)
return -1;
- if (((sta->sta.ht_info.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
+ if (((sta->ht_info.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
== WLAN_HT_CAP_SM_PS_STATIC)
return -1;
@@ -1208,7 +1196,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
static int rs_switch_to_siso(struct iwl_priv *priv,
struct iwl_lq_sta *lq_sta,
struct ieee80211_conf *conf,
- struct sta_info *sta,
+ struct ieee80211_sta *sta,
struct iwl_scale_tbl_info *tbl, int index)
{
u16 rate_mask;
@@ -1216,7 +1204,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
s32 rate;
if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) ||
- !sta->sta.ht_info.ht_supported)
+ !sta->ht_info.ht_supported)
return -1;
IWL_DEBUG_RATE("LQ: try to switch to SISO\n");
@@ -1268,7 +1256,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
static int rs_move_legacy_other(struct iwl_priv *priv,
struct iwl_lq_sta *lq_sta,
struct ieee80211_conf *conf,
- struct sta_info *sta,
+ struct ieee80211_sta *sta,
int index)
{
struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
@@ -1376,7 +1364,7 @@ out:
static int rs_move_siso_to_other(struct iwl_priv *priv,
struct iwl_lq_sta *lq_sta,
struct ieee80211_conf *conf,
- struct sta_info *sta, int index)
+ struct ieee80211_sta *sta, int index)
{
u8 is_green = lq_sta->is_green;
struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
@@ -1487,7 +1475,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
static int rs_move_mimo_to_other(struct iwl_priv *priv,
struct iwl_lq_sta *lq_sta,
struct ieee80211_conf *conf,
- struct sta_info *sta, int index)
+ struct ieee80211_sta *sta, int index)
{
s8 is_green = lq_sta->is_green;
struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
@@ -1680,12 +1668,11 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
* Do rate scaling and search for new modulation mode.
*/
static void rs_rate_scale_perform(struct iwl_priv *priv,
- struct net_device *dev,
struct ieee80211_hdr *hdr,
- struct sta_info *sta)
+ struct ieee80211_sta *sta,
+ struct iwl_lq_sta *lq_sta)
{
- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
- struct ieee80211_hw *hw = local_to_hw(local);
+ struct ieee80211_hw *hw = priv->hw;
struct ieee80211_conf *conf = &hw->conf;
int low = IWL_RATE_INVALID;
int high = IWL_RATE_INVALID;
@@ -1700,7 +1687,6 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
__le16 fc;
u16 rate_mask;
u8 update_lq = 0;
- struct iwl_lq_sta *lq_sta;
struct iwl_scale_tbl_info *tbl, *tbl1;
u16 rate_scale_index_msk = 0;
u32 rate;
@@ -1721,11 +1707,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
return;
}
- if (!sta || !sta->rate_ctrl_priv)
+ if (!sta || !lq_sta)
return;
- lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
- lq_sta->supp_rates = sta->sta.supp_rates[lq_sta->band];
+ lq_sta->supp_rates = sta->supp_rates[lq_sta->band];
tid = rs_tl_add_packet(lq_sta, hdr);
@@ -2064,9 +2049,9 @@ out:
static void rs_initialize_lq(struct iwl_priv *priv,
struct ieee80211_conf *conf,
- struct sta_info *sta)
+ struct ieee80211_sta *sta,
+ struct iwl_lq_sta *lq_sta)
{
- struct iwl_lq_sta *lq_sta;
struct iwl_scale_tbl_info *tbl;
int rate_idx;
int i;
@@ -2075,10 +2060,9 @@ static void rs_initialize_lq(struct iwl_priv *priv,
u8 active_tbl = 0;
u8 valid_tx_ant;
- if (!sta || !sta->rate_ctrl_priv)
+ if (!sta || !lq_sta)
goto out;
- lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
i = lq_sta->last_txrate_idx;
if ((lq_sta->lq.sta_id == 0xff) &&
@@ -2119,37 +2103,30 @@ static void rs_initialize_lq(struct iwl_priv *priv,
return;
}
-static void rs_get_rate(void *priv_rate, struct net_device *dev,
- struct ieee80211_supported_band *sband,
- struct sk_buff *skb,
- struct rate_selection *sel)
+static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta, void *priv_sta,
+ struct sk_buff *skb, struct rate_selection *sel)
{
int i;
- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
- struct ieee80211_conf *conf = &local->hw.conf;
+ struct iwl_priv *priv = (struct iwl_priv *)priv_r;
+ struct ieee80211_conf *conf = &priv->hw->conf;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- struct sta_info *sta;
__le16 fc;
- struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
struct iwl_lq_sta *lq_sta;
IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
- rcu_read_lock();
-
- sta = sta_info_get(local, hdr->addr1);
-
/* Send management frames and broadcast/multicast data using lowest
* rate. */
fc = hdr->frame_control;
if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
- !sta || !sta->rate_ctrl_priv) {
- sel->rate_idx = rate_lowest_index(local, sband, sta);
- goto out;
+ !sta || !priv_sta) {
+ sel->rate_idx = rate_lowest_index(sband, sta);
+ return;
}
- lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
+ lq_sta = (struct iwl_lq_sta *)priv_sta;
i = lq_sta->last_txrate_idx;
if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
@@ -2167,23 +2144,22 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
lq_sta->lq.sta_id = sta_id;
lq_sta->lq.rs_table[0].rate_n_flags = 0;
lq_sta->ibss_sta_added = 1;
- rs_initialize_lq(priv, conf, sta);
+ rs_initialize_lq(priv, conf, sta, lq_sta);
}
}
if ((i < 0) || (i > IWL_RATE_COUNT)) {
- sel->rate_idx = rate_lowest_index(local, sband, sta);
- goto out;
+ sel->rate_idx = rate_lowest_index(sband, sta);
+ return;
}
if (sband->band == IEEE80211_BAND_5GHZ)
i -= IWL_FIRST_OFDM_RATE;
sel->rate_idx = i;
-out:
- rcu_read_unlock();
}
-static void *rs_alloc_sta(void *priv_rate, gfp_t gfp)
+static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
+ gfp_t gfp)
{
struct iwl_lq_sta *lq_sta;
struct iwl_priv *priv;
@@ -2206,20 +2182,16 @@ static void *rs_alloc_sta(void *priv_rate, gfp_t gfp)
return lq_sta;
}
-static void rs_rate_init(void *priv_rate, void *priv_sta,
- struct ieee80211_local *local,
- struct sta_info *sta)
+static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta, void *priv_sta)
{
int i, j;
- struct ieee80211_conf *conf = &local->hw.conf;
- struct ieee80211_supported_band *sband;
- struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
+ struct iwl_priv *priv = (struct iwl_priv *)priv_r;
+ struct ieee80211_conf *conf = &priv->hw->conf;
struct iwl_lq_sta *lq_sta = priv_sta;
- sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
lq_sta->flush_timer = 0;
- lq_sta->supp_rates = sta->sta.supp_rates[sband->band];
+ lq_sta->supp_rates = sta->supp_rates[sband->band];
for (j = 0; j < LQ_SIZE; j++)
for (i = 0; i < IWL_RATE_COUNT; i++)
rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
@@ -2232,17 +2204,17 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
lq_sta->ibss_sta_added = 0;
if (priv->iw_mode == NL80211_IFTYPE_AP) {
- u8 sta_id = iwl_find_station(priv, sta->sta.addr);
+ u8 sta_id = iwl_find_station(priv, sta->addr);
DECLARE_MAC_BUF(mac);
/* for IBSS the call are from tasklet */
IWL_DEBUG_RATE("LQ: ADD station %s\n",
- print_mac(mac, sta->sta.addr));
+ print_mac(mac, sta->addr));
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_RATE("LQ: ADD station %s\n",
- print_mac(mac, sta->sta.addr));
- sta_id = iwl_add_station_flags(priv, sta->sta.addr,
+ print_mac(mac, sta->addr));
+ sta_id = iwl_add_station_flags(priv, sta->addr,
0, CMD_ASYNC, NULL);
}
if ((sta_id != IWL_INVALID_STATION)) {
@@ -2256,11 +2228,11 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
/* Find highest tx rate supported by hardware and destination station */
lq_sta->last_txrate_idx = 3;
for (i = 0; i < sband->n_bitrates; i++)
- if (sta->sta.supp_rates[sband->band] & BIT(i))
+ if (sta->supp_rates[sband->band] & BIT(i))
lq_sta->last_txrate_idx = i;
/* For MODE_IEEE80211A, skip over cck rates in global rate table */
- if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ)
+ if (sband->band == IEEE80211_BAND_5GHZ)
lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
lq_sta->is_dup = 0;
@@ -2301,7 +2273,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
lq_sta->drv = priv;
- rs_initialize_lq(priv, conf, sta);
+ rs_initialize_lq(priv, conf, sta, lq_sta);
}
static void rs_fill_link_cmd(const struct iwl_priv *priv,
@@ -2423,9 +2395,9 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv,
lq_cmd->agg_params.agg_time_limit = cpu_to_le16(4000);
}
-static void *rs_alloc(struct ieee80211_local *local)
+static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
{
- return local->hw.priv;
+ return hw->priv;
}
/* rate scale requires free function to be implemented */
static void rs_free(void *priv_rate)
@@ -2446,12 +2418,12 @@ static void rs_clear(void *priv_rate)
#endif /* CONFIG_IWLWIFI_DEBUG */
}
-static void rs_free_sta(void *priv_rate, void *priv_sta)
+static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta,
+ void *priv_sta)
{
struct iwl_lq_sta *lq_sta = priv_sta;
- struct iwl_priv *priv;
+ struct iwl_priv *priv = priv_r;
- priv = (struct iwl_priv *)priv_rate;
IWL_DEBUG_RATE("enter\n");
kfree(lq_sta);
IWL_DEBUG_RATE("leave\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 62b26befddc5..d15a2c997954 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -7370,15 +7370,6 @@ static ssize_t show_temperature(struct device *d,
static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
-static ssize_t show_rs_window(struct device *d,
- struct device_attribute *attr,
- char *buf)
-{
- struct iwl3945_priv *priv = d->driver_data;
- return iwl3945_fill_rs_info(priv->hw, buf, IWL_AP_ID);
-}
-static DEVICE_ATTR(rs_window, S_IRUGO, show_rs_window, NULL);
-
static ssize_t show_tx_power(struct device *d,
struct device_attribute *attr, char *buf)
{
@@ -7840,7 +7831,6 @@ static struct attribute *iwl3945_sysfs_entries[] = {
#endif
&dev_attr_power_level.attr,
&dev_attr_retry_rate.attr,
- &dev_attr_rs_window.attr,
&dev_attr_statistics.attr,
&dev_attr_status.attr,
&dev_attr_temperature.attr,
@@ -7908,6 +7898,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
SET_IEEE80211_DEV(hw, &pdev->dev);
hw->rate_control_algorithm = "iwl-3945-rs";
+ hw->sta_data_size = sizeof(struct iwl3945_sta_priv);
IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
priv = hw->priv;