1*7ac9a364SKalle Valo /****************************************************************************** 2*7ac9a364SKalle Valo * 3*7ac9a364SKalle Valo * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. 4*7ac9a364SKalle Valo * 5*7ac9a364SKalle Valo * This program is free software; you can redistribute it and/or modify it 6*7ac9a364SKalle Valo * under the terms of version 2 of the GNU General Public License as 7*7ac9a364SKalle Valo * published by the Free Software Foundation. 8*7ac9a364SKalle Valo * 9*7ac9a364SKalle Valo * This program is distributed in the hope that it will be useful, but WITHOUT 10*7ac9a364SKalle Valo * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11*7ac9a364SKalle Valo * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12*7ac9a364SKalle Valo * more details. 13*7ac9a364SKalle Valo * 14*7ac9a364SKalle Valo * You should have received a copy of the GNU General Public License along with 15*7ac9a364SKalle Valo * this program; if not, write to the Free Software Foundation, Inc., 16*7ac9a364SKalle Valo * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 17*7ac9a364SKalle Valo * 18*7ac9a364SKalle Valo * The full GNU General Public License is included in this distribution in the 19*7ac9a364SKalle Valo * file called LICENSE. 20*7ac9a364SKalle Valo * 21*7ac9a364SKalle Valo * Contact Information: 22*7ac9a364SKalle Valo * Intel Linux Wireless <ilw@linux.intel.com> 23*7ac9a364SKalle Valo * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 24*7ac9a364SKalle Valo * 25*7ac9a364SKalle Valo *****************************************************************************/ 26*7ac9a364SKalle Valo 27*7ac9a364SKalle Valo #include <linux/kernel.h> 28*7ac9a364SKalle Valo #include <linux/skbuff.h> 29*7ac9a364SKalle Valo #include <linux/slab.h> 30*7ac9a364SKalle Valo #include <net/mac80211.h> 31*7ac9a364SKalle Valo 32*7ac9a364SKalle Valo #include <linux/netdevice.h> 33*7ac9a364SKalle Valo #include <linux/etherdevice.h> 34*7ac9a364SKalle Valo #include <linux/delay.h> 35*7ac9a364SKalle Valo 36*7ac9a364SKalle Valo #include <linux/workqueue.h> 37*7ac9a364SKalle Valo 38*7ac9a364SKalle Valo #include "commands.h" 39*7ac9a364SKalle Valo #include "3945.h" 40*7ac9a364SKalle Valo 41*7ac9a364SKalle Valo #define RS_NAME "iwl-3945-rs" 42*7ac9a364SKalle Valo 43*7ac9a364SKalle Valo static s32 il3945_expected_tpt_g[RATE_COUNT_3945] = { 44*7ac9a364SKalle Valo 7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202 45*7ac9a364SKalle Valo }; 46*7ac9a364SKalle Valo 47*7ac9a364SKalle Valo static s32 il3945_expected_tpt_g_prot[RATE_COUNT_3945] = { 48*7ac9a364SKalle Valo 7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125 49*7ac9a364SKalle Valo }; 50*7ac9a364SKalle Valo 51*7ac9a364SKalle Valo static s32 il3945_expected_tpt_a[RATE_COUNT_3945] = { 52*7ac9a364SKalle Valo 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186 53*7ac9a364SKalle Valo }; 54*7ac9a364SKalle Valo 55*7ac9a364SKalle Valo static s32 il3945_expected_tpt_b[RATE_COUNT_3945] = { 56*7ac9a364SKalle Valo 7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0 57*7ac9a364SKalle Valo }; 58*7ac9a364SKalle Valo 59*7ac9a364SKalle Valo struct il3945_tpt_entry { 60*7ac9a364SKalle Valo s8 min_rssi; 61*7ac9a364SKalle Valo u8 idx; 62*7ac9a364SKalle Valo }; 63*7ac9a364SKalle Valo 64*7ac9a364SKalle Valo static struct il3945_tpt_entry il3945_tpt_table_a[] = { 65*7ac9a364SKalle Valo {-60, RATE_54M_IDX}, 66*7ac9a364SKalle Valo {-64, RATE_48M_IDX}, 67*7ac9a364SKalle Valo {-72, RATE_36M_IDX}, 68*7ac9a364SKalle Valo {-80, RATE_24M_IDX}, 69*7ac9a364SKalle Valo {-84, RATE_18M_IDX}, 70*7ac9a364SKalle Valo {-85, RATE_12M_IDX}, 71*7ac9a364SKalle Valo {-87, RATE_9M_IDX}, 72*7ac9a364SKalle Valo {-89, RATE_6M_IDX} 73*7ac9a364SKalle Valo }; 74*7ac9a364SKalle Valo 75*7ac9a364SKalle Valo static struct il3945_tpt_entry il3945_tpt_table_g[] = { 76*7ac9a364SKalle Valo {-60, RATE_54M_IDX}, 77*7ac9a364SKalle Valo {-64, RATE_48M_IDX}, 78*7ac9a364SKalle Valo {-68, RATE_36M_IDX}, 79*7ac9a364SKalle Valo {-80, RATE_24M_IDX}, 80*7ac9a364SKalle Valo {-84, RATE_18M_IDX}, 81*7ac9a364SKalle Valo {-85, RATE_12M_IDX}, 82*7ac9a364SKalle Valo {-86, RATE_11M_IDX}, 83*7ac9a364SKalle Valo {-88, RATE_5M_IDX}, 84*7ac9a364SKalle Valo {-90, RATE_2M_IDX}, 85*7ac9a364SKalle Valo {-92, RATE_1M_IDX} 86*7ac9a364SKalle Valo }; 87*7ac9a364SKalle Valo 88*7ac9a364SKalle Valo #define RATE_MAX_WINDOW 62 89*7ac9a364SKalle Valo #define RATE_FLUSH (3*HZ) 90*7ac9a364SKalle Valo #define RATE_WIN_FLUSH (HZ/2) 91*7ac9a364SKalle Valo #define IL39_RATE_HIGH_TH 11520 92*7ac9a364SKalle Valo #define IL_SUCCESS_UP_TH 8960 93*7ac9a364SKalle Valo #define IL_SUCCESS_DOWN_TH 10880 94*7ac9a364SKalle Valo #define RATE_MIN_FAILURE_TH 6 95*7ac9a364SKalle Valo #define RATE_MIN_SUCCESS_TH 8 96*7ac9a364SKalle Valo #define RATE_DECREASE_TH 1920 97*7ac9a364SKalle Valo #define RATE_RETRY_TH 15 98*7ac9a364SKalle Valo 99*7ac9a364SKalle Valo static u8 100*7ac9a364SKalle Valo il3945_get_rate_idx_by_rssi(s32 rssi, enum ieee80211_band band) 101*7ac9a364SKalle Valo { 102*7ac9a364SKalle Valo u32 idx = 0; 103*7ac9a364SKalle Valo u32 table_size = 0; 104*7ac9a364SKalle Valo struct il3945_tpt_entry *tpt_table = NULL; 105*7ac9a364SKalle Valo 106*7ac9a364SKalle Valo if (rssi < IL_MIN_RSSI_VAL || rssi > IL_MAX_RSSI_VAL) 107*7ac9a364SKalle Valo rssi = IL_MIN_RSSI_VAL; 108*7ac9a364SKalle Valo 109*7ac9a364SKalle Valo switch (band) { 110*7ac9a364SKalle Valo case IEEE80211_BAND_2GHZ: 111*7ac9a364SKalle Valo tpt_table = il3945_tpt_table_g; 112*7ac9a364SKalle Valo table_size = ARRAY_SIZE(il3945_tpt_table_g); 113*7ac9a364SKalle Valo break; 114*7ac9a364SKalle Valo case IEEE80211_BAND_5GHZ: 115*7ac9a364SKalle Valo tpt_table = il3945_tpt_table_a; 116*7ac9a364SKalle Valo table_size = ARRAY_SIZE(il3945_tpt_table_a); 117*7ac9a364SKalle Valo break; 118*7ac9a364SKalle Valo default: 119*7ac9a364SKalle Valo BUG(); 120*7ac9a364SKalle Valo break; 121*7ac9a364SKalle Valo } 122*7ac9a364SKalle Valo 123*7ac9a364SKalle Valo while (idx < table_size && rssi < tpt_table[idx].min_rssi) 124*7ac9a364SKalle Valo idx++; 125*7ac9a364SKalle Valo 126*7ac9a364SKalle Valo idx = min(idx, table_size - 1); 127*7ac9a364SKalle Valo 128*7ac9a364SKalle Valo return tpt_table[idx].idx; 129*7ac9a364SKalle Valo } 130*7ac9a364SKalle Valo 131*7ac9a364SKalle Valo static void 132*7ac9a364SKalle Valo il3945_clear_win(struct il3945_rate_scale_data *win) 133*7ac9a364SKalle Valo { 134*7ac9a364SKalle Valo win->data = 0; 135*7ac9a364SKalle Valo win->success_counter = 0; 136*7ac9a364SKalle Valo win->success_ratio = -1; 137*7ac9a364SKalle Valo win->counter = 0; 138*7ac9a364SKalle Valo win->average_tpt = IL_INVALID_VALUE; 139*7ac9a364SKalle Valo win->stamp = 0; 140*7ac9a364SKalle Valo } 141*7ac9a364SKalle Valo 142*7ac9a364SKalle Valo /** 143*7ac9a364SKalle Valo * il3945_rate_scale_flush_wins - flush out the rate scale wins 144*7ac9a364SKalle Valo * 145*7ac9a364SKalle Valo * Returns the number of wins that have gathered data but were 146*7ac9a364SKalle Valo * not flushed. If there were any that were not flushed, then 147*7ac9a364SKalle Valo * reschedule the rate flushing routine. 148*7ac9a364SKalle Valo */ 149*7ac9a364SKalle Valo static int 150*7ac9a364SKalle Valo il3945_rate_scale_flush_wins(struct il3945_rs_sta *rs_sta) 151*7ac9a364SKalle Valo { 152*7ac9a364SKalle Valo int unflushed = 0; 153*7ac9a364SKalle Valo int i; 154*7ac9a364SKalle Valo unsigned long flags; 155*7ac9a364SKalle Valo struct il_priv *il __maybe_unused = rs_sta->il; 156*7ac9a364SKalle Valo 157*7ac9a364SKalle Valo /* 158*7ac9a364SKalle Valo * For each rate, if we have collected data on that rate 159*7ac9a364SKalle Valo * and it has been more than RATE_WIN_FLUSH 160*7ac9a364SKalle Valo * since we flushed, clear out the gathered stats 161*7ac9a364SKalle Valo */ 162*7ac9a364SKalle Valo for (i = 0; i < RATE_COUNT_3945; i++) { 163*7ac9a364SKalle Valo if (!rs_sta->win[i].counter) 164*7ac9a364SKalle Valo continue; 165*7ac9a364SKalle Valo 166*7ac9a364SKalle Valo spin_lock_irqsave(&rs_sta->lock, flags); 167*7ac9a364SKalle Valo if (time_after(jiffies, rs_sta->win[i].stamp + RATE_WIN_FLUSH)) { 168*7ac9a364SKalle Valo D_RATE("flushing %d samples of rate " "idx %d\n", 169*7ac9a364SKalle Valo rs_sta->win[i].counter, i); 170*7ac9a364SKalle Valo il3945_clear_win(&rs_sta->win[i]); 171*7ac9a364SKalle Valo } else 172*7ac9a364SKalle Valo unflushed++; 173*7ac9a364SKalle Valo spin_unlock_irqrestore(&rs_sta->lock, flags); 174*7ac9a364SKalle Valo } 175*7ac9a364SKalle Valo 176*7ac9a364SKalle Valo return unflushed; 177*7ac9a364SKalle Valo } 178*7ac9a364SKalle Valo 179*7ac9a364SKalle Valo #define RATE_FLUSH_MAX 5000 /* msec */ 180*7ac9a364SKalle Valo #define RATE_FLUSH_MIN 50 /* msec */ 181*7ac9a364SKalle Valo #define IL_AVERAGE_PACKETS 1500 182*7ac9a364SKalle Valo 183*7ac9a364SKalle Valo static void 184*7ac9a364SKalle Valo il3945_bg_rate_scale_flush(unsigned long data) 185*7ac9a364SKalle Valo { 186*7ac9a364SKalle Valo struct il3945_rs_sta *rs_sta = (void *)data; 187*7ac9a364SKalle Valo struct il_priv *il __maybe_unused = rs_sta->il; 188*7ac9a364SKalle Valo int unflushed = 0; 189*7ac9a364SKalle Valo unsigned long flags; 190*7ac9a364SKalle Valo u32 packet_count, duration, pps; 191*7ac9a364SKalle Valo 192*7ac9a364SKalle Valo D_RATE("enter\n"); 193*7ac9a364SKalle Valo 194*7ac9a364SKalle Valo unflushed = il3945_rate_scale_flush_wins(rs_sta); 195*7ac9a364SKalle Valo 196*7ac9a364SKalle Valo spin_lock_irqsave(&rs_sta->lock, flags); 197*7ac9a364SKalle Valo 198*7ac9a364SKalle Valo /* Number of packets Rx'd since last time this timer ran */ 199*7ac9a364SKalle Valo packet_count = (rs_sta->tx_packets - rs_sta->last_tx_packets) + 1; 200*7ac9a364SKalle Valo 201*7ac9a364SKalle Valo rs_sta->last_tx_packets = rs_sta->tx_packets + 1; 202*7ac9a364SKalle Valo 203*7ac9a364SKalle Valo if (unflushed) { 204*7ac9a364SKalle Valo duration = 205*7ac9a364SKalle Valo jiffies_to_msecs(jiffies - rs_sta->last_partial_flush); 206*7ac9a364SKalle Valo 207*7ac9a364SKalle Valo D_RATE("Tx'd %d packets in %dms\n", packet_count, duration); 208*7ac9a364SKalle Valo 209*7ac9a364SKalle Valo /* Determine packets per second */ 210*7ac9a364SKalle Valo if (duration) 211*7ac9a364SKalle Valo pps = (packet_count * 1000) / duration; 212*7ac9a364SKalle Valo else 213*7ac9a364SKalle Valo pps = 0; 214*7ac9a364SKalle Valo 215*7ac9a364SKalle Valo if (pps) { 216*7ac9a364SKalle Valo duration = (IL_AVERAGE_PACKETS * 1000) / pps; 217*7ac9a364SKalle Valo if (duration < RATE_FLUSH_MIN) 218*7ac9a364SKalle Valo duration = RATE_FLUSH_MIN; 219*7ac9a364SKalle Valo else if (duration > RATE_FLUSH_MAX) 220*7ac9a364SKalle Valo duration = RATE_FLUSH_MAX; 221*7ac9a364SKalle Valo } else 222*7ac9a364SKalle Valo duration = RATE_FLUSH_MAX; 223*7ac9a364SKalle Valo 224*7ac9a364SKalle Valo rs_sta->flush_time = msecs_to_jiffies(duration); 225*7ac9a364SKalle Valo 226*7ac9a364SKalle Valo D_RATE("new flush period: %d msec ave %d\n", duration, 227*7ac9a364SKalle Valo packet_count); 228*7ac9a364SKalle Valo 229*7ac9a364SKalle Valo mod_timer(&rs_sta->rate_scale_flush, 230*7ac9a364SKalle Valo jiffies + rs_sta->flush_time); 231*7ac9a364SKalle Valo 232*7ac9a364SKalle Valo rs_sta->last_partial_flush = jiffies; 233*7ac9a364SKalle Valo } else { 234*7ac9a364SKalle Valo rs_sta->flush_time = RATE_FLUSH; 235*7ac9a364SKalle Valo rs_sta->flush_pending = 0; 236*7ac9a364SKalle Valo } 237*7ac9a364SKalle Valo /* If there weren't any unflushed entries, we don't schedule the timer 238*7ac9a364SKalle Valo * to run again */ 239*7ac9a364SKalle Valo 240*7ac9a364SKalle Valo rs_sta->last_flush = jiffies; 241*7ac9a364SKalle Valo 242*7ac9a364SKalle Valo spin_unlock_irqrestore(&rs_sta->lock, flags); 243*7ac9a364SKalle Valo 244*7ac9a364SKalle Valo D_RATE("leave\n"); 245*7ac9a364SKalle Valo } 246*7ac9a364SKalle Valo 247*7ac9a364SKalle Valo /** 248*7ac9a364SKalle Valo * il3945_collect_tx_data - Update the success/failure sliding win 249*7ac9a364SKalle Valo * 250*7ac9a364SKalle Valo * We keep a sliding win of the last 64 packets transmitted 251*7ac9a364SKalle Valo * at this rate. win->data contains the bitmask of successful 252*7ac9a364SKalle Valo * packets. 253*7ac9a364SKalle Valo */ 254*7ac9a364SKalle Valo static void 255*7ac9a364SKalle Valo il3945_collect_tx_data(struct il3945_rs_sta *rs_sta, 256*7ac9a364SKalle Valo struct il3945_rate_scale_data *win, int success, 257*7ac9a364SKalle Valo int retries, int idx) 258*7ac9a364SKalle Valo { 259*7ac9a364SKalle Valo unsigned long flags; 260*7ac9a364SKalle Valo s32 fail_count; 261*7ac9a364SKalle Valo struct il_priv *il __maybe_unused = rs_sta->il; 262*7ac9a364SKalle Valo 263*7ac9a364SKalle Valo if (!retries) { 264*7ac9a364SKalle Valo D_RATE("leave: retries == 0 -- should be at least 1\n"); 265*7ac9a364SKalle Valo return; 266*7ac9a364SKalle Valo } 267*7ac9a364SKalle Valo 268*7ac9a364SKalle Valo spin_lock_irqsave(&rs_sta->lock, flags); 269*7ac9a364SKalle Valo 270*7ac9a364SKalle Valo /* 271*7ac9a364SKalle Valo * Keep track of only the latest 62 tx frame attempts in this rate's 272*7ac9a364SKalle Valo * history win; anything older isn't really relevant any more. 273*7ac9a364SKalle Valo * If we have filled up the sliding win, drop the oldest attempt; 274*7ac9a364SKalle Valo * if the oldest attempt (highest bit in bitmap) shows "success", 275*7ac9a364SKalle Valo * subtract "1" from the success counter (this is the main reason 276*7ac9a364SKalle Valo * we keep these bitmaps!). 277*7ac9a364SKalle Valo * */ 278*7ac9a364SKalle Valo while (retries > 0) { 279*7ac9a364SKalle Valo if (win->counter >= RATE_MAX_WINDOW) { 280*7ac9a364SKalle Valo 281*7ac9a364SKalle Valo /* remove earliest */ 282*7ac9a364SKalle Valo win->counter = RATE_MAX_WINDOW - 1; 283*7ac9a364SKalle Valo 284*7ac9a364SKalle Valo if (win->data & (1ULL << (RATE_MAX_WINDOW - 1))) { 285*7ac9a364SKalle Valo win->data &= ~(1ULL << (RATE_MAX_WINDOW - 1)); 286*7ac9a364SKalle Valo win->success_counter--; 287*7ac9a364SKalle Valo } 288*7ac9a364SKalle Valo } 289*7ac9a364SKalle Valo 290*7ac9a364SKalle Valo /* Increment frames-attempted counter */ 291*7ac9a364SKalle Valo win->counter++; 292*7ac9a364SKalle Valo 293*7ac9a364SKalle Valo /* Shift bitmap by one frame (throw away oldest history), 294*7ac9a364SKalle Valo * OR in "1", and increment "success" if this 295*7ac9a364SKalle Valo * frame was successful. */ 296*7ac9a364SKalle Valo win->data <<= 1; 297*7ac9a364SKalle Valo if (success > 0) { 298*7ac9a364SKalle Valo win->success_counter++; 299*7ac9a364SKalle Valo win->data |= 0x1; 300*7ac9a364SKalle Valo success--; 301*7ac9a364SKalle Valo } 302*7ac9a364SKalle Valo 303*7ac9a364SKalle Valo retries--; 304*7ac9a364SKalle Valo } 305*7ac9a364SKalle Valo 306*7ac9a364SKalle Valo /* Calculate current success ratio, avoid divide-by-0! */ 307*7ac9a364SKalle Valo if (win->counter > 0) 308*7ac9a364SKalle Valo win->success_ratio = 309*7ac9a364SKalle Valo 128 * (100 * win->success_counter) / win->counter; 310*7ac9a364SKalle Valo else 311*7ac9a364SKalle Valo win->success_ratio = IL_INVALID_VALUE; 312*7ac9a364SKalle Valo 313*7ac9a364SKalle Valo fail_count = win->counter - win->success_counter; 314*7ac9a364SKalle Valo 315*7ac9a364SKalle Valo /* Calculate average throughput, if we have enough history. */ 316*7ac9a364SKalle Valo if (fail_count >= RATE_MIN_FAILURE_TH || 317*7ac9a364SKalle Valo win->success_counter >= RATE_MIN_SUCCESS_TH) 318*7ac9a364SKalle Valo win->average_tpt = 319*7ac9a364SKalle Valo ((win->success_ratio * rs_sta->expected_tpt[idx] + 320*7ac9a364SKalle Valo 64) / 128); 321*7ac9a364SKalle Valo else 322*7ac9a364SKalle Valo win->average_tpt = IL_INVALID_VALUE; 323*7ac9a364SKalle Valo 324*7ac9a364SKalle Valo /* Tag this win as having been updated */ 325*7ac9a364SKalle Valo win->stamp = jiffies; 326*7ac9a364SKalle Valo 327*7ac9a364SKalle Valo spin_unlock_irqrestore(&rs_sta->lock, flags); 328*7ac9a364SKalle Valo } 329*7ac9a364SKalle Valo 330*7ac9a364SKalle Valo /* 331*7ac9a364SKalle Valo * Called after adding a new station to initialize rate scaling 332*7ac9a364SKalle Valo */ 333*7ac9a364SKalle Valo void 334*7ac9a364SKalle Valo il3945_rs_rate_init(struct il_priv *il, struct ieee80211_sta *sta, u8 sta_id) 335*7ac9a364SKalle Valo { 336*7ac9a364SKalle Valo struct ieee80211_hw *hw = il->hw; 337*7ac9a364SKalle Valo struct ieee80211_conf *conf = &il->hw->conf; 338*7ac9a364SKalle Valo struct il3945_sta_priv *psta; 339*7ac9a364SKalle Valo struct il3945_rs_sta *rs_sta; 340*7ac9a364SKalle Valo struct ieee80211_supported_band *sband; 341*7ac9a364SKalle Valo int i; 342*7ac9a364SKalle Valo 343*7ac9a364SKalle Valo D_INFO("enter\n"); 344*7ac9a364SKalle Valo if (sta_id == il->hw_params.bcast_id) 345*7ac9a364SKalle Valo goto out; 346*7ac9a364SKalle Valo 347*7ac9a364SKalle Valo psta = (struct il3945_sta_priv *)sta->drv_priv; 348*7ac9a364SKalle Valo rs_sta = &psta->rs_sta; 349*7ac9a364SKalle Valo sband = hw->wiphy->bands[conf->chandef.chan->band]; 350*7ac9a364SKalle Valo 351*7ac9a364SKalle Valo rs_sta->il = il; 352*7ac9a364SKalle Valo 353*7ac9a364SKalle Valo rs_sta->start_rate = RATE_INVALID; 354*7ac9a364SKalle Valo 355*7ac9a364SKalle Valo /* default to just 802.11b */ 356*7ac9a364SKalle Valo rs_sta->expected_tpt = il3945_expected_tpt_b; 357*7ac9a364SKalle Valo 358*7ac9a364SKalle Valo rs_sta->last_partial_flush = jiffies; 359*7ac9a364SKalle Valo rs_sta->last_flush = jiffies; 360*7ac9a364SKalle Valo rs_sta->flush_time = RATE_FLUSH; 361*7ac9a364SKalle Valo rs_sta->last_tx_packets = 0; 362*7ac9a364SKalle Valo 363*7ac9a364SKalle Valo rs_sta->rate_scale_flush.data = (unsigned long)rs_sta; 364*7ac9a364SKalle Valo rs_sta->rate_scale_flush.function = il3945_bg_rate_scale_flush; 365*7ac9a364SKalle Valo 366*7ac9a364SKalle Valo for (i = 0; i < RATE_COUNT_3945; i++) 367*7ac9a364SKalle Valo il3945_clear_win(&rs_sta->win[i]); 368*7ac9a364SKalle Valo 369*7ac9a364SKalle Valo /* TODO: what is a good starting rate for STA? About middle? Maybe not 370*7ac9a364SKalle Valo * the lowest or the highest rate.. Could consider using RSSI from 371*7ac9a364SKalle Valo * previous packets? Need to have IEEE 802.1X auth succeed immediately 372*7ac9a364SKalle Valo * after assoc.. */ 373*7ac9a364SKalle Valo 374*7ac9a364SKalle Valo for (i = sband->n_bitrates - 1; i >= 0; i--) { 375*7ac9a364SKalle Valo if (sta->supp_rates[sband->band] & (1 << i)) { 376*7ac9a364SKalle Valo rs_sta->last_txrate_idx = i; 377*7ac9a364SKalle Valo break; 378*7ac9a364SKalle Valo } 379*7ac9a364SKalle Valo } 380*7ac9a364SKalle Valo 381*7ac9a364SKalle Valo il->_3945.sta_supp_rates = sta->supp_rates[sband->band]; 382*7ac9a364SKalle Valo /* For 5 GHz band it start at IL_FIRST_OFDM_RATE */ 383*7ac9a364SKalle Valo if (sband->band == IEEE80211_BAND_5GHZ) { 384*7ac9a364SKalle Valo rs_sta->last_txrate_idx += IL_FIRST_OFDM_RATE; 385*7ac9a364SKalle Valo il->_3945.sta_supp_rates <<= IL_FIRST_OFDM_RATE; 386*7ac9a364SKalle Valo } 387*7ac9a364SKalle Valo 388*7ac9a364SKalle Valo out: 389*7ac9a364SKalle Valo il->stations[sta_id].used &= ~IL_STA_UCODE_INPROGRESS; 390*7ac9a364SKalle Valo 391*7ac9a364SKalle Valo D_INFO("leave\n"); 392*7ac9a364SKalle Valo } 393*7ac9a364SKalle Valo 394*7ac9a364SKalle Valo static void * 395*7ac9a364SKalle Valo il3945_rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) 396*7ac9a364SKalle Valo { 397*7ac9a364SKalle Valo return hw->priv; 398*7ac9a364SKalle Valo } 399*7ac9a364SKalle Valo 400*7ac9a364SKalle Valo /* rate scale requires free function to be implemented */ 401*7ac9a364SKalle Valo static void 402*7ac9a364SKalle Valo il3945_rs_free(void *il) 403*7ac9a364SKalle Valo { 404*7ac9a364SKalle Valo } 405*7ac9a364SKalle Valo 406*7ac9a364SKalle Valo static void * 407*7ac9a364SKalle Valo il3945_rs_alloc_sta(void *il_priv, struct ieee80211_sta *sta, gfp_t gfp) 408*7ac9a364SKalle Valo { 409*7ac9a364SKalle Valo struct il3945_rs_sta *rs_sta; 410*7ac9a364SKalle Valo struct il3945_sta_priv *psta = (void *)sta->drv_priv; 411*7ac9a364SKalle Valo struct il_priv *il __maybe_unused = il_priv; 412*7ac9a364SKalle Valo 413*7ac9a364SKalle Valo D_RATE("enter\n"); 414*7ac9a364SKalle Valo 415*7ac9a364SKalle Valo rs_sta = &psta->rs_sta; 416*7ac9a364SKalle Valo 417*7ac9a364SKalle Valo spin_lock_init(&rs_sta->lock); 418*7ac9a364SKalle Valo init_timer(&rs_sta->rate_scale_flush); 419*7ac9a364SKalle Valo 420*7ac9a364SKalle Valo D_RATE("leave\n"); 421*7ac9a364SKalle Valo 422*7ac9a364SKalle Valo return rs_sta; 423*7ac9a364SKalle Valo } 424*7ac9a364SKalle Valo 425*7ac9a364SKalle Valo static void 426*7ac9a364SKalle Valo il3945_rs_free_sta(void *il_priv, struct ieee80211_sta *sta, void *il_sta) 427*7ac9a364SKalle Valo { 428*7ac9a364SKalle Valo struct il3945_rs_sta *rs_sta = il_sta; 429*7ac9a364SKalle Valo 430*7ac9a364SKalle Valo /* 431*7ac9a364SKalle Valo * Be careful not to use any members of il3945_rs_sta (like trying 432*7ac9a364SKalle Valo * to use il_priv to print out debugging) since it may not be fully 433*7ac9a364SKalle Valo * initialized at this point. 434*7ac9a364SKalle Valo */ 435*7ac9a364SKalle Valo del_timer_sync(&rs_sta->rate_scale_flush); 436*7ac9a364SKalle Valo } 437*7ac9a364SKalle Valo 438*7ac9a364SKalle Valo /** 439*7ac9a364SKalle Valo * il3945_rs_tx_status - Update rate control values based on Tx results 440*7ac9a364SKalle Valo * 441*7ac9a364SKalle Valo * NOTE: Uses il_priv->retry_rate for the # of retries attempted by 442*7ac9a364SKalle Valo * the hardware for each rate. 443*7ac9a364SKalle Valo */ 444*7ac9a364SKalle Valo static void 445*7ac9a364SKalle Valo il3945_rs_tx_status(void *il_rate, struct ieee80211_supported_band *sband, 446*7ac9a364SKalle Valo struct ieee80211_sta *sta, void *il_sta, 447*7ac9a364SKalle Valo struct sk_buff *skb) 448*7ac9a364SKalle Valo { 449*7ac9a364SKalle Valo s8 retries = 0, current_count; 450*7ac9a364SKalle Valo int scale_rate_idx, first_idx, last_idx; 451*7ac9a364SKalle Valo unsigned long flags; 452*7ac9a364SKalle Valo struct il_priv *il = (struct il_priv *)il_rate; 453*7ac9a364SKalle Valo struct il3945_rs_sta *rs_sta = il_sta; 454*7ac9a364SKalle Valo struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 455*7ac9a364SKalle Valo 456*7ac9a364SKalle Valo D_RATE("enter\n"); 457*7ac9a364SKalle Valo 458*7ac9a364SKalle Valo retries = info->status.rates[0].count; 459*7ac9a364SKalle Valo /* Sanity Check for retries */ 460*7ac9a364SKalle Valo if (retries > RATE_RETRY_TH) 461*7ac9a364SKalle Valo retries = RATE_RETRY_TH; 462*7ac9a364SKalle Valo 463*7ac9a364SKalle Valo first_idx = sband->bitrates[info->status.rates[0].idx].hw_value; 464*7ac9a364SKalle Valo if (first_idx < 0 || first_idx >= RATE_COUNT_3945) { 465*7ac9a364SKalle Valo D_RATE("leave: Rate out of bounds: %d\n", first_idx); 466*7ac9a364SKalle Valo return; 467*7ac9a364SKalle Valo } 468*7ac9a364SKalle Valo 469*7ac9a364SKalle Valo if (!il_sta) { 470*7ac9a364SKalle Valo D_RATE("leave: No STA il data to update!\n"); 471*7ac9a364SKalle Valo return; 472*7ac9a364SKalle Valo } 473*7ac9a364SKalle Valo 474*7ac9a364SKalle Valo /* Treat uninitialized rate scaling data same as non-existing. */ 475*7ac9a364SKalle Valo if (!rs_sta->il) { 476*7ac9a364SKalle Valo D_RATE("leave: STA il data uninitialized!\n"); 477*7ac9a364SKalle Valo return; 478*7ac9a364SKalle Valo } 479*7ac9a364SKalle Valo 480*7ac9a364SKalle Valo rs_sta->tx_packets++; 481*7ac9a364SKalle Valo 482*7ac9a364SKalle Valo scale_rate_idx = first_idx; 483*7ac9a364SKalle Valo last_idx = first_idx; 484*7ac9a364SKalle Valo 485*7ac9a364SKalle Valo /* 486*7ac9a364SKalle Valo * Update the win for each rate. We determine which rates 487*7ac9a364SKalle Valo * were Tx'd based on the total number of retries vs. the number 488*7ac9a364SKalle Valo * of retries configured for each rate -- currently set to the 489*7ac9a364SKalle Valo * il value 'retry_rate' vs. rate specific 490*7ac9a364SKalle Valo * 491*7ac9a364SKalle Valo * On exit from this while loop last_idx indicates the rate 492*7ac9a364SKalle Valo * at which the frame was finally transmitted (or failed if no 493*7ac9a364SKalle Valo * ACK) 494*7ac9a364SKalle Valo */ 495*7ac9a364SKalle Valo while (retries > 1) { 496*7ac9a364SKalle Valo if ((retries - 1) < il->retry_rate) { 497*7ac9a364SKalle Valo current_count = (retries - 1); 498*7ac9a364SKalle Valo last_idx = scale_rate_idx; 499*7ac9a364SKalle Valo } else { 500*7ac9a364SKalle Valo current_count = il->retry_rate; 501*7ac9a364SKalle Valo last_idx = il3945_rs_next_rate(il, scale_rate_idx); 502*7ac9a364SKalle Valo } 503*7ac9a364SKalle Valo 504*7ac9a364SKalle Valo /* Update this rate accounting for as many retries 505*7ac9a364SKalle Valo * as was used for it (per current_count) */ 506*7ac9a364SKalle Valo il3945_collect_tx_data(rs_sta, &rs_sta->win[scale_rate_idx], 0, 507*7ac9a364SKalle Valo current_count, scale_rate_idx); 508*7ac9a364SKalle Valo D_RATE("Update rate %d for %d retries.\n", scale_rate_idx, 509*7ac9a364SKalle Valo current_count); 510*7ac9a364SKalle Valo 511*7ac9a364SKalle Valo retries -= current_count; 512*7ac9a364SKalle Valo 513*7ac9a364SKalle Valo scale_rate_idx = last_idx; 514*7ac9a364SKalle Valo } 515*7ac9a364SKalle Valo 516*7ac9a364SKalle Valo /* Update the last idx win with success/failure based on ACK */ 517*7ac9a364SKalle Valo D_RATE("Update rate %d with %s.\n", last_idx, 518*7ac9a364SKalle Valo (info->flags & IEEE80211_TX_STAT_ACK) ? "success" : "failure"); 519*7ac9a364SKalle Valo il3945_collect_tx_data(rs_sta, &rs_sta->win[last_idx], 520*7ac9a364SKalle Valo info->flags & IEEE80211_TX_STAT_ACK, 1, 521*7ac9a364SKalle Valo last_idx); 522*7ac9a364SKalle Valo 523*7ac9a364SKalle Valo /* We updated the rate scale win -- if its been more than 524*7ac9a364SKalle Valo * flush_time since the last run, schedule the flush 525*7ac9a364SKalle Valo * again */ 526*7ac9a364SKalle Valo spin_lock_irqsave(&rs_sta->lock, flags); 527*7ac9a364SKalle Valo 528*7ac9a364SKalle Valo if (!rs_sta->flush_pending && 529*7ac9a364SKalle Valo time_after(jiffies, rs_sta->last_flush + rs_sta->flush_time)) { 530*7ac9a364SKalle Valo 531*7ac9a364SKalle Valo rs_sta->last_partial_flush = jiffies; 532*7ac9a364SKalle Valo rs_sta->flush_pending = 1; 533*7ac9a364SKalle Valo mod_timer(&rs_sta->rate_scale_flush, 534*7ac9a364SKalle Valo jiffies + rs_sta->flush_time); 535*7ac9a364SKalle Valo } 536*7ac9a364SKalle Valo 537*7ac9a364SKalle Valo spin_unlock_irqrestore(&rs_sta->lock, flags); 538*7ac9a364SKalle Valo 539*7ac9a364SKalle Valo D_RATE("leave\n"); 540*7ac9a364SKalle Valo } 541*7ac9a364SKalle Valo 542*7ac9a364SKalle Valo static u16 543*7ac9a364SKalle Valo il3945_get_adjacent_rate(struct il3945_rs_sta *rs_sta, u8 idx, u16 rate_mask, 544*7ac9a364SKalle Valo enum ieee80211_band band) 545*7ac9a364SKalle Valo { 546*7ac9a364SKalle Valo u8 high = RATE_INVALID; 547*7ac9a364SKalle Valo u8 low = RATE_INVALID; 548*7ac9a364SKalle Valo struct il_priv *il __maybe_unused = rs_sta->il; 549*7ac9a364SKalle Valo 550*7ac9a364SKalle Valo /* 802.11A walks to the next literal adjacent rate in 551*7ac9a364SKalle Valo * the rate table */ 552*7ac9a364SKalle Valo if (unlikely(band == IEEE80211_BAND_5GHZ)) { 553*7ac9a364SKalle Valo int i; 554*7ac9a364SKalle Valo u32 mask; 555*7ac9a364SKalle Valo 556*7ac9a364SKalle Valo /* Find the previous rate that is in the rate mask */ 557*7ac9a364SKalle Valo i = idx - 1; 558*7ac9a364SKalle Valo for (mask = (1 << i); i >= 0; i--, mask >>= 1) { 559*7ac9a364SKalle Valo if (rate_mask & mask) { 560*7ac9a364SKalle Valo low = i; 561*7ac9a364SKalle Valo break; 562*7ac9a364SKalle Valo } 563*7ac9a364SKalle Valo } 564*7ac9a364SKalle Valo 565*7ac9a364SKalle Valo /* Find the next rate that is in the rate mask */ 566*7ac9a364SKalle Valo i = idx + 1; 567*7ac9a364SKalle Valo for (mask = (1 << i); i < RATE_COUNT_3945; i++, mask <<= 1) { 568*7ac9a364SKalle Valo if (rate_mask & mask) { 569*7ac9a364SKalle Valo high = i; 570*7ac9a364SKalle Valo break; 571*7ac9a364SKalle Valo } 572*7ac9a364SKalle Valo } 573*7ac9a364SKalle Valo 574*7ac9a364SKalle Valo return (high << 8) | low; 575*7ac9a364SKalle Valo } 576*7ac9a364SKalle Valo 577*7ac9a364SKalle Valo low = idx; 578*7ac9a364SKalle Valo while (low != RATE_INVALID) { 579*7ac9a364SKalle Valo if (rs_sta->tgg) 580*7ac9a364SKalle Valo low = il3945_rates[low].prev_rs_tgg; 581*7ac9a364SKalle Valo else 582*7ac9a364SKalle Valo low = il3945_rates[low].prev_rs; 583*7ac9a364SKalle Valo if (low == RATE_INVALID) 584*7ac9a364SKalle Valo break; 585*7ac9a364SKalle Valo if (rate_mask & (1 << low)) 586*7ac9a364SKalle Valo break; 587*7ac9a364SKalle Valo D_RATE("Skipping masked lower rate: %d\n", low); 588*7ac9a364SKalle Valo } 589*7ac9a364SKalle Valo 590*7ac9a364SKalle Valo high = idx; 591*7ac9a364SKalle Valo while (high != RATE_INVALID) { 592*7ac9a364SKalle Valo if (rs_sta->tgg) 593*7ac9a364SKalle Valo high = il3945_rates[high].next_rs_tgg; 594*7ac9a364SKalle Valo else 595*7ac9a364SKalle Valo high = il3945_rates[high].next_rs; 596*7ac9a364SKalle Valo if (high == RATE_INVALID) 597*7ac9a364SKalle Valo break; 598*7ac9a364SKalle Valo if (rate_mask & (1 << high)) 599*7ac9a364SKalle Valo break; 600*7ac9a364SKalle Valo D_RATE("Skipping masked higher rate: %d\n", high); 601*7ac9a364SKalle Valo } 602*7ac9a364SKalle Valo 603*7ac9a364SKalle Valo return (high << 8) | low; 604*7ac9a364SKalle Valo } 605*7ac9a364SKalle Valo 606*7ac9a364SKalle Valo /** 607*7ac9a364SKalle Valo * il3945_rs_get_rate - find the rate for the requested packet 608*7ac9a364SKalle Valo * 609*7ac9a364SKalle Valo * Returns the ieee80211_rate structure allocated by the driver. 610*7ac9a364SKalle Valo * 611*7ac9a364SKalle Valo * The rate control algorithm has no internal mapping between hw_mode's 612*7ac9a364SKalle Valo * rate ordering and the rate ordering used by the rate control algorithm. 613*7ac9a364SKalle Valo * 614*7ac9a364SKalle Valo * The rate control algorithm uses a single table of rates that goes across 615*7ac9a364SKalle Valo * the entire A/B/G spectrum vs. being limited to just one particular 616*7ac9a364SKalle Valo * hw_mode. 617*7ac9a364SKalle Valo * 618*7ac9a364SKalle Valo * As such, we can't convert the idx obtained below into the hw_mode's 619*7ac9a364SKalle Valo * rate table and must reference the driver allocated rate table 620*7ac9a364SKalle Valo * 621*7ac9a364SKalle Valo */ 622*7ac9a364SKalle Valo static void 623*7ac9a364SKalle Valo il3945_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta, 624*7ac9a364SKalle Valo struct ieee80211_tx_rate_control *txrc) 625*7ac9a364SKalle Valo { 626*7ac9a364SKalle Valo struct ieee80211_supported_band *sband = txrc->sband; 627*7ac9a364SKalle Valo struct sk_buff *skb = txrc->skb; 628*7ac9a364SKalle Valo u8 low = RATE_INVALID; 629*7ac9a364SKalle Valo u8 high = RATE_INVALID; 630*7ac9a364SKalle Valo u16 high_low; 631*7ac9a364SKalle Valo int idx; 632*7ac9a364SKalle Valo struct il3945_rs_sta *rs_sta = il_sta; 633*7ac9a364SKalle Valo struct il3945_rate_scale_data *win = NULL; 634*7ac9a364SKalle Valo int current_tpt = IL_INVALID_VALUE; 635*7ac9a364SKalle Valo int low_tpt = IL_INVALID_VALUE; 636*7ac9a364SKalle Valo int high_tpt = IL_INVALID_VALUE; 637*7ac9a364SKalle Valo u32 fail_count; 638*7ac9a364SKalle Valo s8 scale_action = 0; 639*7ac9a364SKalle Valo unsigned long flags; 640*7ac9a364SKalle Valo u16 rate_mask; 641*7ac9a364SKalle Valo s8 max_rate_idx = -1; 642*7ac9a364SKalle Valo struct il_priv *il __maybe_unused = (struct il_priv *)il_r; 643*7ac9a364SKalle Valo struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 644*7ac9a364SKalle Valo 645*7ac9a364SKalle Valo D_RATE("enter\n"); 646*7ac9a364SKalle Valo 647*7ac9a364SKalle Valo /* Treat uninitialized rate scaling data same as non-existing. */ 648*7ac9a364SKalle Valo if (rs_sta && !rs_sta->il) { 649*7ac9a364SKalle Valo D_RATE("Rate scaling information not initialized yet.\n"); 650*7ac9a364SKalle Valo il_sta = NULL; 651*7ac9a364SKalle Valo } 652*7ac9a364SKalle Valo 653*7ac9a364SKalle Valo if (rate_control_send_low(sta, il_sta, txrc)) 654*7ac9a364SKalle Valo return; 655*7ac9a364SKalle Valo 656*7ac9a364SKalle Valo rate_mask = sta->supp_rates[sband->band]; 657*7ac9a364SKalle Valo 658*7ac9a364SKalle Valo /* get user max rate if set */ 659*7ac9a364SKalle Valo max_rate_idx = txrc->max_rate_idx; 660*7ac9a364SKalle Valo if (sband->band == IEEE80211_BAND_5GHZ && max_rate_idx != -1) 661*7ac9a364SKalle Valo max_rate_idx += IL_FIRST_OFDM_RATE; 662*7ac9a364SKalle Valo if (max_rate_idx < 0 || max_rate_idx >= RATE_COUNT) 663*7ac9a364SKalle Valo max_rate_idx = -1; 664*7ac9a364SKalle Valo 665*7ac9a364SKalle Valo idx = min(rs_sta->last_txrate_idx & 0xffff, RATE_COUNT_3945 - 1); 666*7ac9a364SKalle Valo 667*7ac9a364SKalle Valo if (sband->band == IEEE80211_BAND_5GHZ) 668*7ac9a364SKalle Valo rate_mask = rate_mask << IL_FIRST_OFDM_RATE; 669*7ac9a364SKalle Valo 670*7ac9a364SKalle Valo spin_lock_irqsave(&rs_sta->lock, flags); 671*7ac9a364SKalle Valo 672*7ac9a364SKalle Valo /* for recent assoc, choose best rate regarding 673*7ac9a364SKalle Valo * to rssi value 674*7ac9a364SKalle Valo */ 675*7ac9a364SKalle Valo if (rs_sta->start_rate != RATE_INVALID) { 676*7ac9a364SKalle Valo if (rs_sta->start_rate < idx && 677*7ac9a364SKalle Valo (rate_mask & (1 << rs_sta->start_rate))) 678*7ac9a364SKalle Valo idx = rs_sta->start_rate; 679*7ac9a364SKalle Valo rs_sta->start_rate = RATE_INVALID; 680*7ac9a364SKalle Valo } 681*7ac9a364SKalle Valo 682*7ac9a364SKalle Valo /* force user max rate if set by user */ 683*7ac9a364SKalle Valo if (max_rate_idx != -1 && max_rate_idx < idx) { 684*7ac9a364SKalle Valo if (rate_mask & (1 << max_rate_idx)) 685*7ac9a364SKalle Valo idx = max_rate_idx; 686*7ac9a364SKalle Valo } 687*7ac9a364SKalle Valo 688*7ac9a364SKalle Valo win = &(rs_sta->win[idx]); 689*7ac9a364SKalle Valo 690*7ac9a364SKalle Valo fail_count = win->counter - win->success_counter; 691*7ac9a364SKalle Valo 692*7ac9a364SKalle Valo if (fail_count < RATE_MIN_FAILURE_TH && 693*7ac9a364SKalle Valo win->success_counter < RATE_MIN_SUCCESS_TH) { 694*7ac9a364SKalle Valo spin_unlock_irqrestore(&rs_sta->lock, flags); 695*7ac9a364SKalle Valo 696*7ac9a364SKalle Valo D_RATE("Invalid average_tpt on rate %d: " 697*7ac9a364SKalle Valo "counter: %d, success_counter: %d, " 698*7ac9a364SKalle Valo "expected_tpt is %sNULL\n", idx, win->counter, 699*7ac9a364SKalle Valo win->success_counter, 700*7ac9a364SKalle Valo rs_sta->expected_tpt ? "not " : ""); 701*7ac9a364SKalle Valo 702*7ac9a364SKalle Valo /* Can't calculate this yet; not enough history */ 703*7ac9a364SKalle Valo win->average_tpt = IL_INVALID_VALUE; 704*7ac9a364SKalle Valo goto out; 705*7ac9a364SKalle Valo 706*7ac9a364SKalle Valo } 707*7ac9a364SKalle Valo 708*7ac9a364SKalle Valo current_tpt = win->average_tpt; 709*7ac9a364SKalle Valo 710*7ac9a364SKalle Valo high_low = 711*7ac9a364SKalle Valo il3945_get_adjacent_rate(rs_sta, idx, rate_mask, sband->band); 712*7ac9a364SKalle Valo low = high_low & 0xff; 713*7ac9a364SKalle Valo high = (high_low >> 8) & 0xff; 714*7ac9a364SKalle Valo 715*7ac9a364SKalle Valo /* If user set max rate, dont allow higher than user constrain */ 716*7ac9a364SKalle Valo if (max_rate_idx != -1 && max_rate_idx < high) 717*7ac9a364SKalle Valo high = RATE_INVALID; 718*7ac9a364SKalle Valo 719*7ac9a364SKalle Valo /* Collect Measured throughputs of adjacent rates */ 720*7ac9a364SKalle Valo if (low != RATE_INVALID) 721*7ac9a364SKalle Valo low_tpt = rs_sta->win[low].average_tpt; 722*7ac9a364SKalle Valo 723*7ac9a364SKalle Valo if (high != RATE_INVALID) 724*7ac9a364SKalle Valo high_tpt = rs_sta->win[high].average_tpt; 725*7ac9a364SKalle Valo 726*7ac9a364SKalle Valo spin_unlock_irqrestore(&rs_sta->lock, flags); 727*7ac9a364SKalle Valo 728*7ac9a364SKalle Valo scale_action = 0; 729*7ac9a364SKalle Valo 730*7ac9a364SKalle Valo /* Low success ratio , need to drop the rate */ 731*7ac9a364SKalle Valo if (win->success_ratio < RATE_DECREASE_TH || !current_tpt) { 732*7ac9a364SKalle Valo D_RATE("decrease rate because of low success_ratio\n"); 733*7ac9a364SKalle Valo scale_action = -1; 734*7ac9a364SKalle Valo /* No throughput measured yet for adjacent rates, 735*7ac9a364SKalle Valo * try increase */ 736*7ac9a364SKalle Valo } else if (low_tpt == IL_INVALID_VALUE && high_tpt == IL_INVALID_VALUE) { 737*7ac9a364SKalle Valo 738*7ac9a364SKalle Valo if (high != RATE_INVALID && 739*7ac9a364SKalle Valo win->success_ratio >= RATE_INCREASE_TH) 740*7ac9a364SKalle Valo scale_action = 1; 741*7ac9a364SKalle Valo else if (low != RATE_INVALID) 742*7ac9a364SKalle Valo scale_action = 0; 743*7ac9a364SKalle Valo 744*7ac9a364SKalle Valo /* Both adjacent throughputs are measured, but neither one has 745*7ac9a364SKalle Valo * better throughput; we're using the best rate, don't change 746*7ac9a364SKalle Valo * it! */ 747*7ac9a364SKalle Valo } else if (low_tpt != IL_INVALID_VALUE && high_tpt != IL_INVALID_VALUE 748*7ac9a364SKalle Valo && low_tpt < current_tpt && high_tpt < current_tpt) { 749*7ac9a364SKalle Valo 750*7ac9a364SKalle Valo D_RATE("No action -- low [%d] & high [%d] < " 751*7ac9a364SKalle Valo "current_tpt [%d]\n", low_tpt, high_tpt, current_tpt); 752*7ac9a364SKalle Valo scale_action = 0; 753*7ac9a364SKalle Valo 754*7ac9a364SKalle Valo /* At least one of the rates has better throughput */ 755*7ac9a364SKalle Valo } else { 756*7ac9a364SKalle Valo if (high_tpt != IL_INVALID_VALUE) { 757*7ac9a364SKalle Valo 758*7ac9a364SKalle Valo /* High rate has better throughput, Increase 759*7ac9a364SKalle Valo * rate */ 760*7ac9a364SKalle Valo if (high_tpt > current_tpt && 761*7ac9a364SKalle Valo win->success_ratio >= RATE_INCREASE_TH) 762*7ac9a364SKalle Valo scale_action = 1; 763*7ac9a364SKalle Valo else { 764*7ac9a364SKalle Valo D_RATE("decrease rate because of high tpt\n"); 765*7ac9a364SKalle Valo scale_action = 0; 766*7ac9a364SKalle Valo } 767*7ac9a364SKalle Valo } else if (low_tpt != IL_INVALID_VALUE) { 768*7ac9a364SKalle Valo if (low_tpt > current_tpt) { 769*7ac9a364SKalle Valo D_RATE("decrease rate because of low tpt\n"); 770*7ac9a364SKalle Valo scale_action = -1; 771*7ac9a364SKalle Valo } else if (win->success_ratio >= RATE_INCREASE_TH) { 772*7ac9a364SKalle Valo /* Lower rate has better 773*7ac9a364SKalle Valo * throughput,decrease rate */ 774*7ac9a364SKalle Valo scale_action = 1; 775*7ac9a364SKalle Valo } 776*7ac9a364SKalle Valo } 777*7ac9a364SKalle Valo } 778*7ac9a364SKalle Valo 779*7ac9a364SKalle Valo /* Sanity check; asked for decrease, but success rate or throughput 780*7ac9a364SKalle Valo * has been good at old rate. Don't change it. */ 781*7ac9a364SKalle Valo if (scale_action == -1 && low != RATE_INVALID && 782*7ac9a364SKalle Valo (win->success_ratio > RATE_HIGH_TH || 783*7ac9a364SKalle Valo current_tpt > 100 * rs_sta->expected_tpt[low])) 784*7ac9a364SKalle Valo scale_action = 0; 785*7ac9a364SKalle Valo 786*7ac9a364SKalle Valo switch (scale_action) { 787*7ac9a364SKalle Valo case -1: 788*7ac9a364SKalle Valo /* Decrese rate */ 789*7ac9a364SKalle Valo if (low != RATE_INVALID) 790*7ac9a364SKalle Valo idx = low; 791*7ac9a364SKalle Valo break; 792*7ac9a364SKalle Valo case 1: 793*7ac9a364SKalle Valo /* Increase rate */ 794*7ac9a364SKalle Valo if (high != RATE_INVALID) 795*7ac9a364SKalle Valo idx = high; 796*7ac9a364SKalle Valo 797*7ac9a364SKalle Valo break; 798*7ac9a364SKalle Valo case 0: 799*7ac9a364SKalle Valo default: 800*7ac9a364SKalle Valo /* No change */ 801*7ac9a364SKalle Valo break; 802*7ac9a364SKalle Valo } 803*7ac9a364SKalle Valo 804*7ac9a364SKalle Valo D_RATE("Selected %d (action %d) - low %d high %d\n", idx, scale_action, 805*7ac9a364SKalle Valo low, high); 806*7ac9a364SKalle Valo 807*7ac9a364SKalle Valo out: 808*7ac9a364SKalle Valo 809*7ac9a364SKalle Valo if (sband->band == IEEE80211_BAND_5GHZ) { 810*7ac9a364SKalle Valo if (WARN_ON_ONCE(idx < IL_FIRST_OFDM_RATE)) 811*7ac9a364SKalle Valo idx = IL_FIRST_OFDM_RATE; 812*7ac9a364SKalle Valo rs_sta->last_txrate_idx = idx; 813*7ac9a364SKalle Valo info->control.rates[0].idx = idx - IL_FIRST_OFDM_RATE; 814*7ac9a364SKalle Valo } else { 815*7ac9a364SKalle Valo rs_sta->last_txrate_idx = idx; 816*7ac9a364SKalle Valo info->control.rates[0].idx = rs_sta->last_txrate_idx; 817*7ac9a364SKalle Valo } 818*7ac9a364SKalle Valo info->control.rates[0].count = 1; 819*7ac9a364SKalle Valo 820*7ac9a364SKalle Valo D_RATE("leave: %d\n", idx); 821*7ac9a364SKalle Valo } 822*7ac9a364SKalle Valo 823*7ac9a364SKalle Valo #ifdef CONFIG_MAC80211_DEBUGFS 824*7ac9a364SKalle Valo 825*7ac9a364SKalle Valo static ssize_t 826*7ac9a364SKalle Valo il3945_sta_dbgfs_stats_table_read(struct file *file, char __user *user_buf, 827*7ac9a364SKalle Valo size_t count, loff_t *ppos) 828*7ac9a364SKalle Valo { 829*7ac9a364SKalle Valo char *buff; 830*7ac9a364SKalle Valo int desc = 0; 831*7ac9a364SKalle Valo int j; 832*7ac9a364SKalle Valo ssize_t ret; 833*7ac9a364SKalle Valo struct il3945_rs_sta *lq_sta = file->private_data; 834*7ac9a364SKalle Valo 835*7ac9a364SKalle Valo buff = kmalloc(1024, GFP_KERNEL); 836*7ac9a364SKalle Valo if (!buff) 837*7ac9a364SKalle Valo return -ENOMEM; 838*7ac9a364SKalle Valo 839*7ac9a364SKalle Valo desc += 840*7ac9a364SKalle Valo sprintf(buff + desc, 841*7ac9a364SKalle Valo "tx packets=%d last rate idx=%d\n" 842*7ac9a364SKalle Valo "rate=0x%X flush time %d\n", lq_sta->tx_packets, 843*7ac9a364SKalle Valo lq_sta->last_txrate_idx, lq_sta->start_rate, 844*7ac9a364SKalle Valo jiffies_to_msecs(lq_sta->flush_time)); 845*7ac9a364SKalle Valo for (j = 0; j < RATE_COUNT_3945; j++) { 846*7ac9a364SKalle Valo desc += 847*7ac9a364SKalle Valo sprintf(buff + desc, "counter=%d success=%d %%=%d\n", 848*7ac9a364SKalle Valo lq_sta->win[j].counter, 849*7ac9a364SKalle Valo lq_sta->win[j].success_counter, 850*7ac9a364SKalle Valo lq_sta->win[j].success_ratio); 851*7ac9a364SKalle Valo } 852*7ac9a364SKalle Valo ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); 853*7ac9a364SKalle Valo kfree(buff); 854*7ac9a364SKalle Valo return ret; 855*7ac9a364SKalle Valo } 856*7ac9a364SKalle Valo 857*7ac9a364SKalle Valo static const struct file_operations rs_sta_dbgfs_stats_table_ops = { 858*7ac9a364SKalle Valo .read = il3945_sta_dbgfs_stats_table_read, 859*7ac9a364SKalle Valo .open = simple_open, 860*7ac9a364SKalle Valo .llseek = default_llseek, 861*7ac9a364SKalle Valo }; 862*7ac9a364SKalle Valo 863*7ac9a364SKalle Valo static void 864*7ac9a364SKalle Valo il3945_add_debugfs(void *il, void *il_sta, struct dentry *dir) 865*7ac9a364SKalle Valo { 866*7ac9a364SKalle Valo struct il3945_rs_sta *lq_sta = il_sta; 867*7ac9a364SKalle Valo 868*7ac9a364SKalle Valo lq_sta->rs_sta_dbgfs_stats_table_file = 869*7ac9a364SKalle Valo debugfs_create_file("rate_stats_table", 0600, dir, lq_sta, 870*7ac9a364SKalle Valo &rs_sta_dbgfs_stats_table_ops); 871*7ac9a364SKalle Valo 872*7ac9a364SKalle Valo } 873*7ac9a364SKalle Valo 874*7ac9a364SKalle Valo static void 875*7ac9a364SKalle Valo il3945_remove_debugfs(void *il, void *il_sta) 876*7ac9a364SKalle Valo { 877*7ac9a364SKalle Valo struct il3945_rs_sta *lq_sta = il_sta; 878*7ac9a364SKalle Valo debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); 879*7ac9a364SKalle Valo } 880*7ac9a364SKalle Valo #endif 881*7ac9a364SKalle Valo 882*7ac9a364SKalle Valo /* 883*7ac9a364SKalle Valo * Initialization of rate scaling information is done by driver after 884*7ac9a364SKalle Valo * the station is added. Since mac80211 calls this function before a 885*7ac9a364SKalle Valo * station is added we ignore it. 886*7ac9a364SKalle Valo */ 887*7ac9a364SKalle Valo static void 888*7ac9a364SKalle Valo il3945_rs_rate_init_stub(void *il_r, struct ieee80211_supported_band *sband, 889*7ac9a364SKalle Valo struct cfg80211_chan_def *chandef, 890*7ac9a364SKalle Valo struct ieee80211_sta *sta, void *il_sta) 891*7ac9a364SKalle Valo { 892*7ac9a364SKalle Valo } 893*7ac9a364SKalle Valo 894*7ac9a364SKalle Valo static const struct rate_control_ops rs_ops = { 895*7ac9a364SKalle Valo .name = RS_NAME, 896*7ac9a364SKalle Valo .tx_status = il3945_rs_tx_status, 897*7ac9a364SKalle Valo .get_rate = il3945_rs_get_rate, 898*7ac9a364SKalle Valo .rate_init = il3945_rs_rate_init_stub, 899*7ac9a364SKalle Valo .alloc = il3945_rs_alloc, 900*7ac9a364SKalle Valo .free = il3945_rs_free, 901*7ac9a364SKalle Valo .alloc_sta = il3945_rs_alloc_sta, 902*7ac9a364SKalle Valo .free_sta = il3945_rs_free_sta, 903*7ac9a364SKalle Valo #ifdef CONFIG_MAC80211_DEBUGFS 904*7ac9a364SKalle Valo .add_sta_debugfs = il3945_add_debugfs, 905*7ac9a364SKalle Valo .remove_sta_debugfs = il3945_remove_debugfs, 906*7ac9a364SKalle Valo #endif 907*7ac9a364SKalle Valo 908*7ac9a364SKalle Valo }; 909*7ac9a364SKalle Valo 910*7ac9a364SKalle Valo void 911*7ac9a364SKalle Valo il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) 912*7ac9a364SKalle Valo { 913*7ac9a364SKalle Valo struct il_priv *il = hw->priv; 914*7ac9a364SKalle Valo s32 rssi = 0; 915*7ac9a364SKalle Valo unsigned long flags; 916*7ac9a364SKalle Valo struct il3945_rs_sta *rs_sta; 917*7ac9a364SKalle Valo struct ieee80211_sta *sta; 918*7ac9a364SKalle Valo struct il3945_sta_priv *psta; 919*7ac9a364SKalle Valo 920*7ac9a364SKalle Valo D_RATE("enter\n"); 921*7ac9a364SKalle Valo 922*7ac9a364SKalle Valo rcu_read_lock(); 923*7ac9a364SKalle Valo 924*7ac9a364SKalle Valo sta = ieee80211_find_sta(il->vif, il->stations[sta_id].sta.sta.addr); 925*7ac9a364SKalle Valo if (!sta) { 926*7ac9a364SKalle Valo D_RATE("Unable to find station to initialize rate scaling.\n"); 927*7ac9a364SKalle Valo rcu_read_unlock(); 928*7ac9a364SKalle Valo return; 929*7ac9a364SKalle Valo } 930*7ac9a364SKalle Valo 931*7ac9a364SKalle Valo psta = (void *)sta->drv_priv; 932*7ac9a364SKalle Valo rs_sta = &psta->rs_sta; 933*7ac9a364SKalle Valo 934*7ac9a364SKalle Valo spin_lock_irqsave(&rs_sta->lock, flags); 935*7ac9a364SKalle Valo 936*7ac9a364SKalle Valo rs_sta->tgg = 0; 937*7ac9a364SKalle Valo switch (il->band) { 938*7ac9a364SKalle Valo case IEEE80211_BAND_2GHZ: 939*7ac9a364SKalle Valo /* TODO: this always does G, not a regression */ 940*7ac9a364SKalle Valo if (il->active.flags & RXON_FLG_TGG_PROTECT_MSK) { 941*7ac9a364SKalle Valo rs_sta->tgg = 1; 942*7ac9a364SKalle Valo rs_sta->expected_tpt = il3945_expected_tpt_g_prot; 943*7ac9a364SKalle Valo } else 944*7ac9a364SKalle Valo rs_sta->expected_tpt = il3945_expected_tpt_g; 945*7ac9a364SKalle Valo break; 946*7ac9a364SKalle Valo case IEEE80211_BAND_5GHZ: 947*7ac9a364SKalle Valo rs_sta->expected_tpt = il3945_expected_tpt_a; 948*7ac9a364SKalle Valo break; 949*7ac9a364SKalle Valo default: 950*7ac9a364SKalle Valo BUG(); 951*7ac9a364SKalle Valo break; 952*7ac9a364SKalle Valo } 953*7ac9a364SKalle Valo 954*7ac9a364SKalle Valo spin_unlock_irqrestore(&rs_sta->lock, flags); 955*7ac9a364SKalle Valo 956*7ac9a364SKalle Valo rssi = il->_3945.last_rx_rssi; 957*7ac9a364SKalle Valo if (rssi == 0) 958*7ac9a364SKalle Valo rssi = IL_MIN_RSSI_VAL; 959*7ac9a364SKalle Valo 960*7ac9a364SKalle Valo D_RATE("Network RSSI: %d\n", rssi); 961*7ac9a364SKalle Valo 962*7ac9a364SKalle Valo rs_sta->start_rate = il3945_get_rate_idx_by_rssi(rssi, il->band); 963*7ac9a364SKalle Valo 964*7ac9a364SKalle Valo D_RATE("leave: rssi %d assign rate idx: " "%d (plcp 0x%x)\n", rssi, 965*7ac9a364SKalle Valo rs_sta->start_rate, il3945_rates[rs_sta->start_rate].plcp); 966*7ac9a364SKalle Valo rcu_read_unlock(); 967*7ac9a364SKalle Valo } 968*7ac9a364SKalle Valo 969*7ac9a364SKalle Valo int 970*7ac9a364SKalle Valo il3945_rate_control_register(void) 971*7ac9a364SKalle Valo { 972*7ac9a364SKalle Valo return ieee80211_rate_control_register(&rs_ops); 973*7ac9a364SKalle Valo } 974*7ac9a364SKalle Valo 975*7ac9a364SKalle Valo void 976*7ac9a364SKalle Valo il3945_rate_control_unregister(void) 977*7ac9a364SKalle Valo { 978*7ac9a364SKalle Valo ieee80211_rate_control_unregister(&rs_ops); 979*7ac9a364SKalle Valo } 980