1 #include <linux/module.h>
2 #include <linux/dcache.h>
3 #include <linux/debugfs.h>
4 #include <linux/delay.h>
6 #include <linux/string.h>
7 #include <linux/etherdevice.h>
8 #include <net/iw_handler.h>
9 #include <linux/mmc/sdio_func.h>
11 #include "rda5890_defs.h"
12 #include "rda5890_dev.h"
13 #include "rda5890_wid.h"
14 #include "rda5890_wext.h"
15 #include "rda5890_txrx.h"
16 #include "rda5890_if_sdio.h"
18 static unsigned char is_need_set_notch = 0;
20 /* for both Query and Write */
21 int rda5890_wid_request(struct rda5890_private *priv,
22 char *wid_req, unsigned short wid_req_len,
23 char *wid_rsp, unsigned short *wid_rsp_len)
27 char data_buf[RDA5890_MAX_WID_LEN + 2];
28 unsigned short data_len;
29 struct if_sdio_card * card = (struct if_sdio_card *)priv->card;
31 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
32 "%s <<<\n", __func__);
35 if(rda_5990_wifi_in_test_mode())
37 #endif //end WIFI_TEST_MODE
39 mutex_lock(&priv->wid_lock);
40 priv->wid_rsp = wid_rsp;
41 priv->wid_rsp_len = *wid_rsp_len;
42 priv->wid_pending = 1;
44 data_len = wid_req_len + 2;
45 data_buf[0] = (char)(data_len&0xFF);
46 data_buf[1] = (char)((data_len>>8)&0x0F);
47 data_buf[1] |= 0x40; // for Request(Q/W) 0x4
48 memcpy(data_buf + 2, wid_req, wid_req_len);
50 init_completion(&priv->wid_done);
51 #ifdef WIFI_UNLOCK_SYSTEM
54 ret = rda5890_host_to_card(priv, data_buf, data_len, WID_REQUEST_PACKET);
56 RDA5890_ERRP("host_to_card send failed, ret = %d\n", ret);
57 priv->wid_pending = 0;
61 atomic_inc(&card->wid_complete_flag);
62 timeleft = wait_for_completion_timeout(&priv->wid_done, msecs_to_jiffies(450));
64 RDA5890_ERRP("respose timeout wid :%x %x \n", wid_req[4], wid_req[5]);
65 priv->wid_pending = 0;
70 *wid_rsp_len = priv->wid_rsp_len;
73 mutex_unlock(&priv->wid_lock);
74 atomic_set(&card->wid_complete_flag, 0);
75 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
76 "%s >>> wid: %x %x \n", __func__, wid_req[4],wid_req[5]);
77 #ifdef WIFI_UNLOCK_SYSTEM
83 int rda5890_wid_request_polling(struct rda5890_private *priv,
84 char *wid_req, unsigned short wid_req_len,
85 char *wid_rsp, unsigned short *wid_rsp_len)
89 char data_buf[RDA5890_MAX_WID_LEN + 2];
90 unsigned short data_len;
92 unsigned int retry = 0, count = 0;
93 struct if_sdio_card * card = (struct if_sdio_card*)priv->card;
95 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
96 "%s >>>\n", __func__);
98 priv->wid_rsp = wid_rsp;
99 priv->wid_rsp_len = *wid_rsp_len;
101 data_len = wid_req_len + 2;
102 data_buf[0] = (char)(data_len&0xFF);
103 data_buf[1] = (char)((data_len>>8)&0x0F);
104 data_buf[1] |= 0x40; // for Request(Q/W) 0x4
105 memcpy(data_buf + 2, wid_req, wid_req_len);
110 ret = rda5890_host_to_card(priv, data_buf, data_len, WID_REQUEST_POLLING_PACKET);
112 RDA5890_ERRP("host_to_card send failed, ret = %d\n", ret);
116 rda5890_shedule_timeout(3); //3ms delay
119 sdio_claim_host(card->func);
120 status = sdio_readb(card->func, IF_SDIO_FUN1_INT_STAT, &ret);
121 sdio_release_host(card->func);
125 if (status & IF_SDIO_INT_AHB2SDIO)
128 u8 size_l = 0, size_h = 0;
131 sdio_claim_host(card->func);
132 size_l = sdio_readb(card->func, IF_SDIO_AHB2SDIO_PKTLEN_L, &ret);
133 sdio_release_host(card->func);
135 RDA5890_ERRP("read PKTLEN_L reg fail\n");
139 RDA5890_ERRP("read PKTLEN_L reg size_l:%d \n", size_l);
141 sdio_claim_host(card->func);
142 size_h = sdio_readb(card->func, IF_SDIO_AHB2SDIO_PKTLEN_H, &ret);
143 sdio_release_host(card->func);
145 RDA5890_ERRP("read PKTLEN_H reg fail\n");
149 RDA5890_ERRP("read PKTLEN_H reg size_h:%d\n",size_h);
151 size = (size_l | ((size_h & 0x7f) << 8)) * 4;
153 RDA5890_ERRP("invalid packet size (%d bytes) from firmware\n", size);
158 /* alignment is handled on firmside */
159 //chunk = sdio_align_size(card->func, size);
162 RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_NORM,
163 "if_sdio_card_to_host, size = %d, aligned size = %d\n", size, chunk);
165 /* TODO: handle multiple packets here */
166 sdio_claim_host(card->func);
167 ret = sdio_readsb(card->func, card->buffer, IF_SDIO_FUN1_FIFO_RD, chunk);
168 sdio_release_host(card->func);
170 RDA5890_ERRP("sdio_readsb fail, ret = %d\n", ret);
174 if(priv->version == 7)
175 sdio_writeb(card->func, 0x20 ,IF_SDIO_FUN1_INT_PEND, &ret);
178 /* TODO: this chunk size need to be handled here */
180 unsigned char rx_type;
181 unsigned short rx_length;
182 unsigned char msg_type;
183 unsigned char *packet = (unsigned char *)card->buffer;
185 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
186 "%s >>>\n", __func__);
188 rx_type = (unsigned char)packet[1]&0xF0;
189 rx_length = (unsigned short)(packet[0] + ((packet[1]&0x0f) << 8));
191 if (rx_length > chunk) {
192 RDA5890_ERRP("packet_len %d less than header specified length %d\n",
197 if( rx_type == 0x30 )
199 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_NORM,
200 "Message Packet type =%x \n", msg_type);
201 msg_type = packet[2];
206 if(priv->wid_msg_id - 1 == packet[1])
209 if(priv->wid_rsp_len > rx_length - 2)
211 priv->wid_rsp_len = rx_length - 2;
212 memcpy(priv->wid_rsp, packet, rx_length -2);
217 RDA5890_ERRP("rda5890_wid_request_polling wid_msg_id is wrong %d %d wid=%x \n", priv->wid_msg_id -1, packet[1], (packet[4] | (packet[5] << 8)));
223 rda5890_shedule_timeout(3); //3ms delay
228 if(ret < 0 && count <= 3)
232 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
233 "%s <<< wid: %x %x retry: %d count = %d \n", __func__, wid_req[4],wid_req[5], retry, count);
237 void rda5890_wid_response(struct rda5890_private *priv,
238 char *wid_rsp, unsigned short wid_rsp_len)
240 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
241 "%s >>>\n", __func__);
243 if (!priv->wid_pending) {
244 RDA5890_ERRP("no wid pending\n");
248 if (wid_rsp_len > priv->wid_rsp_len) {
249 RDA5890_ERRP("not enough space for wid response, size = %d, buf = %d\n",
250 wid_rsp_len, priv->wid_rsp_len);
251 complete(&priv->wid_done);
255 memcpy(priv->wid_rsp, wid_rsp, wid_rsp_len);
256 priv->wid_rsp_len = wid_rsp_len;
257 priv->wid_pending = 0;
259 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
260 "%s <<<\n", __func__);
262 complete(&priv->wid_done);
265 void rda5890_wid_status(struct rda5890_private *priv,
266 char *wid_status, unsigned short wid_status_len)
270 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
271 "%s >>>\n", __func__);
273 #ifdef WIFI_UNLOCK_SYSTEM
277 mac_status = wid_status[7];
278 if (mac_status == MAC_CONNECTED) {
279 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_CRIT,
282 priv->connect_status = MAC_CONNECTED;
283 netif_carrier_on(priv->dev);
284 netif_wake_queue(priv->dev);
285 rda5890_indicate_connected(priv);
287 priv->first_init = 0;
288 cancel_delayed_work(&priv->assoc_done_work);
289 queue_delayed_work(priv->work_thread, &priv->assoc_done_work, 0);
291 if(test_and_clear_bit(ASSOC_FLAG_ASSOC_RETRY, &priv->assoc_flags))
293 cancel_delayed_work_sync(&priv->assoc_work);
296 if(test_bit(ASSOC_FLAG_WLAN_CONNECTING, &priv->assoc_flags))
297 cancel_delayed_work(&priv->wlan_connect_work);
299 set_bit(ASSOC_FLAG_WLAN_CONNECTING, &priv->assoc_flags);
300 queue_delayed_work(priv->work_thread, &priv->wlan_connect_work, HZ*20);
303 else if (mac_status == MAC_DISCONNECTED) {
305 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_CRIT,
306 "MAC DISCONNECTED\n");
308 if(priv->connect_status == MAC_CONNECTED)
309 is_need_set_notch = 1;
311 is_need_set_notch = 0;
313 if(!test_bit(ASSOC_FLAG_ASSOC_RETRY, &priv->assoc_flags))
315 priv->connect_status = MAC_DISCONNECTED;
316 netif_stop_queue(priv->dev);
317 netif_carrier_off(priv->dev);
318 if(!priv->first_init) // the first disconnect should not send to upper
319 rda5890_indicate_disconnected(priv);
321 priv->first_init = 0;
323 if(test_bit(ASSOC_FLAG_ASSOC_START, &priv->assoc_flags))
325 cancel_delayed_work(&priv->wlan_connect_work);
326 queue_delayed_work(priv->work_thread, &priv->wlan_connect_work, HZ*4);
329 clear_bit(ASSOC_FLAG_ASSOC_START, &priv->assoc_flags);
330 clear_bit(ASSOC_FLAG_WLAN_CONNECTING, &priv->assoc_flags);
334 RDA5890_ERRP("********wep assoc will be retry ---------- 0x%02x\n", mac_status);
338 RDA5890_ERRP("Invalid MAC Status 0x%02x\n", mac_status);
341 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
342 "%s <<<\n", __func__);
344 #ifdef WIFI_UNLOCK_SYSTEM
345 rda5990_wakeUnlock();
349 void rda5890_card_to_host(struct rda5890_private *priv,
350 char *packet, unsigned short packet_len)
352 unsigned char rx_type;
353 unsigned short rx_length;
354 unsigned char msg_type;
356 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
357 "%s >>>\n", __func__);
359 rx_type = (unsigned char)packet[1]&0xF0;
360 rx_length = (unsigned short)(packet[0] + ((packet[1]&0x0f) << 8));
362 if (rx_length > packet_len) {
363 RDA5890_ERRP("packet_len %d less than header specified length %d\n",
364 packet_len, rx_length);
368 if( rx_type == 0x30 )
370 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_NORM,
372 msg_type = packet[2];
375 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_NORM,
376 "Indication Message\n");
377 rda5890_wid_status(priv, packet + 2, rx_length - 2);
379 else if (msg_type == 'R')
381 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_NORM,
383 rda5890_wid_response(priv, packet + 2, rx_length - 2);
385 #ifdef GET_SCAN_FROM_NETWORK_INFO
386 else if(msg_type == 'N')
388 extern void rda5890_network_information(struct rda5890_private *priv,
389 char *info, unsigned short info_len);
390 rda5890_network_information(priv, packet + 2, rx_length - 2);
394 //RDA5890_ERRP("Invalid Message Type '%c'\n", msg_type);
397 else if(rx_type == 0x20)
399 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_NORM,
401 rda5890_data_rx(priv, packet + 2, rx_length - 2);
404 RDA5890_ERRP("Invalid Packet Type 0x%02x\n", rx_type);
409 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
410 "%s <<<\n", __func__);
414 * check wid response header
415 * if no error, return the pointer to the payload
416 * support only 1 wid per packet
418 int rda5890_check_wid_response(char *wid_rsp, unsigned short wid_rsp_len,
419 unsigned short wid, char wid_msg_id,
420 char payload_len, char **ptr_payload)
422 unsigned short rsp_len;
423 unsigned short rsp_wid;
424 unsigned char msg_len;
426 if (wid_rsp[0] != 'R') {
427 RDA5890_ERRP("wid_rsp[0] != 'R'\n");
431 if (wid_rsp[1] != wid_msg_id) {
432 RDA5890_ERRP("wid_msg_id not match msg_id: %d \n", wid_rsp[1]);
436 if (wid_rsp_len < 4) {
437 RDA5890_ERRP("wid_rsp_len < 4\n");
441 rsp_len = wid_rsp[2] | (wid_rsp[3] << 8);
442 if (wid_rsp_len != rsp_len) {
443 RDA5890_ERRP("wid_rsp_len not match, %d != %d\n", wid_rsp_len, rsp_len);
447 if (wid_rsp_len < 7) {
448 RDA5890_ERRP("wid_rsp_len < 7\n");
452 rsp_wid = wid_rsp[4] | (wid_rsp[5] << 8);
453 if (wid != rsp_wid) {
454 RDA5890_ERRP("wid not match, 0x%04x != 0x%04x\n", wid, rsp_wid);
458 msg_len = wid_rsp[6];
459 if (wid_rsp_len != msg_len + 7) {
460 RDA5890_ERRP("msg_len not match, %d + 7 != %d\n", msg_len, wid_rsp_len);
464 if (payload_len != msg_len) {
465 RDA5890_ERRP("payload_len not match, %d != %d\n", msg_len, payload_len);
469 *ptr_payload = wid_rsp + 7;
474 RDA5890_ERRP("rda5890_check_wid_response failed wid=0x%04x wid_msg_id:%d \n" ,wid_rsp[4] | (wid_rsp[5] << 8), wid_msg_id);
479 * check wid status response
481 int rda5890_check_wid_status(char *wid_rsp, unsigned short wid_rsp_len,
485 unsigned short wid = WID_STATUS;
489 ret = rda5890_check_wid_response(wid_rsp, wid_rsp_len, wid, wid_msg_id,
492 RDA5890_ERRP("rda5890_check_wid_status, check_wid_response fail\n");
496 status_val = ptr_payload[0];
497 if (status_val != WID_STATUS_SUCCESS) {
498 RDA5890_ERRP("check_wid_status NOT success, status = %d\n", status_val);
505 int rda5890_generic_get_uchar(struct rda5890_private *priv,
506 unsigned short wid, unsigned char *val)
510 unsigned short wid_req_len = 6;
512 unsigned short wid_rsp_len = 32;
513 char wid_msg_id = priv->wid_msg_id++;
517 wid_req[1] = wid_msg_id;
519 wid_req[2] = (char)(wid_req_len&0x00FF);
520 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
522 wid_req[4] = (char)(wid&0x00FF);
523 wid_req[5] = (char)((wid&0xFF00) >> 8);
525 ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
527 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
531 ret = rda5890_check_wid_response(wid_rsp, wid_rsp_len, wid, wid_msg_id,
532 sizeof(unsigned char), &ptr_payload);
534 RDA5890_ERRP("check_wid_response fail, ret = %d\n", ret);
543 int rda5890_generic_set_uchar(struct rda5890_private *priv,
544 unsigned short wid, unsigned char val)
547 char wid_req[7 + sizeof(unsigned char)];
548 unsigned short wid_req_len = 7 + 1;
550 unsigned short wid_rsp_len = 32;
551 char wid_msg_id = priv->wid_msg_id++;
554 wid_req[1] = wid_msg_id;
556 wid_req[2] = (char)(wid_req_len&0x00FF);
557 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
559 wid_req[4] = (char)(wid&0x00FF);
560 wid_req[5] = (char)((wid&0xFF00) >> 8);
564 ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
566 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
570 ret = rda5890_check_wid_status(wid_rsp, wid_rsp_len, wid_msg_id);
572 RDA5890_ERRP("check_wid_status fail, ret = %d\n", ret);
581 int rda5890_generic_get_ushort(struct rda5890_private *priv,
582 unsigned short wid, unsigned short *val)
586 unsigned short wid_req_len = 6;
588 unsigned short wid_rsp_len = 32;
589 char wid_msg_id = priv->wid_msg_id++;
593 wid_req[1] = wid_msg_id;
595 wid_req[2] = (char)(wid_req_len&0x00FF);
596 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
598 wid_req[4] = (char)(wid&0x00FF);
599 wid_req[5] = (char)((wid&0xFF00) >> 8);
601 ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
603 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
607 ret = rda5890_check_wid_response(wid_rsp, wid_rsp_len, wid, wid_msg_id,
608 sizeof(unsigned short), &ptr_payload);
610 RDA5890_ERRP("check_wid_response fail, ret = %d\n", ret);
614 memcpy(val, ptr_payload, sizeof(unsigned short));
620 int rda5890_generic_set_ushort(struct rda5890_private *priv,
621 unsigned short wid, unsigned short val)
624 char wid_req[7 + sizeof(unsigned short)];
625 unsigned short wid_req_len = 7 + sizeof(unsigned short);
627 unsigned short wid_rsp_len = 32;
628 char wid_msg_id = priv->wid_msg_id++;
631 wid_req[1] = wid_msg_id;
633 wid_req[2] = (char)(wid_req_len&0x00FF);
634 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
636 wid_req[4] = (char)(wid&0x00FF);
637 wid_req[5] = (char)((wid&0xFF00) >> 8);
639 wid_req[6] = (char)(sizeof(unsigned short));
640 memcpy(wid_req + 7, &val, sizeof(unsigned short));
642 ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
644 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
648 ret = rda5890_check_wid_status(wid_rsp, wid_rsp_len, wid_msg_id);
650 RDA5890_ERRP("check_wid_status fail, ret = %d\n", ret);
659 int rda5890_generic_get_ulong(struct rda5890_private *priv,
660 unsigned short wid, unsigned long *val)
664 unsigned short wid_req_len = 6;
666 unsigned short wid_rsp_len = 32;
667 char wid_msg_id = priv->wid_msg_id++;
671 wid_req[1] = wid_msg_id;
673 wid_req[2] = (char)(wid_req_len&0x00FF);
674 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
676 wid_req[4] = (char)(wid&0x00FF);
677 wid_req[5] = (char)((wid&0xFF00) >> 8);
679 ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
681 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
685 ret = rda5890_check_wid_response(wid_rsp, wid_rsp_len, wid, wid_msg_id,
686 sizeof(unsigned long), &ptr_payload);
688 RDA5890_ERRP("check_wid_response fail, ret = %d\n", ret);
692 memcpy(val, ptr_payload, sizeof(unsigned long));
698 int rda5890_generic_set_ulong(struct rda5890_private *priv,
699 unsigned short wid, unsigned long val)
702 char wid_req[7 + sizeof(unsigned long)];
703 unsigned short wid_req_len = 7 + sizeof(unsigned long);
705 unsigned short wid_rsp_len = 32;
706 char wid_msg_id = priv->wid_msg_id++;
709 wid_req[1] = wid_msg_id;
711 wid_req[2] = (char)(wid_req_len&0x00FF);
712 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
714 wid_req[4] = (char)(wid&0x00FF);
715 wid_req[5] = (char)((wid&0xFF00) >> 8);
717 wid_req[6] = (char)(sizeof(unsigned long));
718 memcpy(wid_req + 7, &val, sizeof(unsigned long));
720 ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
722 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
726 ret = rda5890_check_wid_status(wid_rsp, wid_rsp_len, wid_msg_id);
728 RDA5890_ERRP("check_wid_status fail, ret = %d\n", ret);
736 int rda5890_generic_get_str(struct rda5890_private *priv,
737 unsigned short wid, unsigned char *val, unsigned char len)
741 unsigned short wid_req_len = 6;
742 char wid_rsp[RDA5890_MAX_WID_LEN];
743 unsigned short wid_rsp_len = RDA5890_MAX_WID_LEN;
744 char wid_msg_id = priv->wid_msg_id++;
748 wid_req[1] = wid_msg_id;
750 wid_req[2] = (char)(wid_req_len&0x00FF);
751 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
753 wid_req[4] = (char)(wid&0x00FF);
754 wid_req[5] = (char)((wid&0xFF00) >> 8);
756 ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
758 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
762 ret = rda5890_check_wid_response(wid_rsp, wid_rsp_len, wid, wid_msg_id,
763 (char)len, &ptr_payload);
765 RDA5890_ERRP("check_wid_response fail, ret = %d\n", ret);
769 memcpy(val, ptr_payload, len);
775 int rda5890_generic_set_str(struct rda5890_private *priv,
776 unsigned short wid, unsigned char *val, unsigned char len)
779 char wid_req[RDA5890_MAX_WID_LEN];
780 unsigned short wid_req_len = 7 + len;
781 char wid_rsp[RDA5890_MAX_WID_LEN];
782 unsigned short wid_rsp_len = RDA5890_MAX_WID_LEN;
783 char wid_msg_id = priv->wid_msg_id++;
786 wid_req[1] = wid_msg_id;
788 wid_req[2] = (char)(wid_req_len&0x00FF);
789 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
791 wid_req[4] = (char)(wid&0x00FF);
792 wid_req[5] = (char)((wid&0xFF00) >> 8);
794 wid_req[6] = (char)(len);
795 memcpy(wid_req + 7, val, len);
797 ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
799 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
803 ret = rda5890_check_wid_status(wid_rsp, wid_rsp_len, wid_msg_id);
805 RDA5890_ERRP("check_wid_status fail, ret = %d\n", ret);
813 int rda5890_check_wid_response_unknown_len(
814 char *wid_rsp, unsigned short wid_rsp_len,
815 unsigned short wid, char wid_msg_id,
816 char *payload_len, char **ptr_payload)
818 unsigned short rsp_len;
819 unsigned short rsp_wid;
820 unsigned char msg_len;
822 if (wid_rsp[0] != 'R') {
823 RDA5890_ERRP("wid_rsp[0] != 'R'\n");
827 if (wid_rsp[1] != wid_msg_id) {
828 RDA5890_ERRP("wid_msg_id not match\n");
832 if (wid_rsp_len < 4) {
833 RDA5890_ERRP("wid_rsp_len < 4\n");
837 rsp_len = wid_rsp[2] | (wid_rsp[3] << 8);
838 if (wid_rsp_len != rsp_len) {
839 RDA5890_ERRP("wid_rsp_len not match, %d != %d\n", wid_rsp_len, rsp_len);
843 if (wid_rsp_len < 7) {
844 RDA5890_ERRP("wid_rsp_len < 7\n");
848 rsp_wid = wid_rsp[4] | (wid_rsp[5] << 8);
849 if (wid != rsp_wid) {
850 RDA5890_ERRP("wid not match, 0x%04x != 0x%04x\n", wid, rsp_wid);
854 msg_len = wid_rsp[6];
855 if (wid_rsp_len != msg_len + 7) {
856 RDA5890_ERRP("msg_len not match, %d + 7 != %d\n", msg_len, wid_rsp_len);
860 *payload_len = msg_len;
862 *ptr_payload = wid_rsp + 7;
867 RDA5890_ERRP("wid is %x wid_msg %d \n", wid_rsp[4] | (wid_rsp[5] << 8), wid_rsp[1]);
871 int rda5890_get_str_unknown_len(struct rda5890_private *priv,
872 unsigned short wid, unsigned char *val, unsigned char *len)
876 unsigned short wid_req_len = 6;
877 char wid_rsp[RDA5890_MAX_WID_LEN];
878 unsigned short wid_rsp_len = RDA5890_MAX_WID_LEN;
879 char wid_msg_id = priv->wid_msg_id++;
883 wid_req[1] = wid_msg_id;
885 wid_req[2] = (char)(wid_req_len&0x00FF);
886 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
888 wid_req[4] = (char)(wid&0x00FF);
889 wid_req[5] = (char)((wid&0xFF00) >> 8);
891 ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
893 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
897 ret = rda5890_check_wid_response_unknown_len(
898 wid_rsp, wid_rsp_len, wid, wid_msg_id, (char*)len, &ptr_payload);
900 RDA5890_ERRP("check_wid_response fail, ret = %d\n", ret);
904 memcpy(val, ptr_payload, *len);
910 extern int rda5890_sdio_set_default_notch(struct rda5890_private *priv);
911 int rda5890_start_scan(struct rda5890_private *priv)
915 unsigned short wid_req_len = 12;
917 unsigned short wid_rsp_len = 32;
921 if(priv->connect_status != MAC_CONNECTED)
923 rda5890_sdio_set_default_notch(priv);
926 wid_msg_id = priv->wid_msg_id++;
929 wid_req[1] = wid_msg_id;
931 wid_req[2] = (char)(wid_req_len&0x00FF);
932 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
934 wid = WID_SITE_SURVEY;
935 wid_req[4] = (char)(wid&0x00FF);
936 wid_req[5] = (char)((wid&0xFF00) >> 8);
938 wid_req[6] = (char)(0x01);
939 wid_req[7] = (char)(0x01);
941 wid = WID_START_SCAN_REQ;
942 wid_req[8] = (char)(wid&0x00FF);
943 wid_req[9] = (char)((wid&0xFF00) >> 8);
945 wid_req[10] = (char)(0x01);
946 wid_req[11] = (char)(0x01);
950 wid_req[2] = (char)(wid_req_len&0x00FF);
951 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
953 ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
955 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
959 ret = rda5890_check_wid_status(wid_rsp, wid_rsp_len, wid_msg_id);
961 RDA5890_ERRP("check_wid_status fail, ret = %d\n", ret);
970 int rda5890_start_scan_enable_network_info(struct rda5890_private *priv)
974 unsigned short wid_req_len = 12;
976 unsigned short wid_rsp_len = 32;
980 if(priv->connect_status != MAC_CONNECTED)
982 rda5890_sdio_set_default_notch(priv);
985 wid_msg_id = priv->wid_msg_id++;
988 wid_req[1] = wid_msg_id;
990 wid_req[2] = (char)(wid_req_len&0x00FF);
991 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
993 wid = WID_SITE_SURVEY;
994 wid_req[4] = (char)(wid&0x00FF);
995 wid_req[5] = (char)((wid&0xFF00) >> 8);
997 wid_req[6] = (char)(0x01);
998 wid_req[7] = (char)(0x01);
1000 wid = WID_START_SCAN_REQ;
1001 wid_req[8] = (char)(wid&0x00FF);
1002 wid_req[9] = (char)((wid&0xFF00) >> 8);
1004 wid_req[10] = (char)(0x01);
1005 wid_req[11] = (char)(0x01);
1007 wid = WID_NETWORK_INFO_EN;
1008 wid_req[12] = (char)(wid&0x00FF);
1009 wid_req[13] = (char)((wid&0xFF00) >> 8);
1011 wid_req[14] = (char)(0x01);
1012 wid_req[15] = (char)(0x01); // 0x01 scan network info
1015 wid_req[2] = (char)(wid_req_len&0x00FF);
1016 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
1018 ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
1020 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
1024 ret = rda5890_check_wid_status(wid_rsp, wid_rsp_len, wid_msg_id);
1026 RDA5890_ERRP("check_wid_status fail, ret = %d\n", ret);
1034 int rda5890_start_join(struct rda5890_private *priv)
1038 unsigned short wid_req_len = 0;
1040 unsigned short wid_rsp_len = 32;
1042 char wid_msg_id = priv->wid_msg_id++;
1043 unsigned short i = 0;
1044 unsigned char * wep_key = 0, key_str_len = 0;
1045 unsigned char key_str[26 + 1] , * key, *pWid_req;
1047 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
1048 "%s <<< mode:%d authtype:%d ssid:%s\n", __func__, priv->imode, priv->authtype,
1052 wid_req[1] = wid_msg_id;
1055 wid = WID_802_11I_MODE;
1056 wid_req[4] = (char)(wid&0x00FF);
1057 wid_req[5] = (char)((wid&0xFF00) >> 8);
1060 wid_req[7] = priv->imode;
1062 wid = WID_AUTH_TYPE;
1063 wid_req[8] = (char)(wid&0x00FF);
1064 wid_req[9] = (char)((wid&0xFF00) >> 8);
1067 wid_req[11] = priv->authtype;
1069 #ifdef GET_SCAN_FROM_NETWORK_INFO
1070 wid = WID_NETWORK_INFO_EN;
1071 wid_req[12] = (char)(wid&0x00FF);
1072 wid_req[13] = (char)((wid&0xFF00) >> 8);
1077 wid = WID_CURRENT_TX_RATE;
1078 wid_req[16] = (char)(wid&0x00FF);
1079 wid_req[17] = (char)((wid&0xFF00) >> 8);
1085 pWid_req = wid_req + 20;
1088 pWid_req = wid_req + 12;
1090 wid = WID_WEP_KEY_VALUE0;
1091 if(priv->imode == 3 || priv->imode == 7) //write wep key
1093 for(i = 0 ; i < 4; i ++)
1095 key = priv->wep_keys[i].key;
1097 if(priv->wep_keys[i].len == 0)
1100 if (priv->wep_keys[i].len == KEY_LEN_WEP_40) {
1101 sprintf(key_str, "%02x%02x%02x%02x%02x\n",
1102 key[0], key[1], key[2], key[3], key[4]);
1104 key_str[key_str_len] = '\0';
1106 else if (priv->wep_keys[i].len == KEY_LEN_WEP_104) {
1107 sprintf(key_str, "%02x%02x%02x%02x%02x"
1108 "%02x%02x%02x%02x%02x"
1110 key[0], key[1], key[2], key[3], key[4],
1111 key[5], key[6], key[7], key[8], key[9],
1112 key[10], key[11], key[12]);
1114 key_str[key_str_len] = '\0';
1119 pWid_req[0] = (char)((wid + i)&0x00FF);
1120 pWid_req[1] = (char)(((wid + i)&0xFF00) >> 8);
1122 pWid_req[2] = key_str_len;
1123 memcpy(pWid_req + 3, key_str, key_str_len);
1125 pWid_req += 3 + key_str_len;
1126 wid_req_len += 3 + key_str_len;
1132 pWid_req[0] = (char)(wid&0x00FF);
1133 pWid_req[1] = (char)((wid&0xFF00) >> 8);
1135 pWid_req[2] = priv->assoc_ssid_len;
1136 memcpy(pWid_req + 3, priv->assoc_ssid, priv->assoc_ssid_len);
1138 wid_req_len += 3 + priv->assoc_ssid_len;
1141 wid_req[2] = (char)(wid_req_len&0x00FF);
1142 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
1144 ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
1146 RDA5890_ERRP("rda5890_start_join fail, ret = %d\n", ret);
1150 ret = rda5890_check_wid_status(wid_rsp, wid_rsp_len, wid_msg_id);
1152 RDA5890_ERRP("rda5890_start_join check status fail, ret = %d\n", ret);
1158 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
1159 "%s >>> ret = %d req len %d mod:0x%x auth_type:0x%x \n", __func__, ret, wid_req_len, priv->imode
1164 int rda5890_set_txrate(struct rda5890_private *priv, unsigned char mbps)
1168 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1169 "rda5890_set_txrate <<< \n");
1171 ret = rda5890_generic_set_uchar(priv, WID_CURRENT_TX_RATE, mbps); //O FOR AUTO 1FOR 1MBPS
1176 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1177 "rda5890_set_txrate success >>> \n");
1183 int rda5890_set_core_init_polling(struct rda5890_private *priv, const unsigned int (*data)[2], unsigned char num)
1187 unsigned short wid_req_len = 4 + 14*num;
1189 unsigned short wid_rsp_len = 32;
1191 char wid_msg_id = priv->wid_msg_id++;
1192 char count = 0, *p_wid_req = NULL;
1194 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
1195 "%s <<< \n", __func__);
1198 wid_req[1] = wid_msg_id;
1200 wid_req[2] = (char)(wid_req_len&0x00FF);
1201 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
1203 p_wid_req = wid_req + 4;
1204 for(count = 0; count < num; count ++)
1206 wid = WID_MEMORY_ADDRESS;
1207 p_wid_req[0] = (char)(wid&0x00FF);
1208 p_wid_req[1] = (char)((wid&0xFF00) >> 8);
1210 p_wid_req[2] = (char)4;
1211 memcpy(p_wid_req + 3, (char*)&data[count][0], 4);
1213 wid = WID_MEMORY_ACCESS_32BIT;
1214 p_wid_req[7] = (char)(wid&0x00FF);
1215 p_wid_req[8] = (char)((wid&0xFF00) >> 8);
1217 p_wid_req[9] = (char)4;
1218 memcpy(p_wid_req + 10, (char*)&data[count][1], 4);
1221 ret = rda5890_wid_request_polling(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
1223 RDA5890_ERRP("rda5890_set_sdio_core_init fail, ret = %d\n", ret);
1228 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
1229 "%s >>> \n", __func__);
1233 int rda5890_set_core_init(struct rda5890_private *priv, const unsigned int (*data)[2], unsigned char num)
1237 unsigned short wid_req_len = 4 + 14*num;
1239 unsigned short wid_rsp_len = 32;
1241 char wid_msg_id = priv->wid_msg_id++;
1242 char count = 0, *p_wid_req = NULL;
1245 wid_req[1] = wid_msg_id;
1247 wid_req[2] = (char)(wid_req_len&0x00FF);
1248 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
1250 p_wid_req = wid_req + 4;
1251 for(count = 0; count < num; count ++)
1253 wid = WID_MEMORY_ADDRESS;
1254 p_wid_req[0] = (char)(wid&0x00FF);
1255 p_wid_req[1] = (char)((wid&0xFF00) >> 8);
1257 p_wid_req[2] = (char)4;
1258 memcpy(p_wid_req + 3, (char*)&data[count][0], 4);
1260 wid = WID_MEMORY_ACCESS_32BIT;
1261 p_wid_req[7] = (char)(wid&0x00FF);
1262 p_wid_req[8] = (char)((wid&0xFF00) >> 8);
1264 p_wid_req[9] = (char)4;
1265 memcpy(p_wid_req + 10, (char*)&data[count][1], 4);
1268 ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
1270 RDA5890_ERRP("rda5890_set_sdio_core_init fail, ret = %d\n", ret);
1278 int rda5890_set_core_patch_polling(struct rda5890_private *priv, const unsigned char (*patch)[2], unsigned char num)
1282 unsigned short wid_req_len = 4 + 8*num;
1284 unsigned short wid_rsp_len = 32;
1286 char wid_msg_id = priv->wid_msg_id++;
1287 char count = 0 , *p_wid_req = NULL;
1289 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
1290 "%s <<< \n", __func__);
1293 wid_req[1] = wid_msg_id;
1295 wid_req[2] = (char)(wid_req_len&0x00FF);
1296 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
1298 p_wid_req = wid_req + 4;
1299 for(count = 0; count < num; count ++)
1301 wid = WID_PHY_ACTIVE_REG;
1302 p_wid_req[0] = (char)(wid&0x00FF);
1303 p_wid_req[1] = (char)((wid&0xFF00) >> 8);
1305 p_wid_req[2] = (char)(0x01);
1306 p_wid_req[3] = patch[count][0];
1308 wid = WID_PHY_ACTIVE_REG_VAL;
1309 p_wid_req[4] = (char)(wid&0x00FF);
1310 p_wid_req[5] = (char)((wid&0xFF00) >> 8);
1312 p_wid_req[6] = (char)(0x01);
1313 p_wid_req[7] = patch[count][1];
1316 ret = rda5890_wid_request_polling(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
1318 RDA5890_ERRP("rda5890_set_core_patch fail, ret = %d \n", ret);
1323 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
1324 "%s >>> \n", __func__);
1328 int rda5890_set_core_patch(struct rda5890_private *priv, const unsigned char (*patch)[2], unsigned char num)
1332 unsigned short wid_req_len = 4 + 8*num;
1334 unsigned short wid_rsp_len = 32;
1336 char wid_msg_id = priv->wid_msg_id++;
1337 char count = 0 , *p_wid_req = NULL;
1340 wid_req[1] = wid_msg_id;
1342 wid_req[2] = (char)(wid_req_len&0x00FF);
1343 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
1345 p_wid_req = wid_req + 4;
1346 for(count = 0; count < num; count ++)
1348 wid = WID_PHY_ACTIVE_REG;
1349 p_wid_req[0] = (char)(wid&0x00FF);
1350 p_wid_req[1] = (char)((wid&0xFF00) >> 8);
1352 p_wid_req[2] = (char)(0x01);
1353 p_wid_req[3] = patch[count][0];
1355 wid = WID_PHY_ACTIVE_REG_VAL;
1356 p_wid_req[4] = (char)(wid&0x00FF);
1357 p_wid_req[5] = (char)((wid&0xFF00) >> 8);
1359 p_wid_req[6] = (char)(0x01);
1360 p_wid_req[7] = patch[count][1];
1363 ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
1365 RDA5890_ERRP("rda5890_set_core_patch fail, ret = %d \n", ret);
1374 int rda5890_get_fw_ver(struct rda5890_private *priv, unsigned long *fw_ver)
1378 ret = rda5890_generic_get_ulong(priv, WID_SYS_FW_VER, fw_ver);
1383 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1384 "Get FW_VER 0x%08lx\n", *fw_ver);
1390 int rda5890_get_mac_addr(struct rda5890_private *priv, unsigned char *mac_addr)
1394 ret = rda5890_generic_get_str(priv, WID_MAC_ADDR, mac_addr, ETH_ALEN);
1399 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1400 "STA MAC Address [%02x:%02x:%02x:%02x:%02x:%02x]\n",
1401 mac_addr[0], mac_addr[1], mac_addr[2],
1402 mac_addr[3], mac_addr[4], mac_addr[5]);
1407 /* support only one bss per packet for now */
1408 int rda5890_get_scan_results(struct rda5890_private *priv,
1409 struct rda5890_bss_descriptor *bss_desc)
1414 unsigned char buf[sizeof(struct rda5890_bss_descriptor)*RDA5890_MAX_NETWORK_NUM + 2];
1415 unsigned char first_send = 0;
1417 ret = rda5890_get_str_unknown_len(priv, WID_SITE_SURVEY_RESULTS,
1422 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1423 "Get Scan Result, len = %d\n", len);
1425 if ((len - 2) % sizeof(struct rda5890_bss_descriptor)) {
1426 RDA5890_ERRP("Scan Result len not correct, %d\n", len);
1430 count = (len - 2) / sizeof(struct rda5890_bss_descriptor);
1432 first_send = *(buf + 1);
1433 memcpy(bss_desc, buf + 2, (len - 2));
1435 return (count | first_send << 8);
1438 int rda5890_get_bssid(struct rda5890_private *priv, unsigned char *bssid)
1442 ret = rda5890_generic_get_str(priv, WID_BSSID, bssid, ETH_ALEN);
1447 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1448 "Get BSSID [%02x:%02x:%02x:%02x:%02x:%02x]\n",
1449 bssid[0], bssid[1], bssid[2],
1450 bssid[3], bssid[4], bssid[5]);
1455 int rda5890_get_channel(struct rda5890_private *priv, unsigned char *channel)
1459 ret = rda5890_generic_get_uchar(priv, WID_CURRENT_CHANNEL, channel);
1464 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1465 "Get Channel %d\n", *channel);
1471 int rda5890_get_rssi(struct rda5890_private *priv, unsigned char *rssi)
1476 ret = rda5890_generic_get_uchar(priv, WID_RSSI, rssi);
1482 if(priv->connect_status == MAC_CONNECTED)
1486 rda5890_rssi_up_to_200(priv);
1490 rda5890_sdio_set_notch_by_channel(priv, priv->curbssparams.channel);
1496 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1497 "Get RSSI <<< %d\n", *(char*)rssi);
1503 int rda5890_set_mac_addr(struct rda5890_private *priv, unsigned char *mac_addr)
1507 ret = rda5890_generic_set_str(priv, WID_MAC_ADDR, mac_addr, ETH_ALEN);
1512 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1513 "Set STA MAC Address [%02x:%02x:%02x:%02x:%02x:%02x]\n",
1514 mac_addr[0], mac_addr[1], mac_addr[2],
1515 mac_addr[3], mac_addr[4], mac_addr[5]);
1520 int rda5890_set_preamble(struct rda5890_private *priv, unsigned char preamble)
1524 ret = rda5890_generic_set_uchar(priv, WID_PREAMBLE, preamble);
1529 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE, "rda5890_set_preamble \n");
1534 #ifdef GET_SCAN_FROM_NETWORK_INFO
1536 int rda5890_set_scan_complete(struct rda5890_private *priv)
1540 ret = rda5890_generic_set_uchar(priv, WID_NETWORK_INFO_EN, 0);
1546 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE, "rda5890_set_scan_complete ret=%d \n", ret);
1551 int rda5890_set_ssid(struct rda5890_private *priv,
1552 unsigned char *ssid, unsigned char ssid_len)
1556 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1557 "Set SSID: %s, len = %d\n", ssid, ssid_len);
1559 ret = rda5890_generic_set_str(priv, WID_SSID, ssid, ssid_len);
1564 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1571 int rda5890_get_ssid(struct rda5890_private *priv,
1572 unsigned char *ssid, unsigned char *ssid_len)
1576 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1579 ret = rda5890_get_str_unknown_len(priv, WID_SSID, ssid, ssid_len);
1581 ssid[*ssid_len] = '\0';
1583 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1584 "Get SSID Done len:%d %s\n", *ssid_len, *ssid_len > 0? ssid:"NULL");
1588 int rda5890_set_bssid(struct rda5890_private *priv, unsigned char *bssid)
1592 ret = rda5890_generic_set_str(priv, WID_BSSID, bssid, ETH_ALEN);
1597 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1598 "Set BSSID [%02x:%02x:%02x:%02x:%02x:%02x]\n",
1599 bssid[0], bssid[1], bssid[2],
1600 bssid[3], bssid[4], bssid[5]);
1606 int rda5890_set_imode(struct rda5890_private *priv, unsigned char imode)
1610 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1611 "Set IMode 0x%02x\n", imode);
1613 ret = rda5890_generic_set_uchar(priv, WID_802_11I_MODE, imode);
1618 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1619 "Set IMode Done\n");
1625 int rda5890_set_authtype(struct rda5890_private *priv, unsigned char authtype)
1629 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1630 "Set AuthType 0x%02x\n", authtype);
1632 ret = rda5890_generic_set_uchar(priv, WID_AUTH_TYPE, authtype);
1637 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1638 "Set AuthType Done\n");
1644 int rda5890_set_listen_interval(struct rda5890_private *priv, unsigned char interval)
1648 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1649 "Set rda5890_set_listen_interval 0x%02x\n", interval);
1651 ret = rda5890_generic_set_uchar(priv, WID_LISTEN_INTERVAL, interval);
1656 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1657 "Set rda5890_set_listen_interval Done\n");
1663 int rda5890_set_link_loss_threshold(struct rda5890_private *priv, unsigned char threshold)
1667 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1668 "Set rda5890_set_link_loss_threshold 0x%02x\n", threshold);
1670 ret = rda5890_generic_set_uchar(priv, WID_LINK_LOSS_THRESHOLD, threshold);
1675 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1676 "Set rda5890_set_link_loss_threshold Done\n");
1683 int rda5890_set_wepkey(struct rda5890_private *priv,
1684 unsigned short index, unsigned char *key, unsigned char key_len)
1687 unsigned char key_str[26 + 1]; // plus 1 for debug print
1688 unsigned char key_str_len;
1690 if (key_len == KEY_LEN_WEP_40) {
1691 sprintf(key_str, "%02x%02x%02x%02x%02x\n",
1692 key[0], key[1], key[2], key[3], key[4]);
1694 key_str[key_str_len] = '\0';
1696 else if (key_len == KEY_LEN_WEP_104) {
1697 sprintf(key_str, "%02x%02x%02x%02x%02x"
1698 "%02x%02x%02x%02x%02x"
1700 key[0], key[1], key[2], key[3], key[4],
1701 key[5], key[6], key[7], key[8], key[9],
1702 key[10], key[11], key[12]);
1704 key_str[key_str_len] = '\0';
1707 RDA5890_ERRP("Error in WEP Key length %d\n", key_len);
1712 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1713 "Set WEP KEY[%d]: %s\n", index, key_str);
1715 ret = rda5890_generic_set_str(priv,
1716 (WID_WEP_KEY_VALUE0 + index), key_str, key_str_len);
1721 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1722 "Set WEP KEY[%d] Done\n", index);
1728 static void dump_key(unsigned char *key, unsigned char key_len)
1730 RDA5890_DBGP("%02x %02x %02x %02x %02x %02x %02x %02x\n",
1731 key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]);
1732 RDA5890_DBGP("%02x %02x %02x %02x %02x %02x %02x %02x\n",
1733 key[8], key[9], key[10], key[11], key[12], key[13], key[14], key[15]);
1735 RDA5890_DBGP("%02x %02x %02x %02x %02x %02x %02x %02x\n",
1736 key[16], key[17], key[18], key[19], key[20], key[21], key[22], key[23]);
1738 RDA5890_DBGP("%02x %02x %02x %02x %02x %02x %02x %02x\n",
1739 key[24], key[25], key[26], key[27], key[28], key[29], key[30], key[31]);
1742 int rda5890_set_ptk(struct rda5890_private *priv,
1743 unsigned char *key, unsigned char key_len)
1746 unsigned char key_str[32 + ETH_ALEN + 1];
1747 unsigned char key_str_len = key_len + ETH_ALEN + 1;
1749 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1750 "Set PTK: len = %d\n", key_len);
1751 if (RDA5890_DBGLA(RDA5890_DA_WID, RDA5890_DL_VERB))
1752 dump_key(key, key_len);
1754 if (priv->connect_status != MAC_CONNECTED) {
1755 RDA5890_ERRP("Adding PTK while not connected\n");
1760 /*----------------------------------------*/
1761 /* STA Addr | KeyLength | Key */
1762 /*----------------------------------------*/
1763 /* 6 | 1 | KeyLength */
1764 /*----------------------------------------*/
1766 /*---------------------------------------------------------*/
1768 /*---------------------------------------------------------*/
1769 /* Temporal Key | Rx Micheal Key | Tx Micheal Key */
1770 /*---------------------------------------------------------*/
1771 /* 16 bytes | 8 bytes | 8 bytes */
1772 /*---------------------------------------------------------*/
1774 memcpy(key_str, priv->curbssparams.bssid, ETH_ALEN);
1775 key_str[6] = key_len;
1776 memcpy(key_str + 7, key, 16);
1778 /* swap TX MIC and RX MIC, rda5890 need RX MIC to be ahead */
1780 memcpy(key_str + 7 + 16, key + 24, 8);
1781 memcpy(key_str + 7 + 24, key + 16, 8);
1785 ret = rda5890_generic_set_str(priv,
1786 WID_ADD_WAPI_PTK, key_str, key_str_len);
1788 ret = rda5890_generic_set_str(priv,
1789 WID_ADD_PTK, key_str, key_str_len);
1794 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1801 int rda5890_set_gtk(struct rda5890_private *priv, unsigned char key_id,
1802 unsigned char *key_rsc, unsigned char key_rsc_len,
1803 unsigned char *key, unsigned char key_len)
1806 unsigned char key_str[32 + ETH_ALEN + 8 + 2];
1807 unsigned char key_str_len = key_len + ETH_ALEN + 8 + 2;
1809 /*---------------------------------------------------------*/
1810 /* STA Addr | KeyRSC | KeyID | KeyLength | Key */
1811 /*---------------------------------------------------------*/
1812 /* 6 | 8 | 1 | 1 | KeyLength */
1813 /*---------------------------------------------------------*/
1815 /*-------------------------------------*/
1817 /*-------------------------------------*/
1818 /* Temporal Key | Rx Micheal Key */
1819 /*-------------------------------------*/
1820 /* 16 bytes | 8 bytes */
1821 /*-------------------------------------*/
1823 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1824 "Set GTK: len = %d\n", key_len);
1825 if (RDA5890_DBGLA(RDA5890_DA_WID, RDA5890_DL_VERB))
1826 dump_key(key, key_len);
1828 if (priv->connect_status != MAC_CONNECTED) {
1829 RDA5890_ERRP("Adding PTK while not connected\n");
1834 memcpy(key_str, priv->curbssparams.bssid, ETH_ALEN);
1835 memcpy(key_str + 6, key_rsc, key_rsc_len);
1836 key_str[14] = key_id;
1837 key_str[15] = key_len;
1838 memcpy(key_str + 16, key, 16);
1840 /* swap TX MIC and RX MIC, rda5890 need RX MIC to be ahead */
1842 //memcpy(key_str + 16 + 16, key + 16, key_len - 16);
1843 memcpy(key_str + 16 + 16, key + 24, 8);
1844 memcpy(key_str + 16 + 24, key + 16, 8);
1848 ret = rda5890_generic_set_str(priv,
1849 WID_ADD_WAPI_RX_GTK, key_str, key_str_len);
1851 ret = rda5890_generic_set_str(priv,
1852 WID_ADD_RX_GTK, key_str, key_str_len);
1857 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1864 int rda5890_set_scan_timeout(struct rda5890_private *priv)
1868 unsigned short wid_req_len = 19;
1870 unsigned short wid_rsp_len = 32;
1871 char wid_msg_id = priv->wid_msg_id++;
1873 unsigned short wid = 0;
1875 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1876 "rda5890_set_scan_timeout <<< \n");
1878 wid = WID_SITE_SURVEY_SCAN_TIME;
1881 wid_req[1] = wid_msg_id;
1883 wid_req[2] = (char)(wid_req_len&0x00FF);
1884 wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
1886 wid_req[4] = (char)(wid&0x00FF);
1887 wid_req[5] = (char)((wid&0xFF00) >> 8);
1889 wid_req[7] = 50; //50 ms one channel
1892 wid = WID_ACTIVE_SCAN_TIME;
1893 wid_req[9] = (char)(wid&0x00FF);
1894 wid_req[10] = (char)((wid&0xFF00) >> 8);
1896 wid_req[12] = 50; //50 ms one channel
1899 wid = WID_PASSIVE_SCAN_TIME;
1900 wid_req[14] = (char)(wid&0x00FF);
1901 wid_req[15] = (char)((wid&0xFF00) >> 8);
1903 wid_req[17] = 50; //50 ms one channel
1906 ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
1908 RDA5890_ERRP("rda5890_set_scan_timeout fail, ret = %d\n", ret);
1912 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1913 "rda5890_set_scan_timeout >>> \n");
1920 int rda5890_set_pm_mode(struct rda5890_private *priv, unsigned char pm_mode)
1924 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1925 "Set PM Mode 0x%02x\n", pm_mode);
1927 ret = rda5890_generic_set_uchar(priv, WID_POWER_MANAGEMENT, pm_mode);
1932 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1933 "Set PM Mode Done\n");
1939 int rda5890_set_preasso_sleep(struct rda5890_private *priv, unsigned int preasso_sleep)
1943 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1944 "Set Preasso Sleep 0x%08x\n", preasso_sleep);
1946 ret = rda5890_generic_set_ulong(priv, WID_PREASSO_SLEEP, preasso_sleep);
1951 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1952 "Set Preasso Sleep Done\n");