Loading drivers/net/wireless/wl12xx/cmd.c +3 −0 Original line number Diff line number Diff line Loading @@ -1835,6 +1835,9 @@ int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif) wlvif->bss_type == BSS_TYPE_IBSS))) return -EINVAL; /* flush all pending packets */ wl1271_tx_work_locked(wl); if (test_bit(wlvif->dev_role_id, wl->roc_map)) { ret = wl12xx_croc(wl, wlvif->dev_role_id); if (ret < 0) Loading drivers/net/wireless/wl12xx/event.c +1 −1 Original line number Diff line number Diff line Loading @@ -267,8 +267,8 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_COMPLETE_EVENT " "(status 0x%0x)", mbox->scheduled_scan_status); if (wl->sched_scanning) { wl1271_scan_sched_scan_stop(wl); ieee80211_sched_scan_stopped(wl->hw); wl->sched_scanning = false; } } Loading drivers/net/wireless/wl12xx/main.c +53 −51 Original line number Diff line number Diff line Loading @@ -450,7 +450,16 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, if (wl->state == WL1271_STATE_OFF) goto out; if (dev->operstate != IF_OPER_UP) goto out; /* * The correct behavior should be just getting the appropriate wlvif * from the given dev, but currently we don't have a mac80211 * interface for it. */ wl12xx_for_each_wlvif_sta(wl, wlvif) { struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) continue; Loading @@ -458,7 +467,8 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, if (ret < 0) goto out; wl1271_check_operstate(wl, wlvif, dev->operstate); wl1271_check_operstate(wl, wlvif, ieee80211_get_operstate(vif)); wl1271_ps_elp_sleep(wl); } Loading Loading @@ -2036,6 +2046,11 @@ static bool wl12xx_init_fw(struct wl1271 *wl) return booted; } static bool wl12xx_dev_role_started(struct wl12xx_vif *wlvif) { return wlvif->dev_hlid != WL12XX_INVALID_LINK_ID; } static int wl1271_op_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { Loading Loading @@ -2184,7 +2199,11 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, if (ret < 0) goto deinit; if (wlvif->bss_type == BSS_TYPE_STA_BSS) { if (wlvif->bss_type == BSS_TYPE_STA_BSS || wlvif->bss_type == BSS_TYPE_IBSS) { if (wl12xx_dev_role_started(wlvif)) wl12xx_stop_dev(wl, wlvif); ret = wl12xx_cmd_role_disable(wl, &wlvif->dev_role_id); if (ret < 0) goto deinit; Loading Loading @@ -2269,6 +2288,17 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, cancel_work_sync(&wl->recovery_work); } static int wl12xx_op_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum nl80211_iftype new_type, bool p2p) { wl1271_op_remove_interface(hw, vif); vif->type = ieee80211_iftype_p2p(new_type, p2p); vif->p2p = p2p; return wl1271_op_add_interface(hw, vif); } static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif, bool set_assoc) { Loading Loading @@ -2358,25 +2388,18 @@ static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif) wlvif->rate_set = wlvif->basic_rate_set; } static bool wl12xx_is_roc(struct wl1271 *wl) { u8 role_id; role_id = find_first_bit(wl->roc_map, WL12XX_MAX_ROLES); if (role_id >= WL12XX_MAX_ROLES) return false; return true; } static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif, bool idle) { int ret; bool cur_idle = !test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags); if (idle == cur_idle) return 0; if (idle) { /* no need to croc if we weren't busy (e.g. during boot) */ if (wl12xx_is_roc(wl)) { if (wl12xx_dev_role_started(wlvif)) { ret = wl12xx_stop_dev(wl, wlvif); if (ret < 0) goto out; Loading @@ -2391,7 +2414,7 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif, ACX_KEEP_ALIVE_TPL_INVALID); if (ret < 0) goto out; set_bit(WL1271_FLAG_IDLE, &wl->flags); clear_bit(WLVIF_FLAG_IN_USE, &wlvif->flags); } else { /* The current firmware only supports sched_scan in idle */ if (wl->sched_scanning) { Loading @@ -2402,7 +2425,7 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif, ret = wl12xx_start_dev(wl, wlvif); if (ret < 0) goto out; clear_bit(WL1271_FLAG_IDLE, &wl->flags); set_bit(WLVIF_FLAG_IN_USE, &wlvif->flags); } out: Loading Loading @@ -2446,7 +2469,7 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) { if (wl12xx_is_roc(wl)) { if (wl12xx_dev_role_started(wlvif)) { /* roaming */ ret = wl12xx_croc(wl, wlvif->dev_role_id); Loading @@ -2463,7 +2486,7 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, * not idle. otherwise, CROC will be called * anyway. */ if (wl12xx_is_roc(wl) && if (wl12xx_dev_role_started(wlvif) && !(conf->flags & IEEE80211_CONF_IDLE)) { ret = wl12xx_stop_dev(wl, wlvif); if (ret < 0) Loading Loading @@ -3010,15 +3033,16 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, if (ret < 0) goto out; /* cancel ROC before scanning */ if (wl12xx_is_roc(wl)) { if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) { if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) && test_bit(wlvif->role_id, wl->roc_map)) { /* don't allow scanning right now */ ret = -EBUSY; goto out_sleep; } /* cancel ROC before scanning */ if (wl12xx_dev_role_started(wlvif)) wl12xx_stop_dev(wl, wlvif); } ret = wl1271_scan(hw->priv, vif, ssid, len, req); out_sleep: Loading Loading @@ -3829,9 +3853,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, } /* * stop device role if started (we might already be in * STA role). TODO: make it better. * STA/IBSS role). */ if (wlvif->dev_role_id != WL12XX_INVALID_ROLE_ID) { if (wl12xx_dev_role_started(wlvif)) { ret = wl12xx_stop_dev(wl, wlvif); if (ret < 0) goto out; Loading Loading @@ -3948,31 +3972,8 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, else ps_scheme = CONF_PS_SCHEME_LEGACY; if (wl->state == WL1271_STATE_OFF) { /* * If the state is off, the parameters will be recorded and * configured on init. This happens in AP-mode. */ struct conf_tx_ac_category *conf_ac = &wl->conf.tx.ac_conf[wl1271_tx_get_queue(queue)]; struct conf_tx_tid *conf_tid = &wl->conf.tx.tid_conf[wl1271_tx_get_queue(queue)]; conf_ac->ac = wl1271_tx_get_queue(queue); conf_ac->cw_min = (u8)params->cw_min; conf_ac->cw_max = params->cw_max; conf_ac->aifsn = params->aifs; conf_ac->tx_op_limit = params->txop << 5; conf_tid->queue_id = wl1271_tx_get_queue(queue); conf_tid->channel_type = CONF_CHANNEL_TYPE_EDCF; conf_tid->tsid = wl1271_tx_get_queue(queue); conf_tid->ps_scheme = ps_scheme; conf_tid->ack_policy = CONF_ACK_POLICY_LEGACY; conf_tid->apsd_conf[0] = 0; conf_tid->apsd_conf[1] = 0; if (!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)) goto out; } ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) Loading Loading @@ -4629,6 +4630,7 @@ static const struct ieee80211_ops wl1271_ops = { .stop = wl1271_op_stop, .add_interface = wl1271_op_add_interface, .remove_interface = wl1271_op_remove_interface, .change_interface = wl12xx_op_change_interface, #ifdef CONFIG_PM .suspend = wl1271_op_suspend, .resume = wl1271_op_resume, Loading drivers/net/wireless/wl12xx/ps.c +8 −2 Original line number Diff line number Diff line Loading @@ -53,8 +53,11 @@ void wl1271_elp_work(struct work_struct *work) goto out; wl12xx_for_each_wlvif(wl, wlvif) { if (wlvif->bss_type == BSS_TYPE_AP_BSS) goto out; if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags) && !test_bit(WL1271_FLAG_IDLE, &wl->flags)) test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) goto out; } Loading @@ -78,8 +81,11 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) return; wl12xx_for_each_wlvif(wl, wlvif) { if (wlvif->bss_type == BSS_TYPE_AP_BSS) return; if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags) && !test_bit(WL1271_FLAG_IDLE, &wl->flags)) test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) return; } Loading drivers/net/wireless/wl12xx/scan.c +9 −9 Original line number Diff line number Diff line Loading @@ -437,18 +437,19 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, if (flags & IEEE80211_CHAN_RADAR) { channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS; channels[j].passive_duration = cpu_to_le16(c->dwell_time_dfs); } else if (flags & IEEE80211_CHAN_PASSIVE_SCAN) { } else { channels[j].passive_duration = cpu_to_le16(c->dwell_time_passive); } else { } channels[j].min_duration = cpu_to_le16(c->min_dwell_time_active); channels[j].max_duration = cpu_to_le16(c->max_dwell_time_active); } channels[j].tx_power_att = req->channels[i]->max_power; channels[j].channel = req->channels[i]->hw_value; Loading Loading @@ -703,7 +704,7 @@ int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif) if (wlvif->bss_type != BSS_TYPE_STA_BSS) return -EOPNOTSUPP; if (!test_bit(WL1271_FLAG_IDLE, &wl->flags)) if (test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) return -EBUSY; start = kzalloc(sizeof(*start), GFP_KERNEL); Loading Loading @@ -753,7 +754,6 @@ void wl1271_scan_sched_scan_stop(struct wl1271 *wl) wl1271_error("failed to send sched scan stop command"); goto out_free; } wl->sched_scanning = false; out_free: kfree(stop); Loading Loading
drivers/net/wireless/wl12xx/cmd.c +3 −0 Original line number Diff line number Diff line Loading @@ -1835,6 +1835,9 @@ int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif) wlvif->bss_type == BSS_TYPE_IBSS))) return -EINVAL; /* flush all pending packets */ wl1271_tx_work_locked(wl); if (test_bit(wlvif->dev_role_id, wl->roc_map)) { ret = wl12xx_croc(wl, wlvif->dev_role_id); if (ret < 0) Loading
drivers/net/wireless/wl12xx/event.c +1 −1 Original line number Diff line number Diff line Loading @@ -267,8 +267,8 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_COMPLETE_EVENT " "(status 0x%0x)", mbox->scheduled_scan_status); if (wl->sched_scanning) { wl1271_scan_sched_scan_stop(wl); ieee80211_sched_scan_stopped(wl->hw); wl->sched_scanning = false; } } Loading
drivers/net/wireless/wl12xx/main.c +53 −51 Original line number Diff line number Diff line Loading @@ -450,7 +450,16 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, if (wl->state == WL1271_STATE_OFF) goto out; if (dev->operstate != IF_OPER_UP) goto out; /* * The correct behavior should be just getting the appropriate wlvif * from the given dev, but currently we don't have a mac80211 * interface for it. */ wl12xx_for_each_wlvif_sta(wl, wlvif) { struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif); if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) continue; Loading @@ -458,7 +467,8 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what, if (ret < 0) goto out; wl1271_check_operstate(wl, wlvif, dev->operstate); wl1271_check_operstate(wl, wlvif, ieee80211_get_operstate(vif)); wl1271_ps_elp_sleep(wl); } Loading Loading @@ -2036,6 +2046,11 @@ static bool wl12xx_init_fw(struct wl1271 *wl) return booted; } static bool wl12xx_dev_role_started(struct wl12xx_vif *wlvif) { return wlvif->dev_hlid != WL12XX_INVALID_LINK_ID; } static int wl1271_op_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { Loading Loading @@ -2184,7 +2199,11 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, if (ret < 0) goto deinit; if (wlvif->bss_type == BSS_TYPE_STA_BSS) { if (wlvif->bss_type == BSS_TYPE_STA_BSS || wlvif->bss_type == BSS_TYPE_IBSS) { if (wl12xx_dev_role_started(wlvif)) wl12xx_stop_dev(wl, wlvif); ret = wl12xx_cmd_role_disable(wl, &wlvif->dev_role_id); if (ret < 0) goto deinit; Loading Loading @@ -2269,6 +2288,17 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, cancel_work_sync(&wl->recovery_work); } static int wl12xx_op_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum nl80211_iftype new_type, bool p2p) { wl1271_op_remove_interface(hw, vif); vif->type = ieee80211_iftype_p2p(new_type, p2p); vif->p2p = p2p; return wl1271_op_add_interface(hw, vif); } static int wl1271_join(struct wl1271 *wl, struct wl12xx_vif *wlvif, bool set_assoc) { Loading Loading @@ -2358,25 +2388,18 @@ static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif) wlvif->rate_set = wlvif->basic_rate_set; } static bool wl12xx_is_roc(struct wl1271 *wl) { u8 role_id; role_id = find_first_bit(wl->roc_map, WL12XX_MAX_ROLES); if (role_id >= WL12XX_MAX_ROLES) return false; return true; } static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif, bool idle) { int ret; bool cur_idle = !test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags); if (idle == cur_idle) return 0; if (idle) { /* no need to croc if we weren't busy (e.g. during boot) */ if (wl12xx_is_roc(wl)) { if (wl12xx_dev_role_started(wlvif)) { ret = wl12xx_stop_dev(wl, wlvif); if (ret < 0) goto out; Loading @@ -2391,7 +2414,7 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif, ACX_KEEP_ALIVE_TPL_INVALID); if (ret < 0) goto out; set_bit(WL1271_FLAG_IDLE, &wl->flags); clear_bit(WLVIF_FLAG_IN_USE, &wlvif->flags); } else { /* The current firmware only supports sched_scan in idle */ if (wl->sched_scanning) { Loading @@ -2402,7 +2425,7 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif, ret = wl12xx_start_dev(wl, wlvif); if (ret < 0) goto out; clear_bit(WL1271_FLAG_IDLE, &wl->flags); set_bit(WLVIF_FLAG_IN_USE, &wlvif->flags); } out: Loading Loading @@ -2446,7 +2469,7 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) { if (wl12xx_is_roc(wl)) { if (wl12xx_dev_role_started(wlvif)) { /* roaming */ ret = wl12xx_croc(wl, wlvif->dev_role_id); Loading @@ -2463,7 +2486,7 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, * not idle. otherwise, CROC will be called * anyway. */ if (wl12xx_is_roc(wl) && if (wl12xx_dev_role_started(wlvif) && !(conf->flags & IEEE80211_CONF_IDLE)) { ret = wl12xx_stop_dev(wl, wlvif); if (ret < 0) Loading Loading @@ -3010,15 +3033,16 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, if (ret < 0) goto out; /* cancel ROC before scanning */ if (wl12xx_is_roc(wl)) { if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) { if (test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags) && test_bit(wlvif->role_id, wl->roc_map)) { /* don't allow scanning right now */ ret = -EBUSY; goto out_sleep; } /* cancel ROC before scanning */ if (wl12xx_dev_role_started(wlvif)) wl12xx_stop_dev(wl, wlvif); } ret = wl1271_scan(hw->priv, vif, ssid, len, req); out_sleep: Loading Loading @@ -3829,9 +3853,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, } /* * stop device role if started (we might already be in * STA role). TODO: make it better. * STA/IBSS role). */ if (wlvif->dev_role_id != WL12XX_INVALID_ROLE_ID) { if (wl12xx_dev_role_started(wlvif)) { ret = wl12xx_stop_dev(wl, wlvif); if (ret < 0) goto out; Loading Loading @@ -3948,31 +3972,8 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, else ps_scheme = CONF_PS_SCHEME_LEGACY; if (wl->state == WL1271_STATE_OFF) { /* * If the state is off, the parameters will be recorded and * configured on init. This happens in AP-mode. */ struct conf_tx_ac_category *conf_ac = &wl->conf.tx.ac_conf[wl1271_tx_get_queue(queue)]; struct conf_tx_tid *conf_tid = &wl->conf.tx.tid_conf[wl1271_tx_get_queue(queue)]; conf_ac->ac = wl1271_tx_get_queue(queue); conf_ac->cw_min = (u8)params->cw_min; conf_ac->cw_max = params->cw_max; conf_ac->aifsn = params->aifs; conf_ac->tx_op_limit = params->txop << 5; conf_tid->queue_id = wl1271_tx_get_queue(queue); conf_tid->channel_type = CONF_CHANNEL_TYPE_EDCF; conf_tid->tsid = wl1271_tx_get_queue(queue); conf_tid->ps_scheme = ps_scheme; conf_tid->ack_policy = CONF_ACK_POLICY_LEGACY; conf_tid->apsd_conf[0] = 0; conf_tid->apsd_conf[1] = 0; if (!test_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags)) goto out; } ret = wl1271_ps_elp_wakeup(wl); if (ret < 0) Loading Loading @@ -4629,6 +4630,7 @@ static const struct ieee80211_ops wl1271_ops = { .stop = wl1271_op_stop, .add_interface = wl1271_op_add_interface, .remove_interface = wl1271_op_remove_interface, .change_interface = wl12xx_op_change_interface, #ifdef CONFIG_PM .suspend = wl1271_op_suspend, .resume = wl1271_op_resume, Loading
drivers/net/wireless/wl12xx/ps.c +8 −2 Original line number Diff line number Diff line Loading @@ -53,8 +53,11 @@ void wl1271_elp_work(struct work_struct *work) goto out; wl12xx_for_each_wlvif(wl, wlvif) { if (wlvif->bss_type == BSS_TYPE_AP_BSS) goto out; if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags) && !test_bit(WL1271_FLAG_IDLE, &wl->flags)) test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) goto out; } Loading @@ -78,8 +81,11 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) return; wl12xx_for_each_wlvif(wl, wlvif) { if (wlvif->bss_type == BSS_TYPE_AP_BSS) return; if (!test_bit(WLVIF_FLAG_PSM, &wlvif->flags) && !test_bit(WL1271_FLAG_IDLE, &wl->flags)) test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) return; } Loading
drivers/net/wireless/wl12xx/scan.c +9 −9 Original line number Diff line number Diff line Loading @@ -437,18 +437,19 @@ wl1271_scan_get_sched_scan_channels(struct wl1271 *wl, if (flags & IEEE80211_CHAN_RADAR) { channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS; channels[j].passive_duration = cpu_to_le16(c->dwell_time_dfs); } else if (flags & IEEE80211_CHAN_PASSIVE_SCAN) { } else { channels[j].passive_duration = cpu_to_le16(c->dwell_time_passive); } else { } channels[j].min_duration = cpu_to_le16(c->min_dwell_time_active); channels[j].max_duration = cpu_to_le16(c->max_dwell_time_active); } channels[j].tx_power_att = req->channels[i]->max_power; channels[j].channel = req->channels[i]->hw_value; Loading Loading @@ -703,7 +704,7 @@ int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif) if (wlvif->bss_type != BSS_TYPE_STA_BSS) return -EOPNOTSUPP; if (!test_bit(WL1271_FLAG_IDLE, &wl->flags)) if (test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) return -EBUSY; start = kzalloc(sizeof(*start), GFP_KERNEL); Loading Loading @@ -753,7 +754,6 @@ void wl1271_scan_sched_scan_stop(struct wl1271 *wl) wl1271_error("failed to send sched scan stop command"); goto out_free; } wl->sched_scanning = false; out_free: kfree(stop); Loading