Lines Matching +full:hw +full:- +full:channels

1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
6 * Copyright (c) 2010, ST-Ericsson
15 static void wfx_ieee80211_scan_completed_compat(struct ieee80211_hw *hw, bool aborted) in wfx_ieee80211_scan_completed_compat() argument
21 ieee80211_scan_completed(hw, &info); in wfx_ieee80211_scan_completed_compat()
29 skb = ieee80211_probereq_get(wvif->wdev->hw, vif->addr, NULL, 0, in update_probe_tmpl()
30 req->ie_len); in update_probe_tmpl()
32 return -ENOMEM; in update_probe_tmpl()
34 skb_put_data(skb, req->ie, req->ie_len); in update_probe_tmpl()
46 for (i = start_idx; i < req->n_channels; i++) { in send_scan_req()
47 ch_start = req->channels[start_idx]; in send_scan_req()
48 ch_cur = req->channels[i]; in send_scan_req()
49 WARN(ch_cur->band != NL80211_BAND_2GHZ, "band not supported"); in send_scan_req()
50 if (ch_cur->max_power != ch_start->max_power) in send_scan_req()
52 if ((ch_cur->flags ^ ch_start->flags) & IEEE80211_CHAN_NO_IR) in send_scan_req()
55 wfx_tx_lock_flush(wvif->wdev); in send_scan_req()
56 wvif->scan_abort = false; in send_scan_req()
57 reinit_completion(&wvif->scan_complete); in send_scan_req()
58 ret = wfx_hif_scan(wvif, req, start_idx, i - start_idx); in send_scan_req()
60 wfx_tx_unlock(wvif->wdev); in send_scan_req()
61 return -EIO; in send_scan_req()
63 ret = wait_for_completion_timeout(&wvif->scan_complete, 1 * HZ); in send_scan_req()
66 ret = wait_for_completion_timeout(&wvif->scan_complete, 1 * HZ); in send_scan_req()
67 dev_dbg(wvif->wdev->dev, "scan timeout (%d channels done)\n", in send_scan_req()
68 wvif->scan_nb_chan_done); in send_scan_req()
71 dev_err(wvif->wdev->dev, "scan didn't stop\n"); in send_scan_req()
72 ret = -ETIMEDOUT; in send_scan_req()
73 } else if (wvif->scan_abort) { in send_scan_req()
74 dev_notice(wvif->wdev->dev, "scan abort\n"); in send_scan_req()
75 ret = -ECONNABORTED; in send_scan_req()
76 } else if (wvif->scan_nb_chan_done > i - start_idx) { in send_scan_req()
77 ret = -EIO; in send_scan_req()
79 ret = wvif->scan_nb_chan_done; in send_scan_req()
81 if (req->channels[start_idx]->max_power != vif->bss_conf.txpower) in send_scan_req()
82 wfx_hif_set_output_power(wvif, vif->bss_conf.txpower); in send_scan_req()
83 wfx_tx_unlock(wvif->wdev); in send_scan_req()
94 struct ieee80211_scan_request *hw_req = wvif->scan_req; in wfx_hw_scan_work()
97 mutex_lock(&wvif->wdev->conf_mutex); in wfx_hw_scan_work()
98 mutex_lock(&wvif->wdev->scan_lock); in wfx_hw_scan_work()
99 if (wvif->join_in_progress) { in wfx_hw_scan_work()
100 dev_info(wvif->wdev->dev, "abort in-progress REQ_JOIN"); in wfx_hw_scan_work()
103 update_probe_tmpl(wvif, &hw_req->req); in wfx_hw_scan_work()
107 ret = send_scan_req(wvif, &hw_req->req, chan_cur); in wfx_hw_scan_work()
115 dev_err(wvif->wdev->dev, "scan has not been able to start\n"); in wfx_hw_scan_work()
116 ret = -ETIMEDOUT; in wfx_hw_scan_work()
118 } while (ret >= 0 && chan_cur < hw_req->req.n_channels); in wfx_hw_scan_work()
119 mutex_unlock(&wvif->wdev->scan_lock); in wfx_hw_scan_work()
120 mutex_unlock(&wvif->wdev->conf_mutex); in wfx_hw_scan_work()
121 wfx_ieee80211_scan_completed_compat(wvif->wdev->hw, ret < 0); in wfx_hw_scan_work()
124 int wfx_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, in wfx_hw_scan() argument
127 struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; in wfx_hw_scan()
129 WARN_ON(hw_req->req.n_channels > HIF_API_MAX_NB_CHANNELS); in wfx_hw_scan()
130 wvif->scan_req = hw_req; in wfx_hw_scan()
131 schedule_work(&wvif->scan_work); in wfx_hw_scan()
135 void wfx_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif) in wfx_cancel_hw_scan() argument
137 struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; in wfx_cancel_hw_scan()
139 wvif->scan_abort = true; in wfx_cancel_hw_scan()
145 wvif->scan_nb_chan_done = nb_chan_done; in wfx_scan_complete()
146 complete(&wvif->scan_complete); in wfx_scan_complete()
152 struct ieee80211_channel *chan = wvif->remain_on_channel_chan; in wfx_remain_on_channel_work()
153 int duration = wvif->remain_on_channel_duration; in wfx_remain_on_channel_work()
156 /* Hijack scan request to implement Remain-On-Channel */ in wfx_remain_on_channel_work()
157 mutex_lock(&wvif->wdev->conf_mutex); in wfx_remain_on_channel_work()
158 mutex_lock(&wvif->wdev->scan_lock); in wfx_remain_on_channel_work()
159 if (wvif->join_in_progress) { in wfx_remain_on_channel_work()
160 dev_info(wvif->wdev->dev, "abort in-progress REQ_JOIN"); in wfx_remain_on_channel_work()
163 wfx_tx_flush(wvif->wdev); in wfx_remain_on_channel_work()
165 reinit_completion(&wvif->scan_complete); in wfx_remain_on_channel_work()
169 ieee80211_ready_on_channel(wvif->wdev->hw); in wfx_remain_on_channel_work()
170 ret = wait_for_completion_timeout(&wvif->scan_complete, in wfx_remain_on_channel_work()
174 ret = wait_for_completion_timeout(&wvif->scan_complete, 1 * HZ); in wfx_remain_on_channel_work()
175 dev_dbg(wvif->wdev->dev, "roc timeout\n"); in wfx_remain_on_channel_work()
178 dev_err(wvif->wdev->dev, "roc didn't stop\n"); in wfx_remain_on_channel_work()
179 ieee80211_remain_on_channel_expired(wvif->wdev->hw); in wfx_remain_on_channel_work()
181 mutex_unlock(&wvif->wdev->scan_lock); in wfx_remain_on_channel_work()
182 mutex_unlock(&wvif->wdev->conf_mutex); in wfx_remain_on_channel_work()
183 wfx_bh_request_tx(wvif->wdev); in wfx_remain_on_channel_work()
186 int wfx_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif, in wfx_remain_on_channel() argument
190 struct wfx_dev *wdev = hw->priv; in wfx_remain_on_channel()
191 struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; in wfx_remain_on_channel()
194 return -EOPNOTSUPP; in wfx_remain_on_channel()
196 wvif->remain_on_channel_duration = duration; in wfx_remain_on_channel()
197 wvif->remain_on_channel_chan = chan; in wfx_remain_on_channel()
198 schedule_work(&wvif->remain_on_channel_work); in wfx_remain_on_channel()
202 int wfx_cancel_remain_on_channel(struct ieee80211_hw *hw, struct ieee80211_vif *vif) in wfx_cancel_remain_on_channel() argument
204 struct wfx_vif *wvif = (struct wfx_vif *)vif->drv_priv; in wfx_cancel_remain_on_channel()
207 flush_work(&wvif->remain_on_channel_work); in wfx_cancel_remain_on_channel()