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); }
static void rt2x00usb_watchdog_tx_dma(struct data_queue *queue) { rt2x00_warn(queue->rt2x00dev, "TX queue %d DMA timed out, invoke forced forced reset\n", queue->qid); rt2x00queue_stop_queue(queue); rt2x00queue_flush_queue(queue, true); rt2x00queue_start_queue(queue); }
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 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); }
int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed) { struct rt2x00_dev *rt2x00dev = hw->priv; struct ieee80211_conf *conf = &hw->conf; /* * mac80211 might be calling this function while we are trying * to remove the device or perhaps suspending it. */ if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) return 0; /* * Some configuration parameters (e.g. channel and antenna values) can * only be set when the radio is enabled, but do require the RX to * be off. During this period we should keep link tuning enabled, * if for any reason the link tuner must be reset, this will be * handled by rt2x00lib_config(). */ rt2x00queue_stop_queue(rt2x00dev->rx); /* * When we've just turned on the radio, we want to reprogram * everything to ensure a consistent state */ rt2x00lib_config(rt2x00dev, conf, changed); /* * After the radio has been enabled we need to configure * the antenna to the default settings. rt2x00lib_config_antenna() * should determine if any action should be taken based on * checking if diversity has been enabled or no antenna changes * have been made since the last configuration change. */ rt2x00lib_config_antenna(rt2x00dev, rt2x00dev->default_ant); /* Turn RX back on */ rt2x00queue_start_queue(rt2x00dev->rx); return 0; }
void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, u32 changes) { struct rt2x00_dev *rt2x00dev = hw->priv; struct rt2x00_intf *intf = vif_to_intf(vif); /* * mac80211 might be calling this function while we are trying * to remove the device or perhaps suspending it. */ if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) return; /* * Update the BSSID. */ if (changes & BSS_CHANGED_BSSID) rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL, bss_conf->bssid); /* * Start/stop beaconing. */ if (changes & BSS_CHANGED_BEACON_ENABLED) { if (!bss_conf->enable_beacon && intf->enable_beacon) { rt2x00dev->intf_beaconing--; intf->enable_beacon = false; /* * Clear beacon in the H/W for this vif. This is needed * to disable beaconing on this particular interface * and keep it running on other interfaces. */ rt2x00queue_clear_beacon(rt2x00dev, vif); if (rt2x00dev->intf_beaconing == 0) { /* * Last beaconing interface disabled * -> stop beacon queue. */ mutex_lock(&intf->beacon_skb_mutex); rt2x00queue_stop_queue(rt2x00dev->bcn); mutex_unlock(&intf->beacon_skb_mutex); } } else if (bss_conf->enable_beacon && !intf->enable_beacon) { rt2x00dev->intf_beaconing++; intf->enable_beacon = true; /* * Upload beacon to the H/W. This is only required on * USB devices. PCI devices fetch beacons periodically. */ if (rt2x00_is_usb(rt2x00dev)) rt2x00queue_update_beacon(rt2x00dev, vif); if (rt2x00dev->intf_beaconing == 1) { /* * First beaconing interface enabled * -> start beacon queue. */ mutex_lock(&intf->beacon_skb_mutex); rt2x00queue_start_queue(rt2x00dev->bcn); mutex_unlock(&intf->beacon_skb_mutex); } } } /* * When the association status has changed we must reset the link * tuner counter. This is because some drivers determine if they * should perform link tuning based on the number of seconds * while associated or not associated. */ if (changes & BSS_CHANGED_ASSOC) { rt2x00dev->link.count = 0; if (bss_conf->assoc) rt2x00dev->intf_associated++; else rt2x00dev->intf_associated--; rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated); clear_bit(CONFIG_QOS_DISABLED, &rt2x00dev->flags); } /* * Check for access point which do not support 802.11e . We have to * generate data frames sequence number in S/W for such AP, because * of H/W bug. */ if (changes & BSS_CHANGED_QOS && !bss_conf->qos) set_bit(CONFIG_QOS_DISABLED, &rt2x00dev->flags); /* * When the erp information has changed, we should perform * additional configuration steps. For all other changes we are done. */ if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE | BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BASIC_RATES | BSS_CHANGED_BEACON_INT | BSS_CHANGED_HT)) rt2x00lib_config_erp(rt2x00dev, intf, bss_conf, changes); }