diff options
Diffstat (limited to 'drivers/net/wireless/ti/wlcore/main.c')
| -rw-r--r-- | drivers/net/wireless/ti/wlcore/main.c | 507 |
1 files changed, 244 insertions, 263 deletions
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 5669f17b395f..12f0167d7380 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -117,7 +117,7 @@ int wl1271_recalc_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif) else { ret = wl1271_set_rx_streaming(wl, wlvif, false); /* don't cancel_work_sync since we might deadlock */ - del_timer_sync(&wlvif->rx_streaming_timer); + timer_delete_sync(&wlvif->rx_streaming_timer); } out: return ret; @@ -141,11 +141,9 @@ static void wl1271_rx_streaming_enable_work(struct work_struct *work) if (!wl->conf.rx_streaming.interval) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl1271_set_rx_streaming(wl, wlvif, true); if (ret < 0) @@ -156,7 +154,6 @@ static void wl1271_rx_streaming_enable_work(struct work_struct *work) jiffies + msecs_to_jiffies(wl->conf.rx_streaming.duration)); out_sleep: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -174,18 +171,15 @@ static void wl1271_rx_streaming_disable_work(struct work_struct *work) if (!test_bit(WLVIF_FLAG_RX_STREAMING_STARTED, &wlvif->flags)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl1271_set_rx_streaming(wl, wlvif, false); if (ret) goto out_sleep; out_sleep: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -193,7 +187,8 @@ out: static void wl1271_rx_streaming_timer(struct timer_list *t) { - struct wl12xx_vif *wlvif = from_timer(wlvif, t, rx_streaming_timer); + struct wl12xx_vif *wlvif = timer_container_of(wlvif, t, + rx_streaming_timer); struct wl1271 *wl = wlvif->wl; ieee80211_queue_work(wl->hw, &wlvif->rx_streaming_disable_work); } @@ -223,11 +218,9 @@ static void wlcore_rc_update_work(struct work_struct *work) if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } if (ieee80211_vif_is_mesh(vif)) { ret = wl1271_acx_set_ht_capabilities(wl, &wlvif->rc_ht_cap, @@ -239,7 +232,6 @@ static void wlcore_rc_update_work(struct work_struct *work) } out_sleep: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -385,6 +377,8 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl, static int wlcore_fw_status(struct wl1271 *wl, struct wl_fw_status *status) { + struct wl12xx_vif *wlvifsta; + struct wl12xx_vif *wlvifap; struct wl12xx_vif *wlvif; u32 old_tx_blk_count = wl->tx_blocks_available; int avail, freed_blocks; @@ -398,7 +392,7 @@ static int wlcore_fw_status(struct wl1271 *wl, struct wl_fw_status *status) if (ret < 0) return ret; - wlcore_hw_convert_fw_status(wl, wl->raw_fw_status, wl->fw_status); + wlcore_hw_convert_fw_status(wl, wl->raw_fw_status, status); wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " "drv_rx_counter = %d, tx_results_counter = %d)", @@ -416,23 +410,100 @@ static int wlcore_fw_status(struct wl1271 *wl, struct wl_fw_status *status) wl->tx_pkts_freed[i] = status->counters.tx_released_pkts[i]; } + /* Find an authorized STA vif */ + wlvifsta = NULL; + wl12xx_for_each_wlvif_sta(wl, wlvif) { + if (wlvif->sta.hlid != WL12XX_INVALID_LINK_ID && + test_bit(WLVIF_FLAG_STA_AUTHORIZED, &wlvif->flags)) { + wlvifsta = wlvif; + break; + } + } + + /* Find a started AP vif */ + wlvifap = NULL; + wl12xx_for_each_wlvif(wl, wlvif) { + if (wlvif->bss_type == BSS_TYPE_AP_BSS && + wlvif->inconn_count == 0 && + test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) { + wlvifap = wlvif; + break; + } + } for_each_set_bit(i, wl->links_map, wl->num_links) { - u8 diff; + u16 diff16, sec_pn16; + u8 diff, tx_lnk_free_pkts; + lnk = &wl->links[i]; /* prevent wrap-around in freed-packets counter */ - diff = (status->counters.tx_lnk_free_pkts[i] - - lnk->prev_freed_pkts) & 0xff; + tx_lnk_free_pkts = status->counters.tx_lnk_free_pkts[i]; + diff = (tx_lnk_free_pkts - lnk->prev_freed_pkts) & 0xff; - if (diff == 0) + if (diff) { + lnk->allocated_pkts -= diff; + lnk->prev_freed_pkts = tx_lnk_free_pkts; + } + + /* Get the current sec_pn16 value if present */ + if (status->counters.tx_lnk_sec_pn16) + sec_pn16 = __le16_to_cpu(status->counters.tx_lnk_sec_pn16[i]); + else + sec_pn16 = 0; + /* prevent wrap-around in pn16 counter */ + diff16 = (sec_pn16 - lnk->prev_sec_pn16) & 0xffff; + + /* FIXME: since free_pkts is a 8-bit counter of packets that + * rolls over, it can become zero. If it is zero, then we + * omit processing below. Is that really correct? + */ + if (tx_lnk_free_pkts <= 0) continue; - lnk->allocated_pkts -= diff; - lnk->prev_freed_pkts = status->counters.tx_lnk_free_pkts[i]; + /* For a station that has an authorized link: */ + if (wlvifsta && wlvifsta->sta.hlid == i) { + if (wlvifsta->encryption_type == KEY_TKIP || + wlvifsta->encryption_type == KEY_AES) { + if (diff16) { + lnk->prev_sec_pn16 = sec_pn16; + /* accumulate the prev_freed_pkts + * counter according to the PN from + * firmware + */ + lnk->total_freed_pkts += diff16; + } + } else { + if (diff) + /* accumulate the prev_freed_pkts + * counter according to the free packets + * count from firmware + */ + lnk->total_freed_pkts += diff; + } + } - /* accumulate the prev_freed_pkts counter */ - lnk->total_freed_pkts += diff; + /* For an AP that has been started */ + if (wlvifap && test_bit(i, wlvifap->ap.sta_hlid_map)) { + if (wlvifap->encryption_type == KEY_TKIP || + wlvifap->encryption_type == KEY_AES) { + if (diff16) { + lnk->prev_sec_pn16 = sec_pn16; + /* accumulate the prev_freed_pkts + * counter according to the PN from + * firmware + */ + lnk->total_freed_pkts += diff16; + } + } else { + if (diff) + /* accumulate the prev_freed_pkts + * counter according to the free packets + * count from firmware + */ + lnk->total_freed_pkts += diff; + } + } } /* prevent wrap-around in total blocks counter */ @@ -537,11 +608,9 @@ static int wlcore_irq_locked(struct wl1271 *wl) if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } while (!done && loopcount--) { smp_mb__after_atomic(); @@ -639,7 +708,6 @@ static int wlcore_irq_locked(struct wl1271 *wl) } err_ret: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: @@ -838,11 +906,9 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) * Do not send a stop fwlog command if the fw is hanged or if * dbgpins are used (due to some fw bug). */ - error = pm_runtime_get_sync(wl->dev); - if (error < 0) { - pm_runtime_put_noidle(wl->dev); + error = pm_runtime_resume_and_get(wl->dev); + if (error < 0) return; - } if (!wl->watchdog_recovery && wl->conf.fwlog.output != WL12XX_FWLOG_OUTPUT_DBG_PINS) wl12xx_cmd_stop_fwlog(wl); @@ -937,11 +1003,9 @@ static void wl1271_recovery_work(struct work_struct *work) if (wl->state == WLCORE_STATE_OFF || wl->plt) goto out_unlock; - error = pm_runtime_get_sync(wl->dev); - if (error < 0) { + error = pm_runtime_resume_and_get(wl->dev); + if (error < 0) wl1271_warning("Enable for recovery failed"); - pm_runtime_put_noidle(wl->dev); - } wlcore_disable_interrupts_nosync(wl); if (!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)) { @@ -979,7 +1043,6 @@ static void wl1271_recovery_work(struct work_struct *work) } wlcore_op_stop_locked(wl); - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); ieee80211_restart_hw(wl->hw); @@ -1138,7 +1201,7 @@ int wl1271_plt_start(struct wl1271 *wl, const enum plt_mode plt_mode) /* update hw/fw version info in wiphy struct */ wiphy->hw_version = wl->chip.id; - strncpy(wiphy->fw_version, wl->chip.fw_ver_str, + strscpy(wiphy->fw_version, wl->chip.fw_ver_str, sizeof(wiphy->fw_version)); goto out; @@ -1741,9 +1804,8 @@ static int __maybe_unused wl1271_op_suspend(struct ieee80211_hw *hw, mutex_lock(&wl->mutex); - ret = pm_runtime_get_sync(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); if (ret < 0) { - pm_runtime_put_noidle(wl->dev); mutex_unlock(&wl->mutex); return ret; } @@ -1855,11 +1917,9 @@ static int __maybe_unused wl1271_op_resume(struct ieee80211_hw *hw) goto out_sleep; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl12xx_for_each_wlvif(wl, wlvif) { if (wlcore_is_p2p_mgmt(wlvif)) @@ -1878,7 +1938,6 @@ static int __maybe_unused wl1271_op_resume(struct ieee80211_hw *hw) goto out_sleep; out_sleep: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: @@ -2021,7 +2080,7 @@ static void wlcore_op_stop_locked(struct wl1271 *wl) memset(wl->reg_ch_conf_last, 0, sizeof(wl->reg_ch_conf_last)); } -static void wlcore_op_stop(struct ieee80211_hw *hw) +static void wlcore_op_stop(struct ieee80211_hw *hw, bool suspend) { struct wl1271 *wl = hw->priv; @@ -2058,17 +2117,14 @@ static void wlcore_channel_switch_work(struct work_struct *work) goto out; vif = wl12xx_wlvif_to_vif(wlvif); - ieee80211_chswitch_done(vif, false); + ieee80211_chswitch_done(vif, false, 0); - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl12xx_cmd_stop_channel_switch(wl, wlvif); - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -2131,16 +2187,13 @@ static void wlcore_pending_auth_complete_work(struct work_struct *work) if (!time_after(time_spare, wlvif->pending_auth_reply_time)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } /* cancel the ROC if active */ wlcore_update_inconn_sta(wl, wlvif, NULL, false); - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -2363,7 +2416,7 @@ power_off: /* update hw/fw version info in wiphy struct */ wiphy->hw_version = wl->chip.id; - strncpy(wiphy->fw_version, wl->chip.fw_ver_str, + strscpy(wiphy->fw_version, wl->chip.fw_ver_str, sizeof(wiphy->fw_version)); /* @@ -2552,24 +2605,24 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags) || test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)) { ret = -EBUSY; - goto out; + goto out_unlock; } ret = wl12xx_init_vif_data(wl, vif); if (ret < 0) - goto out; + goto out_unlock; wlvif->wl = wl; role_type = wl12xx_get_role_type(wl, wlvif); if (role_type == WL12XX_INVALID_ROLE_TYPE) { ret = -EINVAL; - goto out; + goto out_unlock; } ret = wlcore_allocate_hw_queue_base(wl, wlvif); if (ret < 0) - goto out; + goto out_unlock; /* * TODO: after the nvs issue will be solved, move this block @@ -2584,18 +2637,16 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, ret = wl12xx_init_fw(wl); if (ret < 0) - goto out; + goto out_unlock; } /* * Call runtime PM only after possible wl12xx_init_fw() above * is done. Otherwise we do not have interrupts enabled. */ - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out_unlock; - } if (wl12xx_need_fw_change(wl, vif_count, true)) { wl12xx_force_active_psm(wl); @@ -2635,7 +2686,6 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, else wl->sta_count++; out: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out_unlock: mutex_unlock(&wl->mutex); @@ -2691,11 +2741,9 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) { /* disable active roles */ - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto deinit; - } if (wlvif->bss_type == BSS_TYPE_STA_BSS || wlvif->bss_type == BSS_TYPE_IBSS) { @@ -2717,7 +2765,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, } } - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); } deinit: @@ -2785,7 +2832,7 @@ deinit: unlock: mutex_unlock(&wl->mutex); - del_timer_sync(&wlvif->rx_streaming_timer); + timer_delete_sync(&wlvif->rx_streaming_timer); cancel_work_sync(&wlvif->rx_streaming_enable_work); cancel_work_sync(&wlvif->rx_streaming_disable_work); cancel_work_sync(&wlvif->rc_update_work); @@ -2927,11 +2974,13 @@ static int wlcore_set_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif, struct ieee80211_bss_conf *bss_conf, u32 sta_rate_set) { + struct ieee80211_vif *vif = container_of(bss_conf, struct ieee80211_vif, + bss_conf); int ieoffset; int ret; - wlvif->aid = bss_conf->aid; - wlvif->channel_type = cfg80211_get_chandef_type(&bss_conf->chandef); + wlvif->aid = vif->cfg.aid; + wlvif->channel_type = cfg80211_get_chandef_type(&bss_conf->chanreq.oper); wlvif->beacon_int = bss_conf->beacon_int; wlvif->wmm_enabled = bss_conf->qos; @@ -3051,7 +3100,7 @@ static int wlcore_unset_assoc(struct wl1271 *wl, struct wl12xx_vif *wlvif) struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); wl12xx_cmd_stop_channel_switch(wl, wlvif); - ieee80211_chswitch_done(vif, false); + ieee80211_chswitch_done(vif, false, 0); cancel_delayed_work(&wlvif->channel_switch_work); } @@ -3107,7 +3156,7 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, return 0; } -static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) +static int wl1271_op_config(struct ieee80211_hw *hw, int radio_idx, u32 changed) { struct wl1271 *wl = hw->priv; struct wl12xx_vif *wlvif; @@ -3129,11 +3178,9 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } /* configure each interface */ wl12xx_for_each_wlvif(wl, wlvif) { @@ -3143,7 +3190,6 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed) } out_sleep: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: @@ -3213,11 +3259,9 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw, if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl12xx_for_each_wlvif(wl, wlvif) { if (wlcore_is_p2p_mgmt(wlvif)) @@ -3260,7 +3304,6 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw, */ out_sleep: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: @@ -3470,15 +3513,12 @@ static int wlcore_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, goto out_wake_queues; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out_wake_queues; - } ret = wlcore_hw_set_key(wl, cmd, vif, sta, key_conf); - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out_wake_queues: @@ -3564,6 +3604,10 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, return ret; } + /* Store AP encryption key type */ + if (wlvif->bss_type == BSS_TYPE_AP_BSS) + wlvif->encryption_type = key_type; + /* * reconfiguring arp response if the unicast (or common) * encryption key type was changed @@ -3622,11 +3666,9 @@ static void wl1271_op_set_default_key_idx(struct ieee80211_hw *hw, goto out_unlock; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out_unlock; - } wlvif->default_key = key_idx; @@ -3640,7 +3682,6 @@ static void wl1271_op_set_default_key_idx(struct ieee80211_hw *hw, } out_sleep: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out_unlock: @@ -3659,11 +3700,9 @@ void wlcore_regdomain_config(struct wl1271 *wl) if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_autosuspend(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wlcore_cmd_regdomain_config_locked(wl); if (ret < 0) { @@ -3671,7 +3710,6 @@ void wlcore_regdomain_config(struct wl1271 *wl) goto out; } - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -3706,11 +3744,9 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } /* fail if there is any role in ROC */ if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) < WL12XX_MAX_ROLES) { @@ -3721,7 +3757,6 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, ret = wlcore_scan(hw->priv, vif, ssid, len, req); out_sleep: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -3749,11 +3784,9 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw, if (wl->scan.state == WL1271_SCAN_STATE_IDLE) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } if (wl->scan.state != WL1271_SCAN_STATE_DONE) { ret = wl->ops->scan_stop(wl, wlvif); @@ -3774,7 +3807,6 @@ static void wl1271_op_cancel_hw_scan(struct ieee80211_hw *hw, ieee80211_scan_completed(wl->hw, &info); out_sleep: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -3800,11 +3832,9 @@ static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw, goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl->ops->sched_scan_start(wl, wlvif, req, ies); if (ret < 0) @@ -3813,7 +3843,6 @@ static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw, wl->sched_vif = wlvif; out_sleep: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -3834,15 +3863,12 @@ static int wl1271_op_sched_scan_stop(struct ieee80211_hw *hw, if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl->ops->sched_scan_stop(wl, wlvif); - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -3850,7 +3876,8 @@ out: return 0; } -static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) +static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, + int radio_idx, u32 value) { struct wl1271 *wl = hw->priv; int ret = 0; @@ -3862,17 +3889,14 @@ static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value) goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl1271_acx_frag_threshold(wl, value); if (ret < 0) wl1271_warning("wl1271_op_set_frag_threshold failed: %d", ret); - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: @@ -3881,7 +3905,8 @@ out: return ret; } -static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) +static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, + u32 value) { struct wl1271 *wl = hw->priv; struct wl12xx_vif *wlvif; @@ -3894,18 +3919,15 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value) goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl12xx_for_each_wlvif(wl, wlvif) { ret = wl1271_acx_rts_threshold(wl, wlvif, value); if (ret < 0) wl1271_warning("set rts threshold failed: %d", ret); } - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: @@ -3980,7 +4002,6 @@ static int wl1271_ap_set_probe_resp_tmpl_legacy(struct wl1271 *wl, u32 rates) { struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); - struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; u8 probe_rsp_templ[WL1271_CMD_TEMPL_MAX_SIZE]; int ssid_ie_offset, ie_offset, templ_len; const u8 *ptr; @@ -3993,7 +4014,7 @@ static int wl1271_ap_set_probe_resp_tmpl_legacy(struct wl1271 *wl, probe_rsp_len, 0, rates); - if (probe_rsp_len + bss_conf->ssid_len > WL1271_CMD_TEMPL_MAX_SIZE) { + if (probe_rsp_len + vif->cfg.ssid_len > WL1271_CMD_TEMPL_MAX_SIZE) { wl1271_error("probe_rsp template too big"); return -EINVAL; } @@ -4015,12 +4036,12 @@ static int wl1271_ap_set_probe_resp_tmpl_legacy(struct wl1271 *wl, /* insert SSID from bss_conf */ probe_rsp_templ[ssid_ie_offset] = WLAN_EID_SSID; - probe_rsp_templ[ssid_ie_offset + 1] = bss_conf->ssid_len; + probe_rsp_templ[ssid_ie_offset + 1] = vif->cfg.ssid_len; memcpy(probe_rsp_templ + ssid_ie_offset + 2, - bss_conf->ssid, bss_conf->ssid_len); - templ_len = ssid_ie_offset + 2 + bss_conf->ssid_len; + vif->cfg.ssid, vif->cfg.ssid_len); + templ_len = ssid_ie_offset + 2 + vif->cfg.ssid_len; - memcpy(probe_rsp_templ + ssid_ie_offset + 2 + bss_conf->ssid_len, + memcpy(probe_rsp_templ + ssid_ie_offset + 2 + vif->cfg.ssid_len, ptr, probe_rsp_len - (ptr - probe_rsp_data)); templ_len += probe_rsp_len - (ptr - probe_rsp_data); @@ -4083,7 +4104,7 @@ static int wlcore_set_beacon_template(struct wl1271 *wl, u32 min_rate; int ret; int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable); - struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif); + struct sk_buff *beacon = ieee80211_beacon_get(wl->hw, vif, 0); u16 tmpl_id; if (!beacon) { @@ -4286,7 +4307,7 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl, /* Handle HT information change */ if ((changed & BSS_CHANGED_HT) && - (bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT)) { + (bss_conf->chanreq.oper.width != NL80211_CHAN_WIDTH_20_NOHT)) { ret = wl1271_acx_set_ht_information(wl, wlvif, bss_conf->ht_operation_mode); if (ret < 0) { @@ -4300,15 +4321,15 @@ out: } static int wlcore_set_bssid(struct wl1271 *wl, struct wl12xx_vif *wlvif, - struct ieee80211_bss_conf *bss_conf, - u32 sta_rate_set) + struct ieee80211_vif *vif, u32 sta_rate_set) { + struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; u32 rates; int ret; wl1271_debug(DEBUG_MAC80211, "changed_bssid: %pM, aid: %d, bcn_int: %d, brates: 0x%x sta_rate_set: 0x%x", - bss_conf->bssid, bss_conf->aid, + bss_conf->bssid, vif->cfg.aid, bss_conf->beacon_int, bss_conf->basic_rates, sta_rate_set); @@ -4396,7 +4417,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, } if (changed & BSS_CHANGED_IBSS) { - if (bss_conf->ibss_joined) { + if (vif->cfg.ibss_joined) { set_bit(WLVIF_FLAG_IBSS_JOINED, &wlvif->flags); ibss_joined = true; } else { @@ -4420,7 +4441,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, } if (changed & BSS_CHANGED_IDLE && !is_ibss) - wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle); + wl1271_sta_handle_idle(wl, wlvif, vif->cfg.idle); if (changed & BSS_CHANGED_CQM) { bool enable = false; @@ -4439,15 +4460,15 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, rcu_read_lock(); sta = ieee80211_find_sta(vif, bss_conf->bssid); if (sta) { - u8 *rx_mask = sta->ht_cap.mcs.rx_mask; + u8 *rx_mask = sta->deflink.ht_cap.mcs.rx_mask; /* save the supp_rates of the ap */ - sta_rate_set = sta->supp_rates[wlvif->band]; - if (sta->ht_cap.ht_supported) + sta_rate_set = sta->deflink.supp_rates[wlvif->band]; + if (sta->deflink.ht_cap.ht_supported) sta_rate_set |= (rx_mask[0] << HW_HT_RATES_OFFSET) | (rx_mask[1] << HW_MIMO_RATES_OFFSET); - sta_ht_cap = sta->ht_cap; + sta_ht_cap = sta->deflink.ht_cap; sta_exists = true; } @@ -4456,7 +4477,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, if (changed & BSS_CHANGED_BSSID) { if (!is_zero_ether_addr(bss_conf->bssid)) { - ret = wlcore_set_bssid(wl, wlvif, bss_conf, + ret = wlcore_set_bssid(wl, wlvif, vif, sta_rate_set); if (ret < 0) goto out; @@ -4472,9 +4493,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, if (changed & BSS_CHANGED_IBSS) { wl1271_debug(DEBUG_ADHOC, "ibss_joined: %d", - bss_conf->ibss_joined); + vif->cfg.ibss_joined); - if (bss_conf->ibss_joined) { + if (vif->cfg.ibss_joined) { u32 rates = bss_conf->basic_rates; wlvif->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates, @@ -4511,7 +4532,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, } if (changed & BSS_CHANGED_ASSOC) { - if (bss_conf->assoc) { + if (vif->cfg.assoc) { ret = wlcore_set_assoc(wl, wlvif, bss_conf, sta_rate_set); if (ret < 0) @@ -4525,7 +4546,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, } if (changed & BSS_CHANGED_PS) { - if ((bss_conf->ps) && + if (vif->cfg.ps && test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) && !test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) { int ps_mode; @@ -4545,7 +4566,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, if (ret < 0) wl1271_warning("enter %s ps failed %d", ps_mode_str, ret); - } else if (!bss_conf->ps && + } else if (!vif->cfg.ps && test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) { wl1271_debug(DEBUG_PSM, "auto ps disabled"); @@ -4559,7 +4580,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, /* Handle new association with HT. Do this after join. */ if (sta_exists) { bool enabled = - bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT; + bss_conf->chanreq.oper.width != NL80211_CHAN_WIDTH_20_NOHT; ret = wlcore_hw_set_peer_cap(wl, &sta_ht_cap, @@ -4586,11 +4607,11 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, /* Handle arp filtering. Done after join. */ if ((changed & BSS_CHANGED_ARP_FILTER) || (!is_ibss && (changed & BSS_CHANGED_QOS))) { - __be32 addr = bss_conf->arp_addr_list[0]; + __be32 addr = vif->cfg.arp_addr_list[0]; wlvif->sta.qos = bss_conf->qos; WARN_ON(wlvif->bss_type != BSS_TYPE_STA_BSS); - if (bss_conf->arp_addr_cnt == 1 && bss_conf->assoc) { + if (vif->cfg.arp_addr_cnt == 1 && vif->cfg.assoc) { wlvif->ip_addr = addr; /* * The template should have been configured only upon @@ -4624,7 +4645,7 @@ out: static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *bss_conf, - u32 changed) + u64 changed) { struct wl1271 *wl = hw->priv; struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); @@ -4653,11 +4674,9 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } if ((changed & BSS_CHANGED_TXPOWER) && bss_conf->txpower != wlvif->power_level) { @@ -4674,7 +4693,6 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw, else wl1271_bss_info_changed_sta(wl, vif, bss_conf, changed); - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: @@ -4714,17 +4732,15 @@ static void wlcore_op_change_chanctx(struct ieee80211_hw *hw, mutex_lock(&wl->mutex); - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl12xx_for_each_wlvif(wl, wlvif) { struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); rcu_read_lock(); - if (rcu_access_pointer(vif->chanctx_conf) != ctx) { + if (rcu_access_pointer(vif->bss_conf.chanctx_conf) != ctx) { rcu_read_unlock(); continue; } @@ -4741,7 +4757,6 @@ static void wlcore_op_change_chanctx(struct ieee80211_hw *hw, } } - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -4749,6 +4764,7 @@ out: static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, struct ieee80211_chanctx_conf *ctx) { struct wl1271 *wl = hw->priv; @@ -4771,11 +4787,9 @@ static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw, if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wlvif->band = ctx->def.chan->band; wlvif->channel = channel; @@ -4791,7 +4805,6 @@ static int wlcore_op_assign_vif_chanctx(struct ieee80211_hw *hw, wlvif->radar_enabled = true; } - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -4801,6 +4814,7 @@ out: static void wlcore_op_unassign_vif_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, struct ieee80211_chanctx_conf *ctx) { struct wl1271 *wl = hw->priv; @@ -4823,11 +4837,9 @@ static void wlcore_op_unassign_vif_chanctx(struct ieee80211_hw *hw, if (unlikely(!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags))) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } if (wlvif->radar_enabled) { wl1271_debug(DEBUG_MAC80211, "Stop radar detection"); @@ -4835,7 +4847,6 @@ static void wlcore_op_unassign_vif_chanctx(struct ieee80211_hw *hw, wlvif->radar_enabled = false; } - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -4893,11 +4904,9 @@ wlcore_op_switch_vif_chanctx(struct ieee80211_hw *hw, mutex_lock(&wl->mutex); - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } for (i = 0; i < n_vifs; i++) { struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vifs[i].vif); @@ -4907,7 +4916,6 @@ wlcore_op_switch_vif_chanctx(struct ieee80211_hw *hw, goto out_sleep; } out_sleep: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -4916,7 +4924,8 @@ out: } static int wl1271_op_conf_tx(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, u16 queue, + struct ieee80211_vif *vif, + unsigned int link_id, u16 queue, const struct ieee80211_tx_queue_params *params) { struct wl1271 *wl = hw->priv; @@ -4939,11 +4948,9 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, if (!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } /* * the txop is confed in units of 32us by the mac80211, @@ -4962,7 +4969,6 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, 0, 0); out_sleep: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: @@ -4987,18 +4993,15 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw, if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl12xx_acx_tsf_info(wl, wlvif, &mactime); if (ret < 0) goto out_sleep; out_sleep: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: @@ -5194,19 +5197,23 @@ static int wl12xx_update_sta_state(struct wl1271 *wl, /* Add station (AP mode) */ if (is_ap && - old_state == IEEE80211_STA_NOTEXIST && - new_state == IEEE80211_STA_NONE) { + old_state == IEEE80211_STA_AUTH && + new_state == IEEE80211_STA_ASSOC) { ret = wl12xx_sta_add(wl, wlvif, sta); if (ret) return ret; + wl_sta->fw_added = true; + wlcore_update_inconn_sta(wl, wlvif, wl_sta, true); } /* Remove station (AP mode) */ if (is_ap && - old_state == IEEE80211_STA_NONE && - new_state == IEEE80211_STA_NOTEXIST) { + old_state == IEEE80211_STA_ASSOC && + new_state == IEEE80211_STA_AUTH) { + wl_sta->fw_added = false; + /* must not fail */ wl12xx_sta_remove(wl, wlvif, sta); @@ -5220,12 +5227,8 @@ static int wl12xx_update_sta_state(struct wl1271 *wl, if (ret < 0) return ret; - /* reconfigure rates */ - ret = wl12xx_cmd_add_peer(wl, wlvif, sta, wl_sta->hlid); - if (ret < 0) - return ret; - - ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true, + ret = wl1271_acx_set_ht_capabilities(wl, &sta->deflink.ht_cap, + true, wl_sta->hlid); if (ret) return ret; @@ -5305,15 +5308,12 @@ static int wl12xx_op_sta_state(struct ieee80211_hw *hw, goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl12xx_update_sta_state(wl, wlvif, sta, old_state, new_state); - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -5363,11 +5363,9 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw, ba_bitmap = &wl->links[hlid].ba_bitmap; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl1271_debug(DEBUG_MAC80211, "mac80211 ampdu: Rx tid %d action %d", tid, action); @@ -5440,7 +5438,6 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw, ret = -EINVAL; } - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: @@ -5475,18 +5472,15 @@ static int wl12xx_set_bitrate_mask(struct ieee80211_hw *hw, if (wlvif->bss_type == BSS_TYPE_STA_BSS && !test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) { - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } wl1271_set_band_rate(wl, wlvif); wlvif->basic_rate = wl1271_tx_min_rate_get(wl, wlvif->basic_rate_set); ret = wl1271_acx_sta_rate_policies(wl, wlvif); - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); } out: @@ -5511,17 +5505,15 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, if (unlikely(wl->state == WLCORE_STATE_OFF)) { if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) - ieee80211_chswitch_done(vif, false); + ieee80211_chswitch_done(vif, false, 0); goto out; } else if (unlikely(wl->state != WLCORE_STATE_ON)) { goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } /* TODO: change mac80211 to pass vif as param */ @@ -5543,7 +5535,6 @@ static void wl12xx_op_channel_switch(struct ieee80211_hw *hw, } out_sleep: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: @@ -5556,7 +5547,7 @@ static const void *wlcore_get_beacon_ie(struct wl1271 *wl, { int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable); struct sk_buff *beacon = - ieee80211_beacon_get(wl->hw, wl12xx_wlvif_to_vif(wlvif)); + ieee80211_beacon_get(wl->hw, wl12xx_wlvif_to_vif(wlvif), 0); if (!beacon) return NULL; @@ -5611,11 +5602,9 @@ static void wlcore_op_channel_switch_beacon(struct ieee80211_hw *hw, goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl->ops->channel_switch(wl, wlvif, &ch_switch); if (ret) @@ -5624,7 +5613,6 @@ static void wlcore_op_channel_switch_beacon(struct ieee80211_hw *hw, set_bit(WLVIF_FLAG_CS_PROGRESS, &wlvif->flags); out_sleep: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -5666,11 +5654,9 @@ static int wlcore_op_remain_on_channel(struct ieee80211_hw *hw, goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = wl12xx_start_dev(wl, wlvif, chan->band, channel); if (ret < 0) @@ -5680,7 +5666,6 @@ static int wlcore_op_remain_on_channel(struct ieee80211_hw *hw, ieee80211_queue_delayed_work(hw, &wl->roc_complete_work, msecs_to_jiffies(duration)); out_sleep: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -5723,15 +5708,12 @@ static int wlcore_roc_completed(struct wl1271 *wl) goto out; } - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out; - } ret = __wlcore_roc_completed(wl); - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: mutex_unlock(&wl->mutex); @@ -5775,9 +5757,10 @@ static int wlcore_op_cancel_remain_on_channel(struct ieee80211_hw *hw, static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta, + struct ieee80211_link_sta *link_sta, u32 changed) { + struct ieee80211_sta *sta = link_sta->sta; struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); wl1271_debug(DEBUG_MAC80211, "mac80211 sta_rc_update"); @@ -5786,8 +5769,9 @@ static void wlcore_op_sta_rc_update(struct ieee80211_hw *hw, return; /* this callback is atomic, so schedule a new work */ - wlvif->rc_update_bw = sta->bandwidth; - memcpy(&wlvif->rc_ht_cap, &sta->ht_cap, sizeof(sta->ht_cap)); + wlvif->rc_update_bw = sta->deflink.bandwidth; + memcpy(&wlvif->rc_ht_cap, &sta->deflink.ht_cap, + sizeof(sta->deflink.ht_cap)); ieee80211_queue_work(hw, &wlvif->rc_update_work); } @@ -5808,11 +5792,9 @@ static void wlcore_op_sta_statistics(struct ieee80211_hw *hw, if (unlikely(wl->state != WLCORE_STATE_ON)) goto out; - ret = pm_runtime_get_sync(wl->dev); - if (ret < 0) { - pm_runtime_put_noidle(wl->dev); + ret = pm_runtime_resume_and_get(wl->dev); + if (ret < 0) goto out_sleep; - } ret = wlcore_acx_average_rssi(wl, wlvif, &rssi_dbm); if (ret < 0) @@ -5822,7 +5804,6 @@ static void wlcore_op_sta_statistics(struct ieee80211_hw *hw, sinfo->signal = rssi_dbm; out_sleep: - pm_runtime_mark_last_busy(wl->dev); pm_runtime_put_autosuspend(wl->dev); out: @@ -6011,6 +5992,7 @@ static const struct ieee80211_ops wl1271_ops = { .prepare_multicast = wl1271_op_prepare_multicast, .configure_filter = wl1271_op_configure_filter, .tx = wl1271_op_tx, + .wake_tx_queue = ieee80211_handle_wake_tx_queue, .set_key = wlcore_op_set_key, .hw_scan = wl1271_op_hw_scan, .cancel_hw_scan = wl1271_op_cancel_hw_scan, @@ -6038,7 +6020,7 @@ static const struct ieee80211_ops wl1271_ops = { .assign_vif_chanctx = wlcore_op_assign_vif_chanctx, .unassign_vif_chanctx = wlcore_op_unassign_vif_chanctx, .switch_vif_chanctx = wlcore_op_switch_vif_chanctx, - .sta_rc_update = wlcore_op_sta_rc_update, + .link_sta_rc_update = wlcore_op_sta_rc_update, .sta_statistics = wlcore_op_sta_statistics, .get_expected_throughput = wlcore_op_get_expected_throughput, CFG80211_TESTMODE_CMD(wl1271_tm_cmd) @@ -6169,7 +6151,7 @@ static int wl1271_register_hw(struct wl1271 *wl) wl1271_warning("Fuse mac address is zero. using random mac"); /* Use TI oui and a random nic */ oui_addr = WLCORE_TI_OUI_ADDRESS; - nic_addr = get_random_int(); + nic_addr = get_random_u32(); } else { oui_addr = wl->fuse_oui_addr; /* fuse has the BD_ADDR, the WLAN addresses are the next two */ @@ -6805,7 +6787,7 @@ int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) } EXPORT_SYMBOL_GPL(wlcore_probe); -int wlcore_remove(struct platform_device *pdev) +void wlcore_remove(struct platform_device *pdev) { struct wlcore_platdev_data *pdev_data = dev_get_platdata(&pdev->dev); struct wl1271 *wl = platform_get_drvdata(pdev); @@ -6820,7 +6802,7 @@ int wlcore_remove(struct platform_device *pdev) if (pdev_data->family && pdev_data->family->nvs_name) wait_for_completion(&wl->nvs_loading_complete); if (!wl->initialized) - return 0; + return; if (wl->wakeirq >= 0) { dev_pm_clear_wake_irq(wl->dev); @@ -6840,8 +6822,6 @@ int wlcore_remove(struct platform_device *pdev) free_irq(wl->irq, wl); wlcore_free_hw(wl); - - return 0; } EXPORT_SYMBOL_GPL(wlcore_remove); @@ -6863,6 +6843,7 @@ MODULE_PARM_DESC(bug_on_recovery, "BUG() on fw recovery"); module_param(no_recovery, int, 0600); MODULE_PARM_DESC(no_recovery, "Prevent HW recovery. FW will remain stuck."); +MODULE_DESCRIPTION("TI WLAN core driver"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>"); |
