mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-30 12:06:41 +07:00
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
John W. Linville says: ==================== Please pull this batch of fixes intended for the 3.14 stream! For the mac80211 bits, Johannes says: "This is just a collection of small fixes, the commit logs explain the details. The only thing that isn't strictly a fix is the 5/10 MHz enabling, I had forgotten this and there's little point in waiting longer. The patch simply removes the force-disable code that I put in when there was a problem with the userspace API (that has long been fixed.)" For the iwlwifi bits, Emmanuel says: "I have an important fix that disables A band in case the driver thought it was enabled, and the firmware disagreed. We ended up making the firmware unhappy. I also fix the station table in AP mode and fix the scan while we have BT working. Johannes removes a static variable that could potentially lead to to issues on multi-device setups and disables scheduled scan to avoid issues with old versions of wpa_supplicant. A small fix from David on scan and a few new device IDs for 7265." On top of that... Oleksij Rempel adds a USB ID to the ar5523 driver and changes the default powersave setting for ath9k_htc to "off", due to observed stability issues (based on an equivalent ath9k patch). Stanislaw Gruszka similarly disables powersave for a couple of rt2x00 drivers. He also fixes a couple of scheduling while atomic issues in ath9k_htc. Sujith Manoharan rounds-out the powersave disables with one for ath9k. He also fixes a build prolem with ath9k on ARM and fixes an ath9k Tx power calculation. Finally, Andrea Merello fixes a couple of lingering DMA mapping problems in the rtl8180 driver. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
872c7e6fd2
@ -1764,7 +1764,7 @@ static struct usb_device_id ar5523_id_table[] = {
|
|||||||
AR5523_DEVICE_UG(0x07d1, 0x3a07), /* D-Link / WUA-2340 rev A1 */
|
AR5523_DEVICE_UG(0x07d1, 0x3a07), /* D-Link / WUA-2340 rev A1 */
|
||||||
AR5523_DEVICE_UG(0x1690, 0x0712), /* Gigaset / AR5523 */
|
AR5523_DEVICE_UG(0x1690, 0x0712), /* Gigaset / AR5523 */
|
||||||
AR5523_DEVICE_UG(0x1690, 0x0710), /* Gigaset / SMCWUSBTG */
|
AR5523_DEVICE_UG(0x1690, 0x0710), /* Gigaset / SMCWUSBTG */
|
||||||
AR5523_DEVICE_UG(0x129b, 0x160c), /* Gigaset / USB stick 108
|
AR5523_DEVICE_UG(0x129b, 0x160b), /* Gigaset / USB stick 108
|
||||||
(CyberTAN Technology) */
|
(CyberTAN Technology) */
|
||||||
AR5523_DEVICE_UG(0x16ab, 0x7801), /* Globalsun / AR5523_1 */
|
AR5523_DEVICE_UG(0x16ab, 0x7801), /* Globalsun / AR5523_1 */
|
||||||
AR5523_DEVICE_UX(0x16ab, 0x7811), /* Globalsun / AR5523_2 */
|
AR5523_DEVICE_UX(0x16ab, 0x7811), /* Globalsun / AR5523_2 */
|
||||||
|
@ -5065,6 +5065,10 @@ static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is2GHz && !twiceMaxEdgePower)
|
||||||
|
twiceMaxEdgePower = 60;
|
||||||
|
|
||||||
return twiceMaxEdgePower;
|
return twiceMaxEdgePower;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,6 +262,8 @@ enum tid_aggr_state {
|
|||||||
struct ath9k_htc_sta {
|
struct ath9k_htc_sta {
|
||||||
u8 index;
|
u8 index;
|
||||||
enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID];
|
enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID];
|
||||||
|
struct work_struct rc_update_work;
|
||||||
|
struct ath9k_htc_priv *htc_priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ATH9K_HTC_RXBUF 256
|
#define ATH9K_HTC_RXBUF 256
|
||||||
|
@ -34,6 +34,10 @@ static int ath9k_htc_btcoex_enable;
|
|||||||
module_param_named(btcoex_enable, ath9k_htc_btcoex_enable, int, 0444);
|
module_param_named(btcoex_enable, ath9k_htc_btcoex_enable, int, 0444);
|
||||||
MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
|
MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
|
||||||
|
|
||||||
|
static int ath9k_ps_enable;
|
||||||
|
module_param_named(ps_enable, ath9k_ps_enable, int, 0444);
|
||||||
|
MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave");
|
||||||
|
|
||||||
#define CHAN2G(_freq, _idx) { \
|
#define CHAN2G(_freq, _idx) { \
|
||||||
.center_freq = (_freq), \
|
.center_freq = (_freq), \
|
||||||
.hw_value = (_idx), \
|
.hw_value = (_idx), \
|
||||||
@ -725,12 +729,14 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
|
|||||||
IEEE80211_HW_SPECTRUM_MGMT |
|
IEEE80211_HW_SPECTRUM_MGMT |
|
||||||
IEEE80211_HW_HAS_RATE_CONTROL |
|
IEEE80211_HW_HAS_RATE_CONTROL |
|
||||||
IEEE80211_HW_RX_INCLUDES_FCS |
|
IEEE80211_HW_RX_INCLUDES_FCS |
|
||||||
IEEE80211_HW_SUPPORTS_PS |
|
|
||||||
IEEE80211_HW_PS_NULLFUNC_STACK |
|
IEEE80211_HW_PS_NULLFUNC_STACK |
|
||||||
IEEE80211_HW_REPORTS_TX_ACK_STATUS |
|
IEEE80211_HW_REPORTS_TX_ACK_STATUS |
|
||||||
IEEE80211_HW_MFP_CAPABLE |
|
IEEE80211_HW_MFP_CAPABLE |
|
||||||
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
|
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
|
||||||
|
|
||||||
|
if (ath9k_ps_enable)
|
||||||
|
hw->flags |= IEEE80211_HW_SUPPORTS_PS;
|
||||||
|
|
||||||
hw->wiphy->interface_modes =
|
hw->wiphy->interface_modes =
|
||||||
BIT(NL80211_IFTYPE_STATION) |
|
BIT(NL80211_IFTYPE_STATION) |
|
||||||
BIT(NL80211_IFTYPE_ADHOC) |
|
BIT(NL80211_IFTYPE_ADHOC) |
|
||||||
|
@ -1270,18 +1270,50 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw,
|
|||||||
mutex_unlock(&priv->mutex);
|
mutex_unlock(&priv->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ath9k_htc_sta_rc_update_work(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct ath9k_htc_sta *ista =
|
||||||
|
container_of(work, struct ath9k_htc_sta, rc_update_work);
|
||||||
|
struct ieee80211_sta *sta =
|
||||||
|
container_of((void *)ista, struct ieee80211_sta, drv_priv);
|
||||||
|
struct ath9k_htc_priv *priv = ista->htc_priv;
|
||||||
|
struct ath_common *common = ath9k_hw_common(priv->ah);
|
||||||
|
struct ath9k_htc_target_rate trate;
|
||||||
|
|
||||||
|
mutex_lock(&priv->mutex);
|
||||||
|
ath9k_htc_ps_wakeup(priv);
|
||||||
|
|
||||||
|
memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
|
||||||
|
ath9k_htc_setup_rate(priv, sta, &trate);
|
||||||
|
if (!ath9k_htc_send_rate_cmd(priv, &trate))
|
||||||
|
ath_dbg(common, CONFIG,
|
||||||
|
"Supported rates for sta: %pM updated, rate caps: 0x%X\n",
|
||||||
|
sta->addr, be32_to_cpu(trate.capflags));
|
||||||
|
else
|
||||||
|
ath_dbg(common, CONFIG,
|
||||||
|
"Unable to update supported rates for sta: %pM\n",
|
||||||
|
sta->addr);
|
||||||
|
|
||||||
|
ath9k_htc_ps_restore(priv);
|
||||||
|
mutex_unlock(&priv->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
static int ath9k_htc_sta_add(struct ieee80211_hw *hw,
|
static int ath9k_htc_sta_add(struct ieee80211_hw *hw,
|
||||||
struct ieee80211_vif *vif,
|
struct ieee80211_vif *vif,
|
||||||
struct ieee80211_sta *sta)
|
struct ieee80211_sta *sta)
|
||||||
{
|
{
|
||||||
struct ath9k_htc_priv *priv = hw->priv;
|
struct ath9k_htc_priv *priv = hw->priv;
|
||||||
|
struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&priv->mutex);
|
mutex_lock(&priv->mutex);
|
||||||
ath9k_htc_ps_wakeup(priv);
|
ath9k_htc_ps_wakeup(priv);
|
||||||
ret = ath9k_htc_add_station(priv, vif, sta);
|
ret = ath9k_htc_add_station(priv, vif, sta);
|
||||||
if (!ret)
|
if (!ret) {
|
||||||
|
INIT_WORK(&ista->rc_update_work, ath9k_htc_sta_rc_update_work);
|
||||||
|
ista->htc_priv = priv;
|
||||||
ath9k_htc_init_rate(priv, sta);
|
ath9k_htc_init_rate(priv, sta);
|
||||||
|
}
|
||||||
ath9k_htc_ps_restore(priv);
|
ath9k_htc_ps_restore(priv);
|
||||||
mutex_unlock(&priv->mutex);
|
mutex_unlock(&priv->mutex);
|
||||||
|
|
||||||
@ -1293,12 +1325,13 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw,
|
|||||||
struct ieee80211_sta *sta)
|
struct ieee80211_sta *sta)
|
||||||
{
|
{
|
||||||
struct ath9k_htc_priv *priv = hw->priv;
|
struct ath9k_htc_priv *priv = hw->priv;
|
||||||
struct ath9k_htc_sta *ista;
|
struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
cancel_work_sync(&ista->rc_update_work);
|
||||||
|
|
||||||
mutex_lock(&priv->mutex);
|
mutex_lock(&priv->mutex);
|
||||||
ath9k_htc_ps_wakeup(priv);
|
ath9k_htc_ps_wakeup(priv);
|
||||||
ista = (struct ath9k_htc_sta *) sta->drv_priv;
|
|
||||||
htc_sta_drain(priv->htc, ista->index);
|
htc_sta_drain(priv->htc, ista->index);
|
||||||
ret = ath9k_htc_remove_station(priv, vif, sta);
|
ret = ath9k_htc_remove_station(priv, vif, sta);
|
||||||
ath9k_htc_ps_restore(priv);
|
ath9k_htc_ps_restore(priv);
|
||||||
@ -1311,28 +1344,12 @@ static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw,
|
|||||||
struct ieee80211_vif *vif,
|
struct ieee80211_vif *vif,
|
||||||
struct ieee80211_sta *sta, u32 changed)
|
struct ieee80211_sta *sta, u32 changed)
|
||||||
{
|
{
|
||||||
struct ath9k_htc_priv *priv = hw->priv;
|
struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv;
|
||||||
struct ath_common *common = ath9k_hw_common(priv->ah);
|
|
||||||
struct ath9k_htc_target_rate trate;
|
|
||||||
|
|
||||||
mutex_lock(&priv->mutex);
|
if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED))
|
||||||
ath9k_htc_ps_wakeup(priv);
|
return;
|
||||||
|
|
||||||
if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
|
schedule_work(&ista->rc_update_work);
|
||||||
memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
|
|
||||||
ath9k_htc_setup_rate(priv, sta, &trate);
|
|
||||||
if (!ath9k_htc_send_rate_cmd(priv, &trate))
|
|
||||||
ath_dbg(common, CONFIG,
|
|
||||||
"Supported rates for sta: %pM updated, rate caps: 0x%X\n",
|
|
||||||
sta->addr, be32_to_cpu(trate.capflags));
|
|
||||||
else
|
|
||||||
ath_dbg(common, CONFIG,
|
|
||||||
"Unable to update supported rates for sta: %pM\n",
|
|
||||||
sta->addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
ath9k_htc_ps_restore(priv);
|
|
||||||
mutex_unlock(&priv->mutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ath9k_htc_conf_tx(struct ieee80211_hw *hw,
|
static int ath9k_htc_conf_tx(struct ieee80211_hw *hw,
|
||||||
|
@ -1316,7 +1316,7 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
|
|||||||
if (AR_SREV_9300_20_OR_LATER(ah))
|
if (AR_SREV_9300_20_OR_LATER(ah))
|
||||||
udelay(50);
|
udelay(50);
|
||||||
else if (AR_SREV_9100(ah))
|
else if (AR_SREV_9100(ah))
|
||||||
udelay(10000);
|
mdelay(10);
|
||||||
else
|
else
|
||||||
udelay(100);
|
udelay(100);
|
||||||
|
|
||||||
@ -2051,9 +2051,8 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah)
|
|||||||
|
|
||||||
REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
|
REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
|
||||||
AR_RTC_FORCE_WAKE_EN);
|
AR_RTC_FORCE_WAKE_EN);
|
||||||
|
|
||||||
if (AR_SREV_9100(ah))
|
if (AR_SREV_9100(ah))
|
||||||
udelay(10000);
|
mdelay(10);
|
||||||
else
|
else
|
||||||
udelay(50);
|
udelay(50);
|
||||||
|
|
||||||
|
@ -57,6 +57,10 @@ static int ath9k_bt_ant_diversity;
|
|||||||
module_param_named(bt_ant_diversity, ath9k_bt_ant_diversity, int, 0444);
|
module_param_named(bt_ant_diversity, ath9k_bt_ant_diversity, int, 0444);
|
||||||
MODULE_PARM_DESC(bt_ant_diversity, "Enable WLAN/BT RX antenna diversity");
|
MODULE_PARM_DESC(bt_ant_diversity, "Enable WLAN/BT RX antenna diversity");
|
||||||
|
|
||||||
|
static int ath9k_ps_enable;
|
||||||
|
module_param_named(ps_enable, ath9k_ps_enable, int, 0444);
|
||||||
|
MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave");
|
||||||
|
|
||||||
bool is_ath9k_unloaded;
|
bool is_ath9k_unloaded;
|
||||||
/* We use the hw_value as an index into our private channel structure */
|
/* We use the hw_value as an index into our private channel structure */
|
||||||
|
|
||||||
@ -903,13 +907,15 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
|
|||||||
hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
|
hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
|
||||||
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
|
IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
|
||||||
IEEE80211_HW_SIGNAL_DBM |
|
IEEE80211_HW_SIGNAL_DBM |
|
||||||
IEEE80211_HW_SUPPORTS_PS |
|
|
||||||
IEEE80211_HW_PS_NULLFUNC_STACK |
|
IEEE80211_HW_PS_NULLFUNC_STACK |
|
||||||
IEEE80211_HW_SPECTRUM_MGMT |
|
IEEE80211_HW_SPECTRUM_MGMT |
|
||||||
IEEE80211_HW_REPORTS_TX_ACK_STATUS |
|
IEEE80211_HW_REPORTS_TX_ACK_STATUS |
|
||||||
IEEE80211_HW_SUPPORTS_RC_TABLE |
|
IEEE80211_HW_SUPPORTS_RC_TABLE |
|
||||||
IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
|
IEEE80211_HW_SUPPORTS_HT_CCK_RATES;
|
||||||
|
|
||||||
|
if (ath9k_ps_enable)
|
||||||
|
hw->flags |= IEEE80211_HW_SUPPORTS_PS;
|
||||||
|
|
||||||
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
|
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
|
||||||
hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
|
hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
|
||||||
|
|
||||||
|
@ -182,6 +182,11 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
|
|||||||
|
|
||||||
for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) {
|
for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) {
|
||||||
ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
|
ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
|
||||||
|
|
||||||
|
if (ch_idx >= NUM_2GHZ_CHANNELS &&
|
||||||
|
!data->sku_cap_band_52GHz_enable)
|
||||||
|
ch_flags &= ~NVM_CHANNEL_VALID;
|
||||||
|
|
||||||
if (!(ch_flags & NVM_CHANNEL_VALID)) {
|
if (!(ch_flags & NVM_CHANNEL_VALID)) {
|
||||||
IWL_DEBUG_EEPROM(dev,
|
IWL_DEBUG_EEPROM(dev,
|
||||||
"Ch. %d Flags %x [%sGHz] - No traffic\n",
|
"Ch. %d Flags %x [%sGHz] - No traffic\n",
|
||||||
|
@ -504,6 +504,7 @@ struct iwl_scan_offload_profile {
|
|||||||
* @match_notify: clients waiting for match found notification
|
* @match_notify: clients waiting for match found notification
|
||||||
* @pass_match: clients waiting for the results
|
* @pass_match: clients waiting for the results
|
||||||
* @active_clients: active clients bitmap - enum scan_framework_client
|
* @active_clients: active clients bitmap - enum scan_framework_client
|
||||||
|
* @any_beacon_notify: clients waiting for match notification without match
|
||||||
*/
|
*/
|
||||||
struct iwl_scan_offload_profile_cfg {
|
struct iwl_scan_offload_profile_cfg {
|
||||||
struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES];
|
struct iwl_scan_offload_profile profiles[IWL_SCAN_MAX_PROFILES];
|
||||||
@ -512,7 +513,8 @@ struct iwl_scan_offload_profile_cfg {
|
|||||||
u8 match_notify;
|
u8 match_notify;
|
||||||
u8 pass_match;
|
u8 pass_match;
|
||||||
u8 active_clients;
|
u8 active_clients;
|
||||||
u8 reserved[3];
|
u8 any_beacon_notify;
|
||||||
|
u8 reserved[2];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -246,7 +246,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
|||||||
else
|
else
|
||||||
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||||
|
|
||||||
if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SCHED_SCAN) {
|
if (0 && mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SCHED_SCAN) {
|
||||||
hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
|
hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
|
||||||
hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX;
|
hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX;
|
||||||
hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES;
|
hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES;
|
||||||
|
@ -344,7 +344,8 @@ int iwl_mvm_scan_request(struct iwl_mvm *mvm,
|
|||||||
|
|
||||||
iwl_mvm_scan_fill_ssids(cmd, req, basic_ssid ? 1 : 0);
|
iwl_mvm_scan_fill_ssids(cmd, req, basic_ssid ? 1 : 0);
|
||||||
|
|
||||||
cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL);
|
cmd->tx_cmd.tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
|
||||||
|
TX_CMD_FLG_BT_DIS);
|
||||||
cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id;
|
cmd->tx_cmd.sta_id = mvm->aux_sta.sta_id;
|
||||||
cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
|
cmd->tx_cmd.life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE);
|
||||||
cmd->tx_cmd.rate_n_flags =
|
cmd->tx_cmd.rate_n_flags =
|
||||||
@ -807,6 +808,8 @@ int iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
|
|||||||
profile_cfg->active_clients = SCAN_CLIENT_SCHED_SCAN;
|
profile_cfg->active_clients = SCAN_CLIENT_SCHED_SCAN;
|
||||||
profile_cfg->pass_match = SCAN_CLIENT_SCHED_SCAN;
|
profile_cfg->pass_match = SCAN_CLIENT_SCHED_SCAN;
|
||||||
profile_cfg->match_notify = SCAN_CLIENT_SCHED_SCAN;
|
profile_cfg->match_notify = SCAN_CLIENT_SCHED_SCAN;
|
||||||
|
if (!req->n_match_sets || !req->match_sets[0].ssid.ssid_len)
|
||||||
|
profile_cfg->any_beacon_notify = SCAN_CLIENT_SCHED_SCAN;
|
||||||
|
|
||||||
for (i = 0; i < req->n_match_sets; i++) {
|
for (i = 0; i < req->n_match_sets; i++) {
|
||||||
profile = &profile_cfg->profiles[i];
|
profile = &profile_cfg->profiles[i];
|
||||||
|
@ -652,7 +652,7 @@ int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
|
|||||||
{
|
{
|
||||||
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
|
||||||
static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
static const u8 *baddr = _baddr;
|
const u8 *baddr = _baddr;
|
||||||
|
|
||||||
lockdep_assert_held(&mvm->mutex);
|
lockdep_assert_held(&mvm->mutex);
|
||||||
|
|
||||||
|
@ -659,8 +659,14 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
|||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
|
|
||||||
sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
|
sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
|
||||||
|
/*
|
||||||
|
* sta can't be NULL otherwise it'd mean that the sta has been freed in
|
||||||
|
* the firmware while we still have packets for it in the Tx queues.
|
||||||
|
*/
|
||||||
|
if (WARN_ON_ONCE(!sta))
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (!IS_ERR_OR_NULL(sta)) {
|
if (!IS_ERR(sta)) {
|
||||||
mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
mvmsta = iwl_mvm_sta_from_mac80211(sta);
|
||||||
|
|
||||||
if (tid != IWL_TID_NON_QOS) {
|
if (tid != IWL_TID_NON_QOS) {
|
||||||
@ -675,7 +681,6 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
|||||||
spin_unlock_bh(&mvmsta->lock);
|
spin_unlock_bh(&mvmsta->lock);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sta = NULL;
|
|
||||||
mvmsta = NULL;
|
mvmsta = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -683,42 +688,38 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
|
|||||||
* If the txq is not an AMPDU queue, there is no chance we freed
|
* If the txq is not an AMPDU queue, there is no chance we freed
|
||||||
* several skbs. Check that out...
|
* several skbs. Check that out...
|
||||||
*/
|
*/
|
||||||
if (txq_id < mvm->first_agg_queue && !WARN_ON(skb_freed > 1) &&
|
if (txq_id >= mvm->first_agg_queue)
|
||||||
atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id])) {
|
goto out;
|
||||||
if (mvmsta) {
|
|
||||||
/*
|
/* We can't free more than one frame at once on a shared queue */
|
||||||
* If there are no pending frames for this STA, notify
|
WARN_ON(skb_freed > 1);
|
||||||
* mac80211 that this station can go to sleep in its
|
|
||||||
* STA table.
|
/* If we have still frames from this STA nothing to do here */
|
||||||
*/
|
if (!atomic_sub_and_test(skb_freed, &mvm->pending_frames[sta_id]))
|
||||||
if (mvmsta->vif->type == NL80211_IFTYPE_AP)
|
goto out;
|
||||||
ieee80211_sta_block_awake(mvm->hw, sta, false);
|
|
||||||
/*
|
if (mvmsta && mvmsta->vif->type == NL80211_IFTYPE_AP) {
|
||||||
* We might very well have taken mvmsta pointer while
|
/*
|
||||||
* the station was being removed. The remove flow might
|
* If there are no pending frames for this STA, notify
|
||||||
* have seen a pending_frame (because we didn't take
|
* mac80211 that this station can go to sleep in its
|
||||||
* the lock) even if now the queues are drained. So make
|
* STA table.
|
||||||
* really sure now that this the station is not being
|
* If mvmsta is not NULL, sta is valid.
|
||||||
* removed. If it is, run the drain worker to remove it.
|
*/
|
||||||
*/
|
ieee80211_sta_block_awake(mvm->hw, sta, false);
|
||||||
spin_lock_bh(&mvmsta->lock);
|
|
||||||
sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);
|
|
||||||
if (!sta || PTR_ERR(sta) == -EBUSY) {
|
|
||||||
/*
|
|
||||||
* Station disappeared in the meantime:
|
|
||||||
* so we are draining.
|
|
||||||
*/
|
|
||||||
set_bit(sta_id, mvm->sta_drained);
|
|
||||||
schedule_work(&mvm->sta_drained_wk);
|
|
||||||
}
|
|
||||||
spin_unlock_bh(&mvmsta->lock);
|
|
||||||
} else if (!mvmsta && PTR_ERR(sta) == -EBUSY) {
|
|
||||||
/* Tx response without STA, so we are draining */
|
|
||||||
set_bit(sta_id, mvm->sta_drained);
|
|
||||||
schedule_work(&mvm->sta_drained_wk);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PTR_ERR(sta) == -EBUSY || PTR_ERR(sta) == -ENOENT) {
|
||||||
|
/*
|
||||||
|
* We are draining and this was the last packet - pre_rcu_remove
|
||||||
|
* has been called already. We might be after the
|
||||||
|
* synchronize_net already.
|
||||||
|
* Don't rely on iwl_mvm_rm_sta to see the empty Tx queues.
|
||||||
|
*/
|
||||||
|
set_bit(sta_id, mvm->sta_drained);
|
||||||
|
schedule_work(&mvm->sta_drained_wk);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,6 +411,8 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
|
|||||||
mvm->status, table.valid);
|
mvm->status, table.valid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IWL_ERR(mvm, "Loaded firmware version: %s\n", mvm->fw->fw_version);
|
||||||
|
|
||||||
trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low,
|
trace_iwlwifi_dev_ucode_error(trans->dev, table.error_id, table.tsf_low,
|
||||||
table.data1, table.data2, table.data3,
|
table.data1, table.data2, table.data3,
|
||||||
table.blink1, table.blink2, table.ilink1,
|
table.blink1, table.blink2, table.ilink1,
|
||||||
|
@ -359,20 +359,25 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
|
|||||||
/* 7265 Series */
|
/* 7265 Series */
|
||||||
{IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)},
|
{IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)},
|
||||||
{IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)},
|
{IWL_PCI_DEVICE(0x095A, 0x5110, iwl7265_2ac_cfg)},
|
||||||
|
{IWL_PCI_DEVICE(0x095A, 0x5112, iwl7265_2ac_cfg)},
|
||||||
|
{IWL_PCI_DEVICE(0x095A, 0x5100, iwl7265_2ac_cfg)},
|
||||||
|
{IWL_PCI_DEVICE(0x095A, 0x510A, iwl7265_2ac_cfg)},
|
||||||
{IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)},
|
{IWL_PCI_DEVICE(0x095B, 0x5310, iwl7265_2ac_cfg)},
|
||||||
{IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_2ac_cfg)},
|
{IWL_PCI_DEVICE(0x095B, 0x5302, iwl7265_2ac_cfg)},
|
||||||
{IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)},
|
{IWL_PCI_DEVICE(0x095B, 0x5210, iwl7265_2ac_cfg)},
|
||||||
{IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)},
|
{IWL_PCI_DEVICE(0x095A, 0x5012, iwl7265_2ac_cfg)},
|
||||||
{IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2ac_cfg)},
|
|
||||||
{IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)},
|
{IWL_PCI_DEVICE(0x095A, 0x5410, iwl7265_2ac_cfg)},
|
||||||
{IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)},
|
{IWL_PCI_DEVICE(0x095A, 0x5400, iwl7265_2ac_cfg)},
|
||||||
{IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)},
|
{IWL_PCI_DEVICE(0x095A, 0x1010, iwl7265_2ac_cfg)},
|
||||||
{IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)},
|
{IWL_PCI_DEVICE(0x095A, 0x5000, iwl7265_2n_cfg)},
|
||||||
|
{IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2n_cfg)},
|
||||||
{IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)},
|
{IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)},
|
||||||
{IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)},
|
{IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)},
|
||||||
{IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)},
|
{IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)},
|
||||||
{IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)},
|
{IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)},
|
||||||
|
{IWL_PCI_DEVICE(0x095A, 0x9012, iwl7265_2ac_cfg)},
|
||||||
{IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)},
|
{IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)},
|
||||||
|
{IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)},
|
||||||
{IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)},
|
{IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)},
|
||||||
{IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)},
|
{IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)},
|
||||||
{IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)},
|
{IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)},
|
||||||
|
@ -1876,6 +1876,11 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
|||||||
rt2x00_eeprom_addr(rt2x00dev,
|
rt2x00_eeprom_addr(rt2x00dev,
|
||||||
EEPROM_MAC_ADDR_0));
|
EEPROM_MAC_ADDR_0));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable powersaving as default.
|
||||||
|
*/
|
||||||
|
rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize hw_mode information.
|
* Initialize hw_mode information.
|
||||||
*/
|
*/
|
||||||
|
@ -1706,6 +1706,11 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
|||||||
IEEE80211_HW_SUPPORTS_PS |
|
IEEE80211_HW_SUPPORTS_PS |
|
||||||
IEEE80211_HW_PS_NULLFUNC_STACK;
|
IEEE80211_HW_PS_NULLFUNC_STACK;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disable powersaving as default.
|
||||||
|
*/
|
||||||
|
rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||||
|
|
||||||
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
|
SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
|
||||||
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
|
SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
|
||||||
rt2x00_eeprom_addr(rt2x00dev,
|
rt2x00_eeprom_addr(rt2x00dev,
|
||||||
|
@ -7458,10 +7458,9 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
|
|||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disable powersaving as default on PCI devices.
|
* Disable powersaving as default.
|
||||||
*/
|
*/
|
||||||
if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev))
|
rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||||
rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize all hw fields.
|
* Initialize all hw fields.
|
||||||
|
@ -107,6 +107,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
|
|||||||
struct rtl8180_priv *priv = dev->priv;
|
struct rtl8180_priv *priv = dev->priv;
|
||||||
unsigned int count = 32;
|
unsigned int count = 32;
|
||||||
u8 signal, agc, sq;
|
u8 signal, agc, sq;
|
||||||
|
dma_addr_t mapping;
|
||||||
|
|
||||||
while (count--) {
|
while (count--) {
|
||||||
struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx];
|
struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx];
|
||||||
@ -128,6 +129,17 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
|
|||||||
if (unlikely(!new_skb))
|
if (unlikely(!new_skb))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
mapping = pci_map_single(priv->pdev,
|
||||||
|
skb_tail_pointer(new_skb),
|
||||||
|
MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
|
||||||
|
|
||||||
|
if (pci_dma_mapping_error(priv->pdev, mapping)) {
|
||||||
|
kfree_skb(new_skb);
|
||||||
|
dev_err(&priv->pdev->dev, "RX DMA map error\n");
|
||||||
|
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
pci_unmap_single(priv->pdev,
|
pci_unmap_single(priv->pdev,
|
||||||
*((dma_addr_t *)skb->cb),
|
*((dma_addr_t *)skb->cb),
|
||||||
MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
|
MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
|
||||||
@ -158,9 +170,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
|
|||||||
|
|
||||||
skb = new_skb;
|
skb = new_skb;
|
||||||
priv->rx_buf[priv->rx_idx] = skb;
|
priv->rx_buf[priv->rx_idx] = skb;
|
||||||
*((dma_addr_t *) skb->cb) =
|
*((dma_addr_t *) skb->cb) = mapping;
|
||||||
pci_map_single(priv->pdev, skb_tail_pointer(skb),
|
|
||||||
MAX_RX_SIZE, PCI_DMA_FROMDEVICE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
@ -266,6 +276,13 @@ static void rtl8180_tx(struct ieee80211_hw *dev,
|
|||||||
mapping = pci_map_single(priv->pdev, skb->data,
|
mapping = pci_map_single(priv->pdev, skb->data,
|
||||||
skb->len, PCI_DMA_TODEVICE);
|
skb->len, PCI_DMA_TODEVICE);
|
||||||
|
|
||||||
|
if (pci_dma_mapping_error(priv->pdev, mapping)) {
|
||||||
|
kfree_skb(skb);
|
||||||
|
dev_err(&priv->pdev->dev, "TX DMA mapping error\n");
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS |
|
tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS |
|
||||||
RTL818X_TX_DESC_FLAG_LS |
|
RTL818X_TX_DESC_FLAG_LS |
|
||||||
(ieee80211_get_tx_rate(dev, info)->hw_value << 24) |
|
(ieee80211_get_tx_rate(dev, info)->hw_value << 24) |
|
||||||
|
@ -1021,8 +1021,10 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
|||||||
IEEE80211_P2P_OPPPS_ENABLE_BIT;
|
IEEE80211_P2P_OPPPS_ENABLE_BIT;
|
||||||
|
|
||||||
err = ieee80211_assign_beacon(sdata, ¶ms->beacon);
|
err = ieee80211_assign_beacon(sdata, ¶ms->beacon);
|
||||||
if (err < 0)
|
if (err < 0) {
|
||||||
|
ieee80211_vif_release_channel(sdata);
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
changed |= err;
|
changed |= err;
|
||||||
|
|
||||||
err = drv_start_ap(sdata->local, sdata);
|
err = drv_start_ap(sdata->local, sdata);
|
||||||
@ -1032,6 +1034,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
|||||||
if (old)
|
if (old)
|
||||||
kfree_rcu(old, rcu_head);
|
kfree_rcu(old, rcu_head);
|
||||||
RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
|
RCU_INIT_POINTER(sdata->u.ap.beacon, NULL);
|
||||||
|
ieee80211_vif_release_channel(sdata);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1090,8 +1093,6 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
|
|||||||
kfree(sdata->u.ap.next_beacon);
|
kfree(sdata->u.ap.next_beacon);
|
||||||
sdata->u.ap.next_beacon = NULL;
|
sdata->u.ap.next_beacon = NULL;
|
||||||
|
|
||||||
cancel_work_sync(&sdata->u.ap.request_smps_work);
|
|
||||||
|
|
||||||
/* turn off carrier for this interface and dependent VLANs */
|
/* turn off carrier for this interface and dependent VLANs */
|
||||||
list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
|
list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
|
||||||
netif_carrier_off(vlan->dev);
|
netif_carrier_off(vlan->dev);
|
||||||
@ -1103,6 +1104,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
|
|||||||
kfree_rcu(old_beacon, rcu_head);
|
kfree_rcu(old_beacon, rcu_head);
|
||||||
if (old_probe_resp)
|
if (old_probe_resp)
|
||||||
kfree_rcu(old_probe_resp, rcu_head);
|
kfree_rcu(old_probe_resp, rcu_head);
|
||||||
|
sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
|
||||||
|
|
||||||
__sta_info_flush(sdata, true);
|
__sta_info_flush(sdata, true);
|
||||||
ieee80211_free_keys(sdata, true);
|
ieee80211_free_keys(sdata, true);
|
||||||
@ -2638,6 +2640,24 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
|
|||||||
INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work);
|
INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work);
|
||||||
INIT_LIST_HEAD(&roc->dependents);
|
INIT_LIST_HEAD(&roc->dependents);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cookie is either the roc cookie (for normal roc)
|
||||||
|
* or the SKB (for mgmt TX)
|
||||||
|
*/
|
||||||
|
if (!txskb) {
|
||||||
|
/* local->mtx protects this */
|
||||||
|
local->roc_cookie_counter++;
|
||||||
|
roc->cookie = local->roc_cookie_counter;
|
||||||
|
/* wow, you wrapped 64 bits ... more likely a bug */
|
||||||
|
if (WARN_ON(roc->cookie == 0)) {
|
||||||
|
roc->cookie = 1;
|
||||||
|
local->roc_cookie_counter++;
|
||||||
|
}
|
||||||
|
*cookie = roc->cookie;
|
||||||
|
} else {
|
||||||
|
*cookie = (unsigned long)txskb;
|
||||||
|
}
|
||||||
|
|
||||||
/* if there's one pending or we're scanning, queue this one */
|
/* if there's one pending or we're scanning, queue this one */
|
||||||
if (!list_empty(&local->roc_list) ||
|
if (!list_empty(&local->roc_list) ||
|
||||||
local->scanning || local->radar_detect_enabled)
|
local->scanning || local->radar_detect_enabled)
|
||||||
@ -2772,24 +2792,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
|
|||||||
if (!queued)
|
if (!queued)
|
||||||
list_add_tail(&roc->list, &local->roc_list);
|
list_add_tail(&roc->list, &local->roc_list);
|
||||||
|
|
||||||
/*
|
|
||||||
* cookie is either the roc cookie (for normal roc)
|
|
||||||
* or the SKB (for mgmt TX)
|
|
||||||
*/
|
|
||||||
if (!txskb) {
|
|
||||||
/* local->mtx protects this */
|
|
||||||
local->roc_cookie_counter++;
|
|
||||||
roc->cookie = local->roc_cookie_counter;
|
|
||||||
/* wow, you wrapped 64 bits ... more likely a bug */
|
|
||||||
if (WARN_ON(roc->cookie == 0)) {
|
|
||||||
roc->cookie = 1;
|
|
||||||
local->roc_cookie_counter++;
|
|
||||||
}
|
|
||||||
*cookie = roc->cookie;
|
|
||||||
} else {
|
|
||||||
*cookie = (unsigned long)txskb;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,7 +466,9 @@ void ieee80211_request_smps_ap_work(struct work_struct *work)
|
|||||||
u.ap.request_smps_work);
|
u.ap.request_smps_work);
|
||||||
|
|
||||||
sdata_lock(sdata);
|
sdata_lock(sdata);
|
||||||
__ieee80211_request_smps_ap(sdata, sdata->u.ap.driver_smps_mode);
|
if (sdata_dereference(sdata->u.ap.beacon, sdata))
|
||||||
|
__ieee80211_request_smps_ap(sdata,
|
||||||
|
sdata->u.ap.driver_smps_mode);
|
||||||
sdata_unlock(sdata);
|
sdata_unlock(sdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,12 +695,9 @@ static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata)
|
|||||||
struct cfg80211_bss *cbss;
|
struct cfg80211_bss *cbss;
|
||||||
struct beacon_data *presp;
|
struct beacon_data *presp;
|
||||||
struct sta_info *sta;
|
struct sta_info *sta;
|
||||||
int active_ibss;
|
|
||||||
u16 capability;
|
u16 capability;
|
||||||
|
|
||||||
active_ibss = ieee80211_sta_active_ibss(sdata);
|
if (!is_zero_ether_addr(ifibss->bssid)) {
|
||||||
|
|
||||||
if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) {
|
|
||||||
capability = WLAN_CAPABILITY_IBSS;
|
capability = WLAN_CAPABILITY_IBSS;
|
||||||
|
|
||||||
if (ifibss->privacy)
|
if (ifibss->privacy)
|
||||||
|
@ -418,20 +418,24 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_lock(&local->iflist_mtx);
|
||||||
|
rcu_assign_pointer(local->monitor_sdata, sdata);
|
||||||
|
mutex_unlock(&local->iflist_mtx);
|
||||||
|
|
||||||
mutex_lock(&local->mtx);
|
mutex_lock(&local->mtx);
|
||||||
ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef,
|
ret = ieee80211_vif_use_channel(sdata, &local->monitor_chandef,
|
||||||
IEEE80211_CHANCTX_EXCLUSIVE);
|
IEEE80211_CHANCTX_EXCLUSIVE);
|
||||||
mutex_unlock(&local->mtx);
|
mutex_unlock(&local->mtx);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
mutex_lock(&local->iflist_mtx);
|
||||||
|
rcu_assign_pointer(local->monitor_sdata, NULL);
|
||||||
|
mutex_unlock(&local->iflist_mtx);
|
||||||
|
synchronize_net();
|
||||||
drv_remove_interface(local, sdata);
|
drv_remove_interface(local, sdata);
|
||||||
kfree(sdata);
|
kfree(sdata);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&local->iflist_mtx);
|
|
||||||
rcu_assign_pointer(local->monitor_sdata, sdata);
|
|
||||||
mutex_unlock(&local->iflist_mtx);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -770,12 +774,19 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
|
|||||||
|
|
||||||
ieee80211_roc_purge(local, sdata);
|
ieee80211_roc_purge(local, sdata);
|
||||||
|
|
||||||
if (sdata->vif.type == NL80211_IFTYPE_STATION)
|
switch (sdata->vif.type) {
|
||||||
|
case NL80211_IFTYPE_STATION:
|
||||||
ieee80211_mgd_stop(sdata);
|
ieee80211_mgd_stop(sdata);
|
||||||
|
break;
|
||||||
if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
|
case NL80211_IFTYPE_ADHOC:
|
||||||
ieee80211_ibss_stop(sdata);
|
ieee80211_ibss_stop(sdata);
|
||||||
|
break;
|
||||||
|
case NL80211_IFTYPE_AP:
|
||||||
|
cancel_work_sync(&sdata->u.ap.request_smps_work);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove all stations associated with this interface.
|
* Remove all stations associated with this interface.
|
||||||
|
@ -878,7 +878,7 @@ static int ieee80211_fragment(struct ieee80211_tx_data *tx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* adjust first fragment's length */
|
/* adjust first fragment's length */
|
||||||
skb->len = hdrlen + per_fragm;
|
skb_trim(skb, hdrlen + per_fragm);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,8 +203,11 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
|
|||||||
|
|
||||||
rdev->opencount--;
|
rdev->opencount--;
|
||||||
|
|
||||||
WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev &&
|
if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
|
||||||
!rdev->scan_req->notified);
|
if (WARN_ON(!rdev->scan_req->notified))
|
||||||
|
rdev->scan_req->aborted = true;
|
||||||
|
___cfg80211_scan_done(rdev, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cfg80211_rfkill_set_block(void *data, bool blocked)
|
static int cfg80211_rfkill_set_block(void *data, bool blocked)
|
||||||
@ -440,9 +443,6 @@ int wiphy_register(struct wiphy *wiphy)
|
|||||||
int i;
|
int i;
|
||||||
u16 ifmodes = wiphy->interface_modes;
|
u16 ifmodes = wiphy->interface_modes;
|
||||||
|
|
||||||
/* support for 5/10 MHz is broken due to nl80211 API mess - disable */
|
|
||||||
wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_5_10_MHZ;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There are major locking problems in nl80211/mac80211 for CSA,
|
* There are major locking problems in nl80211/mac80211 for CSA,
|
||||||
* disable for all drivers until this has been reworked.
|
* disable for all drivers until this has been reworked.
|
||||||
@ -859,8 +859,11 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
|
|||||||
break;
|
break;
|
||||||
case NETDEV_DOWN:
|
case NETDEV_DOWN:
|
||||||
cfg80211_update_iface_num(rdev, wdev->iftype, -1);
|
cfg80211_update_iface_num(rdev, wdev->iftype, -1);
|
||||||
WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev &&
|
if (rdev->scan_req && rdev->scan_req->wdev == wdev) {
|
||||||
!rdev->scan_req->notified);
|
if (WARN_ON(!rdev->scan_req->notified))
|
||||||
|
rdev->scan_req->aborted = true;
|
||||||
|
___cfg80211_scan_done(rdev, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (WARN_ON(rdev->sched_scan_req &&
|
if (WARN_ON(rdev->sched_scan_req &&
|
||||||
rdev->sched_scan_req->dev == wdev->netdev)) {
|
rdev->sched_scan_req->dev == wdev->netdev)) {
|
||||||
|
@ -62,6 +62,7 @@ struct cfg80211_registered_device {
|
|||||||
struct rb_root bss_tree;
|
struct rb_root bss_tree;
|
||||||
u32 bss_generation;
|
u32 bss_generation;
|
||||||
struct cfg80211_scan_request *scan_req; /* protected by RTNL */
|
struct cfg80211_scan_request *scan_req; /* protected by RTNL */
|
||||||
|
struct sk_buff *scan_msg;
|
||||||
struct cfg80211_sched_scan_request *sched_scan_req;
|
struct cfg80211_sched_scan_request *sched_scan_req;
|
||||||
unsigned long suspend_at;
|
unsigned long suspend_at;
|
||||||
struct work_struct scan_done_wk;
|
struct work_struct scan_done_wk;
|
||||||
@ -361,7 +362,8 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
|
|||||||
struct key_params *params, int key_idx,
|
struct key_params *params, int key_idx,
|
||||||
bool pairwise, const u8 *mac_addr);
|
bool pairwise, const u8 *mac_addr);
|
||||||
void __cfg80211_scan_done(struct work_struct *wk);
|
void __cfg80211_scan_done(struct work_struct *wk);
|
||||||
void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev);
|
void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
|
||||||
|
bool send_message);
|
||||||
void __cfg80211_sched_scan_results(struct work_struct *wk);
|
void __cfg80211_sched_scan_results(struct work_struct *wk);
|
||||||
int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
|
int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
|
||||||
bool driver_initiated);
|
bool driver_initiated);
|
||||||
|
@ -1719,9 +1719,10 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
|
|||||||
* We can then retry with the larger buffer.
|
* We can then retry with the larger buffer.
|
||||||
*/
|
*/
|
||||||
if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
|
if ((ret == -ENOBUFS || ret == -EMSGSIZE) &&
|
||||||
!skb->len &&
|
!skb->len && !state->split &&
|
||||||
cb->min_dump_alloc < 4096) {
|
cb->min_dump_alloc < 4096) {
|
||||||
cb->min_dump_alloc = 4096;
|
cb->min_dump_alloc = 4096;
|
||||||
|
state->split_start = 0;
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -5244,7 +5245,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
|
|||||||
if (!rdev->ops->scan)
|
if (!rdev->ops->scan)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (rdev->scan_req) {
|
if (rdev->scan_req || rdev->scan_msg) {
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
@ -10011,40 +10012,31 @@ void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
|
|||||||
NL80211_MCGRP_SCAN, GFP_KERNEL);
|
NL80211_MCGRP_SCAN, GFP_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
|
struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
|
||||||
struct wireless_dev *wdev)
|
struct wireless_dev *wdev, bool aborted)
|
||||||
{
|
{
|
||||||
struct sk_buff *msg;
|
struct sk_buff *msg;
|
||||||
|
|
||||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return;
|
return NULL;
|
||||||
|
|
||||||
if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
|
if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
|
||||||
NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
|
aborted ? NL80211_CMD_SCAN_ABORTED :
|
||||||
|
NL80211_CMD_NEW_SCAN_RESULTS) < 0) {
|
||||||
nlmsg_free(msg);
|
nlmsg_free(msg);
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
|
return msg;
|
||||||
NL80211_MCGRP_SCAN, GFP_KERNEL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
|
void nl80211_send_scan_result(struct cfg80211_registered_device *rdev,
|
||||||
struct wireless_dev *wdev)
|
struct sk_buff *msg)
|
||||||
{
|
{
|
||||||
struct sk_buff *msg;
|
|
||||||
|
|
||||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
|
||||||
if (!msg)
|
if (!msg)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0,
|
|
||||||
NL80211_CMD_SCAN_ABORTED) < 0) {
|
|
||||||
nlmsg_free(msg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
|
genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
|
||||||
NL80211_MCGRP_SCAN, GFP_KERNEL);
|
NL80211_MCGRP_SCAN, GFP_KERNEL);
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,10 @@ void nl80211_exit(void);
|
|||||||
void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev);
|
void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev);
|
||||||
void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
|
void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
|
||||||
struct wireless_dev *wdev);
|
struct wireless_dev *wdev);
|
||||||
void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
|
struct sk_buff *nl80211_build_scan_msg(struct cfg80211_registered_device *rdev,
|
||||||
struct wireless_dev *wdev);
|
struct wireless_dev *wdev, bool aborted);
|
||||||
void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
|
void nl80211_send_scan_result(struct cfg80211_registered_device *rdev,
|
||||||
struct wireless_dev *wdev);
|
struct sk_buff *msg);
|
||||||
void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
|
void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
|
||||||
struct net_device *netdev, u32 cmd);
|
struct net_device *netdev, u32 cmd);
|
||||||
void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
|
void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
|
||||||
|
@ -161,18 +161,25 @@ static void __cfg80211_bss_expire(struct cfg80211_registered_device *dev,
|
|||||||
dev->bss_generation++;
|
dev->bss_generation++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev)
|
void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
|
||||||
|
bool send_message)
|
||||||
{
|
{
|
||||||
struct cfg80211_scan_request *request;
|
struct cfg80211_scan_request *request;
|
||||||
struct wireless_dev *wdev;
|
struct wireless_dev *wdev;
|
||||||
|
struct sk_buff *msg;
|
||||||
#ifdef CONFIG_CFG80211_WEXT
|
#ifdef CONFIG_CFG80211_WEXT
|
||||||
union iwreq_data wrqu;
|
union iwreq_data wrqu;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ASSERT_RTNL();
|
ASSERT_RTNL();
|
||||||
|
|
||||||
request = rdev->scan_req;
|
if (rdev->scan_msg) {
|
||||||
|
nl80211_send_scan_result(rdev, rdev->scan_msg);
|
||||||
|
rdev->scan_msg = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
request = rdev->scan_req;
|
||||||
if (!request)
|
if (!request)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -186,18 +193,16 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev)
|
|||||||
if (wdev->netdev)
|
if (wdev->netdev)
|
||||||
cfg80211_sme_scan_done(wdev->netdev);
|
cfg80211_sme_scan_done(wdev->netdev);
|
||||||
|
|
||||||
if (request->aborted) {
|
if (!request->aborted &&
|
||||||
nl80211_send_scan_aborted(rdev, wdev);
|
request->flags & NL80211_SCAN_FLAG_FLUSH) {
|
||||||
} else {
|
/* flush entries from previous scans */
|
||||||
if (request->flags & NL80211_SCAN_FLAG_FLUSH) {
|
spin_lock_bh(&rdev->bss_lock);
|
||||||
/* flush entries from previous scans */
|
__cfg80211_bss_expire(rdev, request->scan_start);
|
||||||
spin_lock_bh(&rdev->bss_lock);
|
spin_unlock_bh(&rdev->bss_lock);
|
||||||
__cfg80211_bss_expire(rdev, request->scan_start);
|
|
||||||
spin_unlock_bh(&rdev->bss_lock);
|
|
||||||
}
|
|
||||||
nl80211_send_scan_done(rdev, wdev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msg = nl80211_build_scan_msg(rdev, wdev, request->aborted);
|
||||||
|
|
||||||
#ifdef CONFIG_CFG80211_WEXT
|
#ifdef CONFIG_CFG80211_WEXT
|
||||||
if (wdev->netdev && !request->aborted) {
|
if (wdev->netdev && !request->aborted) {
|
||||||
memset(&wrqu, 0, sizeof(wrqu));
|
memset(&wrqu, 0, sizeof(wrqu));
|
||||||
@ -211,6 +216,11 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev)
|
|||||||
|
|
||||||
rdev->scan_req = NULL;
|
rdev->scan_req = NULL;
|
||||||
kfree(request);
|
kfree(request);
|
||||||
|
|
||||||
|
if (!send_message)
|
||||||
|
rdev->scan_msg = msg;
|
||||||
|
else
|
||||||
|
nl80211_send_scan_result(rdev, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __cfg80211_scan_done(struct work_struct *wk)
|
void __cfg80211_scan_done(struct work_struct *wk)
|
||||||
@ -221,7 +231,7 @@ void __cfg80211_scan_done(struct work_struct *wk)
|
|||||||
scan_done_wk);
|
scan_done_wk);
|
||||||
|
|
||||||
rtnl_lock();
|
rtnl_lock();
|
||||||
___cfg80211_scan_done(rdev);
|
___cfg80211_scan_done(rdev, true);
|
||||||
rtnl_unlock();
|
rtnl_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1079,7 +1089,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
|
|||||||
if (IS_ERR(rdev))
|
if (IS_ERR(rdev))
|
||||||
return PTR_ERR(rdev);
|
return PTR_ERR(rdev);
|
||||||
|
|
||||||
if (rdev->scan_req) {
|
if (rdev->scan_req || rdev->scan_msg) {
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -1481,7 +1491,7 @@ int cfg80211_wext_giwscan(struct net_device *dev,
|
|||||||
if (IS_ERR(rdev))
|
if (IS_ERR(rdev))
|
||||||
return PTR_ERR(rdev);
|
return PTR_ERR(rdev);
|
||||||
|
|
||||||
if (rdev->scan_req)
|
if (rdev->scan_req || rdev->scan_msg)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
res = ieee80211_scan_results(rdev, info, extra, data->length);
|
res = ieee80211_scan_results(rdev, info, extra, data->length);
|
||||||
|
@ -67,7 +67,7 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
|
|||||||
ASSERT_RDEV_LOCK(rdev);
|
ASSERT_RDEV_LOCK(rdev);
|
||||||
ASSERT_WDEV_LOCK(wdev);
|
ASSERT_WDEV_LOCK(wdev);
|
||||||
|
|
||||||
if (rdev->scan_req)
|
if (rdev->scan_req || rdev->scan_msg)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
if (wdev->conn->params.channel)
|
if (wdev->conn->params.channel)
|
||||||
|
Loading…
Reference in New Issue
Block a user