CHAN5G(5825, 37), /* Channel 165 */ }; /* Atheros hardware rate code addition for short premble */ #define SHPCHECK(__hw_rate, __flags) \ ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04) : 0) #define RATE(_bitrate, _hw_rate, _flags) { \ .bitrate = (_bitrate), \ .flags = (_flags), \ .hw_value = (_hw_rate), \ .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \ } static struct ieee80211_rate ath9k_legacy_rates[] = { RATE(10, 0x1b, 0), RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp : 0x1e */ RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp: 0x1d */ RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), /* short: 0x1c */ RATE(60, 0x0b, 0), RATE(90, 0x0f, 0), RATE(120, 0x0a, 0), RATE(180, 0x0e, 0), RATE(240, 0x09, 0), RATE(360, 0x0d, 0), RATE(480, 0x08, 0), RATE(540, 0x0c, 0), }; #ifdef CONFIG_MAC80211_LEDS static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = {
IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS), /* UNII-3 */ CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS), CHAN5GHZ(153, IEEE80211_CHAN_NO_HT40PLUS), CHAN5GHZ(157, IEEE80211_CHAN_NO_HT40MINUS), CHAN5GHZ(161, IEEE80211_CHAN_NO_HT40PLUS), CHAN5GHZ(165, IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS) }; /* * The rate table is used for both 2.4G and 5G rates. The * latter being a subset as it does not support CCK rates. */ static struct ieee80211_rate legacy_ratetable[] = { RATE(10, 0), RATE(20, IEEE80211_RATE_SHORT_PREAMBLE), RATE(55, IEEE80211_RATE_SHORT_PREAMBLE), RATE(110, IEEE80211_RATE_SHORT_PREAMBLE), RATE(60, 0), RATE(90, 0), RATE(120, 0), RATE(180, 0), RATE(240, 0), RATE(360, 0), RATE(480, 0), RATE(540, 0), }; static const struct ieee80211_supported_band brcms_band_2GHz_nphy_template = { .band = IEEE80211_BAND_2GHZ,
CHAN5G(5825, 37), /* Channel 165 */ }; /* Atheros hardware rate code addition for short premble */ #define SHPCHECK(__hw_rate, __flags) \ ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0) #define RATE(_bitrate, _hw_rate, _flags) { \ .bitrate = (_bitrate), \ .flags = (_flags), \ .hw_value = (_hw_rate), \ .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \ } static struct ieee80211_rate ath9k_legacy_rates[] = { RATE(10, 0x1b, 0), RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), RATE(60, 0x0b, (IEEE80211_RATE_SUPPORTS_5MHZ | IEEE80211_RATE_SUPPORTS_10MHZ)), RATE(90, 0x0f, (IEEE80211_RATE_SUPPORTS_5MHZ | IEEE80211_RATE_SUPPORTS_10MHZ)), RATE(120, 0x0a, (IEEE80211_RATE_SUPPORTS_5MHZ | IEEE80211_RATE_SUPPORTS_10MHZ)), RATE(180, 0x0e, (IEEE80211_RATE_SUPPORTS_5MHZ | IEEE80211_RATE_SUPPORTS_10MHZ)), RATE(240, 0x09, (IEEE80211_RATE_SUPPORTS_5MHZ | IEEE80211_RATE_SUPPORTS_10MHZ)), RATE(360, 0x0d, (IEEE80211_RATE_SUPPORTS_5MHZ | IEEE80211_RATE_SUPPORTS_10MHZ)),
static int __devinit adxl34x_initialize(bus_device *bus, struct adxl34x *ac) { struct input_dev *input_dev; struct adxl34x_platform_data *devpd = bus->dev.platform_data; struct adxl34x_platform_data *pdata; int err, range; unsigned char revid; if (!bus->irq) { dev_err(&bus->dev, "no IRQ?\n"); return -ENODEV; } if (NULL == devpd) { dev_err(&bus->dev, "No platfrom data: Using default initialization\n"); return -ENOMEM; } memcpy(&ac->pdata, devpd, sizeof(ac->pdata)); pdata = &ac->pdata; input_dev = input_allocate_device(); if (!input_dev) { dev_err(&bus->dev, "%s: input device allocation failed\n", __func__); return -ENOMEM; } ac->input = input_dev; ac->disabled = 1; INIT_WORK(&ac->work, adxl34x_work); mutex_init(&ac->mutex); revid = ac->read(bus, DEVID); switch (revid) { case ID_ADXL345: ac->model = ACC_ADXL345; break; case ID_ADXL346: ac->model = ACC_ADXL346; break; default: dev_err(&bus->dev, "Read ACC ADXL Chip ID Err 0x%x\n", revid); err = -ENODEV; goto err_free_mem; } dev_info(&bus->dev, "Read ACC ADXL OK ,Chip ID is 0x%x\n", revid); snprintf(ac->phys, sizeof(ac->phys), "%s/input0", dev_name(&bus->dev)); input_dev->name = ACCL_INPUT_DEV_NAME; input_dev->phys = ac->phys; input_dev->dev.parent = &bus->dev; input_dev->id.product = ac->model; input_dev->id.bustype = BUS_I2C; /*input_dev->open = adxl34x_input_open;*/ /*input_dev->close = adxl34x_input_close;*/ input_dev->open = NULL; input_dev->close = NULL; input_set_drvdata(input_dev, ac); __set_bit(ac->pdata.ev_type, input_dev->evbit); if (ac->pdata.ev_type == EV_REL) { __set_bit(REL_X, input_dev->relbit); __set_bit(REL_Y, input_dev->relbit); __set_bit(REL_Z, input_dev->relbit); } else { /* EV_ABS */ __set_bit(ABS_X, input_dev->absbit); __set_bit(ABS_Y, input_dev->absbit); __set_bit(ABS_Z, input_dev->absbit); if (pdata->data_range & FULL_RES) range = ADXL_FULLRES_MAX_VAL; /* Signed 13-bit */ else range = ADXL_FIXEDRES_MAX_VAL; /* Signed 10-bit */ input_set_abs_params(input_dev, ABS_X, -range, range, 3, 3); input_set_abs_params(input_dev, ABS_Y, -range, range, 3, 3); input_set_abs_params(input_dev, ABS_Z, -range, range, 3, 3); } __set_bit(EV_KEY, input_dev->evbit); __set_bit(pdata->ev_code_tap_x, input_dev->keybit); __set_bit(pdata->ev_code_tap_y, input_dev->keybit); __set_bit(pdata->ev_code_tap_z, input_dev->keybit); if (pdata->ev_code_ff) { ac->int_mask = FREE_FALL; __set_bit(pdata->ev_code_ff, input_dev->keybit); } if (pdata->ev_code_act_inactivity) __set_bit(pdata->ev_code_act_inactivity, input_dev->keybit); ac->int_mask |= ACTIVITY | INACTIVITY; if (pdata->watermark) { ac->int_mask |= WATERMARK; if (!FIFO_MODE(pdata->fifo_mode)) pdata->fifo_mode |= FIFO_STREAM; } else { ac->int_mask |= DATA_READY; } if (pdata->tap_axis_control & (TAP_X_EN | TAP_Y_EN | TAP_Z_EN)) ac->int_mask |= SINGLE_TAP | DOUBLE_TAP; if (FIFO_MODE(pdata->fifo_mode) == FIFO_BYPASS) ac->fifo_delay = 0; ac->write(bus, POWER_CTL, 0); err = adxl34x_config_gpio(&bus->dev, ac); if (err < 0) { dev_err(&bus->dev, "%s: failed to config gpio lowpower mode\n", __func__); goto err_clear_inputdev; } if (bus->irq >= 0) { err = gpio_request(irq_to_gpio(bus->irq), "gsensor_gpio"); if (err) { dev_err(&bus->dev, "%s: failed to request gpio for irq\n", __func__); goto err_clear_inputdev; } gpio_direction_input(bus->irq); } err = sysfs_create_group(&bus->dev.kobj, &adxl34x_attr_group); if (err) { dev_err(&bus->dev, "ADXL34X register sysfs failed\n"); goto err_free_gpio; } err = input_register_device(input_dev); if (err) { dev_err(&bus->dev, "ADXL34X register input device failed\n"); goto err_remove_attr; } AC_WRITE(ac, THRESH_TAP, pdata->tap_threshold); AC_WRITE(ac, OFSX, pdata->x_axis_offset); ac->hwcal.x = pdata->x_axis_offset; AC_WRITE(ac, OFSY, pdata->y_axis_offset); ac->hwcal.y = pdata->y_axis_offset; AC_WRITE(ac, OFSZ, pdata->z_axis_offset); ac->hwcal.z = pdata->z_axis_offset; AC_WRITE(ac, THRESH_TAP, pdata->tap_threshold); AC_WRITE(ac, DUR, pdata->tap_duration); AC_WRITE(ac, LATENT, pdata->tap_latency); AC_WRITE(ac, WINDOW, pdata->tap_window); AC_WRITE(ac, THRESH_ACT, pdata->activity_threshold); AC_WRITE(ac, THRESH_INACT, pdata->inactivity_threshold); AC_WRITE(ac, TIME_INACT, pdata->inactivity_time); AC_WRITE(ac, THRESH_FF, pdata->free_fall_threshold); AC_WRITE(ac, TIME_FF, pdata->free_fall_time); AC_WRITE(ac, TAP_AXES, pdata->tap_axis_control); AC_WRITE(ac, ACT_INACT_CTL, pdata->act_axis_control); AC_WRITE(ac, BW_RATE, RATE(ac->pdata.data_rate) | (pdata->low_power_mode ? LOW_POWER : 0)); AC_WRITE(ac, DATA_FORMAT, pdata->data_range); AC_WRITE(ac, FIFO_CTL, FIFO_MODE(pdata->fifo_mode) | SAMPLES(pdata->watermark)); AC_WRITE(ac, INT_MAP, 0); /* Map all INTs to INT1 */ AC_WRITE(ac, INT_ENABLE, 0); /* pdata->power_mode &= (PCTL_AUTO_SLEEP | PCTL_LINK); */ pdata->power_mode &= PCTL_LINK; if (bus->irq >= 0) { err = request_irq(bus->irq, adxl34x_irq, IRQF_TRIGGER_HIGH, bus->dev.driver->name, ac); if (err) { dev_err(&bus->dev, "irq %d busy?\n", bus->irq); goto err_unreg_inputdev; } } dev_dbg(&bus->dev, "ADXL%d accelerometer, irq %d\n", ac->model, bus->irq); return 0; err_unreg_inputdev: input_unregister_device(input_dev); err_remove_attr: sysfs_remove_group(&bus->dev.kobj, &adxl34x_attr_group); err_free_gpio: if (bus->irq >= 0) gpio_free(irq_to_gpio(bus->irq)); err_clear_inputdev: input_set_drvdata(input_dev, NULL); err_free_mem: input_free_device(input_dev); return err; }
/* * Initialize the tables for a node. */ static void ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni) { #define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL) #define DOT11RATE(_ix) (rt->info[(_ix)].dot11Rate & IEEE80211_RATE_VAL) #define MCS(_ix) (ni->ni_htrates.rs_rates[_ix] | IEEE80211_RATE_MCS) struct ath_node *an = ATH_NODE(ni); struct sample_node *sn = ATH_NODE_SAMPLE(an); const HAL_RATE_TABLE *rt = sc->sc_currates; int x, y, rix; KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); KASSERT(sc->sc_curmode < IEEE80211_MODE_MAX+2, ("curmode %u", sc->sc_curmode)); sn->sched = mrr_schedules[sc->sc_curmode]; KASSERT(sn->sched != NULL, ("no mrr schedule for mode %u", sc->sc_curmode)); sn->static_rix = -1; ath_rate_update_static_rix(sc, ni); sn->currates = sc->sc_currates; /* * Construct a bitmask of usable rates. This has all * negotiated rates minus those marked by the hal as * to be ignored for doing rate control. */ sn->ratemask = 0; /* MCS rates */ if (ni->ni_flags & IEEE80211_NODE_HT) { for (x = 0; x < ni->ni_htrates.rs_nrates; x++) { rix = sc->sc_rixmap[MCS(x)]; if (rix == 0xff) continue; /* skip rates marked broken by hal */ if (!rt->info[rix].valid) continue; KASSERT(rix < SAMPLE_MAXRATES, ("mcs %u has rix %d", MCS(x), rix)); sn->ratemask |= (uint64_t) 1<<rix; } } /* Legacy rates */ for (x = 0; x < ni->ni_rates.rs_nrates; x++) { rix = sc->sc_rixmap[RATE(x)]; if (rix == 0xff) continue; /* skip rates marked broken by hal */ if (!rt->info[rix].valid) continue; KASSERT(rix < SAMPLE_MAXRATES, ("rate %u has rix %d", RATE(x), rix)); sn->ratemask |= (uint64_t) 1<<rix; } #ifdef IEEE80211_DEBUG if (ieee80211_msg(ni->ni_vap, IEEE80211_MSG_RATECTL)) { uint64_t mask; ieee80211_note(ni->ni_vap, "[%6D] %s: size 1600 rate/tt", ni->ni_macaddr, ":", __func__); for (mask = sn->ratemask, rix = 0; mask != 0; mask >>= 1, rix++) { if ((mask & 1) == 0) continue; printf(" %d %s/%d", dot11rate(rt, rix), dot11rate_label(rt, rix), calc_usecs_unicast_packet(sc, 1600, rix, 0,0, (ni->ni_chw == 40))); } printf("\n"); }
void ath_rate_findrate(struct ath_softc *sc, struct ath_node *an, int shortPreamble, size_t frameLen, u_int8_t *rix0, int *try0, u_int8_t *txrate) { #define DOT11RATE(ix) (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL) #define MCS(ix) (rt->info[ix].dot11Rate | IEEE80211_RATE_MCS) #define RATE(ix) (DOT11RATE(ix) / 2) struct sample_node *sn = ATH_NODE_SAMPLE(an); struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc); struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; const HAL_RATE_TABLE *rt = sc->sc_currates; const int size_bin = size_to_bin(frameLen); int rix, mrr, best_rix, change_rates; unsigned average_tx_time; ath_rate_update_static_rix(sc, &an->an_node); if (sn->currates != sc->sc_currates) { device_printf(sc->sc_dev, "%s: currates != sc_currates!\n", __func__); rix = 0; *try0 = ATH_TXMAXTRY; goto done; } if (sn->static_rix != -1) { rix = sn->static_rix; *try0 = ATH_TXMAXTRY; goto done; } mrr = sc->sc_mrretry; /* XXX check HT protmode too */ if (mrr && (ic->ic_flags & IEEE80211_F_USEPROT && !sc->sc_mrrprot)) mrr = 0; best_rix = pick_best_rate(an, rt, size_bin, !mrr); if (best_rix >= 0) { average_tx_time = sn->stats[size_bin][best_rix].average_tx_time; } else { average_tx_time = 0; } /* * Limit the time measuring the performance of other tx * rates to sample_rate% of the total transmission time. */ if (sn->sample_tt[size_bin] < average_tx_time * (sn->packets_since_sample[size_bin]*ssc->sample_rate/100)) { rix = pick_sample_rate(ssc, an, rt, size_bin); IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, &an->an_node, "att %d sample_tt %d size %u sample rate %d %s current rate %d %s", average_tx_time, sn->sample_tt[size_bin], bin_to_size(size_bin), dot11rate(rt, rix), dot11rate_label(rt, rix), dot11rate(rt, sn->current_rix[size_bin]), dot11rate_label(rt, sn->current_rix[size_bin])); if (rix != sn->current_rix[size_bin]) { sn->current_sample_rix[size_bin] = rix; } else { sn->current_sample_rix[size_bin] = -1; } sn->packets_since_sample[size_bin] = 0; } else { change_rates = 0; if (!sn->packets_sent[size_bin] || best_rix == -1) { /* no packet has been sent successfully yet */ change_rates = 1; if (an->an_node.ni_flags & IEEE80211_NODE_HT) best_rix = ath_rate_pick_seed_rate_ht(sc, an, frameLen); else best_rix = ath_rate_pick_seed_rate_legacy(sc, an, frameLen); } else if (sn->packets_sent[size_bin] < 20) { /* let the bit-rate switch quickly during the first few packets */ IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, &an->an_node, "%s: switching quickly..", __func__); change_rates = 1; } else if (ticks - ssc->min_switch > sn->ticks_since_switch[size_bin]) { /* min_switch seconds have gone by */ IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, &an->an_node, "%s: min_switch %d > ticks_since_switch %d..", __func__, ticks - ssc->min_switch, sn->ticks_since_switch[size_bin]); change_rates = 1; } else if ((! (an->an_node.ni_flags & IEEE80211_NODE_HT)) && (2*average_tx_time < sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time)) { /* the current bit-rate is twice as slow as the best one */ IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, &an->an_node, "%s: 2x att (= %d) < cur_rix att %d", __func__, 2 * average_tx_time, sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time); change_rates = 1; } else if ((an->an_node.ni_flags & IEEE80211_NODE_HT)) { int cur_rix = sn->current_rix[size_bin]; int cur_att = sn->stats[size_bin][cur_rix].average_tx_time; /* * If the node is HT, upgrade it if the MCS rate is * higher and the average tx time is within 20% of * the current rate. It can fail a little. * * This is likely not optimal! */ #if 0 printf("cur rix/att %x/%d, best rix/att %x/%d\n", MCS(cur_rix), cur_att, MCS(best_rix), average_tx_time); #endif if ((MCS(best_rix) > MCS(cur_rix)) && (average_tx_time * 8) <= (cur_att * 10)) { IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, &an->an_node, "%s: HT: best_rix 0x%d > cur_rix 0x%x, average_tx_time %d, cur_att %d", __func__, MCS(best_rix), MCS(cur_rix), average_tx_time, cur_att); change_rates = 1; } } sn->packets_since_sample[size_bin]++; if (change_rates) { if (best_rix != sn->current_rix[size_bin]) { IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, &an->an_node, "%s: size %d switch rate %d (%d/%d) -> %d (%d/%d) after %d packets mrr %d", __func__, bin_to_size(size_bin), RATE(sn->current_rix[size_bin]), sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time, sn->stats[size_bin][sn->current_rix[size_bin]].perfect_tx_time, RATE(best_rix), sn->stats[size_bin][best_rix].average_tx_time, sn->stats[size_bin][best_rix].perfect_tx_time, sn->packets_since_switch[size_bin], mrr); } sn->packets_since_switch[size_bin] = 0; sn->current_rix[size_bin] = best_rix; sn->ticks_since_switch[size_bin] = ticks; /* * Set the visible txrate for this node. */ an->an_node.ni_txrate = (rt->info[best_rix].phy == IEEE80211_T_HT) ? MCS(best_rix) : DOT11RATE(best_rix); } rix = sn->current_rix[size_bin]; sn->packets_since_switch[size_bin]++; } *try0 = mrr ? sn->sched[rix].t0 : ATH_TXMAXTRY; done: /* * This bug totally sucks and should be fixed. * * For now though, let's not panic, so we can start to figure * out how to better reproduce it. */ if (rix < 0 || rix >= rt->rateCount) { printf("%s: ERROR: rix %d out of bounds (rateCount=%d)\n", __func__, rix, rt->rateCount); rix = 0; /* XXX just default for now */ } KASSERT(rix >= 0 && rix < rt->rateCount, ("rix is %d", rix)); *rix0 = rix; *txrate = rt->info[rix].rateCode | (shortPreamble ? rt->info[rix].shortPreamble : 0); sn->packets_sent[size_bin]++; #undef DOT11RATE #undef MCS #undef RATE }
CHAN2G(3, 2422, 0), CHAN2G(4, 2427, 0), CHAN2G(5, 2432, 0), CHAN2G(6, 2437, 0), CHAN2G(7, 2442, 0), CHAN2G(8, 2447, 0), CHAN2G(9, 2452, 0), CHAN2G(10, 2457, 0), CHAN2G(11, 2462, 0), CHAN2G(12, 2467, 0), CHAN2G(13, 2472, 0), CHAN2G(14, 2484, 0), }; static struct ieee80211_rate r92su_ratetable[] = { RATE(10, 0, 0), RATE(20, 1, IEEE80211_RATE_SHORT_PREAMBLE), RATE(55, 2, IEEE80211_RATE_SHORT_PREAMBLE), RATE(110, 3, IEEE80211_RATE_SHORT_PREAMBLE), RATE(60, 4, 0), RATE(90, 5, 0), RATE(120, 6, 0), RATE(180, 7, 0), RATE(240, 8, 0), RATE(360, 9, 0), RATE(480, 10, 0), RATE(540, 11, 0), }; #undef CHAN2G #undef RATE
/* * Initialize the tables for a node. */ static void ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni) { #define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL) struct ieee80211com *ic = &sc->sc_ic; struct ath_node *an = ATH_NODE(ni); struct sample_node *sn = ATH_NODE_SAMPLE(an); const HAL_RATE_TABLE *rt = sc->sc_currates; int x, y, srate; KASSERTMSG(rt != NULL, "no rate table, mode %u", sc->sc_curmode); sn->static_rate_ndx = -1; if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) { /* * A fixed rate is to be used; ic_fixed_rate is an * index into the supported rate set. Convert this * to the index into the negotiated rate set for * the node. We know the rate is there because the * rate set is checked when the station associates. */ const struct ieee80211_rateset *rs = &ic->ic_sup_rates[ic->ic_curmode]; int r = rs->rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL; /* NB: the rate set is assumed sorted */ srate = ni->ni_rates.rs_nrates - 1; for (; srate >= 0 && RATE(srate) != r; srate--) ; KASSERTMSG(srate >= 0, "fixed rate %d not in rate set", ic->ic_fixed_rate); sn->static_rate_ndx = srate; } DPRINTF(sc, "%s: %s size 1600 rate/tt", __func__, ether_sprintf(ni->ni_macaddr)); sn->num_rates = ni->ni_rates.rs_nrates; for (x = 0; x < ni->ni_rates.rs_nrates; x++) { sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL; sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate]; sn->rates[x].rateCode = rt->info[sn->rates[x].rix].rateCode; sn->rates[x].shortPreambleRateCode = rt->info[sn->rates[x].rix].rateCode | rt->info[sn->rates[x].rix].shortPreamble; DPRINTF(sc, " %d/%d", sn->rates[x].rate, calc_usecs_unicast_packet(sc, 1600, sn->rates[x].rix, 0,0)); } DPRINTF(sc, "%s\n", ""); /* set the visible bit-rate to the lowest one available */ ni->ni_txrate = 0; sn->num_rates = ni->ni_rates.rs_nrates; for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) { int size = bin_to_size(y); int ndx = 0; sn->packets_sent[y] = 0; sn->current_sample_ndx[y] = -1; sn->last_sample_ndx[y] = 0; for (x = 0; x < ni->ni_rates.rs_nrates; x++) { sn->stats[y][x].successive_failures = 0; sn->stats[y][x].tries = 0; sn->stats[y][x].total_packets = 0; sn->stats[y][x].packets_acked = 0; sn->stats[y][x].last_tx = 0; sn->stats[y][x].perfect_tx_time = calc_usecs_unicast_packet(sc, size, sn->rates[x].rix, 0, 0); sn->stats[y][x].average_tx_time = sn->stats[y][x].perfect_tx_time; } /* set the initial rate */ for (ndx = sn->num_rates-1; ndx > 0; ndx--) { if (sn->rates[ndx].rate <= 72) { break; } } sn->current_rate[y] = ndx; } DPRINTF(sc, "%s: %s %d rates %d%sMbps (%dus)- %d%sMbps (%dus)\n", __func__, ether_sprintf(ni->ni_macaddr), sn->num_rates, sn->rates[0].rate/2, sn->rates[0].rate % 0x1 ? ".5" : "", sn->stats[1][0].perfect_tx_time, sn->rates[sn->num_rates-1].rate/2, sn->rates[sn->num_rates-1].rate % 0x1 ? ".5" : "", sn->stats[1][sn->num_rates-1].perfect_tx_time ); ni->ni_txrate = sn->current_rate[0]; #undef RATE }
//============================================================================= // spc_UpdateSpeechEnc() //----------------------------------------------------------------------------- /// This function updates speech variables for Tx //============================================================================= PRIVATE VOID spc_UpdateSpeechEnc(UINT32 **InputBuffer, UINT16 *CodecModeInd, UINT8 *TxFrameType) { UINT8 T2=g_mailbox.pal2spc.counters[g_spcCtx->currentSnap].T2;; UINT8 voc_sp=1; SPC_PROFILE_FUNCTION_ENTER(spc_UpdateSpeechEnc); // get info form the current encoding structure *CodecModeInd=spc_MboxToSppSpeechMode(g_spcCtx->speechEncOut.encMode); *TxFrameType=g_spcCtx->speechEncOut.encFrameType; voc_sp=g_spcCtx->speechEncOut.sp; *InputBuffer = (UINT32*) &(g_spcCtx->speechEncOut.encOutBuf[0]); // FIXME test if it works if (SPEECH(g_spcCtx->ChMode)==AMR_CODEC) { if (*CodecModeInd>SPP_MR122_MODE) { // if previous mode was not AMR *CodecModeInd = SPP_INVALID_MODE; } else if (*CodecModeInd!=g_spcCtx->TxCodecMode) { // force the codec mode asuming one step in // activ codec set will not be detectable // but only on CMI frames if((T2==0)||(T2==8)||(T2==17)||(T2==1)||(T2==9)||(T2==18)) { *CodecModeInd = g_spcCtx->TxCodecMode; } } } else { if (*CodecModeInd!=g_spcCtx->TxCodecMode) { *CodecModeInd = g_spcCtx->TxCodecMode;//SPP_INVALID_MODE; } } if (*CodecModeInd==SPP_INVALID_MODE) { *CodecModeInd=g_spcCtx->TxCodecMode; *TxFrameType=SPP_TX_SID_UPDATE; *InputBuffer=(UINT32*) g_spcCtx->SilentFrame; } //----------------------------- DTX ------------------------------- if ((voc_sp == 0) && (SPEECH(g_spcCtx->ChMode)!=AMR_CODEC)) { if(RATE(g_spcCtx->ChMode) == FR_RATE) { if ((g_spcCtx->DTX_on==2)&&(g_spcCtx->voc_dtx_en==1)&& (g_spcCtx->FacchEncoded==0)&&(g_spcCtx->Taf_Flag==0)) { g_spcCtx->Tx_off = TRUE; } if(g_spcCtx->DTX_on<2) { g_spcCtx->DTX_on += 1; } // test if aligned with SACCH if (g_spcCtx->AFNmod104==52) { g_spcCtx->Tx_off = FALSE; g_spcCtx->Taf_Flag = 2; } } else { if ((g_spcCtx->DTX_on)&&(g_spcCtx->voc_dtx_en==1)&& (g_spcCtx->FacchEncoded==0)&&(g_spcCtx->Taf_Flag==0)) { g_spcCtx->Tx_off = TRUE; } g_spcCtx->DTX_on = 1; // test if aligned with SACCH if (SUBCHANNEL(g_spcCtx->ChMode) == 0) { if ((g_spcCtx->AFNmod104==0)||(g_spcCtx->AFNmod104==52)) { g_spcCtx->Tx_off = FALSE; g_spcCtx->Taf_Flag = 2; } } else { if ((g_spcCtx->AFNmod104==14)||(g_spcCtx->AFNmod104==66)) { g_spcCtx->Tx_off = FALSE; g_spcCtx->Taf_Flag = 2; } } } } else { g_spcCtx->DTX_on = 0; g_spcCtx->Tx_off = FALSE; } //----------------------------- DTX ------------------------------- SPC_PROFILE_FUNCTION_EXIT(spc_UpdateSpeechEnc); }
CHAN5G(5825, 37), /* Channel 165 */ }; /* Atheros hardware rate code addition for short premble */ #define SHPCHECK(__hw_rate, __flags) \ ((__flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0) #define RATE(_bitrate, _hw_rate, _flags) { \ .bitrate = (_bitrate), \ .flags = (_flags), \ .hw_value = (_hw_rate), \ .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \ } static struct ath9k_legacy_rate ath9k_legacy_rates[] = { RATE(10, 0x1b, 0), RATE(20, 0x1a, IEEE80211_TX_RC_USE_SHORT_PREAMBLE), RATE(55, 0x19, IEEE80211_TX_RC_USE_SHORT_PREAMBLE), RATE(110, 0x18, IEEE80211_TX_RC_USE_SHORT_PREAMBLE), RATE(60, 0x0b, 0), RATE(90, 0x0f, 0), RATE(120, 0x0a, 0), RATE(180, 0x0e, 0), RATE(240, 0x09, 0), RATE(360, 0x0d, 0), RATE(480, 0x08, 0), RATE(540, 0x0c, 0), }; static void ath9k_deinit_softc(struct ath_softc *sc);
CHAN5G(5745, 149), CHAN5G(5765, 153), CHAN5G(5785, 157), CHAN5G(5805, 161), CHAN5G(5825, 165) }; #define RATE(_bitrate, _hw_rate, _flags) { \ .bitrate = (_bitrate), \ .flags = (_flags), \ .hw_value = (_hw_rate), \ .hw_value_short = (_hw_rate) \ } static struct ieee80211_rate wcn_2ghz_rates[] = { RATE(10, 0x02, 0), RATE(20, 0x04, IEEE80211_RATE_SHORT_PREAMBLE), RATE(55, 0x0B, IEEE80211_RATE_SHORT_PREAMBLE), RATE(110, 0x16, IEEE80211_RATE_SHORT_PREAMBLE), RATE(60, 0x0C, 0), RATE(90, 0x12, 0), RATE(120, 0x18, 0), RATE(180, 0x24, 0), RATE(240, 0x30, 0), RATE(360, 0x48, 0), RATE(480, 0x60, 0), RATE(540, 0x6C, 0) }; static struct ieee80211_rate wcn_5ghz_rates[] = { RATE(60, 0x0C, 0),
/* * Initialize the tables for a node. */ static void ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni) { #define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL) #define DOT11RATE(_ix) (rt->info[(_ix)].dot11Rate & IEEE80211_RATE_VAL) struct ath_node *an = ATH_NODE(ni); const struct ieee80211_txparam *tp = ni->ni_txparms; struct sample_node *sn = ATH_NODE_SAMPLE(an); const HAL_RATE_TABLE *rt = sc->sc_currates; int x, y, srate, rix; KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); KASSERT(sc->sc_curmode < IEEE80211_MODE_MAX+2, ("curmode %u", sc->sc_curmode)); sn->sched = mrr_schedules[sc->sc_curmode]; KASSERT(sn->sched != NULL, ("no mrr schedule for mode %u", sc->sc_curmode)); sn->static_rix = -1; if (tp != NULL && tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { /* * A fixed rate is to be used; ucastrate is the IEEE code * for this rate (sans basic bit). Check this against the * negotiated rate set for the node. Note the fixed rate * may not be available for various reasons so we only * setup the static rate index if the lookup is successful. * XXX handle MCS */ for (srate = ni->ni_rates.rs_nrates - 1; srate >= 0; srate--) if (RATE(srate) == tp->ucastrate) { sn->static_rix = sc->sc_rixmap[tp->ucastrate]; break; } #ifdef IEEE80211_DEBUG if (sn->static_rix == -1) { IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, "%s: ucastrate %u not found, nrates %u", __func__, tp->ucastrate, ni->ni_rates.rs_nrates); } #endif } /* * Construct a bitmask of usable rates. This has all * negotiated rates minus those marked by the hal as * to be ignored for doing rate control. */ sn->ratemask = 0; for (x = 0; x < ni->ni_rates.rs_nrates; x++) { rix = sc->sc_rixmap[RATE(x)]; if (rix == 0xff) continue; /* skip rates marked broken by hal */ if (!rt->info[rix].valid) continue; KASSERT(rix < SAMPLE_MAXRATES, ("rate %u has rix %d", RATE(x), rix)); sn->ratemask |= 1<<rix; } #ifdef IEEE80211_DEBUG if (ieee80211_msg(ni->ni_vap, IEEE80211_MSG_RATECTL)) { uint32_t mask; ieee80211_note(ni->ni_vap, "[%6D] %s: size 1600 rate/tt", ni->ni_macaddr, ":", __func__); for (mask = sn->ratemask, rix = 0; mask != 0; mask >>= 1, rix++) { if ((mask & 1) == 0) continue; printf(" %d/%d", DOT11RATE(rix) / 2, calc_usecs_unicast_packet(sc, 1600, rix, 0,0)); } printf("\n"); }
void ath_rate_findrate(struct ath_softc *sc, struct ath_node *an, int shortPreamble, size_t frameLen, u_int8_t *rix0, int *try0, u_int8_t *txrate) { #define DOT11RATE(ix) (rt->info[ix].dot11Rate & IEEE80211_RATE_VAL) #define RATE(ix) (DOT11RATE(ix) / 2) struct sample_node *sn = ATH_NODE_SAMPLE(an); struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc); struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; const HAL_RATE_TABLE *rt = sc->sc_currates; const int size_bin = size_to_bin(frameLen); int rix, mrr, best_rix, change_rates; unsigned average_tx_time; if (sn->static_rix != -1) { rix = sn->static_rix; *try0 = ATH_TXMAXTRY; goto done; } mrr = sc->sc_mrretry && !(ic->ic_flags & IEEE80211_F_USEPROT); best_rix = pick_best_rate(sn, rt, size_bin, !mrr); if (best_rix >= 0) { average_tx_time = sn->stats[size_bin][best_rix].average_tx_time; } else { average_tx_time = 0; } /* * Limit the time measuring the performance of other tx * rates to sample_rate% of the total transmission time. */ if (sn->sample_tt[size_bin] < average_tx_time * (sn->packets_since_sample[size_bin]*ssc->sample_rate/100)) { rix = pick_sample_rate(ssc, sn, rt, size_bin); IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, &an->an_node, "size %u sample rate %d current rate %d", bin_to_size(size_bin), RATE(rix), RATE(sn->current_rix[size_bin])); if (rix != sn->current_rix[size_bin]) { sn->current_sample_rix[size_bin] = rix; } else { sn->current_sample_rix[size_bin] = -1; } sn->packets_since_sample[size_bin] = 0; } else { change_rates = 0; if (!sn->packets_sent[size_bin] || best_rix == -1) { /* no packet has been sent successfully yet */ for (rix = rt->rateCount-1; rix > 0; rix--) { if ((sn->ratemask & (1<<rix)) == 0) continue; /* * Pick the highest rate <= 36 Mbps * that hasn't failed. */ if (DOT11RATE(rix) <= 72 && sn->stats[size_bin][rix].successive_failures == 0) { break; } } change_rates = 1; best_rix = rix; } else if (sn->packets_sent[size_bin] < 20) { /* let the bit-rate switch quickly during the first few packets */ change_rates = 1; } else if (ticks - ssc->min_switch > sn->ticks_since_switch[size_bin]) { /* min_switch seconds have gone by */ change_rates = 1; } else if (2*average_tx_time < sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time) { /* the current bit-rate is twice as slow as the best one */ change_rates = 1; } sn->packets_since_sample[size_bin]++; if (change_rates) { if (best_rix != sn->current_rix[size_bin]) { IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, &an->an_node, "%s: size %d switch rate %d (%d/%d) -> %d (%d/%d) after %d packets mrr %d", __func__, bin_to_size(size_bin), RATE(sn->current_rix[size_bin]), sn->stats[size_bin][sn->current_rix[size_bin]].average_tx_time, sn->stats[size_bin][sn->current_rix[size_bin]].perfect_tx_time, RATE(best_rix), sn->stats[size_bin][best_rix].average_tx_time, sn->stats[size_bin][best_rix].perfect_tx_time, sn->packets_since_switch[size_bin], mrr); } sn->packets_since_switch[size_bin] = 0; sn->current_rix[size_bin] = best_rix; sn->ticks_since_switch[size_bin] = ticks; /* * Set the visible txrate for this node. */ an->an_node.ni_txrate = DOT11RATE(best_rix); } rix = sn->current_rix[size_bin]; sn->packets_since_switch[size_bin]++; } *try0 = mrr ? sn->sched[rix].t0 : ATH_TXMAXTRY; done: KASSERT(rix >= 0 && rix < rt->rateCount, ("rix is %d", rix)); *rix0 = rix; *txrate = rt->info[rix].rateCode | (shortPreamble ? rt->info[rix].shortPreamble : 0); sn->packets_sent[size_bin]++; #undef DOT11RATE #undef RATE }