diff options
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271.h | 21 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_event.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_main.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_scan.c | 296 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_scan.h | 20 |
5 files changed, 211 insertions, 141 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h index cfdccdb86067..b7c2995d4f40 100644 --- a/drivers/net/wireless/wl12xx/wl1271.h +++ b/drivers/net/wireless/wl12xx/wl1271.h | |||
@@ -300,12 +300,10 @@ struct wl1271_rx_mem_pool_addr { | |||
300 | 300 | ||
301 | struct wl1271_scan { | 301 | struct wl1271_scan { |
302 | struct cfg80211_scan_request *req; | 302 | struct cfg80211_scan_request *req; |
303 | bool *scanned_ch; | ||
303 | u8 state; | 304 | u8 state; |
304 | u8 ssid[IW_ESSID_MAX_SIZE+1]; | 305 | u8 ssid[IW_ESSID_MAX_SIZE+1]; |
305 | size_t ssid_len; | 306 | size_t ssid_len; |
306 | u8 active; | ||
307 | u8 high_prio; | ||
308 | u8 probe_requests; | ||
309 | }; | 307 | }; |
310 | 308 | ||
311 | struct wl1271_if_operations { | 309 | struct wl1271_if_operations { |
@@ -343,15 +341,14 @@ struct wl1271 { | |||
343 | #define WL1271_FLAG_JOINED (2) | 341 | #define WL1271_FLAG_JOINED (2) |
344 | #define WL1271_FLAG_GPIO_POWER (3) | 342 | #define WL1271_FLAG_GPIO_POWER (3) |
345 | #define WL1271_FLAG_TX_QUEUE_STOPPED (4) | 343 | #define WL1271_FLAG_TX_QUEUE_STOPPED (4) |
346 | #define WL1271_FLAG_SCANNING (5) | 344 | #define WL1271_FLAG_IN_ELP (5) |
347 | #define WL1271_FLAG_IN_ELP (6) | 345 | #define WL1271_FLAG_PSM (6) |
348 | #define WL1271_FLAG_PSM (7) | 346 | #define WL1271_FLAG_PSM_REQUESTED (7) |
349 | #define WL1271_FLAG_PSM_REQUESTED (8) | 347 | #define WL1271_FLAG_IRQ_PENDING (8) |
350 | #define WL1271_FLAG_IRQ_PENDING (9) | 348 | #define WL1271_FLAG_IRQ_RUNNING (9) |
351 | #define WL1271_FLAG_IRQ_RUNNING (10) | 349 | #define WL1271_FLAG_IDLE (10) |
352 | #define WL1271_FLAG_IDLE (11) | 350 | #define WL1271_FLAG_IDLE_REQUESTED (11) |
353 | #define WL1271_FLAG_IDLE_REQUESTED (12) | 351 | #define WL1271_FLAG_PSPOLL_FAILURE (12) |
354 | #define WL1271_FLAG_PSPOLL_FAILURE (13) | ||
355 | unsigned long flags; | 352 | unsigned long flags; |
356 | 353 | ||
357 | struct wl1271_partition_set part; | 354 | struct wl1271_partition_set part; |
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c index 3bdae892c29e..25ce2cd5e3f3 100644 --- a/drivers/net/wireless/wl12xx/wl1271_event.c +++ b/drivers/net/wireless/wl12xx/wl1271_event.c | |||
@@ -194,9 +194,7 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) | |||
194 | wl1271_debug(DEBUG_EVENT, "status: 0x%x", | 194 | wl1271_debug(DEBUG_EVENT, "status: 0x%x", |
195 | mbox->scheduled_scan_status); | 195 | mbox->scheduled_scan_status); |
196 | 196 | ||
197 | ret = wl1271_scan_complete(wl); | 197 | wl1271_scan_stm(wl); |
198 | if (ret < 0) | ||
199 | return ret; | ||
200 | } | 198 | } |
201 | 199 | ||
202 | /* disable dynamic PS when requested by the firmware */ | 200 | /* disable dynamic PS when requested by the firmware */ |
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index cdfcc054efe4..d30de58cef90 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c | |||
@@ -942,10 +942,13 @@ static void wl1271_op_remove_interface(struct ieee80211_hw *hw, | |||
942 | if (wl->bss_type == BSS_TYPE_STA_BSS) | 942 | if (wl->bss_type == BSS_TYPE_STA_BSS) |
943 | ieee80211_enable_dyn_ps(wl->vif); | 943 | ieee80211_enable_dyn_ps(wl->vif); |
944 | 944 | ||
945 | if (test_and_clear_bit(WL1271_FLAG_SCANNING, &wl->flags)) { | 945 | if (wl->scan.state != WL1271_SCAN_STATE_IDLE) { |
946 | mutex_unlock(&wl->mutex); | 946 | mutex_unlock(&wl->mutex); |
947 | ieee80211_scan_completed(wl->hw, true); | 947 | ieee80211_scan_completed(wl->hw, true); |
948 | mutex_lock(&wl->mutex); | 948 | mutex_lock(&wl->mutex); |
949 | wl->scan.state = WL1271_SCAN_STATE_IDLE; | ||
950 | kfree(wl->scan.scanned_ch); | ||
951 | wl->scan.scanned_ch = NULL; | ||
949 | } | 952 | } |
950 | 953 | ||
951 | wl->state = WL1271_STATE_OFF; | 954 | wl->state = WL1271_STATE_OFF; |
@@ -1551,11 +1554,9 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, | |||
1551 | goto out; | 1554 | goto out; |
1552 | 1555 | ||
1553 | if (wl1271_11a_enabled()) | 1556 | if (wl1271_11a_enabled()) |
1554 | ret = wl1271_scan(hw->priv, ssid, len, req, | 1557 | ret = wl1271_scan(hw->priv, ssid, len, req); |
1555 | 1, 0, WL1271_SCAN_BAND_DUAL, 3); | ||
1556 | else | 1558 | else |
1557 | ret = wl1271_scan(hw->priv, ssid, len, req, | 1559 | ret = wl1271_scan(hw->priv, ssid, len, req); |
1558 | 1, 0, WL1271_SCAN_BAND_2_4_GHZ, 3); | ||
1559 | 1560 | ||
1560 | wl1271_ps_elp_sleep(wl); | 1561 | wl1271_ps_elp_sleep(wl); |
1561 | 1562 | ||
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c index eb9b4ece4ec3..f938b33912f5 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.c +++ b/drivers/net/wireless/wl12xx/wl1271_scan.c | |||
@@ -28,103 +28,120 @@ | |||
28 | #include "wl1271_scan.h" | 28 | #include "wl1271_scan.h" |
29 | #include "wl1271_acx.h" | 29 | #include "wl1271_acx.h" |
30 | 30 | ||
31 | int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, | 31 | static int wl1271_get_scan_channels(struct wl1271 *wl, |
32 | struct cfg80211_scan_request *req, u8 active_scan, | 32 | struct cfg80211_scan_request *req, |
33 | u8 high_prio, u8 band, u8 probe_requests) | 33 | struct basic_scan_channel_params *channels, |
34 | enum ieee80211_band band, bool passive) | ||
34 | { | 35 | { |
36 | int i, j; | ||
37 | u32 flags; | ||
35 | 38 | ||
36 | struct wl1271_cmd_trigger_scan_to *trigger = NULL; | 39 | for (i = 0, j = 0; |
37 | struct wl1271_cmd_scan *params = NULL; | 40 | i < req->n_channels && j < WL1271_SCAN_MAX_CHANNELS; |
38 | struct ieee80211_channel *channels; | 41 | i++) { |
39 | u32 rate; | ||
40 | int i, j, n_ch, ret; | ||
41 | u16 scan_options = 0; | ||
42 | u8 ieee_band; | ||
43 | |||
44 | if (band == WL1271_SCAN_BAND_2_4_GHZ) { | ||
45 | ieee_band = IEEE80211_BAND_2GHZ; | ||
46 | rate = wl->conf.tx.basic_rate; | ||
47 | } else if (band == WL1271_SCAN_BAND_DUAL && wl1271_11a_enabled()) { | ||
48 | ieee_band = IEEE80211_BAND_2GHZ; | ||
49 | rate = wl->conf.tx.basic_rate; | ||
50 | } else if (band == WL1271_SCAN_BAND_5_GHZ && wl1271_11a_enabled()) { | ||
51 | ieee_band = IEEE80211_BAND_5GHZ; | ||
52 | rate = wl->conf.tx.basic_rate_5; | ||
53 | } else | ||
54 | return -EINVAL; | ||
55 | |||
56 | if (wl->hw->wiphy->bands[ieee_band]->channels == NULL) | ||
57 | return -EINVAL; | ||
58 | |||
59 | channels = wl->hw->wiphy->bands[ieee_band]->channels; | ||
60 | n_ch = wl->hw->wiphy->bands[ieee_band]->n_channels; | ||
61 | |||
62 | if (test_bit(WL1271_FLAG_SCANNING, &wl->flags)) | ||
63 | return -EINVAL; | ||
64 | |||
65 | params = kzalloc(sizeof(*params), GFP_KERNEL); | ||
66 | if (!params) | ||
67 | return -ENOMEM; | ||
68 | |||
69 | params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD); | ||
70 | params->params.rx_filter_options = | ||
71 | cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN); | ||
72 | 42 | ||
73 | if (!active_scan) | 43 | flags = req->channels[i]->flags; |
74 | scan_options |= WL1271_SCAN_OPT_PASSIVE; | ||
75 | if (high_prio) | ||
76 | scan_options |= WL1271_SCAN_OPT_PRIORITY_HIGH; | ||
77 | params->params.scan_options = cpu_to_le16(scan_options); | ||
78 | 44 | ||
79 | params->params.num_probe_requests = probe_requests; | 45 | if (!wl->scan.scanned_ch[i] && |
80 | params->params.tx_rate = cpu_to_le32(rate); | 46 | !(flags & IEEE80211_CHAN_DISABLED) && |
81 | params->params.tid_trigger = 0; | 47 | ((!!(flags & IEEE80211_CHAN_PASSIVE_SCAN)) == passive) && |
82 | params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; | 48 | (req->channels[i]->band == band)) { |
83 | 49 | ||
84 | if (band == WL1271_SCAN_BAND_DUAL) | 50 | wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", |
85 | params->params.band = WL1271_SCAN_BAND_2_4_GHZ; | 51 | req->channels[i]->band, |
86 | else | 52 | req->channels[i]->center_freq); |
87 | params->params.band = band; | 53 | wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X", |
54 | req->channels[i]->hw_value, | ||
55 | req->channels[i]->flags); | ||
56 | wl1271_debug(DEBUG_SCAN, | ||
57 | "max_antenna_gain %d, max_power %d", | ||
58 | req->channels[i]->max_antenna_gain, | ||
59 | req->channels[i]->max_power); | ||
60 | wl1271_debug(DEBUG_SCAN, "beacon_found %d", | ||
61 | req->channels[i]->beacon_found); | ||
88 | 62 | ||
89 | for (i = 0, j = 0; i < n_ch && i < WL1271_SCAN_MAX_CHANNELS; i++) { | 63 | channels[j].min_duration = |
90 | if (!(channels[i].flags & IEEE80211_CHAN_DISABLED)) { | ||
91 | params->channels[j].min_duration = | ||
92 | cpu_to_le32(WL1271_SCAN_CHAN_MIN_DURATION); | 64 | cpu_to_le32(WL1271_SCAN_CHAN_MIN_DURATION); |
93 | params->channels[j].max_duration = | 65 | channels[j].max_duration = |
94 | cpu_to_le32(WL1271_SCAN_CHAN_MAX_DURATION); | 66 | cpu_to_le32(WL1271_SCAN_CHAN_MAX_DURATION); |
95 | memset(¶ms->channels[j].bssid_lsb, 0xff, 4); | 67 | channels[j].early_termination = 0; |
96 | memset(¶ms->channels[j].bssid_msb, 0xff, 2); | 68 | channels[j].tx_power_att = WL1271_SCAN_CURRENT_TX_PWR; |
97 | params->channels[j].early_termination = 0; | 69 | channels[j].channel = req->channels[i]->hw_value; |
98 | params->channels[j].tx_power_att = | 70 | |
99 | WL1271_SCAN_CURRENT_TX_PWR; | 71 | memset(&channels[j].bssid_lsb, 0xff, 4); |
100 | params->channels[j].channel = channels[i].hw_value; | 72 | memset(&channels[j].bssid_msb, 0xff, 2); |
73 | |||
74 | /* Mark the channels we already used */ | ||
75 | wl->scan.scanned_ch[i] = true; | ||
76 | |||
101 | j++; | 77 | j++; |
102 | } | 78 | } |
103 | } | 79 | } |
104 | 80 | ||
105 | params->params.num_channels = j; | 81 | return j; |
82 | } | ||
106 | 83 | ||
107 | if (ssid_len && ssid) { | 84 | #define WL1271_NOTHING_TO_SCAN 1 |
108 | params->params.ssid_len = ssid_len; | 85 | |
109 | memcpy(params->params.ssid, ssid, ssid_len); | 86 | static int wl1271_scan_send(struct wl1271 *wl, enum ieee80211_band band, |
87 | bool passive, u32 basic_rate) | ||
88 | { | ||
89 | struct wl1271_cmd_scan *cmd; | ||
90 | struct wl1271_cmd_trigger_scan_to *trigger; | ||
91 | int ret; | ||
92 | u16 scan_options = 0; | ||
93 | |||
94 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); | ||
95 | trigger = kzalloc(sizeof(*trigger), GFP_KERNEL); | ||
96 | if (!cmd || !trigger) { | ||
97 | ret = -ENOMEM; | ||
98 | goto out; | ||
110 | } | 99 | } |
111 | 100 | ||
112 | ret = wl1271_cmd_build_probe_req(wl, ssid, ssid_len, | 101 | /* We always use high priority scans */ |
113 | req->ie, req->ie_len, ieee_band); | 102 | scan_options = WL1271_SCAN_OPT_PRIORITY_HIGH; |
114 | if (ret < 0) { | 103 | if(passive) |
115 | wl1271_error("PROBE request template failed"); | 104 | scan_options |= WL1271_SCAN_OPT_PASSIVE; |
105 | cmd->params.scan_options = cpu_to_le16(scan_options); | ||
106 | |||
107 | cmd->params.n_ch = wl1271_get_scan_channels(wl, wl->scan.req, | ||
108 | cmd->channels, | ||
109 | band, passive); | ||
110 | if (cmd->params.n_ch == 0) { | ||
111 | ret = WL1271_NOTHING_TO_SCAN; | ||
116 | goto out; | 112 | goto out; |
117 | } | 113 | } |
118 | 114 | ||
119 | trigger = kzalloc(sizeof(*trigger), GFP_KERNEL); | 115 | cmd->params.tx_rate = cpu_to_le32(basic_rate); |
120 | if (!trigger) { | 116 | cmd->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD); |
121 | ret = -ENOMEM; | 117 | cmd->params.rx_filter_options = |
118 | cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN); | ||
119 | |||
120 | cmd->params.n_probe_reqs = WL1271_SCAN_PROBE_REQS; | ||
121 | cmd->params.tx_rate = cpu_to_le32(basic_rate); | ||
122 | cmd->params.tid_trigger = 0; | ||
123 | cmd->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; | ||
124 | |||
125 | if (band == IEEE80211_BAND_2GHZ) | ||
126 | cmd->params.band = WL1271_SCAN_BAND_2_4_GHZ; | ||
127 | else | ||
128 | cmd->params.band = WL1271_SCAN_BAND_5_GHZ; | ||
129 | |||
130 | if (wl->scan.ssid_len && wl->scan.ssid) { | ||
131 | cmd->params.ssid_len = wl->scan.ssid_len; | ||
132 | memcpy(cmd->params.ssid, wl->scan.ssid, wl->scan.ssid_len); | ||
133 | } | ||
134 | |||
135 | ret = wl1271_cmd_build_probe_req(wl, wl->scan.ssid, wl->scan.ssid_len, | ||
136 | wl->scan.req->ie, wl->scan.req->ie_len, | ||
137 | band); | ||
138 | if (ret < 0) { | ||
139 | wl1271_error("PROBE request template failed"); | ||
122 | goto out; | 140 | goto out; |
123 | } | 141 | } |
124 | 142 | ||
125 | /* disable the timeout */ | 143 | /* disable the timeout */ |
126 | trigger->timeout = 0; | 144 | trigger->timeout = 0; |
127 | |||
128 | ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger, | 145 | ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger, |
129 | sizeof(*trigger), 0); | 146 | sizeof(*trigger), 0); |
130 | if (ret < 0) { | 147 | if (ret < 0) { |
@@ -132,60 +149,109 @@ int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, | |||
132 | goto out; | 149 | goto out; |
133 | } | 150 | } |
134 | 151 | ||
135 | wl1271_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params)); | 152 | wl1271_dump(DEBUG_SCAN, "SCAN: ", cmd, sizeof(*cmd)); |
136 | |||
137 | set_bit(WL1271_FLAG_SCANNING, &wl->flags); | ||
138 | if (wl1271_11a_enabled()) { | ||
139 | wl->scan.state = band; | ||
140 | if (band == WL1271_SCAN_BAND_DUAL) { | ||
141 | wl->scan.active = active_scan; | ||
142 | wl->scan.high_prio = high_prio; | ||
143 | wl->scan.probe_requests = probe_requests; | ||
144 | if (ssid_len && ssid) { | ||
145 | wl->scan.ssid_len = ssid_len; | ||
146 | memcpy(wl->scan.ssid, ssid, ssid_len); | ||
147 | } else | ||
148 | wl->scan.ssid_len = 0; | ||
149 | wl->scan.req = req; | ||
150 | } else | ||
151 | wl->scan.req = NULL; | ||
152 | } | ||
153 | 153 | ||
154 | ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params), 0); | 154 | ret = wl1271_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd), 0); |
155 | if (ret < 0) { | 155 | if (ret < 0) { |
156 | wl1271_error("SCAN failed"); | 156 | wl1271_error("SCAN failed"); |
157 | clear_bit(WL1271_FLAG_SCANNING, &wl->flags); | ||
158 | goto out; | 157 | goto out; |
159 | } | 158 | } |
160 | 159 | ||
161 | out: | 160 | out: |
162 | kfree(params); | 161 | kfree(cmd); |
163 | kfree(trigger); | 162 | kfree(trigger); |
164 | return ret; | 163 | return ret; |
165 | } | 164 | } |
166 | 165 | ||
167 | int wl1271_scan_complete(struct wl1271 *wl) | 166 | void wl1271_scan_stm(struct wl1271 *wl) |
168 | { | 167 | { |
169 | if (test_bit(WL1271_FLAG_SCANNING, &wl->flags)) { | 168 | int ret; |
170 | if (wl->scan.state == WL1271_SCAN_BAND_DUAL) { | 169 | |
171 | /* 2.4 GHz band scanned, scan 5 GHz band, pretend to | 170 | switch (wl->scan.state) { |
172 | * the wl1271_scan function that we are not scanning | 171 | case WL1271_SCAN_STATE_IDLE: |
173 | * as it checks that. | 172 | break; |
174 | */ | 173 | |
175 | clear_bit(WL1271_FLAG_SCANNING, &wl->flags); | 174 | case WL1271_SCAN_STATE_2GHZ_ACTIVE: |
176 | /* FIXME: ie missing! */ | 175 | ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, false, |
177 | wl1271_scan(wl, wl->scan.ssid, wl->scan.ssid_len, | 176 | wl->conf.tx.basic_rate); |
178 | wl->scan.req, | 177 | if (ret == WL1271_NOTHING_TO_SCAN) { |
179 | wl->scan.active, | 178 | wl->scan.state = WL1271_SCAN_STATE_2GHZ_PASSIVE; |
180 | wl->scan.high_prio, | 179 | wl1271_scan_stm(wl); |
181 | WL1271_SCAN_BAND_5_GHZ, | 180 | } |
182 | wl->scan.probe_requests); | 181 | |
183 | } else { | 182 | break; |
184 | mutex_unlock(&wl->mutex); | 183 | |
185 | ieee80211_scan_completed(wl->hw, false); | 184 | case WL1271_SCAN_STATE_2GHZ_PASSIVE: |
186 | mutex_lock(&wl->mutex); | 185 | ret = wl1271_scan_send(wl, IEEE80211_BAND_2GHZ, true, |
187 | clear_bit(WL1271_FLAG_SCANNING, &wl->flags); | 186 | wl->conf.tx.basic_rate); |
187 | if (ret == WL1271_NOTHING_TO_SCAN) { | ||
188 | if (wl1271_11a_enabled()) | ||
189 | wl->scan.state = WL1271_SCAN_STATE_5GHZ_ACTIVE; | ||
190 | else | ||
191 | wl->scan.state = WL1271_SCAN_STATE_DONE; | ||
192 | wl1271_scan_stm(wl); | ||
188 | } | 193 | } |
194 | |||
195 | break; | ||
196 | |||
197 | case WL1271_SCAN_STATE_5GHZ_ACTIVE: | ||
198 | ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, false, | ||
199 | wl->conf.tx.basic_rate_5); | ||
200 | if (ret == WL1271_NOTHING_TO_SCAN) { | ||
201 | wl->scan.state = WL1271_SCAN_STATE_5GHZ_PASSIVE; | ||
202 | wl1271_scan_stm(wl); | ||
203 | } | ||
204 | |||
205 | break; | ||
206 | |||
207 | case WL1271_SCAN_STATE_5GHZ_PASSIVE: | ||
208 | ret = wl1271_scan_send(wl, IEEE80211_BAND_5GHZ, true, | ||
209 | wl->conf.tx.basic_rate_5); | ||
210 | if (ret == WL1271_NOTHING_TO_SCAN) { | ||
211 | wl->scan.state = WL1271_SCAN_STATE_DONE; | ||
212 | wl1271_scan_stm(wl); | ||
213 | } | ||
214 | |||
215 | break; | ||
216 | |||
217 | case WL1271_SCAN_STATE_DONE: | ||
218 | mutex_unlock(&wl->mutex); | ||
219 | ieee80211_scan_completed(wl->hw, false); | ||
220 | mutex_lock(&wl->mutex); | ||
221 | |||
222 | kfree(wl->scan.scanned_ch); | ||
223 | wl->scan.scanned_ch = NULL; | ||
224 | |||
225 | wl->scan.state = WL1271_SCAN_STATE_IDLE; | ||
226 | break; | ||
227 | |||
228 | default: | ||
229 | wl1271_error("invalid scan state"); | ||
230 | break; | ||
189 | } | 231 | } |
232 | } | ||
233 | |||
234 | int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, | ||
235 | struct cfg80211_scan_request *req) | ||
236 | { | ||
237 | if (wl->scan.state != WL1271_SCAN_STATE_IDLE) | ||
238 | return -EBUSY; | ||
239 | |||
240 | wl->scan.state = WL1271_SCAN_STATE_2GHZ_ACTIVE; | ||
241 | |||
242 | if (ssid_len && ssid) { | ||
243 | wl->scan.ssid_len = ssid_len; | ||
244 | memcpy(wl->scan.ssid, ssid, ssid_len); | ||
245 | } else { | ||
246 | wl->scan.ssid_len = 0; | ||
247 | } | ||
248 | |||
249 | wl->scan.req = req; | ||
250 | |||
251 | wl->scan.scanned_ch = kzalloc(req->n_channels * | ||
252 | sizeof(*wl->scan.scanned_ch), | ||
253 | GFP_KERNEL); | ||
254 | wl1271_scan_stm(wl); | ||
255 | |||
190 | return 0; | 256 | return 0; |
191 | } | 257 | } |
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.h b/drivers/net/wireless/wl12xx/wl1271_scan.h index 0002e815cb43..b0e36e30a427 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.h +++ b/drivers/net/wireless/wl12xx/wl1271_scan.h | |||
@@ -27,12 +27,11 @@ | |||
27 | #include "wl1271.h" | 27 | #include "wl1271.h" |
28 | 28 | ||
29 | int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, | 29 | int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len, |
30 | struct cfg80211_scan_request *req, u8 active_scan, | 30 | struct cfg80211_scan_request *req); |
31 | u8 high_prio, u8 band, u8 probe_requests); | ||
32 | int wl1271_scan_build_probe_req(struct wl1271 *wl, | 31 | int wl1271_scan_build_probe_req(struct wl1271 *wl, |
33 | const u8 *ssid, size_t ssid_len, | 32 | const u8 *ssid, size_t ssid_len, |
34 | const u8 *ie, size_t ie_len, u8 band); | 33 | const u8 *ie, size_t ie_len, u8 band); |
35 | int wl1271_scan_complete(struct wl1271 *wl); | 34 | void wl1271_scan_stm(struct wl1271 *wl); |
36 | 35 | ||
37 | #define WL1271_SCAN_MAX_CHANNELS 24 | 36 | #define WL1271_SCAN_MAX_CHANNELS 24 |
38 | #define WL1271_SCAN_DEFAULT_TAG 1 | 37 | #define WL1271_SCAN_DEFAULT_TAG 1 |
@@ -44,7 +43,16 @@ int wl1271_scan_complete(struct wl1271 *wl); | |||
44 | #define WL1271_SCAN_CHAN_MAX_DURATION 60000 /* TU */ | 43 | #define WL1271_SCAN_CHAN_MAX_DURATION 60000 /* TU */ |
45 | #define WL1271_SCAN_BAND_2_4_GHZ 0 | 44 | #define WL1271_SCAN_BAND_2_4_GHZ 0 |
46 | #define WL1271_SCAN_BAND_5_GHZ 1 | 45 | #define WL1271_SCAN_BAND_5_GHZ 1 |
47 | #define WL1271_SCAN_BAND_DUAL 2 | 46 | #define WL1271_SCAN_PROBE_REQS 3 |
47 | |||
48 | enum { | ||
49 | WL1271_SCAN_STATE_IDLE, | ||
50 | WL1271_SCAN_STATE_2GHZ_ACTIVE, | ||
51 | WL1271_SCAN_STATE_2GHZ_PASSIVE, | ||
52 | WL1271_SCAN_STATE_5GHZ_ACTIVE, | ||
53 | WL1271_SCAN_STATE_5GHZ_PASSIVE, | ||
54 | WL1271_SCAN_STATE_DONE | ||
55 | }; | ||
48 | 56 | ||
49 | struct basic_scan_params { | 57 | struct basic_scan_params { |
50 | __le32 rx_config_options; | 58 | __le32 rx_config_options; |
@@ -52,10 +60,10 @@ struct basic_scan_params { | |||
52 | /* Scan option flags (WL1271_SCAN_OPT_*) */ | 60 | /* Scan option flags (WL1271_SCAN_OPT_*) */ |
53 | __le16 scan_options; | 61 | __le16 scan_options; |
54 | /* Number of scan channels in the list (maximum 30) */ | 62 | /* Number of scan channels in the list (maximum 30) */ |
55 | u8 num_channels; | 63 | u8 n_ch; |
56 | /* This field indicates the number of probe requests to send | 64 | /* This field indicates the number of probe requests to send |
57 | per channel for an active scan */ | 65 | per channel for an active scan */ |
58 | u8 num_probe_requests; | 66 | u8 n_probe_reqs; |
59 | /* Rate bit field for sending the probes */ | 67 | /* Rate bit field for sending the probes */ |
60 | __le32 tx_rate; | 68 | __le32 tx_rate; |
61 | u8 tid_trigger; | 69 | u8 tid_trigger; |