iPXE
Data Structures | Macros | Functions
rc80211.c File Reference

Simple 802.11 rate-control algorithm. More...

#include <stdlib.h>
#include <ipxe/net80211.h>

Go to the source code of this file.

Data Structures

struct  rc80211_ctx
 A rate control context. More...
 

Macros

#define RC_PKT_OK   0x3
 Two-bit packet status indicator for a packet with no retries. More...
 
#define RC_PKT_RETRIED_ONCE   0x2
 Two-bit packet status indicator for a packet with one retry. More...
 
#define RC_PKT_RETRIED_MULTI   0x1
 Two-bit packet status indicator for a TX packet with multiple retries. More...
 
#define RC_PKT_FAILED   0x0
 Two-bit packet status indicator for a TX packet that was never ACKed. More...
 
#define RC_TX_FACTOR   4
 Number of times to weight TX packets more heavily than RX packets. More...
 
#define RC_TX_EMERG_FAIL   3
 Number of consecutive failed TX packets that cause an automatic rate drop. More...
 
#define RC_GOODNESS_MIN   85
 Minimum net goodness below which we will search for a better rate. More...
 
#define RC_GOODNESS_MAX   95
 Maximum net goodness above which we will try to increase our rate. More...
 
#define RC_UNCERTAINTY_THRESH   4
 Minimum (num RX + RC_TX_FACTOR * num TX) to use a certain rate. More...
 
#define TX   0
 TX direction. More...
 
#define RX   1
 RX direction. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 
 FILE_SECBOOT (FORBIDDEN)
 
struct rc80211_ctxrc80211_init (struct net80211_device *dev __unused)
 Initialize rate-control algorithm. More...
 
static int rc80211_calc_net_goodness (struct rc80211_ctx *ctx, int rate_idx)
 Calculate net goodness for a certain rate. More...
 
static int rc80211_pick_best (struct net80211_device *dev)
 Determine the best rate to switch to and return it. More...
 
static void rc80211_set_rate (struct net80211_device *dev, int rate_idx)
 Set 802.11 device rate. More...
 
static void rc80211_maybe_set_new (struct net80211_device *dev)
 Check rate-control state and change rate if necessary. More...
 
static void rc80211_update (struct net80211_device *dev, int direction, int rate_idx, int retries, int failed)
 Update rate-control state. More...
 
void rc80211_update_tx (struct net80211_device *dev, int retries, int rc)
 Update rate-control state for transmitted packet. More...
 
void rc80211_update_rx (struct net80211_device *dev, int retry, u16 rate)
 Update rate-control state for received packet. More...
 
void rc80211_free (struct rc80211_ctx *ctx)
 Free rate-control context. More...
 

Detailed Description

Simple 802.11 rate-control algorithm.

Definition in file rc80211.c.

Macro Definition Documentation

◆ RC_PKT_OK

#define RC_PKT_OK   0x3

Two-bit packet status indicator for a packet with no retries.

Definition at line 89 of file rc80211.c.

◆ RC_PKT_RETRIED_ONCE

#define RC_PKT_RETRIED_ONCE   0x2

Two-bit packet status indicator for a packet with one retry.

Definition at line 92 of file rc80211.c.

◆ RC_PKT_RETRIED_MULTI

#define RC_PKT_RETRIED_MULTI   0x1

Two-bit packet status indicator for a TX packet with multiple retries.

It is not possible to tell whether an RX packet had one or multiple retries; we rely instead on the fact that failed RX packets won't get to us at all, so if we receive a lot of RX packets on a certain rate it must be pretty good.

Definition at line 101 of file rc80211.c.

◆ RC_PKT_FAILED

#define RC_PKT_FAILED   0x0

Two-bit packet status indicator for a TX packet that was never ACKed.

It is not possible to tell whether an RX packet was setn if it didn't get through to us, but if we don't see one we won't increase the goodness for its rate. This asymmetry is part of why TX packets are weighted much more heavily than RX.

Definition at line 110 of file rc80211.c.

◆ RC_TX_FACTOR

#define RC_TX_FACTOR   4

Number of times to weight TX packets more heavily than RX packets.

Definition at line 113 of file rc80211.c.

◆ RC_TX_EMERG_FAIL

#define RC_TX_EMERG_FAIL   3

Number of consecutive failed TX packets that cause an automatic rate drop.

Definition at line 116 of file rc80211.c.

◆ RC_GOODNESS_MIN

#define RC_GOODNESS_MIN   85

Minimum net goodness below which we will search for a better rate.

Definition at line 119 of file rc80211.c.

◆ RC_GOODNESS_MAX

#define RC_GOODNESS_MAX   95

Maximum net goodness above which we will try to increase our rate.

Definition at line 122 of file rc80211.c.

◆ RC_UNCERTAINTY_THRESH

#define RC_UNCERTAINTY_THRESH   4

Minimum (num RX + RC_TX_FACTOR * num TX) to use a certain rate.

Definition at line 125 of file rc80211.c.

◆ TX

#define TX   0

TX direction.

Definition at line 128 of file rc80211.c.

◆ RX

#define RX   1

RX direction.

Definition at line 131 of file rc80211.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ FILE_SECBOOT()

FILE_SECBOOT ( FORBIDDEN  )

◆ rc80211_init()

struct rc80211_ctx* rc80211_init ( struct net80211_device *dev  __unused)

Initialize rate-control algorithm.

Parameters
dev802.11 device
Return values
ctxRate-control context, to be stored in dev->rctl

Definition at line 155 of file rc80211.c.

156 {
157  struct rc80211_ctx *ret = zalloc ( sizeof ( *ret ) );
158  return ret;
159 }
A rate control context.
Definition: rc80211.c:134
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:662

References zalloc().

Referenced by net80211_step_associate().

◆ rc80211_calc_net_goodness()

static int rc80211_calc_net_goodness ( struct rc80211_ctx ctx,
int  rate_idx 
)
static

Calculate net goodness for a certain rate.

Parameters
ctxRate-control context
rate_idxIndex of rate to calculate net goodness for

Definition at line 167 of file rc80211.c.

169 {
170  int sum[2], num[2], dir, pkt;
171 
172  for ( dir = 0; dir < 2; dir++ ) {
173  u32 good = ctx->goodness[dir][rate_idx];
174 
175  num[dir] = ctx->count[dir][rate_idx];
176  sum[dir] = 0;
177 
178  for ( pkt = 0; pkt < num[dir]; pkt++ )
179  sum[dir] += ( good >> ( 2 * pkt ) ) & 0x3;
180  }
181 
182  if ( ( num[TX] * RC_TX_FACTOR + num[RX] ) < RC_UNCERTAINTY_THRESH )
183  return -1;
184 
185  return ( 33 * ( sum[TX] * RC_TX_FACTOR + sum[RX] ) /
186  ( num[TX] * RC_TX_FACTOR + num[RX] ) );
187 }
#define RX
RX direction.
Definition: rc80211.c:131
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
uint32_t num
Definition: multiboot.h:12
#define RC_TX_FACTOR
Number of times to weight TX packets more heavily than RX packets.
Definition: rc80211.c:113
#define RC_UNCERTAINTY_THRESH
Minimum (num RX + RC_TX_FACTOR * num TX) to use a certain rate.
Definition: rc80211.c:125
#define TX
TX direction.
Definition: rc80211.c:128
uint32_t u32
Definition: stdint.h:24

References ctx, num, RC_TX_FACTOR, RC_UNCERTAINTY_THRESH, RX, and TX.

Referenced by rc80211_maybe_set_new(), and rc80211_pick_best().

◆ rc80211_pick_best()

static int rc80211_pick_best ( struct net80211_device dev)
static

Determine the best rate to switch to and return it.

Parameters
dev802.11 device
Return values
rate_idxIndex of the best rate to switch to

Definition at line 195 of file rc80211.c.

196 {
197  struct rc80211_ctx *ctx = dev->rctl;
198  int best_net_good = 0, best_rate = -1, i;
199 
200  for ( i = 0; i < dev->nr_rates; i++ ) {
201  int net_good = rc80211_calc_net_goodness ( ctx, i );
202 
203  if ( net_good > best_net_good ||
204  ( best_net_good > RC_GOODNESS_MIN &&
205  net_good > RC_GOODNESS_MIN ) ) {
206  best_net_good = net_good;
207  best_rate = i;
208  }
209  }
210 
211  if ( best_rate >= 0 ) {
212  int old_good = rc80211_calc_net_goodness ( ctx, dev->rate );
213  if ( old_good != best_net_good )
214  DBGC ( ctx, "802.11 RC %p switching from goodness "
215  "%d to %d\n", ctx, old_good, best_net_good );
216 
217  ctx->started = 1;
218  return best_rate;
219  }
220 
221  return dev->rate;
222 }
static int rc80211_calc_net_goodness(struct rc80211_ctx *ctx, int rate_idx)
Calculate net goodness for a certain rate.
Definition: rc80211.c:167
#define DBGC(...)
Definition: compiler.h:505
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
A rate control context.
Definition: rc80211.c:134
struct rc80211_ctx * rctl
Rate control state.
Definition: net80211.h:989
u8 nr_rates
The number of transmission rates in the rates array.
Definition: net80211.h:821
#define RC_GOODNESS_MIN
Minimum net goodness below which we will search for a better rate.
Definition: rc80211.c:119
u8 rate
The rate currently in use, as an index into the rates array.
Definition: net80211.h:824

References ctx, DBGC, net80211_device::nr_rates, net80211_device::rate, rc80211_calc_net_goodness(), RC_GOODNESS_MIN, and net80211_device::rctl.

Referenced by rc80211_maybe_set_new().

◆ rc80211_set_rate()

static void rc80211_set_rate ( struct net80211_device dev,
int  rate_idx 
)
inlinestatic

Set 802.11 device rate.

Parameters
dev802.11 device
rate_idxIndex of rate to switch to

This is a thin wrapper around net80211_set_rate_idx to insert a debugging message where appropriate.

Definition at line 233 of file rc80211.c.

235 {
236  DBGC ( dev->rctl, "802.11 RC %p changing rate %d->%d Mbps\n", dev->rctl,
237  dev->rates[dev->rate] / 10, dev->rates[rate_idx] / 10 );
238 
239  net80211_set_rate_idx ( dev, rate_idx );
240 }
#define DBGC(...)
Definition: compiler.h:505
void net80211_set_rate_idx(struct net80211_device *dev, int rate)
Set data transmission rate for 802.11 device.
Definition: net80211.c:2001
struct rc80211_ctx * rctl
Rate control state.
Definition: net80211.h:989
u16 rates[NET80211_MAX_RATES]
A list of all possible TX rates we might use.
Definition: net80211.h:818
u8 rate
The rate currently in use, as an index into the rates array.
Definition: net80211.h:824

References DBGC, net80211_set_rate_idx(), net80211_device::rate, net80211_device::rates, and net80211_device::rctl.

Referenced by rc80211_maybe_set_new(), and rc80211_update_tx().

◆ rc80211_maybe_set_new()

static void rc80211_maybe_set_new ( struct net80211_device dev)
static

Check rate-control state and change rate if necessary.

Parameters
dev802.11 device

Definition at line 247 of file rc80211.c.

248 {
249  struct rc80211_ctx *ctx = dev->rctl;
250  int net_good;
251 
252  net_good = rc80211_calc_net_goodness ( ctx, dev->rate );
253 
254  if ( ! ctx->started ) {
255  rc80211_set_rate ( dev, rc80211_pick_best ( dev ) );
256  return;
257  }
258 
259  if ( net_good < 0 ) /* insufficient data */
260  return;
261 
262  if ( net_good > RC_GOODNESS_MAX && dev->rate + 1 < dev->nr_rates ) {
263  int higher = rc80211_calc_net_goodness ( ctx, dev->rate + 1 );
264  if ( higher > net_good || higher < 0 )
265  rc80211_set_rate ( dev, dev->rate + 1 );
266  else
267  rc80211_set_rate ( dev, rc80211_pick_best ( dev ) );
268  }
269 
270  if ( net_good < RC_GOODNESS_MIN ) {
271  rc80211_set_rate ( dev, rc80211_pick_best ( dev ) );
272  }
273 }
static int rc80211_pick_best(struct net80211_device *dev)
Determine the best rate to switch to and return it.
Definition: rc80211.c:195
static int rc80211_calc_net_goodness(struct rc80211_ctx *ctx, int rate_idx)
Calculate net goodness for a certain rate.
Definition: rc80211.c:167
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
A rate control context.
Definition: rc80211.c:134
struct rc80211_ctx * rctl
Rate control state.
Definition: net80211.h:989
u8 nr_rates
The number of transmission rates in the rates array.
Definition: net80211.h:821
static void rc80211_set_rate(struct net80211_device *dev, int rate_idx)
Set 802.11 device rate.
Definition: rc80211.c:233
#define RC_GOODNESS_MIN
Minimum net goodness below which we will search for a better rate.
Definition: rc80211.c:119
u8 rate
The rate currently in use, as an index into the rates array.
Definition: net80211.h:824
#define RC_GOODNESS_MAX
Maximum net goodness above which we will try to increase our rate.
Definition: rc80211.c:122

References ctx, net80211_device::nr_rates, net80211_device::rate, rc80211_calc_net_goodness(), rc80211_pick_best(), rc80211_set_rate(), RC_GOODNESS_MAX, RC_GOODNESS_MIN, and net80211_device::rctl.

Referenced by rc80211_update().

◆ rc80211_update()

static void rc80211_update ( struct net80211_device dev,
int  direction,
int  rate_idx,
int  retries,
int  failed 
)
static

Update rate-control state.

Parameters
dev802.11 device
directionOne of the direction constants TX or RX
rate_idxIndex of rate at which packet was sent or received
retriesNumber of times packet was retried before success
failedIf nonzero, the packet failed to get through

Definition at line 284 of file rc80211.c.

286 {
287  struct rc80211_ctx *ctx = dev->rctl;
288  u32 goodness = ctx->goodness[direction][rate_idx];
289 
290  if ( ctx->count[direction][rate_idx] < 16 )
291  ctx->count[direction][rate_idx]++;
292 
293  goodness <<= 2;
294  if ( failed )
296  else if ( retries > 1 )
298  else if ( retries )
300  else
301  goodness |= RC_PKT_OK;
302 
303  ctx->goodness[direction][rate_idx] = goodness;
304 
305  ctx->packets++;
306 
307  rc80211_maybe_set_new ( dev );
308 }
static void rc80211_maybe_set_new(struct net80211_device *dev)
Check rate-control state and change rate if necessary.
Definition: rc80211.c:247
#define RC_PKT_FAILED
Two-bit packet status indicator for a TX packet that was never ACKed.
Definition: rc80211.c:110
uint8_t direction
Direction.
Definition: ena.h:14
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
#define RC_PKT_RETRIED_MULTI
Two-bit packet status indicator for a TX packet with multiple retries.
Definition: rc80211.c:101
A rate control context.
Definition: rc80211.c:134
#define RC_PKT_RETRIED_ONCE
Two-bit packet status indicator for a packet with one retry.
Definition: rc80211.c:92
struct rc80211_ctx * rctl
Rate control state.
Definition: net80211.h:989
u32 goodness[2][NET80211_MAX_RATES]
Goodness state for each rate, TX and RX.
Definition: rc80211.c:137
#define RC_PKT_OK
Two-bit packet status indicator for a packet with no retries.
Definition: rc80211.c:89
uint32_t u32
Definition: stdint.h:24

References ctx, direction, rc80211_ctx::goodness, rc80211_maybe_set_new(), RC_PKT_FAILED, RC_PKT_OK, RC_PKT_RETRIED_MULTI, RC_PKT_RETRIED_ONCE, and net80211_device::rctl.

Referenced by rc80211_update_rx(), and rc80211_update_tx().

◆ rc80211_update_tx()

void rc80211_update_tx ( struct net80211_device dev,
int  retries,
int  rc 
)

Update rate-control state for transmitted packet.

Parameters
dev802.11 device
retriesNumber of times packet was transmitted before success
rcReturn status code for transmission

Definition at line 317 of file rc80211.c.

318 {
319  struct rc80211_ctx *ctx = dev->rctl;
320 
321  if ( ! ctx->started )
322  return;
323 
324  rc80211_update ( dev, TX, dev->rate, retries, rc );
325 
326  /* Check if the last RC_TX_EMERG_FAIL packets have all failed */
327  if ( ! ( ctx->goodness[TX][dev->rate] &
328  ( ( 1 << ( 2 * RC_TX_EMERG_FAIL ) ) - 1 ) ) ) {
329  if ( dev->rate == 0 )
330  DBGC ( dev->rctl, "802.11 RC %p saw %d consecutive "
331  "failed TX, but cannot lower rate any further\n",
332  dev->rctl, RC_TX_EMERG_FAIL );
333  else {
334  DBGC ( dev->rctl, "802.11 RC %p lowering rate (%d->%d "
335  "Mbps) due to %d consecutive TX failures\n",
336  dev->rctl, dev->rates[dev->rate] / 10,
337  dev->rates[dev->rate - 1] / 10,
339 
340  rc80211_set_rate ( dev, dev->rate - 1 );
341  }
342  }
343 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void rc80211_update(struct net80211_device *dev, int direction, int rate_idx, int retries, int failed)
Update rate-control state.
Definition: rc80211.c:284
#define DBGC(...)
Definition: compiler.h:505
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
A rate control context.
Definition: rc80211.c:134
struct rc80211_ctx * rctl
Rate control state.
Definition: net80211.h:989
#define RC_TX_EMERG_FAIL
Number of consecutive failed TX packets that cause an automatic rate drop.
Definition: rc80211.c:116
u16 rates[NET80211_MAX_RATES]
A list of all possible TX rates we might use.
Definition: net80211.h:818
#define TX
TX direction.
Definition: rc80211.c:128
static void rc80211_set_rate(struct net80211_device *dev, int rate_idx)
Set 802.11 device rate.
Definition: rc80211.c:233
u8 rate
The rate currently in use, as an index into the rates array.
Definition: net80211.h:824

References ctx, DBGC, net80211_device::rate, net80211_device::rates, rc, rc80211_set_rate(), rc80211_update(), RC_TX_EMERG_FAIL, net80211_device::rctl, and TX.

Referenced by net80211_tx_complete().

◆ rc80211_update_rx()

void rc80211_update_rx ( struct net80211_device dev,
int  retry,
u16  rate 
)

Update rate-control state for received packet.

Parameters
dev802.11 device
retryWhether the received packet had been retransmitted
rateRate at which packet was received, in 100 kbps units

Definition at line 352 of file rc80211.c.

353 {
354  int ridx;
355 
356  for ( ridx = 0; ridx < dev->nr_rates && dev->rates[ridx] != rate;
357  ridx++ )
358  ;
359  if ( ridx >= dev->nr_rates )
360  return; /* couldn't find the rate */
361 
362  rc80211_update ( dev, RX, ridx, retry, 0 );
363 }
static void rc80211_update(struct net80211_device *dev, int direction, int rate_idx, int retries, int failed)
Update rate-control state.
Definition: rc80211.c:284
#define RX
RX direction.
Definition: rc80211.c:131
u8 nr_rates
The number of transmission rates in the rates array.
Definition: net80211.h:821
u16 rates[NET80211_MAX_RATES]
A list of all possible TX rates we might use.
Definition: net80211.h:818

References net80211_device::nr_rates, net80211_device::rates, rc80211_update(), and RX.

Referenced by net80211_rx().

◆ rc80211_free()

void rc80211_free ( struct rc80211_ctx ctx)

Free rate-control context.

Parameters
ctxRate-control context

Definition at line 370 of file rc80211.c.

371 {
372  free ( ctx );
373 }
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55

References ctx, and free.

Referenced by net80211_free().