void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev) { struct link *link = &rt2x00dev->link; /* * Link tuning should only be performed when * an active sta interface exists. AP interfaces * don't need link tuning and monitor mode interfaces * should never have to work with link tuners. */ if (!rt2x00dev->intf_sta_count) return; /** * While scanning, link tuning is disabled. By default * the most sensitive settings will be used to make sure * that all beacons and probe responses will be received * during the scan. */ if (test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags)) return; rt2x00link_reset_tuner(rt2x00dev, false); if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) ieee80211_queue_delayed_work(rt2x00dev->hw, &link->work, LINK_TUNE_INTERVAL); }
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, struct antenna_setup config) { struct link_ant *ant = &rt2x00dev->link.ant; struct antenna_setup *def = &rt2x00dev->default_ant; struct antenna_setup *active = &rt2x00dev->link.ant.active; /* * When the caller tries to send the SW diversity, * we must update the ANTENNA_RX_DIVERSITY flag to * enable the antenna diversity in the link tuner. * * Secondly, we must guarentee we never send the * software antenna diversity command to the driver. */ if (!(ant->flags & ANTENNA_RX_DIVERSITY)) { if (config.rx == ANTENNA_SW_DIVERSITY) { ant->flags |= ANTENNA_RX_DIVERSITY; if (def->rx == ANTENNA_SW_DIVERSITY) config.rx = ANTENNA_B; else config.rx = def->rx; } } else if (config.rx == ANTENNA_SW_DIVERSITY) config.rx = active->rx; if (!(ant->flags & ANTENNA_TX_DIVERSITY)) { if (config.tx == ANTENNA_SW_DIVERSITY) { ant->flags |= ANTENNA_TX_DIVERSITY; if (def->tx == ANTENNA_SW_DIVERSITY) config.tx = ANTENNA_B; else config.tx = def->tx; } } else if (config.tx == ANTENNA_SW_DIVERSITY) config.tx = active->tx; /* * Antenna setup changes require the RX to be disabled, * else the changes will be ignored by the device. */ if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt2x00queue_stop_queue(rt2x00dev->rx); /* * Write new antenna setup to device and reset the link tuner. * The latter is required since we need to recalibrate the * noise-sensitivity ratio for the new setup. */ rt2x00dev->ops->lib->config_ant(rt2x00dev, &config); rt2x00link_reset_tuner(rt2x00dev, true); memcpy(active, &config, sizeof(config)); if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt2x00queue_start_queue(rt2x00dev->rx); }
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, struct antenna_setup config) { struct link_ant *ant = &rt2x00dev->link.ant; struct antenna_setup *def = &rt2x00dev->default_ant; struct antenna_setup *active = &rt2x00dev->link.ant.active; /* * Failsafe: Make sure we are not sending the * ANTENNA_SW_DIVERSITY state to the driver. * If that happens, fallback to hardware defaults, * or our own default. * If diversity handling is active for a particular antenna, * we shouldn't overwrite that antenna. * The calls to rt2x00lib_config_antenna_check() * might have caused that we restore back to the already * active setting. If that has happened we can quit. */ if (!(ant->flags & ANTENNA_RX_DIVERSITY)) config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx); else config.rx = active->rx; if (!(ant->flags & ANTENNA_TX_DIVERSITY)) config.tx = rt2x00lib_config_antenna_check(config.tx, def->tx); else config.tx = active->tx; if (config.rx == active->rx && config.tx == active->tx) return; /* * Antenna setup changes require the RX to be disabled, * else the changes will be ignored by the device. */ if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF_LINK); /* * Write new antenna setup to device and reset the link tuner. * The latter is required since we need to recalibrate the * noise-sensitivity ratio for the new setup. */ rt2x00dev->ops->lib->config_ant(rt2x00dev, &config); rt2x00link_reset_tuner(rt2x00dev, true); memcpy(active, &config, sizeof(config)); if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); }
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf, unsigned int ieee80211_flags) { struct rt2x00lib_conf libconf; u16 hw_value; memset(&libconf, 0, sizeof(libconf)); libconf.conf = conf; if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) { if (conf_is_ht40(conf)) { __set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); hw_value = rt2x00ht_center_channel(rt2x00dev, conf); } else { __clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); hw_value = conf->channel->hw_value; } memcpy(&libconf.rf, &rt2x00dev->spec.channels[hw_value], sizeof(libconf.rf)); memcpy(&libconf.channel, &rt2x00dev->spec.channels_info[hw_value], sizeof(libconf.channel)); } /* * Start configuration. */ rt2x00dev->ops->lib->config(rt2x00dev, &libconf, ieee80211_flags); /* * Some configuration changes affect the link quality * which means we need to reset the link tuner. */ if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) rt2x00link_reset_tuner(rt2x00dev, false); rt2x00dev->curr_band = conf->channel->band; rt2x00dev->curr_freq = conf->channel->center_freq; rt2x00dev->tx_power = conf->power_level; rt2x00dev->short_retry = conf->short_frame_max_tx_count; rt2x00dev->long_retry = conf->long_frame_max_tx_count; }
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, struct antenna_setup config) { struct link_ant *ant = &rt2x00dev->link.ant; struct antenna_setup *def = &rt2x00dev->default_ant; struct antenna_setup *active = &rt2x00dev->link.ant.active; /* * Failsafe: Make sure we are not sending the * ANTENNA_SW_DIVERSITY state to the driver. * If that happens, fallback to hardware defaults, * or our own default. */ if (!(ant->flags & ANTENNA_RX_DIVERSITY)) config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx); else if (config.rx == ANTENNA_SW_DIVERSITY) config.rx = active->rx; if (!(ant->flags & ANTENNA_TX_DIVERSITY)) config.tx = rt2x00lib_config_antenna_check(config.tx, def->tx); else if (config.tx == ANTENNA_SW_DIVERSITY) config.tx = active->tx; /* * Antenna setup changes require the RX to be disabled, * else the changes will be ignored by the device. */ if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt2x00queue_stop_queue(rt2x00dev->rx); /* * Write new antenna setup to device and reset the link tuner. * The latter is required since we need to recalibrate the * noise-sensitivity ratio for the new setup. */ rt2x00dev->ops->lib->config_ant(rt2x00dev, &config); rt2x00link_reset_tuner(rt2x00dev, true); memcpy(active, &config, sizeof(config)); if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt2x00queue_start_queue(rt2x00dev->rx); }
void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev) { struct link *link = &rt2x00dev->link; /* * Link tuning should only be performed when * an active sta or master interface exists. * Single monitor mode interfaces should never have * work with link tuners. */ if (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count) return; rt2x00link_reset_tuner(rt2x00dev, false); if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) ieee80211_queue_delayed_work(rt2x00dev->hw, &link->work, LINK_TUNE_INTERVAL); }
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, struct antenna_setup config) { struct link_ant *ant = &rt2x00dev->link.ant; struct antenna_setup *def = &rt2x00dev->default_ant; struct antenna_setup *active = &rt2x00dev->link.ant.active; if (!(ant->flags & ANTENNA_RX_DIVERSITY)) { if (config.rx == ANTENNA_SW_DIVERSITY) { ant->flags |= ANTENNA_RX_DIVERSITY; if (def->rx == ANTENNA_SW_DIVERSITY) config.rx = ANTENNA_B; else config.rx = def->rx; } } else if (config.rx == ANTENNA_SW_DIVERSITY) config.rx = active->rx; if (!(ant->flags & ANTENNA_TX_DIVERSITY)) { if (config.tx == ANTENNA_SW_DIVERSITY) { ant->flags |= ANTENNA_TX_DIVERSITY; if (def->tx == ANTENNA_SW_DIVERSITY) config.tx = ANTENNA_B; else config.tx = def->tx; } } else if (config.tx == ANTENNA_SW_DIVERSITY) config.tx = active->tx; if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt2x00queue_stop_queue(rt2x00dev->rx); rt2x00dev->ops->lib->config_ant(rt2x00dev, &config); rt2x00link_reset_tuner(rt2x00dev, true); memcpy(active, &config, sizeof(config)); if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) rt2x00queue_start_queue(rt2x00dev->rx); }
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf, unsigned int ieee80211_flags) { struct rt2x00lib_conf libconf; u16 hw_value; u16 autowake_timeout; u16 beacon_int; u16 beacon_diff; memset(&libconf, 0, sizeof(libconf)); libconf.conf = conf; if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) { if (conf_is_ht40(conf)) { set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); hw_value = rt2x00ht_center_channel(rt2x00dev, conf); } else { clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); hw_value = conf->channel->hw_value; } memcpy(&libconf.rf, &rt2x00dev->spec.channels[hw_value], sizeof(libconf.rf)); memcpy(&libconf.channel, &rt2x00dev->spec.channels_info[hw_value], sizeof(libconf.channel)); } if (test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) && (ieee80211_flags & IEEE80211_CONF_CHANGE_PS)) cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); /* * Start configuration. */ rt2x00dev->ops->lib->config(rt2x00dev, &libconf, ieee80211_flags); /* * Some configuration changes affect the link quality * which means we need to reset the link tuner. */ if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) rt2x00link_reset_tuner(rt2x00dev, false); if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) && (ieee80211_flags & IEEE80211_CONF_CHANGE_PS) && (conf->flags & IEEE80211_CONF_PS)) { beacon_diff = (long)jiffies - (long)rt2x00dev->last_beacon; beacon_int = msecs_to_jiffies(rt2x00dev->beacon_int); if (beacon_diff > beacon_int) beacon_diff = 0; autowake_timeout = (conf->max_sleep_period * beacon_int) - beacon_diff; ieee80211_queue_delayed_work(rt2x00dev->hw, &rt2x00dev->autowakeup_work, autowake_timeout - 15); } if (conf->flags & IEEE80211_CONF_PS) set_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); else clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); rt2x00dev->curr_band = conf->channel->band; rt2x00dev->curr_freq = conf->channel->center_freq; rt2x00dev->tx_power = conf->power_level; rt2x00dev->short_retry = conf->short_frame_max_tx_count; rt2x00dev->long_retry = conf->long_frame_max_tx_count; }