diff options
Diffstat (limited to 'drivers/net/wireless/libertas/cmdresp.c')
-rw-r--r-- | drivers/net/wireless/libertas/cmdresp.c | 1031 |
1 files changed, 1031 insertions, 0 deletions
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c new file mode 100644 index 000000000000..cdb012c7e9cf --- /dev/null +++ b/drivers/net/wireless/libertas/cmdresp.c | |||
@@ -0,0 +1,1031 @@ | |||
1 | /** | ||
2 | * This file contains the handling of command | ||
3 | * responses as well as events generated by firmware. | ||
4 | */ | ||
5 | #include <linux/delay.h> | ||
6 | #include <linux/if_arp.h> | ||
7 | #include <linux/netdevice.h> | ||
8 | |||
9 | #include <net/iw_handler.h> | ||
10 | |||
11 | #include "host.h" | ||
12 | #include "sbi.h" | ||
13 | #include "decl.h" | ||
14 | #include "defs.h" | ||
15 | #include "dev.h" | ||
16 | #include "join.h" | ||
17 | #include "wext.h" | ||
18 | |||
19 | /** | ||
20 | * @brief This function handles disconnect event. it | ||
21 | * reports disconnect to upper layer, clean tx/rx packets, | ||
22 | * reset link state etc. | ||
23 | * | ||
24 | * @param priv A pointer to wlan_private structure | ||
25 | * @return n/a | ||
26 | */ | ||
27 | void libertas_mac_event_disconnected(wlan_private * priv) | ||
28 | { | ||
29 | wlan_adapter *adapter = priv->adapter; | ||
30 | union iwreq_data wrqu; | ||
31 | |||
32 | if (adapter->connect_status != libertas_connected) | ||
33 | return; | ||
34 | |||
35 | lbs_pr_debug(1, "Handles disconnect event.\n"); | ||
36 | |||
37 | memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN); | ||
38 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; | ||
39 | |||
40 | /* | ||
41 | * Cisco AP sends EAP failure and de-auth in less than 0.5 ms. | ||
42 | * It causes problem in the Supplicant | ||
43 | */ | ||
44 | |||
45 | msleep_interruptible(1000); | ||
46 | wireless_send_event(priv->wlan_dev.netdev, SIOCGIWAP, &wrqu, NULL); | ||
47 | |||
48 | /* Free Tx and Rx packets */ | ||
49 | kfree_skb(priv->adapter->currenttxskb); | ||
50 | priv->adapter->currenttxskb = NULL; | ||
51 | |||
52 | /* report disconnect to upper layer */ | ||
53 | netif_stop_queue(priv->wlan_dev.netdev); | ||
54 | netif_carrier_off(priv->wlan_dev.netdev); | ||
55 | |||
56 | /* reset SNR/NF/RSSI values */ | ||
57 | memset(adapter->SNR, 0x00, sizeof(adapter->SNR)); | ||
58 | memset(adapter->NF, 0x00, sizeof(adapter->NF)); | ||
59 | memset(adapter->RSSI, 0x00, sizeof(adapter->RSSI)); | ||
60 | memset(adapter->rawSNR, 0x00, sizeof(adapter->rawSNR)); | ||
61 | memset(adapter->rawNF, 0x00, sizeof(adapter->rawNF)); | ||
62 | adapter->nextSNRNF = 0; | ||
63 | adapter->numSNRNF = 0; | ||
64 | adapter->rxpd_rate = 0; | ||
65 | lbs_pr_debug(1, "Current SSID=%s, ssid length=%u\n", | ||
66 | adapter->curbssparams.ssid.ssid, | ||
67 | adapter->curbssparams.ssid.ssidlength); | ||
68 | lbs_pr_debug(1, "Previous SSID=%s, ssid length=%u\n", | ||
69 | adapter->previousssid.ssid, adapter->previousssid.ssidlength); | ||
70 | |||
71 | /* reset internal flags */ | ||
72 | adapter->secinfo.WPAenabled = 0; | ||
73 | adapter->secinfo.WPA2enabled = 0; | ||
74 | adapter->wpa_ie_len = 0; | ||
75 | adapter->secinfo.auth1xalg = WLAN_1X_AUTH_ALG_NONE; | ||
76 | adapter->secinfo.Encryptionmode = CIPHER_NONE; | ||
77 | |||
78 | adapter->connect_status = libertas_disconnected; | ||
79 | |||
80 | /* | ||
81 | * memorize the previous SSID and BSSID | ||
82 | * it could be used for re-assoc | ||
83 | */ | ||
84 | memcpy(&adapter->previousssid, | ||
85 | &adapter->curbssparams.ssid, sizeof(struct WLAN_802_11_SSID)); | ||
86 | memcpy(adapter->previousbssid, | ||
87 | adapter->curbssparams.bssid, ETH_ALEN); | ||
88 | |||
89 | /* need to erase the current SSID and BSSID info */ | ||
90 | adapter->pattemptedbssdesc = NULL; | ||
91 | memset(&adapter->curbssparams, 0, sizeof(adapter->curbssparams)); | ||
92 | |||
93 | if (adapter->psstate != PS_STATE_FULL_POWER) { | ||
94 | /* make firmware to exit PS mode */ | ||
95 | lbs_pr_debug(1, "Disconnected, so exit PS mode.\n"); | ||
96 | libertas_ps_wakeup(priv, 0); | ||
97 | } | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * @brief This function handles MIC failure event. | ||
102 | * | ||
103 | * @param priv A pointer to wlan_private structure | ||
104 | * @para event the event id | ||
105 | * @return n/a | ||
106 | */ | ||
107 | static void handle_mic_failureevent(wlan_private * priv, u32 event) | ||
108 | { | ||
109 | char buf[50]; | ||
110 | |||
111 | memset(buf, 0, sizeof(buf)); | ||
112 | |||
113 | sprintf(buf, "%s", "MLME-MICHAELMICFAILURE.indication "); | ||
114 | |||
115 | if (event == MACREG_INT_CODE_MIC_ERR_UNICAST) { | ||
116 | strcat(buf, "unicast "); | ||
117 | } else { | ||
118 | strcat(buf, "multicast "); | ||
119 | } | ||
120 | |||
121 | libertas_send_iwevcustom_event(priv, buf); | ||
122 | } | ||
123 | |||
124 | static int wlan_ret_reg_access(wlan_private * priv, | ||
125 | u16 type, struct cmd_ds_command *resp) | ||
126 | { | ||
127 | wlan_adapter *adapter = priv->adapter; | ||
128 | |||
129 | ENTER(); | ||
130 | |||
131 | switch (type) { | ||
132 | case cmd_ret_mac_reg_access: | ||
133 | { | ||
134 | struct cmd_ds_mac_reg_access *reg; | ||
135 | |||
136 | reg = | ||
137 | (struct cmd_ds_mac_reg_access *)&resp->params. | ||
138 | macreg; | ||
139 | |||
140 | adapter->offsetvalue.offset = reg->offset; | ||
141 | adapter->offsetvalue.value = reg->value; | ||
142 | break; | ||
143 | } | ||
144 | |||
145 | case cmd_ret_bbp_reg_access: | ||
146 | { | ||
147 | struct cmd_ds_bbp_reg_access *reg; | ||
148 | reg = | ||
149 | (struct cmd_ds_bbp_reg_access *)&resp->params. | ||
150 | bbpreg; | ||
151 | |||
152 | adapter->offsetvalue.offset = reg->offset; | ||
153 | adapter->offsetvalue.value = reg->value; | ||
154 | break; | ||
155 | } | ||
156 | |||
157 | case cmd_ret_rf_reg_access: | ||
158 | { | ||
159 | struct cmd_ds_rf_reg_access *reg; | ||
160 | reg = | ||
161 | (struct cmd_ds_rf_reg_access *)&resp->params. | ||
162 | rfreg; | ||
163 | |||
164 | adapter->offsetvalue.offset = reg->offset; | ||
165 | adapter->offsetvalue.value = reg->value; | ||
166 | break; | ||
167 | } | ||
168 | |||
169 | default: | ||
170 | LEAVE(); | ||
171 | return -1; | ||
172 | } | ||
173 | |||
174 | LEAVE(); | ||
175 | return 0; | ||
176 | } | ||
177 | |||
178 | static int wlan_ret_get_hw_spec(wlan_private * priv, | ||
179 | struct cmd_ds_command *resp) | ||
180 | { | ||
181 | u32 i; | ||
182 | struct cmd_ds_get_hw_spec *hwspec = &resp->params.hwspec; | ||
183 | wlan_adapter *adapter = priv->adapter; | ||
184 | int ret = 0; | ||
185 | |||
186 | ENTER(); | ||
187 | |||
188 | adapter->fwcapinfo = le32_to_cpu(hwspec->fwcapinfo); | ||
189 | |||
190 | adapter->fwreleasenumber = hwspec->fwreleasenumber; | ||
191 | |||
192 | lbs_pr_debug(1, "GET_HW_SPEC: FWReleaseVersion- 0x%X\n", | ||
193 | adapter->fwreleasenumber); | ||
194 | lbs_pr_debug(1, "GET_HW_SPEC: Permanent addr- %2x:%2x:%2x:%2x:%2x:%2x\n", | ||
195 | hwspec->permanentaddr[0], hwspec->permanentaddr[1], | ||
196 | hwspec->permanentaddr[2], hwspec->permanentaddr[3], | ||
197 | hwspec->permanentaddr[4], hwspec->permanentaddr[5]); | ||
198 | lbs_pr_debug(1, "GET_HW_SPEC: hwifversion=0x%X version=0x%X\n", | ||
199 | hwspec->hwifversion, hwspec->version); | ||
200 | |||
201 | adapter->regioncode = le16_to_cpu(hwspec->regioncode); | ||
202 | |||
203 | for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { | ||
204 | /* use the region code to search for the index */ | ||
205 | if (adapter->regioncode == libertas_region_code_to_index[i]) { | ||
206 | adapter->regiontableindex = (u16) i; | ||
207 | break; | ||
208 | } | ||
209 | } | ||
210 | |||
211 | /* if it's unidentified region code, use the default (USA) */ | ||
212 | if (i >= MRVDRV_MAX_REGION_CODE) { | ||
213 | adapter->regioncode = 0x10; | ||
214 | adapter->regiontableindex = 0; | ||
215 | lbs_pr_info( | ||
216 | "unidentified region code, use the default (USA)\n"); | ||
217 | } | ||
218 | |||
219 | if (adapter->current_addr[0] == 0xff) { | ||
220 | memmove(adapter->current_addr, hwspec->permanentaddr, | ||
221 | ETH_ALEN); | ||
222 | } | ||
223 | |||
224 | memcpy(priv->wlan_dev.netdev->dev_addr, adapter->current_addr, ETH_ALEN); | ||
225 | memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN); | ||
226 | |||
227 | if (libertas_set_regiontable(priv, adapter->regioncode, 0)) { | ||
228 | ret = -1; | ||
229 | goto done; | ||
230 | } | ||
231 | |||
232 | if (libertas_set_universaltable(priv, 0)) { | ||
233 | ret = -1; | ||
234 | goto done; | ||
235 | } | ||
236 | |||
237 | done: | ||
238 | LEAVE(); | ||
239 | return ret; | ||
240 | } | ||
241 | |||
242 | static int wlan_ret_802_11_sleep_params(wlan_private * priv, | ||
243 | struct cmd_ds_command *resp) | ||
244 | { | ||
245 | struct cmd_ds_802_11_sleep_params *sp = &resp->params.sleep_params; | ||
246 | wlan_adapter *adapter = priv->adapter; | ||
247 | |||
248 | ENTER(); | ||
249 | |||
250 | lbs_pr_debug(1, "error=%x offset=%x stabletime=%x calcontrol=%x\n" | ||
251 | " extsleepclk=%x\n", sp->error, sp->offset, | ||
252 | sp->stabletime, sp->calcontrol, sp->externalsleepclk); | ||
253 | adapter->sp.sp_error = le16_to_cpu(sp->error); | ||
254 | adapter->sp.sp_offset = le16_to_cpu(sp->offset); | ||
255 | adapter->sp.sp_stabletime = le16_to_cpu(sp->stabletime); | ||
256 | adapter->sp.sp_calcontrol = le16_to_cpu(sp->calcontrol); | ||
257 | adapter->sp.sp_extsleepclk = le16_to_cpu(sp->externalsleepclk); | ||
258 | adapter->sp.sp_reserved = le16_to_cpu(sp->reserved); | ||
259 | |||
260 | LEAVE(); | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static int wlan_ret_802_11_stat(wlan_private * priv, | ||
265 | struct cmd_ds_command *resp) | ||
266 | { | ||
267 | /* currently adapter->wlan802_11Stat is unused | ||
268 | |||
269 | struct cmd_ds_802_11_get_stat *p11Stat = &resp->params.gstat; | ||
270 | wlan_adapter *adapter = priv->adapter; | ||
271 | |||
272 | // TODO Convert it to Big endian befor copy | ||
273 | memcpy(&adapter->wlan802_11Stat, | ||
274 | p11Stat, sizeof(struct cmd_ds_802_11_get_stat)); | ||
275 | */ | ||
276 | return 0; | ||
277 | } | ||
278 | |||
279 | static int wlan_ret_802_11_snmp_mib(wlan_private * priv, | ||
280 | struct cmd_ds_command *resp) | ||
281 | { | ||
282 | struct cmd_ds_802_11_snmp_mib *smib = &resp->params.smib; | ||
283 | u16 oid = le16_to_cpu(smib->oid); | ||
284 | u16 querytype = le16_to_cpu(smib->querytype); | ||
285 | |||
286 | ENTER(); | ||
287 | |||
288 | lbs_pr_debug(1, "SNMP_RESP: value of the oid = %x, querytype=%x\n", oid, | ||
289 | querytype); | ||
290 | lbs_pr_debug(1, "SNMP_RESP: Buf size = %x\n", | ||
291 | le16_to_cpu(smib->bufsize)); | ||
292 | |||
293 | if (querytype == cmd_act_get) { | ||
294 | switch (oid) { | ||
295 | case fragthresh_i: | ||
296 | priv->adapter->fragthsd = | ||
297 | le16_to_cpu(* | ||
298 | ((unsigned short *)(smib->value))); | ||
299 | lbs_pr_debug(1, "SNMP_RESP: fragthsd =%u\n", | ||
300 | priv->adapter->fragthsd); | ||
301 | break; | ||
302 | case rtsthresh_i: | ||
303 | priv->adapter->rtsthsd = | ||
304 | le16_to_cpu(* | ||
305 | ((unsigned short *)(smib->value))); | ||
306 | lbs_pr_debug(1, "SNMP_RESP: rtsthsd =%u\n", | ||
307 | priv->adapter->rtsthsd); | ||
308 | break; | ||
309 | case short_retrylim_i: | ||
310 | priv->adapter->txretrycount = | ||
311 | le16_to_cpu(* | ||
312 | ((unsigned short *)(smib->value))); | ||
313 | lbs_pr_debug(1, "SNMP_RESP: txretrycount =%u\n", | ||
314 | priv->adapter->rtsthsd); | ||
315 | break; | ||
316 | default: | ||
317 | break; | ||
318 | } | ||
319 | } | ||
320 | |||
321 | LEAVE(); | ||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static int wlan_ret_802_11_key_material(wlan_private * priv, | ||
326 | struct cmd_ds_command *resp) | ||
327 | { | ||
328 | struct cmd_ds_802_11_key_material *pkeymaterial = | ||
329 | &resp->params.keymaterial; | ||
330 | wlan_adapter *adapter = priv->adapter; | ||
331 | u16 action = le16_to_cpu(pkeymaterial->action); | ||
332 | |||
333 | ENTER(); | ||
334 | |||
335 | /* Copy the returned key to driver private data */ | ||
336 | if (action == cmd_act_get) { | ||
337 | u8 * buf_ptr = (u8 *) &pkeymaterial->keyParamSet; | ||
338 | u8 * resp_end = (u8 *) (resp + le16_to_cpu(resp->size)); | ||
339 | |||
340 | while (buf_ptr < resp_end) { | ||
341 | struct MrvlIEtype_keyParamSet * pkeyparamset = | ||
342 | (struct MrvlIEtype_keyParamSet *) buf_ptr; | ||
343 | struct WLAN_802_11_KEY * pkey; | ||
344 | u16 key_info = le16_to_cpu(pkeyparamset->keyinfo); | ||
345 | u16 param_set_len = le16_to_cpu(pkeyparamset->length); | ||
346 | u8 * end; | ||
347 | u16 key_len = le16_to_cpu(pkeyparamset->keylen); | ||
348 | |||
349 | end = (u8 *) pkeyparamset + sizeof (pkeyparamset->type) | ||
350 | + sizeof (pkeyparamset->length) | ||
351 | + param_set_len; | ||
352 | /* Make sure we don't access past the end of the IEs */ | ||
353 | if (end > resp_end) | ||
354 | break; | ||
355 | |||
356 | if (key_info & KEY_INFO_WPA_UNICAST) | ||
357 | pkey = &adapter->wpa_unicast_key; | ||
358 | else if (key_info & KEY_INFO_WPA_MCAST) | ||
359 | pkey = &adapter->wpa_mcast_key; | ||
360 | else | ||
361 | break; | ||
362 | |||
363 | /* Copy returned key into driver */ | ||
364 | memset(pkey, 0, sizeof(struct WLAN_802_11_KEY)); | ||
365 | if (key_len > sizeof(pkey->key)) | ||
366 | break; | ||
367 | pkey->type = le16_to_cpu(pkeyparamset->keytypeid); | ||
368 | pkey->flags = le16_to_cpu(pkeyparamset->keyinfo); | ||
369 | pkey->len = le16_to_cpu(pkeyparamset->keylen); | ||
370 | memcpy(pkey->key, pkeyparamset->key, pkey->len); | ||
371 | |||
372 | buf_ptr = end + 1; | ||
373 | } | ||
374 | } | ||
375 | |||
376 | LEAVE(); | ||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | static int wlan_ret_802_11_mac_address(wlan_private * priv, | ||
381 | struct cmd_ds_command *resp) | ||
382 | { | ||
383 | struct cmd_ds_802_11_mac_address *macadd = &resp->params.macadd; | ||
384 | wlan_adapter *adapter = priv->adapter; | ||
385 | |||
386 | ENTER(); | ||
387 | |||
388 | memcpy(adapter->current_addr, macadd->macadd, ETH_ALEN); | ||
389 | |||
390 | LEAVE(); | ||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | static int wlan_ret_802_11_rf_tx_power(wlan_private * priv, | ||
395 | struct cmd_ds_command *resp) | ||
396 | { | ||
397 | struct cmd_ds_802_11_rf_tx_power *rtp = &resp->params.txp; | ||
398 | wlan_adapter *adapter = priv->adapter; | ||
399 | |||
400 | ENTER(); | ||
401 | |||
402 | adapter->txpowerlevel = le16_to_cpu(rtp->currentlevel); | ||
403 | |||
404 | lbs_pr_debug(1, "Current TxPower Level = %d\n", adapter->txpowerlevel); | ||
405 | |||
406 | LEAVE(); | ||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | static int wlan_ret_802_11_rf_antenna(wlan_private * priv, | ||
411 | struct cmd_ds_command *resp) | ||
412 | { | ||
413 | struct cmd_ds_802_11_rf_antenna *pAntenna = &resp->params.rant; | ||
414 | wlan_adapter *adapter = priv->adapter; | ||
415 | u16 action = le16_to_cpu(pAntenna->action); | ||
416 | |||
417 | if (action == cmd_act_get_rx) | ||
418 | adapter->rxantennamode = | ||
419 | le16_to_cpu(pAntenna->antennamode); | ||
420 | |||
421 | if (action == cmd_act_get_tx) | ||
422 | adapter->txantennamode = | ||
423 | le16_to_cpu(pAntenna->antennamode); | ||
424 | |||
425 | lbs_pr_debug(1, "RF_ANT_RESP: action = 0x%x, mode = 0x%04x\n", | ||
426 | action, le16_to_cpu(pAntenna->antennamode)); | ||
427 | |||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | static int wlan_ret_802_11_rate_adapt_rateset(wlan_private * priv, | ||
432 | struct cmd_ds_command *resp) | ||
433 | { | ||
434 | struct cmd_ds_802_11_rate_adapt_rateset *rates = | ||
435 | &resp->params.rateset; | ||
436 | wlan_adapter *adapter = priv->adapter; | ||
437 | |||
438 | ENTER(); | ||
439 | |||
440 | if (rates->action == cmd_act_get) { | ||
441 | adapter->enablehwauto = rates->enablehwauto; | ||
442 | adapter->ratebitmap = rates->bitmap; | ||
443 | } | ||
444 | |||
445 | LEAVE(); | ||
446 | |||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | static int wlan_ret_802_11_data_rate(wlan_private * priv, | ||
451 | struct cmd_ds_command *resp) | ||
452 | { | ||
453 | struct cmd_ds_802_11_data_rate *pdatarate = &resp->params.drate; | ||
454 | wlan_adapter *adapter = priv->adapter; | ||
455 | u8 dot11datarate; | ||
456 | |||
457 | ENTER(); | ||
458 | |||
459 | lbs_dbg_hex("DATA_RATE_RESP: data_rate- ", | ||
460 | (u8 *) pdatarate, sizeof(struct cmd_ds_802_11_data_rate)); | ||
461 | |||
462 | dot11datarate = pdatarate->datarate[0]; | ||
463 | if (pdatarate->action == cmd_act_get_tx_rate) { | ||
464 | memcpy(adapter->libertas_supported_rates, pdatarate->datarate, | ||
465 | sizeof(adapter->libertas_supported_rates)); | ||
466 | } | ||
467 | adapter->datarate = libertas_index_to_data_rate(dot11datarate); | ||
468 | |||
469 | LEAVE(); | ||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | static int wlan_ret_802_11_rf_channel(wlan_private * priv, | ||
474 | struct cmd_ds_command *resp) | ||
475 | { | ||
476 | struct cmd_ds_802_11_rf_channel *rfchannel = | ||
477 | &resp->params.rfchannel; | ||
478 | wlan_adapter *adapter = priv->adapter; | ||
479 | u16 action = le16_to_cpu(rfchannel->action); | ||
480 | u16 newchannel = le16_to_cpu(rfchannel->currentchannel); | ||
481 | |||
482 | ENTER(); | ||
483 | |||
484 | if (action == cmd_opt_802_11_rf_channel_get | ||
485 | && adapter->curbssparams.channel != newchannel) { | ||
486 | lbs_pr_debug(1, "channel Switch: %d to %d\n", | ||
487 | adapter->curbssparams.channel, newchannel); | ||
488 | |||
489 | /* Update the channel again */ | ||
490 | adapter->curbssparams.channel = newchannel; | ||
491 | } | ||
492 | |||
493 | LEAVE(); | ||
494 | return 0; | ||
495 | } | ||
496 | |||
497 | static int wlan_ret_802_11_rssi(wlan_private * priv, | ||
498 | struct cmd_ds_command *resp) | ||
499 | { | ||
500 | struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp; | ||
501 | wlan_adapter *adapter = priv->adapter; | ||
502 | |||
503 | /* store the non average value */ | ||
504 | adapter->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR); | ||
505 | adapter->NF[TYPE_BEACON][TYPE_NOAVG] = | ||
506 | le16_to_cpu(rssirsp->noisefloor); | ||
507 | |||
508 | adapter->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR); | ||
509 | adapter->NF[TYPE_BEACON][TYPE_AVG] = | ||
510 | le16_to_cpu(rssirsp->avgnoisefloor); | ||
511 | |||
512 | adapter->RSSI[TYPE_BEACON][TYPE_NOAVG] = | ||
513 | CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG], | ||
514 | adapter->NF[TYPE_BEACON][TYPE_NOAVG]); | ||
515 | |||
516 | adapter->RSSI[TYPE_BEACON][TYPE_AVG] = | ||
517 | CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE, | ||
518 | adapter->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE); | ||
519 | |||
520 | lbs_pr_debug(1, "Beacon RSSI value = 0x%x\n", | ||
521 | adapter->RSSI[TYPE_BEACON][TYPE_AVG]); | ||
522 | |||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | static int wlan_ret_802_11_eeprom_access(wlan_private * priv, | ||
527 | struct cmd_ds_command *resp) | ||
528 | { | ||
529 | wlan_adapter *adapter = priv->adapter; | ||
530 | struct wlan_ioctl_regrdwr *pbuf; | ||
531 | pbuf = (struct wlan_ioctl_regrdwr *) adapter->prdeeprom; | ||
532 | |||
533 | lbs_pr_debug(1, "eeprom read len=%x\n", | ||
534 | le16_to_cpu(resp->params.rdeeprom.bytecount)); | ||
535 | if (pbuf->NOB < le16_to_cpu(resp->params.rdeeprom.bytecount)) { | ||
536 | pbuf->NOB = 0; | ||
537 | lbs_pr_debug(1, "eeprom read return length is too big\n"); | ||
538 | return -1; | ||
539 | } | ||
540 | pbuf->NOB = le16_to_cpu(resp->params.rdeeprom.bytecount); | ||
541 | if (pbuf->NOB > 0) { | ||
542 | |||
543 | memcpy(&pbuf->value, (u8 *) & resp->params.rdeeprom.value, | ||
544 | le16_to_cpu(resp->params.rdeeprom.bytecount)); | ||
545 | lbs_dbg_hex("adapter", (char *)&pbuf->value, | ||
546 | le16_to_cpu(resp->params.rdeeprom.bytecount)); | ||
547 | } | ||
548 | return 0; | ||
549 | } | ||
550 | |||
551 | static int wlan_ret_get_log(wlan_private * priv, | ||
552 | struct cmd_ds_command *resp) | ||
553 | { | ||
554 | struct cmd_ds_802_11_get_log *logmessage = | ||
555 | (struct cmd_ds_802_11_get_log *)&resp->params.glog; | ||
556 | wlan_adapter *adapter = priv->adapter; | ||
557 | |||
558 | ENTER(); | ||
559 | |||
560 | /* TODO Convert it to Big Endian before copy */ | ||
561 | memcpy(&adapter->logmsg, logmessage, | ||
562 | sizeof(struct cmd_ds_802_11_get_log)); | ||
563 | |||
564 | LEAVE(); | ||
565 | return 0; | ||
566 | } | ||
567 | |||
568 | static inline int handle_cmd_response(u16 respcmd, | ||
569 | struct cmd_ds_command *resp, | ||
570 | wlan_private *priv) | ||
571 | { | ||
572 | int ret = 0; | ||
573 | unsigned long flags; | ||
574 | wlan_adapter *adapter = priv->adapter; | ||
575 | |||
576 | switch (respcmd) { | ||
577 | case cmd_ret_mac_reg_access: | ||
578 | case cmd_ret_bbp_reg_access: | ||
579 | case cmd_ret_rf_reg_access: | ||
580 | ret = wlan_ret_reg_access(priv, respcmd, resp); | ||
581 | break; | ||
582 | |||
583 | case cmd_ret_hw_spec_info: | ||
584 | ret = wlan_ret_get_hw_spec(priv, resp); | ||
585 | break; | ||
586 | |||
587 | case cmd_ret_802_11_scan: | ||
588 | ret = libertas_ret_80211_scan(priv, resp); | ||
589 | break; | ||
590 | |||
591 | case cmd_ret_802_11_get_log: | ||
592 | ret = wlan_ret_get_log(priv, resp); | ||
593 | break; | ||
594 | |||
595 | case cmd_ret_802_11_associate: | ||
596 | case cmd_ret_802_11_reassociate: | ||
597 | ret = libertas_ret_80211_associate(priv, resp); | ||
598 | break; | ||
599 | |||
600 | case cmd_ret_802_11_disassociate: | ||
601 | case cmd_ret_802_11_deauthenticate: | ||
602 | ret = libertas_ret_80211_disassociate(priv, resp); | ||
603 | break; | ||
604 | |||
605 | case cmd_ret_802_11_ad_hoc_start: | ||
606 | case cmd_ret_802_11_ad_hoc_join: | ||
607 | ret = libertas_ret_80211_ad_hoc_start(priv, resp); | ||
608 | break; | ||
609 | |||
610 | case cmd_ret_802_11_stat: | ||
611 | ret = wlan_ret_802_11_stat(priv, resp); | ||
612 | break; | ||
613 | |||
614 | case cmd_ret_802_11_snmp_mib: | ||
615 | ret = wlan_ret_802_11_snmp_mib(priv, resp); | ||
616 | break; | ||
617 | |||
618 | case cmd_ret_802_11_rf_tx_power: | ||
619 | ret = wlan_ret_802_11_rf_tx_power(priv, resp); | ||
620 | break; | ||
621 | |||
622 | case cmd_ret_802_11_set_afc: | ||
623 | case cmd_ret_802_11_get_afc: | ||
624 | spin_lock_irqsave(&adapter->driver_lock, flags); | ||
625 | memmove(adapter->cur_cmd->pdata_buf, | ||
626 | &resp->params.afc, | ||
627 | sizeof(struct cmd_ds_802_11_afc)); | ||
628 | spin_unlock_irqrestore(&adapter->driver_lock, flags); | ||
629 | |||
630 | break; | ||
631 | case cmd_ret_802_11_rf_antenna: | ||
632 | ret = wlan_ret_802_11_rf_antenna(priv, resp); | ||
633 | break; | ||
634 | |||
635 | case cmd_ret_mac_multicast_adr: | ||
636 | case cmd_ret_mac_control: | ||
637 | case cmd_ret_802_11_set_wep: | ||
638 | case cmd_ret_802_11_reset: | ||
639 | case cmd_ret_802_11_authenticate: | ||
640 | case cmd_ret_802_11_radio_control: | ||
641 | case cmd_ret_802_11_beacon_stop: | ||
642 | case cmd_ret_802_11_enable_rsn: | ||
643 | break; | ||
644 | |||
645 | case cmd_ret_802_11_data_rate: | ||
646 | ret = wlan_ret_802_11_data_rate(priv, resp); | ||
647 | break; | ||
648 | case cmd_ret_802_11_rate_adapt_rateset: | ||
649 | ret = wlan_ret_802_11_rate_adapt_rateset(priv, resp); | ||
650 | break; | ||
651 | case cmd_ret_802_11_rf_channel: | ||
652 | ret = wlan_ret_802_11_rf_channel(priv, resp); | ||
653 | break; | ||
654 | |||
655 | case cmd_ret_802_11_rssi: | ||
656 | ret = wlan_ret_802_11_rssi(priv, resp); | ||
657 | break; | ||
658 | |||
659 | case cmd_ret_802_11_mac_address: | ||
660 | ret = wlan_ret_802_11_mac_address(priv, resp); | ||
661 | break; | ||
662 | |||
663 | case cmd_ret_802_11_ad_hoc_stop: | ||
664 | ret = libertas_ret_80211_ad_hoc_stop(priv, resp); | ||
665 | break; | ||
666 | |||
667 | case cmd_ret_802_11_key_material: | ||
668 | lbs_pr_debug(1, "CMD_RESP: KEY_MATERIAL command response\n"); | ||
669 | ret = wlan_ret_802_11_key_material(priv, resp); | ||
670 | break; | ||
671 | |||
672 | case cmd_ret_802_11_eeprom_access: | ||
673 | ret = wlan_ret_802_11_eeprom_access(priv, resp); | ||
674 | break; | ||
675 | |||
676 | case cmd_ret_802_11d_domain_info: | ||
677 | ret = libertas_ret_802_11d_domain_info(priv, resp); | ||
678 | break; | ||
679 | |||
680 | case cmd_ret_802_11_sleep_params: | ||
681 | ret = wlan_ret_802_11_sleep_params(priv, resp); | ||
682 | break; | ||
683 | case cmd_ret_802_11_inactivity_timeout: | ||
684 | spin_lock_irqsave(&adapter->driver_lock, flags); | ||
685 | *((u16 *) adapter->cur_cmd->pdata_buf) = | ||
686 | le16_to_cpu(resp->params.inactivity_timeout.timeout); | ||
687 | spin_unlock_irqrestore(&adapter->driver_lock, flags); | ||
688 | break; | ||
689 | |||
690 | case cmd_ret_802_11_tpc_cfg: | ||
691 | spin_lock_irqsave(&adapter->driver_lock, flags); | ||
692 | memmove(adapter->cur_cmd->pdata_buf, | ||
693 | &resp->params.tpccfg, | ||
694 | sizeof(struct cmd_ds_802_11_tpc_cfg)); | ||
695 | spin_unlock_irqrestore(&adapter->driver_lock, flags); | ||
696 | break; | ||
697 | case cmd_ret_802_11_led_gpio_ctrl: | ||
698 | spin_lock_irqsave(&adapter->driver_lock, flags); | ||
699 | memmove(adapter->cur_cmd->pdata_buf, | ||
700 | &resp->params.ledgpio, | ||
701 | sizeof(struct cmd_ds_802_11_led_ctrl)); | ||
702 | spin_unlock_irqrestore(&adapter->driver_lock, flags); | ||
703 | break; | ||
704 | case cmd_ret_802_11_pwr_cfg: | ||
705 | spin_lock_irqsave(&adapter->driver_lock, flags); | ||
706 | memmove(adapter->cur_cmd->pdata_buf, | ||
707 | &resp->params.pwrcfg, | ||
708 | sizeof(struct cmd_ds_802_11_pwr_cfg)); | ||
709 | spin_unlock_irqrestore(&adapter->driver_lock, flags); | ||
710 | |||
711 | break; | ||
712 | |||
713 | case cmd_ret_get_tsf: | ||
714 | spin_lock_irqsave(&adapter->driver_lock, flags); | ||
715 | memcpy(priv->adapter->cur_cmd->pdata_buf, | ||
716 | &resp->params.gettsf.tsfvalue, sizeof(u64)); | ||
717 | spin_unlock_irqrestore(&adapter->driver_lock, flags); | ||
718 | break; | ||
719 | case cmd_ret_bt_access: | ||
720 | spin_lock_irqsave(&adapter->driver_lock, flags); | ||
721 | if (adapter->cur_cmd->pdata_buf) | ||
722 | memcpy(adapter->cur_cmd->pdata_buf, | ||
723 | &resp->params.bt.addr1, 2 * ETH_ALEN); | ||
724 | spin_unlock_irqrestore(&adapter->driver_lock, flags); | ||
725 | break; | ||
726 | case cmd_ret_fwt_access: | ||
727 | spin_lock_irqsave(&adapter->driver_lock, flags); | ||
728 | if (adapter->cur_cmd->pdata_buf) | ||
729 | memcpy(adapter->cur_cmd->pdata_buf, | ||
730 | &resp->params.fwt, | ||
731 | sizeof(resp->params.fwt)); | ||
732 | spin_unlock_irqrestore(&adapter->driver_lock, flags); | ||
733 | break; | ||
734 | case cmd_ret_mesh_access: | ||
735 | if (adapter->cur_cmd->pdata_buf) | ||
736 | memcpy(adapter->cur_cmd->pdata_buf, | ||
737 | &resp->params.mesh, | ||
738 | sizeof(resp->params.mesh)); | ||
739 | break; | ||
740 | case cmd_rte_802_11_tx_rate_query: | ||
741 | priv->adapter->txrate = resp->params.txrate.txrate; | ||
742 | break; | ||
743 | default: | ||
744 | lbs_pr_debug(1, "CMD_RESP: Unknown command response %#x\n", | ||
745 | resp->command); | ||
746 | break; | ||
747 | } | ||
748 | return ret; | ||
749 | } | ||
750 | |||
751 | int libertas_process_rx_command(wlan_private * priv) | ||
752 | { | ||
753 | u16 respcmd; | ||
754 | struct cmd_ds_command *resp; | ||
755 | wlan_adapter *adapter = priv->adapter; | ||
756 | int ret = 0; | ||
757 | ulong flags; | ||
758 | u16 result; | ||
759 | |||
760 | ENTER(); | ||
761 | |||
762 | lbs_pr_debug(1, "CMD_RESP: @ %lu\n", jiffies); | ||
763 | |||
764 | /* Now we got response from FW, cancel the command timer */ | ||
765 | del_timer(&adapter->command_timer); | ||
766 | |||
767 | mutex_lock(&adapter->lock); | ||
768 | spin_lock_irqsave(&adapter->driver_lock, flags); | ||
769 | |||
770 | if (!adapter->cur_cmd) { | ||
771 | lbs_pr_debug(1, "CMD_RESP: NULL cur_cmd=%p\n", adapter->cur_cmd); | ||
772 | ret = -1; | ||
773 | spin_unlock_irqrestore(&adapter->driver_lock, flags); | ||
774 | goto done; | ||
775 | } | ||
776 | resp = (struct cmd_ds_command *)(adapter->cur_cmd->bufvirtualaddr); | ||
777 | |||
778 | lbs_dbg_hex("CMD_RESP:", adapter->cur_cmd->bufvirtualaddr, | ||
779 | priv->wlan_dev.upld_len); | ||
780 | |||
781 | respcmd = le16_to_cpu(resp->command); | ||
782 | |||
783 | result = le16_to_cpu(resp->result); | ||
784 | |||
785 | lbs_pr_debug(1, "CMD_RESP: %x result: %d length: %d\n", respcmd, | ||
786 | result, priv->wlan_dev.upld_len); | ||
787 | |||
788 | if (!(respcmd & 0x8000)) { | ||
789 | lbs_pr_debug(1, "Invalid response to command!"); | ||
790 | adapter->cur_cmd_retcode = -1; | ||
791 | __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd); | ||
792 | adapter->nr_cmd_pending--; | ||
793 | adapter->cur_cmd = NULL; | ||
794 | spin_unlock_irqrestore(&adapter->driver_lock, flags); | ||
795 | ret = -1; | ||
796 | goto done; | ||
797 | } | ||
798 | |||
799 | /* Store the response code to cur_cmd_retcode. */ | ||
800 | adapter->cur_cmd_retcode = le16_to_cpu(resp->result); | ||
801 | |||
802 | if (respcmd == cmd_ret_802_11_ps_mode) { | ||
803 | struct cmd_ds_802_11_ps_mode *psmode; | ||
804 | |||
805 | psmode = &resp->params.psmode; | ||
806 | lbs_pr_debug(1, | ||
807 | "CMD_RESP: PS_MODE cmd reply result=%#x action=0x%X\n", | ||
808 | resp->result, psmode->action); | ||
809 | psmode->action = cpu_to_le16(psmode->action); | ||
810 | |||
811 | if (result) { | ||
812 | lbs_pr_debug(1, "CMD_RESP: PS command failed- %#x \n", | ||
813 | resp->result); | ||
814 | if (adapter->inframode == wlan802_11ibss) { | ||
815 | /* | ||
816 | * We should not re-try enter-ps command in | ||
817 | * ad-hoc mode. It takes place in | ||
818 | * libertas_execute_next_command(). | ||
819 | */ | ||
820 | if (psmode->action == cmd_subcmd_enter_ps) | ||
821 | adapter->psmode = | ||
822 | wlan802_11powermodecam; | ||
823 | } | ||
824 | } else if (psmode->action == cmd_subcmd_enter_ps) { | ||
825 | adapter->needtowakeup = 0; | ||
826 | adapter->psstate = PS_STATE_AWAKE; | ||
827 | |||
828 | lbs_pr_debug(1, "CMD_RESP: Enter_PS command response\n"); | ||
829 | if (adapter->connect_status != libertas_connected) { | ||
830 | /* | ||
831 | * When Deauth Event received before Enter_PS command | ||
832 | * response, We need to wake up the firmware. | ||
833 | */ | ||
834 | lbs_pr_debug(1, | ||
835 | "Disconnected, Going to invoke libertas_ps_wakeup\n"); | ||
836 | |||
837 | mutex_unlock(&adapter->lock); | ||
838 | spin_unlock_irqrestore(&adapter->driver_lock, flags); | ||
839 | libertas_ps_wakeup(priv, 0); | ||
840 | mutex_lock(&adapter->lock); | ||
841 | spin_lock_irqsave(&adapter->driver_lock, flags); | ||
842 | } | ||
843 | } else if (psmode->action == cmd_subcmd_exit_ps) { | ||
844 | adapter->needtowakeup = 0; | ||
845 | adapter->psstate = PS_STATE_FULL_POWER; | ||
846 | lbs_pr_debug(1, "CMD_RESP: Exit_PS command response\n"); | ||
847 | } else { | ||
848 | lbs_pr_debug(1, "CMD_RESP: PS- action=0x%X\n", | ||
849 | psmode->action); | ||
850 | } | ||
851 | |||
852 | __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd); | ||
853 | adapter->nr_cmd_pending--; | ||
854 | adapter->cur_cmd = NULL; | ||
855 | spin_unlock_irqrestore(&adapter->driver_lock, flags); | ||
856 | |||
857 | ret = 0; | ||
858 | goto done; | ||
859 | } | ||
860 | |||
861 | if (adapter->cur_cmd->cmdflags & CMD_F_HOSTCMD) { | ||
862 | /* Copy the response back to response buffer */ | ||
863 | memcpy(adapter->cur_cmd->pdata_buf, resp, resp->size); | ||
864 | |||
865 | adapter->cur_cmd->cmdflags &= ~CMD_F_HOSTCMD; | ||
866 | } | ||
867 | |||
868 | /* If the command is not successful, cleanup and return failure */ | ||
869 | if ((result != 0 || !(respcmd & 0x8000))) { | ||
870 | lbs_pr_debug(1, "CMD_RESP: command reply %#x result=%#x\n", | ||
871 | resp->command, resp->result); | ||
872 | /* | ||
873 | * Handling errors here | ||
874 | */ | ||
875 | switch (respcmd) { | ||
876 | case cmd_ret_hw_spec_info: | ||
877 | case cmd_ret_802_11_reset: | ||
878 | lbs_pr_debug(1, "CMD_RESP: Reset command failed\n"); | ||
879 | break; | ||
880 | |||
881 | } | ||
882 | |||
883 | __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd); | ||
884 | adapter->nr_cmd_pending--; | ||
885 | adapter->cur_cmd = NULL; | ||
886 | spin_unlock_irqrestore(&adapter->driver_lock, flags); | ||
887 | |||
888 | ret = -1; | ||
889 | goto done; | ||
890 | } | ||
891 | |||
892 | spin_unlock_irqrestore(&adapter->driver_lock, flags); | ||
893 | |||
894 | ret = handle_cmd_response(respcmd, resp, priv); | ||
895 | |||
896 | spin_lock_irqsave(&adapter->driver_lock, flags); | ||
897 | if (adapter->cur_cmd) { | ||
898 | /* Clean up and Put current command back to cmdfreeq */ | ||
899 | __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd); | ||
900 | adapter->nr_cmd_pending--; | ||
901 | WARN_ON(adapter->nr_cmd_pending > 128); | ||
902 | adapter->cur_cmd = NULL; | ||
903 | } | ||
904 | spin_unlock_irqrestore(&adapter->driver_lock, flags); | ||
905 | |||
906 | done: | ||
907 | mutex_unlock(&adapter->lock); | ||
908 | LEAVE(); | ||
909 | return ret; | ||
910 | } | ||
911 | |||
912 | int libertas_process_event(wlan_private * priv) | ||
913 | { | ||
914 | int ret = 0; | ||
915 | wlan_adapter *adapter = priv->adapter; | ||
916 | u32 eventcause; | ||
917 | |||
918 | spin_lock_irq(&adapter->driver_lock); | ||
919 | eventcause = adapter->eventcause; | ||
920 | spin_unlock_irq(&adapter->driver_lock); | ||
921 | |||
922 | ENTER(); | ||
923 | |||
924 | lbs_pr_debug(1, "EVENT Cause %x\n", eventcause); | ||
925 | |||
926 | switch (eventcause >> SBI_EVENT_CAUSE_SHIFT) { | ||
927 | case MACREG_INT_CODE_LINK_SENSED: | ||
928 | lbs_pr_debug(1, "EVENT: MACREG_INT_CODE_LINK_SENSED\n"); | ||
929 | break; | ||
930 | |||
931 | case MACREG_INT_CODE_DEAUTHENTICATED: | ||
932 | lbs_pr_debug(1, "EVENT: Deauthenticated\n"); | ||
933 | libertas_mac_event_disconnected(priv); | ||
934 | break; | ||
935 | |||
936 | case MACREG_INT_CODE_DISASSOCIATED: | ||
937 | lbs_pr_debug(1, "EVENT: Disassociated\n"); | ||
938 | libertas_mac_event_disconnected(priv); | ||
939 | break; | ||
940 | |||
941 | case MACREG_INT_CODE_LINK_LOSE_NO_SCAN: | ||
942 | lbs_pr_debug(1, "EVENT: Link lost\n"); | ||
943 | libertas_mac_event_disconnected(priv); | ||
944 | break; | ||
945 | |||
946 | case MACREG_INT_CODE_PS_SLEEP: | ||
947 | lbs_pr_debug(1, "EVENT: SLEEP\n"); | ||
948 | lbs_pr_debug(1, "_"); | ||
949 | |||
950 | /* handle unexpected PS SLEEP event */ | ||
951 | if (adapter->psstate == PS_STATE_FULL_POWER) { | ||
952 | lbs_pr_debug(1, | ||
953 | "EVENT: In FULL POWER mode - ignore PS SLEEP\n"); | ||
954 | break; | ||
955 | } | ||
956 | adapter->psstate = PS_STATE_PRE_SLEEP; | ||
957 | |||
958 | libertas_ps_confirm_sleep(priv, (u16) adapter->psmode); | ||
959 | |||
960 | break; | ||
961 | |||
962 | case MACREG_INT_CODE_PS_AWAKE: | ||
963 | lbs_pr_debug(1, "EVENT: AWAKE \n"); | ||
964 | lbs_pr_debug(1, "|"); | ||
965 | |||
966 | /* handle unexpected PS AWAKE event */ | ||
967 | if (adapter->psstate == PS_STATE_FULL_POWER) { | ||
968 | lbs_pr_debug(1, | ||
969 | "EVENT: In FULL POWER mode - ignore PS AWAKE\n"); | ||
970 | break; | ||
971 | } | ||
972 | |||
973 | adapter->psstate = PS_STATE_AWAKE; | ||
974 | |||
975 | if (adapter->needtowakeup) { | ||
976 | /* | ||
977 | * wait for the command processing to finish | ||
978 | * before resuming sending | ||
979 | * adapter->needtowakeup will be set to FALSE | ||
980 | * in libertas_ps_wakeup() | ||
981 | */ | ||
982 | lbs_pr_debug(1, "Waking up...\n"); | ||
983 | libertas_ps_wakeup(priv, 0); | ||
984 | } | ||
985 | break; | ||
986 | |||
987 | case MACREG_INT_CODE_MIC_ERR_UNICAST: | ||
988 | lbs_pr_debug(1, "EVENT: UNICAST MIC ERROR\n"); | ||
989 | handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_UNICAST); | ||
990 | break; | ||
991 | |||
992 | case MACREG_INT_CODE_MIC_ERR_MULTICAST: | ||
993 | lbs_pr_debug(1, "EVENT: MULTICAST MIC ERROR\n"); | ||
994 | handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_MULTICAST); | ||
995 | break; | ||
996 | case MACREG_INT_CODE_MIB_CHANGED: | ||
997 | case MACREG_INT_CODE_INIT_DONE: | ||
998 | break; | ||
999 | |||
1000 | case MACREG_INT_CODE_ADHOC_BCN_LOST: | ||
1001 | lbs_pr_debug(1, "EVENT: HWAC - ADHOC BCN LOST\n"); | ||
1002 | break; | ||
1003 | |||
1004 | case MACREG_INT_CODE_RSSI_LOW: | ||
1005 | lbs_pr_alert( "EVENT: RSSI_LOW\n"); | ||
1006 | break; | ||
1007 | case MACREG_INT_CODE_SNR_LOW: | ||
1008 | lbs_pr_alert( "EVENT: SNR_LOW\n"); | ||
1009 | break; | ||
1010 | case MACREG_INT_CODE_MAX_FAIL: | ||
1011 | lbs_pr_alert( "EVENT: MAX_FAIL\n"); | ||
1012 | break; | ||
1013 | case MACREG_INT_CODE_RSSI_HIGH: | ||
1014 | lbs_pr_alert( "EVENT: RSSI_HIGH\n"); | ||
1015 | break; | ||
1016 | case MACREG_INT_CODE_SNR_HIGH: | ||
1017 | lbs_pr_alert( "EVENT: SNR_HIGH\n"); | ||
1018 | break; | ||
1019 | |||
1020 | default: | ||
1021 | lbs_pr_alert( "EVENT: unknown event id: %#x\n", | ||
1022 | eventcause >> SBI_EVENT_CAUSE_SHIFT); | ||
1023 | break; | ||
1024 | } | ||
1025 | |||
1026 | spin_lock_irq(&adapter->driver_lock); | ||
1027 | adapter->eventcause = 0; | ||
1028 | spin_unlock_irq(&adapter->driver_lock); | ||
1029 | LEAVE(); | ||
1030 | return ret; | ||
1031 | } | ||