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)
 
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 88 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 91 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 100 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 109 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 112 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 115 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 118 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 121 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 124 of file rc80211.c.

◆ TX

#define TX   0

TX direction.

Definition at line 127 of file rc80211.c.

◆ RX

#define RX   1

RX direction.

Definition at line 130 of file rc80211.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ 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 154 of file rc80211.c.

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

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 166 of file rc80211.c.

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

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 194 of file rc80211.c.

195 {
196  struct rc80211_ctx *ctx = dev->rctl;
197  int best_net_good = 0, best_rate = -1, i;
198 
199  for ( i = 0; i < dev->nr_rates; i++ ) {
200  int net_good = rc80211_calc_net_goodness ( ctx, i );
201 
202  if ( net_good > best_net_good ||
203  ( best_net_good > RC_GOODNESS_MIN &&
204  net_good > RC_GOODNESS_MIN ) ) {
205  best_net_good = net_good;
206  best_rate = i;
207  }
208  }
209 
210  if ( best_rate >= 0 ) {
211  int old_good = rc80211_calc_net_goodness ( ctx, dev->rate );
212  if ( old_good != best_net_good )
213  DBGC ( ctx, "802.11 RC %p switching from goodness "
214  "%d to %d\n", ctx, old_good, best_net_good );
215 
216  ctx->started = 1;
217  return best_rate;
218  }
219 
220  return dev->rate;
221 }
static int rc80211_calc_net_goodness(struct rc80211_ctx *ctx, int rate_idx)
Calculate net goodness for a certain rate.
Definition: rc80211.c:166
#define DBGC(...)
Definition: compiler.h:505
A rate control context.
Definition: rc80211.c:133
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
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
#define RC_GOODNESS_MIN
Minimum net goodness below which we will search for a better rate.
Definition: rc80211.c:118
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 232 of file rc80211.c.

234 {
235  DBGC ( dev->rctl, "802.11 RC %p changing rate %d->%d Mbps\n", dev->rctl,
236  dev->rates[dev->rate] / 10, dev->rates[rate_idx] / 10 );
237 
238  net80211_set_rate_idx ( dev, rate_idx );
239 }
#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:2000
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 246 of file rc80211.c.

247 {
248  struct rc80211_ctx *ctx = dev->rctl;
249  int net_good;
250 
251  net_good = rc80211_calc_net_goodness ( ctx, dev->rate );
252 
253  if ( ! ctx->started ) {
254  rc80211_set_rate ( dev, rc80211_pick_best ( dev ) );
255  return;
256  }
257 
258  if ( net_good < 0 ) /* insufficient data */
259  return;
260 
261  if ( net_good > RC_GOODNESS_MAX && dev->rate + 1 < dev->nr_rates ) {
262  int higher = rc80211_calc_net_goodness ( ctx, dev->rate + 1 );
263  if ( higher > net_good || higher < 0 )
264  rc80211_set_rate ( dev, dev->rate + 1 );
265  else
266  rc80211_set_rate ( dev, rc80211_pick_best ( dev ) );
267  }
268 
269  if ( net_good < RC_GOODNESS_MIN ) {
270  rc80211_set_rate ( dev, rc80211_pick_best ( dev ) );
271  }
272 }
static int rc80211_pick_best(struct net80211_device *dev)
Determine the best rate to switch to and return it.
Definition: rc80211.c:194
static int rc80211_calc_net_goodness(struct rc80211_ctx *ctx, int rate_idx)
Calculate net goodness for a certain rate.
Definition: rc80211.c:166
A rate control context.
Definition: rc80211.c:133
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
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
static void rc80211_set_rate(struct net80211_device *dev, int rate_idx)
Set 802.11 device rate.
Definition: rc80211.c:232
#define RC_GOODNESS_MIN
Minimum net goodness below which we will search for a better rate.
Definition: rc80211.c:118
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:121

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 283 of file rc80211.c.

285 {
286  struct rc80211_ctx *ctx = dev->rctl;
287  u32 goodness = ctx->goodness[direction][rate_idx];
288 
289  if ( ctx->count[direction][rate_idx] < 16 )
290  ctx->count[direction][rate_idx]++;
291 
292  goodness <<= 2;
293  if ( failed )
295  else if ( retries > 1 )
297  else if ( retries )
299  else
300  goodness |= RC_PKT_OK;
301 
302  ctx->goodness[direction][rate_idx] = goodness;
303 
304  ctx->packets++;
305 
306  rc80211_maybe_set_new ( dev );
307 }
static void rc80211_maybe_set_new(struct net80211_device *dev)
Check rate-control state and change rate if necessary.
Definition: rc80211.c:246
#define RC_PKT_FAILED
Two-bit packet status indicator for a TX packet that was never ACKed.
Definition: rc80211.c:109
uint8_t direction
Direction.
Definition: ena.h:14
#define RC_PKT_RETRIED_MULTI
Two-bit packet status indicator for a TX packet with multiple retries.
Definition: rc80211.c:100
A rate control context.
Definition: rc80211.c:133
#define RC_PKT_RETRIED_ONCE
Two-bit packet status indicator for a packet with one retry.
Definition: rc80211.c:91
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:136
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
#define RC_PKT_OK
Two-bit packet status indicator for a packet with no retries.
Definition: rc80211.c:88
uint32_t u32
Definition: stdint.h:23

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 316 of file rc80211.c.

317 {
318  struct rc80211_ctx *ctx = dev->rctl;
319 
320  if ( ! ctx->started )
321  return;
322 
323  rc80211_update ( dev, TX, dev->rate, retries, rc );
324 
325  /* Check if the last RC_TX_EMERG_FAIL packets have all failed */
326  if ( ! ( ctx->goodness[TX][dev->rate] &
327  ( ( 1 << ( 2 * RC_TX_EMERG_FAIL ) ) - 1 ) ) ) {
328  if ( dev->rate == 0 )
329  DBGC ( dev->rctl, "802.11 RC %p saw %d consecutive "
330  "failed TX, but cannot lower rate any further\n",
331  dev->rctl, RC_TX_EMERG_FAIL );
332  else {
333  DBGC ( dev->rctl, "802.11 RC %p lowering rate (%d->%d "
334  "Mbps) due to %d consecutive TX failures\n",
335  dev->rctl, dev->rates[dev->rate] / 10,
336  dev->rates[dev->rate - 1] / 10,
338 
339  rc80211_set_rate ( dev, dev->rate - 1 );
340  }
341  }
342 }
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:283
#define DBGC(...)
Definition: compiler.h:505
A rate control context.
Definition: rc80211.c:133
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:115
struct golan_eq_context ctx
Definition: CIB_PRM.h:28
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:127
static void rc80211_set_rate(struct net80211_device *dev, int rate_idx)
Set 802.11 device rate.
Definition: rc80211.c:232
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 351 of file rc80211.c.

352 {
353  int ridx;
354 
355  for ( ridx = 0; ridx < dev->nr_rates && dev->rates[ridx] != rate;
356  ridx++ )
357  ;
358  if ( ridx >= dev->nr_rates )
359  return; /* couldn't find the rate */
360 
361  rc80211_update ( dev, RX, ridx, retry, 0 );
362 }
static void rc80211_update(struct net80211_device *dev, int direction, int rate_idx, int retries, int failed)
Update rate-control state.
Definition: rc80211.c:283
#define RX
RX direction.
Definition: rc80211.c:130
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 369 of file rc80211.c.

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

References ctx, and free.

Referenced by net80211_free().