|
@@ -317,13 +317,44 @@ rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
|
|
struct ieee80211_sta *sta, void *priv_sta)
|
|
struct ieee80211_sta *sta, void *priv_sta)
|
|
{
|
|
{
|
|
struct rc_pid_sta_info *spinfo = priv_sta;
|
|
struct rc_pid_sta_info *spinfo = priv_sta;
|
|
|
|
+ struct rc_pid_info *pinfo = priv;
|
|
|
|
+ struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
|
|
struct sta_info *si;
|
|
struct sta_info *si;
|
|
|
|
+ int i, j, tmp;
|
|
|
|
+ bool s;
|
|
|
|
|
|
/* TODO: This routine should consider using RSSI from previous packets
|
|
/* TODO: This routine should consider using RSSI from previous packets
|
|
* as we need to have IEEE 802.1X auth succeed immediately after assoc..
|
|
* as we need to have IEEE 802.1X auth succeed immediately after assoc..
|
|
* Until that method is implemented, we will use the lowest supported
|
|
* Until that method is implemented, we will use the lowest supported
|
|
* rate as a workaround. */
|
|
* rate as a workaround. */
|
|
|
|
|
|
|
|
+ /* Sort the rates. This is optimized for the most common case (i.e.
|
|
|
|
+ * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed
|
|
|
|
+ * mapping too. */
|
|
|
|
+ for (i = 0; i < sband->n_bitrates; i++) {
|
|
|
|
+ rinfo[i].index = i;
|
|
|
|
+ rinfo[i].rev_index = i;
|
|
|
|
+ if (RC_PID_FAST_START)
|
|
|
|
+ rinfo[i].diff = 0;
|
|
|
|
+ else
|
|
|
|
+ rinfo[i].diff = i * pinfo->norm_offset;
|
|
|
|
+ }
|
|
|
|
+ for (i = 1; i < sband->n_bitrates; i++) {
|
|
|
|
+ s = 0;
|
|
|
|
+ for (j = 0; j < sband->n_bitrates - i; j++)
|
|
|
|
+ if (unlikely(sband->bitrates[rinfo[j].index].bitrate >
|
|
|
|
+ sband->bitrates[rinfo[j + 1].index].bitrate)) {
|
|
|
|
+ tmp = rinfo[j].index;
|
|
|
|
+ rinfo[j].index = rinfo[j + 1].index;
|
|
|
|
+ rinfo[j + 1].index = tmp;
|
|
|
|
+ rinfo[rinfo[j].index].rev_index = j;
|
|
|
|
+ rinfo[rinfo[j + 1].index].rev_index = j + 1;
|
|
|
|
+ s = 1;
|
|
|
|
+ }
|
|
|
|
+ if (!s)
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
spinfo->txrate_idx = rate_lowest_index(sband, sta);
|
|
spinfo->txrate_idx = rate_lowest_index(sband, sta);
|
|
/* HACK */
|
|
/* HACK */
|
|
si = container_of(sta, struct sta_info, sta);
|
|
si = container_of(sta, struct sta_info, sta);
|
|
@@ -336,21 +367,22 @@ static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
|
|
struct rc_pid_info *pinfo;
|
|
struct rc_pid_info *pinfo;
|
|
struct rc_pid_rateinfo *rinfo;
|
|
struct rc_pid_rateinfo *rinfo;
|
|
struct ieee80211_supported_band *sband;
|
|
struct ieee80211_supported_band *sband;
|
|
- int i, j, tmp;
|
|
|
|
- bool s;
|
|
|
|
|
|
+ int i, max_rates = 0;
|
|
#ifdef CONFIG_MAC80211_DEBUGFS
|
|
#ifdef CONFIG_MAC80211_DEBUGFS
|
|
struct rc_pid_debugfs_entries *de;
|
|
struct rc_pid_debugfs_entries *de;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- sband = hw->wiphy->bands[hw->conf.channel->band];
|
|
|
|
-
|
|
|
|
pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC);
|
|
pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC);
|
|
if (!pinfo)
|
|
if (!pinfo)
|
|
return NULL;
|
|
return NULL;
|
|
|
|
|
|
- /* We can safely assume that sband won't change unless we get
|
|
|
|
- * reinitialized. */
|
|
|
|
- rinfo = kmalloc(sizeof(*rinfo) * sband->n_bitrates, GFP_ATOMIC);
|
|
|
|
|
|
+ for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
|
|
|
|
+ sband = hw->wiphy->bands[i];
|
|
|
|
+ if (sband->n_bitrates > max_rates)
|
|
|
|
+ max_rates = sband->n_bitrates;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ rinfo = kmalloc(sizeof(*rinfo) * max_rates, GFP_ATOMIC);
|
|
if (!rinfo) {
|
|
if (!rinfo) {
|
|
kfree(pinfo);
|
|
kfree(pinfo);
|
|
return NULL;
|
|
return NULL;
|
|
@@ -368,33 +400,6 @@ static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
|
|
pinfo->rinfo = rinfo;
|
|
pinfo->rinfo = rinfo;
|
|
pinfo->oldrate = 0;
|
|
pinfo->oldrate = 0;
|
|
|
|
|
|
- /* Sort the rates. This is optimized for the most common case (i.e.
|
|
|
|
- * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed
|
|
|
|
- * mapping too. */
|
|
|
|
- for (i = 0; i < sband->n_bitrates; i++) {
|
|
|
|
- rinfo[i].index = i;
|
|
|
|
- rinfo[i].rev_index = i;
|
|
|
|
- if (RC_PID_FAST_START)
|
|
|
|
- rinfo[i].diff = 0;
|
|
|
|
- else
|
|
|
|
- rinfo[i].diff = i * pinfo->norm_offset;
|
|
|
|
- }
|
|
|
|
- for (i = 1; i < sband->n_bitrates; i++) {
|
|
|
|
- s = 0;
|
|
|
|
- for (j = 0; j < sband->n_bitrates - i; j++)
|
|
|
|
- if (unlikely(sband->bitrates[rinfo[j].index].bitrate >
|
|
|
|
- sband->bitrates[rinfo[j + 1].index].bitrate)) {
|
|
|
|
- tmp = rinfo[j].index;
|
|
|
|
- rinfo[j].index = rinfo[j + 1].index;
|
|
|
|
- rinfo[j + 1].index = tmp;
|
|
|
|
- rinfo[rinfo[j].index].rev_index = j;
|
|
|
|
- rinfo[rinfo[j + 1].index].rev_index = j + 1;
|
|
|
|
- s = 1;
|
|
|
|
- }
|
|
|
|
- if (!s)
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
#ifdef CONFIG_MAC80211_DEBUGFS
|
|
#ifdef CONFIG_MAC80211_DEBUGFS
|
|
de = &pinfo->dentries;
|
|
de = &pinfo->dentries;
|
|
de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR,
|
|
de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR,
|