1a1fc1d6de83c195f4561c8be3ab8490cd5b16e9
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rda5990 / rda_wlan / rda5890_wid.c
1 #include <linux/module.h>
2 #include <linux/dcache.h>
3 #include <linux/debugfs.h>
4 #include <linux/delay.h>
5 #include <linux/mm.h>
6 #include <linux/string.h>
7 #include <linux/etherdevice.h>
8 #include <net/iw_handler.h>
9 #include <linux/mmc/sdio_func.h>
10
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"
17
18 static unsigned char is_need_set_notch = 0;
19
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)
24 {
25         int ret = 0;
26         int timeleft = 0;
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;
30
31         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
32                 "%s <<<\n", __func__);
33                 
34 #ifdef WIFI_TEST_MODE
35   if(rda_5990_wifi_in_test_mode())
36       return 0;
37 #endif  //end WIFI_TEST_MODE
38
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;
43
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);
49
50         init_completion(&priv->wid_done);
51 #ifdef WIFI_UNLOCK_SYSTEM
52     rda5990_wakeLock();
53 #endif
54         ret = rda5890_host_to_card(priv, data_buf, data_len, WID_REQUEST_PACKET);
55         if (ret) {
56                 RDA5890_ERRP("host_to_card send failed, ret = %d\n", ret);
57                 priv->wid_pending = 0;
58                 goto out;
59         }
60
61     atomic_inc(&card->wid_complete_flag);
62         timeleft = wait_for_completion_timeout(&priv->wid_done, msecs_to_jiffies(450)); 
63         if (timeleft == 0) {
64                 RDA5890_ERRP("respose timeout wid :%x %x \n", wid_req[4], wid_req[5]);
65                 priv->wid_pending = 0;
66                 ret = -EFAULT; 
67                 goto out;
68         }
69
70         *wid_rsp_len = priv->wid_rsp_len;
71
72 out:
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
78     rda5990_wakeUnlock();
79 #endif
80         return ret;
81 }
82
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)
86 {
87         int ret = -1;
88         int timeleft = 0;
89         char data_buf[RDA5890_MAX_WID_LEN + 2];
90         unsigned short data_len;
91         unsigned char status;
92         unsigned int retry = 0, count = 0;
93     struct if_sdio_card * card = (struct if_sdio_card*)priv->card;
94
95         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
96                 "%s >>>\n", __func__);
97
98         priv->wid_rsp = wid_rsp;
99         priv->wid_rsp_len = *wid_rsp_len;
100
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);
106
107 re_send:
108
109     count += 1;
110         ret = rda5890_host_to_card(priv, data_buf, data_len, WID_REQUEST_POLLING_PACKET);
111         if (ret) {
112                 RDA5890_ERRP("host_to_card send failed, ret = %d\n", ret);
113                 goto out;
114         }
115
116     rda5890_shedule_timeout(3);   //3ms delay
117         while(retry < 20)
118         {
119               sdio_claim_host(card->func);
120                 status = sdio_readb(card->func, IF_SDIO_FUN1_INT_STAT, &ret);
121             sdio_release_host(card->func);
122                 if (ret)
123                     goto out;
124
125                 if (status & IF_SDIO_INT_AHB2SDIO)
126                 {
127                         int ret = 0;
128                         u8 size_l = 0, size_h = 0;
129                         u16 size, chunk;
130
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);
134                         if (ret) {
135                                 RDA5890_ERRP("read PKTLEN_L reg fail\n");
136                         goto out;
137                         }
138                         else
139                                 RDA5890_ERRP("read PKTLEN_L reg size_l:%d \n", size_l);
140
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);
144                         if (ret) {
145                                 RDA5890_ERRP("read PKTLEN_H reg fail\n");
146                                 goto out;
147                         }
148                         else
149                                 RDA5890_ERRP("read PKTLEN_H reg size_h:%d\n",size_h);   
150
151                         size = (size_l | ((size_h & 0x7f) << 8)) * 4;
152                         if (size < 4) {
153                                 RDA5890_ERRP("invalid packet size (%d bytes) from firmware\n", size);
154                                 ret = -EINVAL;
155                                 goto out;
156                         }
157
158                         /* alignment is handled on firmside */
159                         //chunk = sdio_align_size(card->func, size);
160                         chunk = size;
161
162                         RDA5890_DBGLAP(RDA5890_DA_SDIO, RDA5890_DL_NORM,
163                         "if_sdio_card_to_host, size = %d, aligned size = %d\n", size, chunk);
164
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);
169                         if (ret) {
170                                 RDA5890_ERRP("sdio_readsb fail, ret = %d\n", ret);
171                             goto out;
172                         }
173 #if 1
174             if(priv->version == 7)
175                                 sdio_writeb(card->func, 0x20 ,IF_SDIO_FUN1_INT_PEND, &ret);
176 #endif            
177
178                         /* TODO: this chunk size need to be handled here */
179                         {
180                                 unsigned char rx_type;
181                                 unsigned short rx_length;
182                                 unsigned char msg_type;
183                                 unsigned char *packet = (unsigned char *)card->buffer;
184
185                                 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
186                                         "%s >>>\n", __func__);
187
188                                 rx_type = (unsigned char)packet[1]&0xF0;
189                                 rx_length = (unsigned short)(packet[0] + ((packet[1]&0x0f) << 8));
190
191                                 if (rx_length > chunk) {
192                                         RDA5890_ERRP("packet_len %d less than header specified length %d\n", 
193                                                 chunk, rx_length);
194                                         goto out;
195                                 }
196
197                                 if( rx_type == 0x30 )
198                                 {
199                                         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_NORM,
200                                                 "Message Packet type =%x \n", msg_type);
201                                         msg_type = packet[2];
202
203                                         if (msg_type == 'R')
204                                         {               
205                         packet += 2;
206                         if(priv->wid_msg_id - 1 == packet[1])
207                         {
208                             ret = 0;
209                             if(priv->wid_rsp_len > rx_length - 2)
210                             {
211                                 priv->wid_rsp_len = rx_length - 2;
212                                 memcpy(priv->wid_rsp, packet, rx_length -2);
213                             }
214                             break;
215                         }
216                         else
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)));                                        
218                                         }
219                                 }
220                         }
221                 }
222         
223        rda5890_shedule_timeout(3); //3ms delay
224        ret = -1;
225        retry ++;
226         }
227
228     if(ret < 0 && count <= 3)
229         goto re_send;
230 out:
231     
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);
234
235         return ret;
236 }
237 void rda5890_wid_response(struct rda5890_private *priv, 
238                 char *wid_rsp, unsigned short wid_rsp_len)
239 {
240         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
241                 "%s >>>\n", __func__);
242
243         if (!priv->wid_pending) {
244                 RDA5890_ERRP("no wid pending\n");
245                 return;
246         }
247
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); 
252                 return;
253         }
254
255         memcpy(priv->wid_rsp, wid_rsp, wid_rsp_len);
256         priv->wid_rsp_len = wid_rsp_len;
257         priv->wid_pending = 0;
258
259         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
260                 "%s <<<\n", __func__);
261
262         complete(&priv->wid_done); 
263 }
264
265 void rda5890_wid_status(struct rda5890_private *priv, 
266                 char *wid_status, unsigned short wid_status_len)
267 {
268         char mac_status;
269
270         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
271                 "%s >>>\n", __func__);
272
273 #ifdef WIFI_UNLOCK_SYSTEM
274     rda5990_wakeLock();
275 #endif
276
277         mac_status = wid_status[7];
278         if (mac_status == MAC_CONNECTED) {
279                 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_CRIT,
280                         "MAC CONNECTED\n");
281         
282                 priv->connect_status = MAC_CONNECTED;
283                 netif_carrier_on(priv->dev);
284                 netif_wake_queue(priv->dev);
285         rda5890_indicate_connected(priv);
286                 
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);
290         
291         if(test_and_clear_bit(ASSOC_FLAG_ASSOC_RETRY, &priv->assoc_flags))
292         {
293             cancel_delayed_work_sync(&priv->assoc_work);
294         }
295
296         if(test_bit(ASSOC_FLAG_WLAN_CONNECTING, &priv->assoc_flags))        
297             cancel_delayed_work(&priv->wlan_connect_work);
298         
299         set_bit(ASSOC_FLAG_WLAN_CONNECTING, &priv->assoc_flags);
300                 queue_delayed_work(priv->work_thread, &priv->wlan_connect_work, HZ*20);
301         
302         }
303         else if (mac_status == MAC_DISCONNECTED) {
304         
305                 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_CRIT,
306                         "MAC DISCONNECTED\n");
307                 
308         if(priv->connect_status == MAC_CONNECTED)       
309                     is_need_set_notch = 1;
310                 else
311                     is_need_set_notch = 0;
312         
313         if(!test_bit(ASSOC_FLAG_ASSOC_RETRY, &priv->assoc_flags))
314             {
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);
320                 else
321                     priv->first_init = 0;
322                 
323                 if(test_bit(ASSOC_FLAG_ASSOC_START, &priv->assoc_flags))
324                 {
325                     cancel_delayed_work(&priv->wlan_connect_work);
326                             queue_delayed_work(priv->work_thread, &priv->wlan_connect_work, HZ*4);
327                 }
328                 
329                 clear_bit(ASSOC_FLAG_ASSOC_START, &priv->assoc_flags);
330                 clear_bit(ASSOC_FLAG_WLAN_CONNECTING, &priv->assoc_flags);
331             }
332         else
333             {
334                 RDA5890_ERRP("********wep assoc will be retry ---------- 0x%02x\n", mac_status);
335             }
336         }
337         else {
338                 RDA5890_ERRP("Invalid MAC Status 0x%02x\n", mac_status);
339         }
340
341         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
342                 "%s <<<\n", __func__);
343     
344 #ifdef WIFI_UNLOCK_SYSTEM
345     rda5990_wakeUnlock();
346 #endif    
347 }
348
349 void rda5890_card_to_host(struct rda5890_private *priv, 
350                 char *packet, unsigned short packet_len)
351 {
352         unsigned char rx_type;
353         unsigned short rx_length;
354         unsigned char msg_type;
355
356         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
357                 "%s >>>\n", __func__);
358
359         rx_type = (unsigned char)packet[1]&0xF0;
360         rx_length = (unsigned short)(packet[0] + ((packet[1]&0x0f) << 8));
361
362         if (rx_length > packet_len) {
363                 RDA5890_ERRP("packet_len %d less than header specified length %d\n", 
364                         packet_len, rx_length);
365                 goto out;
366         }
367
368         if( rx_type == 0x30 )
369         {
370                 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_NORM,
371                         "Message Packet\n");
372                 msg_type = packet[2];
373                 if(msg_type == 'I')
374                 {
375                         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_NORM,
376                                 "Indication Message\n");
377                         rda5890_wid_status(priv, packet + 2, rx_length - 2);
378                 }
379                 else if (msg_type == 'R')
380                 {
381                         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_NORM,
382                                 "WID Message\n");
383                         rda5890_wid_response(priv, packet + 2, rx_length - 2);
384                 }
385 #ifdef GET_SCAN_FROM_NETWORK_INFO
386         else if(msg_type == 'N')
387         {
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);
391         }
392 #endif             
393                 else {
394                         //RDA5890_ERRP("Invalid Message Type '%c'\n", msg_type);
395                 }
396         }
397         else if(rx_type == 0x20)
398         {
399                 RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_NORM,
400                         "Data Packet\n");
401                 rda5890_data_rx(priv, packet + 2, rx_length - 2);
402         }
403         else {
404                 RDA5890_ERRP("Invalid Packet Type 0x%02x\n", rx_type);
405         }
406
407 out:
408
409         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
410                 "%s <<<\n", __func__);
411 }
412
413 /*
414  * check wid response header
415  * if no error, return the pointer to the payload
416  * support only 1 wid per packet
417  */
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)
421 {
422         unsigned short rsp_len;
423         unsigned short rsp_wid;
424         unsigned char msg_len;
425
426         if (wid_rsp[0] != 'R') {
427                 RDA5890_ERRP("wid_rsp[0] != 'R'\n");
428                 goto err;
429         }
430
431         if (wid_rsp[1] != wid_msg_id) {
432                 RDA5890_ERRP("wid_msg_id not match msg_id: %d \n", wid_rsp[1]);
433                 goto err;
434         }
435
436         if (wid_rsp_len < 4) {
437                 RDA5890_ERRP("wid_rsp_len < 4\n");
438                 goto err;
439         }
440
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);
444                 goto err;
445         }
446
447         if (wid_rsp_len < 7) {
448                 RDA5890_ERRP("wid_rsp_len < 7\n");
449                 goto err;
450         }
451 #if 0
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);
455                 goto err;
456         }
457 #endif
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);
461                 goto err;
462         }
463
464         if (payload_len != msg_len) {
465                 RDA5890_ERRP("payload_len not match, %d  != %d\n", msg_len, payload_len);
466                 goto err;
467         }
468
469         *ptr_payload = wid_rsp + 7;
470
471     return 0;
472     
473 err:
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);
475         return -EINVAL;
476 }
477
478 /*
479  * check wid status response
480  */
481 int rda5890_check_wid_status(char *wid_rsp, unsigned short wid_rsp_len, 
482                 char wid_msg_id)
483 {
484         int ret;
485         unsigned short wid = WID_STATUS;
486         char *ptr_payload;
487         char status_val;
488
489         ret = rda5890_check_wid_response(wid_rsp, wid_rsp_len, wid, wid_msg_id, 
490             1, &ptr_payload);
491         if (ret) {
492                 RDA5890_ERRP("rda5890_check_wid_status, check_wid_response fail\n");
493                 return ret;
494         }
495
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);
499                 return -EINVAL;
500         }
501
502         return 0;
503 }
504
505 int rda5890_generic_get_uchar(struct rda5890_private *priv, 
506                 unsigned short wid, unsigned char *val)
507 {
508         int ret;
509         char wid_req[6];
510         unsigned short wid_req_len = 6;
511         char wid_rsp[32];
512         unsigned short wid_rsp_len = 32;
513         char wid_msg_id = priv->wid_msg_id++;
514         char *ptr_payload;
515
516         wid_req[0] = 'Q';
517         wid_req[1] = wid_msg_id;
518
519         wid_req[2] = (char)(wid_req_len&0x00FF);
520         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
521
522         wid_req[4] = (char)(wid&0x00FF);
523         wid_req[5] = (char)((wid&0xFF00) >> 8);
524
525         ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
526         if (ret) {
527                 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
528                 goto out;
529         }
530
531         ret = rda5890_check_wid_response(wid_rsp, wid_rsp_len, wid, wid_msg_id, 
532                 sizeof(unsigned char), &ptr_payload);
533         if (ret) {
534                 RDA5890_ERRP("check_wid_response fail, ret = %d\n", ret);
535                 goto out;
536         }
537
538         *val = *ptr_payload;
539 out:
540         return ret;
541 }
542
543 int rda5890_generic_set_uchar(struct rda5890_private *priv, 
544                 unsigned short wid, unsigned char val)
545 {
546         int ret;
547         char wid_req[7 + sizeof(unsigned char)];
548         unsigned short wid_req_len = 7 + 1;
549         char wid_rsp[32];
550         unsigned short wid_rsp_len = 32;
551         char wid_msg_id = priv->wid_msg_id++;
552
553         wid_req[0] = 'W';
554         wid_req[1] = wid_msg_id;
555
556         wid_req[2] = (char)(wid_req_len&0x00FF);
557         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
558
559         wid_req[4] = (char)(wid&0x00FF);
560         wid_req[5] = (char)((wid&0xFF00) >> 8);
561
562         wid_req[6] = 1;
563         wid_req[7] = val;
564         ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
565         if (ret) {
566                 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
567                 goto out;
568         }
569
570         ret = rda5890_check_wid_status(wid_rsp, wid_rsp_len, wid_msg_id);
571         if (ret) {
572                 RDA5890_ERRP("check_wid_status fail, ret = %d\n", ret);
573                 goto out;
574         }
575
576 out:
577         return ret;
578 }
579
580 #if 1
581 int rda5890_generic_get_ushort(struct rda5890_private *priv, 
582                 unsigned short wid, unsigned short *val)
583 {
584         int ret;
585         char wid_req[6];
586         unsigned short wid_req_len = 6;
587         char wid_rsp[32];
588         unsigned short wid_rsp_len = 32;
589         char wid_msg_id = priv->wid_msg_id++;
590         char *ptr_payload;
591
592         wid_req[0] = 'Q';
593         wid_req[1] = wid_msg_id;
594
595         wid_req[2] = (char)(wid_req_len&0x00FF);
596         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
597
598         wid_req[4] = (char)(wid&0x00FF);
599         wid_req[5] = (char)((wid&0xFF00) >> 8);
600
601         ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
602         if (ret) {
603                 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
604                 goto out;
605         }
606
607         ret = rda5890_check_wid_response(wid_rsp, wid_rsp_len, wid, wid_msg_id, 
608                 sizeof(unsigned short), &ptr_payload);
609         if (ret) {
610                 RDA5890_ERRP("check_wid_response fail, ret = %d\n", ret);
611                 goto out;
612         }
613
614         memcpy(val, ptr_payload, sizeof(unsigned short)); 
615
616 out:
617         return ret;
618 }
619
620 int rda5890_generic_set_ushort(struct rda5890_private *priv, 
621                 unsigned short wid, unsigned short val)
622 {
623         int ret;
624         char wid_req[7 + sizeof(unsigned short)];
625         unsigned short wid_req_len = 7 + sizeof(unsigned short);
626         char wid_rsp[32];
627         unsigned short wid_rsp_len = 32;
628         char wid_msg_id = priv->wid_msg_id++;
629
630         wid_req[0] = 'W';
631         wid_req[1] = wid_msg_id;
632
633         wid_req[2] = (char)(wid_req_len&0x00FF);
634         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
635
636         wid_req[4] = (char)(wid&0x00FF);
637         wid_req[5] = (char)((wid&0xFF00) >> 8);
638
639         wid_req[6] = (char)(sizeof(unsigned short));
640         memcpy(wid_req + 7, &val, sizeof(unsigned short)); 
641
642         ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
643         if (ret) {
644                 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
645                 goto out;
646         }
647
648         ret = rda5890_check_wid_status(wid_rsp, wid_rsp_len, wid_msg_id);
649         if (ret) {
650                 RDA5890_ERRP("check_wid_status fail, ret = %d\n", ret);
651                 goto out;
652         }
653
654 out:
655         return ret;
656 }
657 #endif
658
659 int rda5890_generic_get_ulong(struct rda5890_private *priv, 
660                 unsigned short wid, unsigned long *val)
661 {
662         int ret;
663         char wid_req[6];
664         unsigned short wid_req_len = 6;
665         char wid_rsp[32];
666         unsigned short wid_rsp_len = 32;
667         char wid_msg_id = priv->wid_msg_id++;
668         char *ptr_payload;
669
670         wid_req[0] = 'Q';
671         wid_req[1] = wid_msg_id;
672
673         wid_req[2] = (char)(wid_req_len&0x00FF);
674         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
675
676         wid_req[4] = (char)(wid&0x00FF);
677         wid_req[5] = (char)((wid&0xFF00) >> 8);
678
679         ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
680         if (ret) {
681                 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
682                 goto out;
683         }
684
685         ret = rda5890_check_wid_response(wid_rsp, wid_rsp_len, wid, wid_msg_id, 
686                 sizeof(unsigned long), &ptr_payload);
687         if (ret) {
688                 RDA5890_ERRP("check_wid_response fail, ret = %d\n", ret);
689                 goto out;
690         }
691
692         memcpy(val, ptr_payload, sizeof(unsigned long)); 
693
694 out:
695         return ret;
696 }
697
698 int rda5890_generic_set_ulong(struct rda5890_private *priv, 
699                 unsigned short wid, unsigned long val)
700 {
701         int ret;
702         char wid_req[7 + sizeof(unsigned long)];
703         unsigned short wid_req_len = 7 + sizeof(unsigned long);
704         char wid_rsp[32];
705         unsigned short wid_rsp_len = 32;
706         char wid_msg_id = priv->wid_msg_id++;
707
708         wid_req[0] = 'W';
709         wid_req[1] = wid_msg_id;
710
711         wid_req[2] = (char)(wid_req_len&0x00FF);
712         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
713
714         wid_req[4] = (char)(wid&0x00FF);
715         wid_req[5] = (char)((wid&0xFF00) >> 8);
716
717         wid_req[6] = (char)(sizeof(unsigned long));
718         memcpy(wid_req + 7, &val, sizeof(unsigned long)); 
719
720         ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
721         if (ret) {
722                 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
723                 goto out;
724         }
725
726         ret = rda5890_check_wid_status(wid_rsp, wid_rsp_len, wid_msg_id);
727         if (ret) {
728                 RDA5890_ERRP("check_wid_status fail, ret = %d\n", ret);
729                 goto out;
730         }
731
732 out:
733         return ret;
734 }
735
736 int rda5890_generic_get_str(struct rda5890_private *priv, 
737                 unsigned short wid, unsigned char *val, unsigned char len)
738 {
739         int ret;
740         char wid_req[6];
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++;
745         char *ptr_payload;
746
747         wid_req[0] = 'Q';
748         wid_req[1] = wid_msg_id;
749
750         wid_req[2] = (char)(wid_req_len&0x00FF);
751         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
752
753         wid_req[4] = (char)(wid&0x00FF);
754         wid_req[5] = (char)((wid&0xFF00) >> 8);
755
756         ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
757         if (ret) {
758                 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
759                 goto out;
760         }
761
762         ret = rda5890_check_wid_response(wid_rsp, wid_rsp_len, wid, wid_msg_id, 
763                 (char)len, &ptr_payload);
764         if (ret) {
765                 RDA5890_ERRP("check_wid_response fail, ret = %d\n", ret);
766                 goto out;
767         }
768
769         memcpy(val, ptr_payload, len); 
770
771 out:
772         return ret;
773 }
774
775 int rda5890_generic_set_str(struct rda5890_private *priv, 
776                 unsigned short wid, unsigned char *val, unsigned char len)
777 {
778         int ret;
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++;
784
785         wid_req[0] = 'W';
786         wid_req[1] = wid_msg_id;
787
788         wid_req[2] = (char)(wid_req_len&0x00FF);
789         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
790
791         wid_req[4] = (char)(wid&0x00FF);
792         wid_req[5] = (char)((wid&0xFF00) >> 8);
793
794         wid_req[6] = (char)(len);
795         memcpy(wid_req + 7, val, len); 
796
797         ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
798         if (ret) {
799                 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
800                 goto out;
801         }
802
803         ret = rda5890_check_wid_status(wid_rsp, wid_rsp_len, wid_msg_id);
804         if (ret) {
805                 RDA5890_ERRP("check_wid_status fail, ret = %d\n", ret);
806                 goto out;
807         }
808
809 out:
810         return ret;
811 }
812
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)
817 {
818         unsigned short rsp_len;
819         unsigned short rsp_wid;
820         unsigned char msg_len;
821
822         if (wid_rsp[0] != 'R') {
823                 RDA5890_ERRP("wid_rsp[0] != 'R'\n");
824                 return -EINVAL;
825         }
826
827         if (wid_rsp[1] != wid_msg_id) {
828                 RDA5890_ERRP("wid_msg_id not match\n");
829                 return -EINVAL;
830         }
831
832         if (wid_rsp_len < 4) {
833                 RDA5890_ERRP("wid_rsp_len < 4\n");
834                 return -EINVAL;
835         }
836
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);
840                 return -EINVAL;
841         }
842
843         if (wid_rsp_len < 7) {
844                 RDA5890_ERRP("wid_rsp_len < 7\n");
845                 return -EINVAL;
846         }
847 #if 0
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);
851                 return -EINVAL;
852         }
853 #endif
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);
857                 return -EINVAL;
858         }
859
860         *payload_len = msg_len;
861
862         *ptr_payload = wid_rsp + 7;
863
864         return 0;
865 err:
866
867     RDA5890_ERRP("wid is %x wid_msg %d \n", wid_rsp[4] | (wid_rsp[5] << 8), wid_rsp[1]);
868     return -EINVAL;
869 }
870
871 int rda5890_get_str_unknown_len(struct rda5890_private *priv, 
872                 unsigned short wid, unsigned char *val, unsigned char *len)
873 {
874         int ret;
875         char wid_req[6];
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++;
880         char *ptr_payload;
881
882         wid_req[0] = 'Q';
883         wid_req[1] = wid_msg_id;
884
885         wid_req[2] = (char)(wid_req_len&0x00FF);
886         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
887
888         wid_req[4] = (char)(wid&0x00FF);
889         wid_req[5] = (char)((wid&0xFF00) >> 8);
890
891         ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
892         if (ret) {
893                 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
894                 goto out;
895         }
896
897         ret = rda5890_check_wid_response_unknown_len(
898             wid_rsp, wid_rsp_len, wid, wid_msg_id, (char*)len, &ptr_payload);
899         if (ret) {
900                 RDA5890_ERRP("check_wid_response fail, ret = %d\n", ret);
901                 goto out;
902         }
903
904         memcpy(val, ptr_payload, *len); 
905
906 out:
907         return ret;
908 }
909
910 extern int rda5890_sdio_set_default_notch(struct rda5890_private *priv);
911 int rda5890_start_scan(struct rda5890_private *priv)
912 {
913         int ret;
914         char wid_req[12];
915         unsigned short wid_req_len = 12;
916         char wid_rsp[32];
917         unsigned short wid_rsp_len = 32;
918         unsigned short wid;
919         char wid_msg_id = 0;
920
921         if(priv->connect_status != MAC_CONNECTED)
922     {
923         rda5890_sdio_set_default_notch(priv);
924     }
925
926     wid_msg_id = priv->wid_msg_id++;
927     
928         wid_req[0] = 'W';
929         wid_req[1] = wid_msg_id;
930
931         wid_req[2] = (char)(wid_req_len&0x00FF);
932         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
933
934         wid = WID_SITE_SURVEY;
935         wid_req[4] = (char)(wid&0x00FF);
936         wid_req[5] = (char)((wid&0xFF00) >> 8);
937
938         wid_req[6] = (char)(0x01);
939         wid_req[7] = (char)(0x01);
940
941         wid = WID_START_SCAN_REQ;
942         wid_req[8] = (char)(wid&0x00FF);
943         wid_req[9] = (char)((wid&0xFF00) >> 8);
944
945         wid_req[10] = (char)(0x01);
946         wid_req[11] = (char)(0x01);
947     
948
949     wid_req_len = 12;
950         wid_req[2] = (char)(wid_req_len&0x00FF);
951         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
952     
953         ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
954         if (ret) {
955                 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
956                 goto out;
957         }
958
959         ret = rda5890_check_wid_status(wid_rsp, wid_rsp_len, wid_msg_id);
960         if (ret) {
961                 RDA5890_ERRP("check_wid_status fail, ret = %d\n", ret);
962                 goto out;
963         }
964
965 out:
966         return ret;
967 }
968
969
970 int rda5890_start_scan_enable_network_info(struct rda5890_private *priv)
971 {
972         int ret;
973         char wid_req[12];
974         unsigned short wid_req_len = 12;
975         char wid_rsp[32];
976         unsigned short wid_rsp_len = 32;
977         unsigned short wid;
978         char wid_msg_id = 0;
979
980         if(priv->connect_status != MAC_CONNECTED)
981     {
982         rda5890_sdio_set_default_notch(priv);
983     }
984
985     wid_msg_id = priv->wid_msg_id++;
986     
987         wid_req[0] = 'W';
988         wid_req[1] = wid_msg_id;
989
990         wid_req[2] = (char)(wid_req_len&0x00FF);
991         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
992
993         wid = WID_SITE_SURVEY;
994         wid_req[4] = (char)(wid&0x00FF);
995         wid_req[5] = (char)((wid&0xFF00) >> 8);
996
997         wid_req[6] = (char)(0x01);
998         wid_req[7] = (char)(0x01);
999
1000         wid = WID_START_SCAN_REQ;
1001         wid_req[8] = (char)(wid&0x00FF);
1002         wid_req[9] = (char)((wid&0xFF00) >> 8);
1003
1004         wid_req[10] = (char)(0x01);
1005         wid_req[11] = (char)(0x01);
1006     
1007     wid = WID_NETWORK_INFO_EN;
1008         wid_req[12] = (char)(wid&0x00FF);
1009         wid_req[13] = (char)((wid&0xFF00) >> 8);
1010
1011         wid_req[14] = (char)(0x01);
1012         wid_req[15] = (char)(0x01); // 0x01 scan network info
1013         
1014         wid_req_len = 16;
1015         wid_req[2] = (char)(wid_req_len&0x00FF);
1016         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
1017
1018         ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
1019         if (ret) {
1020                 RDA5890_ERRP("rda5890_wid_request fail, ret = %d\n", ret);
1021                 goto out;
1022         }
1023
1024         ret = rda5890_check_wid_status(wid_rsp, wid_rsp_len, wid_msg_id);
1025         if (ret) {
1026                 RDA5890_ERRP("check_wid_status fail, ret = %d\n", ret);
1027                 goto out;
1028         }
1029
1030 out:
1031         return ret;
1032 }
1033
1034 int rda5890_start_join(struct rda5890_private *priv)
1035 {
1036     int ret;
1037         char wid_req[255];
1038         unsigned short wid_req_len = 0;
1039         char wid_rsp[32];
1040         unsigned short wid_rsp_len = 32;
1041         unsigned short wid;
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;
1046     
1047     RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
1048         "%s <<< mode:%d authtype:%d ssid:%s\n", __func__, priv->imode, priv->authtype,
1049         priv->assoc_ssid);
1050     
1051         wid_req[0] = 'W';
1052         wid_req[1] = wid_msg_id;
1053
1054
1055     wid = WID_802_11I_MODE;
1056         wid_req[4] = (char)(wid&0x00FF);
1057         wid_req[5] = (char)((wid&0xFF00) >> 8);
1058     
1059         wid_req[6] = 1;
1060     wid_req[7] = priv->imode;
1061
1062     wid = WID_AUTH_TYPE;
1063     wid_req[8] = (char)(wid&0x00FF);
1064         wid_req[9] = (char)((wid&0xFF00) >> 8);
1065     
1066         wid_req[10] = 1;
1067     wid_req[11] = priv->authtype;
1068     
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);
1073     
1074         wid_req[14] = 1;
1075     wid_req[15] = 0;
1076
1077     wid = WID_CURRENT_TX_RATE;
1078     wid_req[16] = (char)(wid&0x00FF);
1079         wid_req[17] = (char)((wid&0xFF00) >> 8);
1080     
1081         wid_req[18] = 1;
1082     wid_req[19] = 1;
1083     
1084     wid_req_len = 20;
1085     pWid_req = wid_req + 20;    
1086 #else
1087     wid_req_len = 12;
1088     pWid_req = wid_req + 12;
1089 #endif
1090     wid = WID_WEP_KEY_VALUE0;
1091     if(priv->imode == 3 || priv->imode == 7) //write wep key
1092     {
1093         for(i = 0 ; i < 4; i ++)
1094         {
1095             key = priv->wep_keys[i].key;
1096
1097             if(priv->wep_keys[i].len == 0)
1098                 continue;
1099             
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]);
1103                 key_str_len = 10;
1104                 key_str[key_str_len] = '\0';
1105             }
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"
1109                 "%02x%02x%02x\n",
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]);
1113                 key_str_len = 26;
1114                 key_str[key_str_len] = '\0';
1115             }
1116             else
1117                 continue;
1118
1119             pWid_req[0] = (char)((wid + i)&0x00FF);
1120                 pWid_req[1] = (char)(((wid + i)&0xFF00) >> 8);
1121     
1122                 pWid_req[2] = key_str_len;
1123             memcpy(pWid_req + 3, key_str, key_str_len);
1124             
1125             pWid_req += 3 + key_str_len;
1126             wid_req_len += 3 + key_str_len;            
1127         }
1128     }
1129
1130 //  ssid
1131     wid = WID_SSID;
1132     pWid_req[0] = (char)(wid&0x00FF);
1133         pWid_req[1] = (char)((wid&0xFF00) >> 8);
1134     
1135         pWid_req[2] = priv->assoc_ssid_len;
1136     memcpy(pWid_req + 3, priv->assoc_ssid, priv->assoc_ssid_len);
1137     
1138     wid_req_len += 3 + priv->assoc_ssid_len;
1139
1140     
1141         wid_req[2] = (char)(wid_req_len&0x00FF);
1142         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
1143
1144         ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
1145         if (ret) {
1146                 RDA5890_ERRP("rda5890_start_join fail, ret = %d\n", ret);
1147                 goto out;
1148         }
1149
1150         ret = rda5890_check_wid_status(wid_rsp, wid_rsp_len, wid_msg_id);
1151         if (ret) {
1152                 RDA5890_ERRP("rda5890_start_join check status fail, ret = %d\n", ret);
1153                 goto out;
1154         }
1155
1156 out:
1157     
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
1160         , priv->authtype);
1161         return ret;    
1162 }
1163
1164 int rda5890_set_txrate(struct rda5890_private *priv, unsigned char mbps)
1165 {
1166         int ret;
1167
1168         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1169                 "rda5890_set_txrate <<< \n");
1170
1171         ret = rda5890_generic_set_uchar(priv, WID_CURRENT_TX_RATE, mbps); //O FOR AUTO 1FOR 1MBPS
1172         if (ret) {
1173                 goto out;
1174         }
1175
1176         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1177                 "rda5890_set_txrate success >>> \n");
1178
1179 out:
1180         return ret;
1181 }
1182
1183 int rda5890_set_core_init_polling(struct rda5890_private *priv, const unsigned int (*data)[2], unsigned char num)
1184 {
1185         int ret = -1;
1186         char wid_req[255];
1187         unsigned short wid_req_len = 4 + 14*num;
1188         char wid_rsp[32];
1189         unsigned short wid_rsp_len = 32;
1190         unsigned short wid;
1191         char wid_msg_id = priv->wid_msg_id++;
1192             char count = 0, *p_wid_req = NULL;
1193
1194         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
1195                 "%s <<< \n", __func__);
1196
1197         wid_req[0] = 'W';
1198         wid_req[1] = wid_msg_id;
1199
1200         wid_req[2] = (char)(wid_req_len&0x00FF);
1201         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
1202
1203         p_wid_req = wid_req + 4;
1204         for(count = 0; count < num; count ++)
1205         {
1206             wid = WID_MEMORY_ADDRESS;
1207             p_wid_req[0] = (char)(wid&0x00FF);
1208             p_wid_req[1] = (char)((wid&0xFF00) >> 8);
1209
1210             p_wid_req[2] = (char)4;
1211             memcpy(p_wid_req + 3, (char*)&data[count][0], 4);
1212
1213             wid = WID_MEMORY_ACCESS_32BIT;
1214             p_wid_req[7] = (char)(wid&0x00FF);
1215             p_wid_req[8] = (char)((wid&0xFF00) >> 8);
1216
1217             p_wid_req[9] = (char)4;
1218             memcpy(p_wid_req + 10, (char*)&data[count][1], 4);
1219             p_wid_req += 14;
1220         }
1221         ret = rda5890_wid_request_polling(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
1222         if (ret) {
1223                 RDA5890_ERRP("rda5890_set_sdio_core_init fail, ret = %d\n", ret);
1224                 goto out;
1225         }
1226
1227 out:
1228         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
1229                 "%s >>> \n", __func__);
1230         return ret;
1231 }
1232
1233 int rda5890_set_core_init(struct rda5890_private *priv, const unsigned int (*data)[2], unsigned char num)
1234 {
1235         int ret = -1;
1236         char wid_req[255];
1237         unsigned short wid_req_len = 4 + 14*num;
1238         char wid_rsp[32];
1239         unsigned short wid_rsp_len = 32;
1240         unsigned short wid;
1241         char wid_msg_id = priv->wid_msg_id++;
1242         char count = 0, *p_wid_req = NULL;
1243
1244         wid_req[0] = 'W';
1245         wid_req[1] = wid_msg_id;
1246
1247         wid_req[2] = (char)(wid_req_len&0x00FF);
1248         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
1249
1250         p_wid_req = wid_req + 4;
1251         for(count = 0; count < num; count ++)
1252         {
1253             wid = WID_MEMORY_ADDRESS;
1254             p_wid_req[0] = (char)(wid&0x00FF);
1255             p_wid_req[1] = (char)((wid&0xFF00) >> 8);
1256
1257             p_wid_req[2] = (char)4;
1258             memcpy(p_wid_req + 3, (char*)&data[count][0], 4);
1259
1260             wid = WID_MEMORY_ACCESS_32BIT;
1261             p_wid_req[7] = (char)(wid&0x00FF);
1262             p_wid_req[8] = (char)((wid&0xFF00) >> 8);
1263
1264             p_wid_req[9] = (char)4;
1265             memcpy(p_wid_req + 10, (char*)&data[count][1], 4);
1266             p_wid_req += 14;
1267         }
1268         ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
1269         if (ret) {
1270                 RDA5890_ERRP("rda5890_set_sdio_core_init fail, ret = %d\n", ret);
1271                 goto out;
1272         }
1273
1274 out:
1275         return ret;
1276 }
1277
1278 int rda5890_set_core_patch_polling(struct rda5890_private *priv, const unsigned char (*patch)[2], unsigned char num)
1279 {
1280         int ret;
1281         char wid_req[255];
1282         unsigned short wid_req_len = 4 + 8*num;
1283         char wid_rsp[32];
1284         unsigned short wid_rsp_len = 32;
1285         unsigned short wid;
1286         char wid_msg_id = priv->wid_msg_id++;
1287         char count = 0 , *p_wid_req = NULL;     
1288         
1289         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
1290                 "%s <<< \n", __func__); 
1291         
1292         wid_req[0] = 'W';
1293         wid_req[1] = wid_msg_id;
1294
1295         wid_req[2] = (char)(wid_req_len&0x00FF);
1296         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
1297
1298         p_wid_req = wid_req + 4;
1299         for(count = 0; count < num; count ++)
1300         {
1301             wid = WID_PHY_ACTIVE_REG;
1302             p_wid_req[0] = (char)(wid&0x00FF);
1303             p_wid_req[1] = (char)((wid&0xFF00) >> 8);
1304
1305             p_wid_req[2] = (char)(0x01);
1306             p_wid_req[3] = patch[count][0];
1307
1308             wid = WID_PHY_ACTIVE_REG_VAL;
1309             p_wid_req[4] = (char)(wid&0x00FF);
1310             p_wid_req[5] = (char)((wid&0xFF00) >> 8);
1311
1312             p_wid_req[6] = (char)(0x01);
1313             p_wid_req[7] = patch[count][1];
1314             p_wid_req += 8;
1315         }
1316         ret = rda5890_wid_request_polling(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
1317         if (ret) {
1318                 RDA5890_ERRP("rda5890_set_core_patch fail, ret = %d \n", ret);
1319                 goto out;
1320         }
1321
1322 out:
1323         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_DEBUG,
1324                 "%s >>> \n", __func__); 
1325         return ret;
1326 }
1327
1328 int rda5890_set_core_patch(struct rda5890_private *priv, const unsigned char (*patch)[2], unsigned char num)
1329 {
1330         int ret;
1331         char wid_req[255];
1332         unsigned short wid_req_len = 4 + 8*num;
1333         char wid_rsp[32];
1334         unsigned short wid_rsp_len = 32;
1335         unsigned short wid;
1336         char wid_msg_id = priv->wid_msg_id++;
1337         char count = 0 , *p_wid_req = NULL;     
1338         
1339         wid_req[0] = 'W';
1340         wid_req[1] = wid_msg_id;
1341
1342         wid_req[2] = (char)(wid_req_len&0x00FF);
1343         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
1344
1345             p_wid_req = wid_req + 4;
1346         for(count = 0; count < num; count ++)
1347         {
1348             wid = WID_PHY_ACTIVE_REG;
1349             p_wid_req[0] = (char)(wid&0x00FF);
1350             p_wid_req[1] = (char)((wid&0xFF00) >> 8);
1351
1352             p_wid_req[2] = (char)(0x01);
1353             p_wid_req[3] = patch[count][0];
1354
1355             wid = WID_PHY_ACTIVE_REG_VAL;
1356             p_wid_req[4] = (char)(wid&0x00FF);
1357             p_wid_req[5] = (char)((wid&0xFF00) >> 8);
1358
1359             p_wid_req[6] = (char)(0x01);
1360             p_wid_req[7] = patch[count][1];
1361             p_wid_req += 8;
1362         }
1363         ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
1364         if (ret) {
1365                 RDA5890_ERRP("rda5890_set_core_patch fail, ret = %d \n", ret);
1366                 goto out;
1367         }
1368
1369 out:
1370         return ret;
1371 }
1372
1373
1374 int rda5890_get_fw_ver(struct rda5890_private *priv, unsigned long *fw_ver)
1375 {
1376         int ret;
1377
1378         ret = rda5890_generic_get_ulong(priv, WID_SYS_FW_VER, fw_ver);
1379         if (ret) {
1380                 goto out;
1381         }
1382
1383         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1384                 "Get FW_VER 0x%08lx\n", *fw_ver);
1385
1386 out:
1387         return ret;
1388 }
1389
1390 int rda5890_get_mac_addr(struct rda5890_private *priv, unsigned char *mac_addr)
1391 {
1392         int ret;
1393
1394         ret = rda5890_generic_get_str(priv, WID_MAC_ADDR, mac_addr, ETH_ALEN);
1395         if (ret) {
1396                 goto out;
1397         }
1398
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]);
1403 out:
1404         return ret;
1405 }
1406
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)
1410 {
1411         int ret;
1412         int count = 0;
1413         unsigned char len;
1414         unsigned char buf[sizeof(struct rda5890_bss_descriptor)*RDA5890_MAX_NETWORK_NUM + 2];
1415     unsigned char first_send = 0;
1416
1417         ret = rda5890_get_str_unknown_len(priv, WID_SITE_SURVEY_RESULTS,
1418                 buf, &len);
1419         if (ret) {
1420                 return ret;
1421         }
1422         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1423                 "Get Scan Result, len = %d\n", len);
1424
1425         if ((len - 2) % sizeof(struct rda5890_bss_descriptor)) {
1426                 RDA5890_ERRP("Scan Result len not correct, %d\n", len);
1427                 return -EINVAL;
1428         }
1429
1430         count = (len - 2) / sizeof(struct rda5890_bss_descriptor);
1431
1432     first_send = *(buf + 1);
1433         memcpy(bss_desc, buf + 2, (len - 2)); 
1434
1435         return (count | first_send << 8);
1436 }
1437
1438 int rda5890_get_bssid(struct rda5890_private *priv, unsigned char *bssid)
1439 {
1440         int ret;
1441
1442         ret = rda5890_generic_get_str(priv, WID_BSSID, bssid, ETH_ALEN);
1443         if (ret) {
1444                 goto out;
1445         }
1446
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]);
1451 out:
1452         return ret;
1453 }
1454
1455 int rda5890_get_channel(struct rda5890_private *priv, unsigned char *channel)
1456 {
1457         int ret;
1458
1459         ret = rda5890_generic_get_uchar(priv, WID_CURRENT_CHANNEL, channel);
1460         if (ret) {
1461                 goto out;
1462         }
1463
1464         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1465                 "Get Channel %d\n", *channel);
1466
1467 out:
1468         return ret;
1469 }
1470
1471 int rda5890_get_rssi(struct rda5890_private *priv, unsigned char *rssi)
1472 {
1473         int ret;
1474
1475     *rssi = 0;
1476         ret = rda5890_generic_get_uchar(priv, WID_RSSI, rssi);
1477         if (ret) {
1478                 goto out;
1479         }
1480
1481
1482         if(priv->connect_status == MAC_CONNECTED)
1483         {
1484                 if(*rssi > 215)
1485                 {
1486                         rda5890_rssi_up_to_200(priv);                   
1487                 }
1488                 else
1489                 {
1490                         rda5890_sdio_set_notch_by_channel(priv, priv->curbssparams.channel);                    
1491                 }
1492         }
1493     else
1494         *rssi = 0;
1495
1496         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1497                 "Get RSSI <<< %d\n", *(char*)rssi);
1498
1499 out:
1500         return ret;
1501 }
1502
1503 int rda5890_set_mac_addr(struct rda5890_private *priv, unsigned char *mac_addr)
1504 {
1505         int ret;
1506
1507         ret = rda5890_generic_set_str(priv, WID_MAC_ADDR, mac_addr, ETH_ALEN);
1508         if (ret) {
1509                 goto out;
1510         }
1511
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]);
1516 out:
1517         return ret;
1518 }
1519
1520 int rda5890_set_preamble(struct rda5890_private *priv, unsigned char  preamble)
1521 {
1522         int ret;
1523
1524         ret = rda5890_generic_set_uchar(priv, WID_PREAMBLE, preamble);
1525         if (ret) {
1526                 goto out;
1527         }
1528
1529         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE, "rda5890_set_preamble \n");
1530 out:
1531         return ret;
1532 }
1533
1534 #ifdef GET_SCAN_FROM_NETWORK_INFO
1535
1536 int rda5890_set_scan_complete(struct rda5890_private *priv)
1537 {
1538         int ret;
1539
1540         ret = rda5890_generic_set_uchar(priv, WID_NETWORK_INFO_EN, 0);
1541         if (ret) {
1542                 goto out;
1543         }
1544      
1545 out:
1546       RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE, "rda5890_set_scan_complete  ret=%d \n", ret);
1547         return ret;
1548 }
1549 #endif
1550
1551 int rda5890_set_ssid(struct rda5890_private *priv, 
1552                 unsigned char *ssid, unsigned char ssid_len)
1553 {
1554         int ret;
1555
1556         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1557                 "Set SSID: %s, len = %d\n", ssid, ssid_len);
1558
1559         ret = rda5890_generic_set_str(priv, WID_SSID, ssid, ssid_len);
1560         if (ret) {
1561                 goto out;
1562         }
1563
1564         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1565                 "Set SSID Done\n");
1566
1567 out:
1568         return ret;
1569 }
1570
1571 int rda5890_get_ssid(struct rda5890_private *priv, 
1572                 unsigned char *ssid, unsigned char *ssid_len)
1573 {
1574     int ret;
1575     
1576         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1577                 "Get SSID \n");
1578     
1579     ret = rda5890_get_str_unknown_len(priv, WID_SSID, ssid, ssid_len);
1580     if(*ssid_len > 0)
1581         ssid[*ssid_len] = '\0';
1582     
1583     RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1584         "Get SSID Done len:%d %s\n", *ssid_len, *ssid_len > 0? ssid:"NULL");
1585 out:
1586         return ret;
1587 }
1588 int rda5890_set_bssid(struct rda5890_private *priv, unsigned char *bssid)
1589 {
1590         int ret;
1591
1592         ret = rda5890_generic_set_str(priv, WID_BSSID, bssid, ETH_ALEN);
1593         if (ret) {
1594                 goto out;
1595         }
1596
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]);
1601 out:
1602         return ret;
1603 }
1604
1605
1606 int rda5890_set_imode(struct rda5890_private *priv, unsigned char imode)
1607 {
1608         int ret;
1609
1610         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1611                 "Set IMode 0x%02x\n", imode);
1612
1613         ret = rda5890_generic_set_uchar(priv, WID_802_11I_MODE, imode);
1614         if (ret) {
1615                 goto out;
1616         }
1617
1618         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1619                 "Set IMode Done\n");
1620
1621 out:
1622         return ret;
1623 }
1624
1625 int rda5890_set_authtype(struct rda5890_private *priv, unsigned char authtype)
1626 {
1627         int ret;
1628
1629         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1630                 "Set AuthType 0x%02x\n", authtype);
1631
1632         ret = rda5890_generic_set_uchar(priv, WID_AUTH_TYPE, authtype);
1633         if (ret) {
1634                 goto out;
1635         }
1636
1637         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1638                 "Set AuthType Done\n");
1639
1640 out:
1641         return ret;
1642 }
1643
1644 int rda5890_set_listen_interval(struct rda5890_private *priv, unsigned char interval)
1645 {
1646         int ret;
1647
1648         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1649                 "Set rda5890_set_listen_interval 0x%02x\n", interval);
1650
1651         ret = rda5890_generic_set_uchar(priv, WID_LISTEN_INTERVAL, interval);
1652         if (ret) {
1653                 goto out;
1654         }
1655
1656         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1657                 "Set rda5890_set_listen_interval Done\n");
1658
1659 out:
1660         return ret;
1661 }
1662
1663 int rda5890_set_link_loss_threshold(struct rda5890_private *priv, unsigned char threshold)
1664 {
1665         int ret;
1666
1667         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1668                 "Set rda5890_set_link_loss_threshold 0x%02x\n", threshold);
1669
1670         ret = rda5890_generic_set_uchar(priv, WID_LINK_LOSS_THRESHOLD, threshold);
1671         if (ret) {
1672                 goto out;
1673         }
1674
1675         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1676                 "Set rda5890_set_link_loss_threshold Done\n");
1677
1678 out:
1679         return ret;
1680 }
1681
1682
1683 int rda5890_set_wepkey(struct rda5890_private *priv, 
1684                 unsigned short index, unsigned char *key, unsigned char key_len)
1685 {
1686         int ret;
1687         unsigned char key_str[26 + 1]; // plus 1 for debug print
1688         unsigned char key_str_len;
1689
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]);
1693                 key_str_len = 10;
1694                 key_str[key_str_len] = '\0';
1695         }
1696         else if (key_len == KEY_LEN_WEP_104) {
1697                 sprintf(key_str, "%02x%02x%02x%02x%02x"
1698                         "%02x%02x%02x%02x%02x"
1699                         "%02x%02x%02x\n",
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]);
1703                 key_str_len = 26;
1704                 key_str[key_str_len] = '\0';
1705         }
1706         else {
1707                 RDA5890_ERRP("Error in WEP Key length %d\n", key_len);
1708                 ret = -EINVAL;
1709                 goto out;
1710         }
1711
1712         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1713                 "Set WEP KEY[%d]: %s\n", index, key_str);
1714
1715         ret = rda5890_generic_set_str(priv,
1716                 (WID_WEP_KEY_VALUE0 + index), key_str, key_str_len);
1717         if (ret) {
1718                 goto out;
1719         }
1720
1721         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1722                 "Set WEP KEY[%d] Done\n", index);
1723
1724 out:
1725         return ret;
1726 }
1727
1728 static void dump_key(unsigned char *key, unsigned char key_len)
1729 {
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]);
1734         if (key_len > 16)
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]);
1737         if (key_len > 24)
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]);
1740 }
1741
1742 int rda5890_set_ptk(struct rda5890_private *priv, 
1743                 unsigned char *key, unsigned char key_len)
1744 {
1745         int ret;
1746         unsigned char key_str[32 + ETH_ALEN + 1]; 
1747         unsigned char key_str_len = key_len + ETH_ALEN + 1;
1748
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);
1753
1754         if (priv->connect_status != MAC_CONNECTED) {
1755                 RDA5890_ERRP("Adding PTK while not connected\n");
1756                 ret = -EINVAL;
1757                 goto out;
1758         }
1759
1760         /*----------------------------------------*/
1761         /*    STA Addr  | KeyLength |   Key       */
1762         /*----------------------------------------*/
1763         /*       6      |     1     |  KeyLength  */
1764         /*----------------------------------------*/
1765
1766         /*---------------------------------------------------------*/
1767         /*                      key                                */
1768         /*---------------------------------------------------------*/
1769         /* Temporal Key    | Rx Micheal Key    |   Tx Micheal Key  */
1770         /*---------------------------------------------------------*/
1771         /*    16 bytes     |      8 bytes      |       8 bytes     */
1772         /*---------------------------------------------------------*/
1773
1774         memcpy(key_str, priv->curbssparams.bssid, ETH_ALEN);
1775         key_str[6] = key_len;
1776         memcpy(key_str + 7, key, 16);
1777
1778         /* swap TX MIC and RX MIC, rda5890 need RX MIC to be ahead */
1779         if(key_len > 16) {
1780                 memcpy(key_str + 7 + 16, key + 24, 8);
1781                 memcpy(key_str + 7 + 24, key + 16, 8);
1782         }
1783
1784         if(priv->is_wapi)
1785                 ret = rda5890_generic_set_str(priv,
1786                         WID_ADD_WAPI_PTK, key_str, key_str_len);
1787         else
1788                 ret = rda5890_generic_set_str(priv,
1789                         WID_ADD_PTK, key_str, key_str_len);
1790         if (ret) {
1791                 goto out;
1792         }
1793
1794         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1795                 "Set PTK Done\n");
1796
1797 out:
1798         return ret;
1799 }
1800
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)
1804 {
1805         int ret;
1806         unsigned char key_str[32 + ETH_ALEN + 8 + 2]; 
1807         unsigned char key_str_len = key_len + ETH_ALEN + 8 + 2;
1808
1809         /*---------------------------------------------------------*/
1810         /*    STA Addr  | KeyRSC | KeyID | KeyLength |   Key       */
1811         /*---------------------------------------------------------*/
1812         /*       6      |   8    |   1   |     1     |  KeyLength  */
1813         /*---------------------------------------------------------*/
1814
1815         /*-------------------------------------*/
1816         /*                      key            */
1817         /*-------------------------------------*/
1818         /* Temporal Key    | Rx Micheal Key    */
1819         /*-------------------------------------*/
1820         /*    16 bytes     |      8 bytes      */
1821         /*-------------------------------------*/
1822
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);
1827
1828         if (priv->connect_status != MAC_CONNECTED) {
1829                 RDA5890_ERRP("Adding PTK while not connected\n");
1830                 ret = -EINVAL;
1831                 goto out;
1832         }
1833
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);
1839
1840         /* swap TX MIC and RX MIC, rda5890 need RX MIC to be ahead */
1841         if(key_len > 16) {
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);
1845         }
1846
1847         if(priv->is_wapi)
1848                 ret = rda5890_generic_set_str(priv,
1849                         WID_ADD_WAPI_RX_GTK, key_str, key_str_len);
1850         else
1851                 ret = rda5890_generic_set_str(priv,
1852                         WID_ADD_RX_GTK, key_str, key_str_len);
1853         if (ret) {
1854                 goto out;
1855         }
1856
1857         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1858                 "Set GTK Done\n");
1859
1860 out:
1861         return ret;
1862 }
1863
1864 int rda5890_set_scan_timeout(struct rda5890_private *priv)
1865 {
1866         int ret;
1867         char wid_req[14];
1868         unsigned short wid_req_len = 19;
1869         char wid_rsp[32];
1870         unsigned short wid_rsp_len = 32;
1871         char wid_msg_id = priv->wid_msg_id++;
1872         char *ptr_payload;
1873     unsigned short wid = 0;
1874
1875         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1876         "rda5890_set_scan_timeout <<< \n");
1877
1878     wid = WID_SITE_SURVEY_SCAN_TIME;
1879     
1880         wid_req[0] = 'W';
1881         wid_req[1] = wid_msg_id;
1882
1883         wid_req[2] = (char)(wid_req_len&0x00FF);
1884         wid_req[3] = (char)((wid_req_len&0xFF00) >> 8);
1885
1886         wid_req[4] = (char)(wid&0x00FF);
1887         wid_req[5] = (char)((wid&0xFF00) >> 8);
1888     wid_req[6] = 2;
1889     wid_req[7] = 50;    //50 ms one channel
1890     wid_req[8] = 0;
1891
1892     wid = WID_ACTIVE_SCAN_TIME;
1893     wid_req[9] = (char)(wid&0x00FF);
1894         wid_req[10] = (char)((wid&0xFF00) >> 8);
1895     wid_req[11] = 2;
1896     wid_req[12] = 50;   //50 ms one channel
1897     wid_req[13] = 0;
1898
1899     wid = WID_PASSIVE_SCAN_TIME;
1900     wid_req[14] = (char)(wid&0x00FF);
1901         wid_req[15] = (char)((wid&0xFF00) >> 8);
1902     wid_req[16] = 2;
1903     wid_req[17] = 50;   //50 ms one channel
1904     wid_req[18] = 0;
1905
1906         ret = rda5890_wid_request(priv, wid_req, wid_req_len, wid_rsp, &wid_rsp_len);
1907         if (ret) {
1908                 RDA5890_ERRP("rda5890_set_scan_timeout fail, ret = %d\n", ret);
1909                 goto out;
1910         }
1911
1912         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1913                 "rda5890_set_scan_timeout >>> \n");
1914
1915 out:
1916         return ret;
1917 }
1918
1919
1920 int rda5890_set_pm_mode(struct rda5890_private *priv, unsigned char pm_mode)
1921 {
1922         int ret;
1923
1924         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1925                 "Set PM Mode 0x%02x\n", pm_mode);
1926
1927         ret = rda5890_generic_set_uchar(priv, WID_POWER_MANAGEMENT, pm_mode);
1928         if (ret) {
1929                 goto out;
1930         }
1931
1932         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1933                 "Set PM Mode Done\n");
1934
1935 out:
1936         return ret;
1937 }
1938
1939 int rda5890_set_preasso_sleep(struct rda5890_private *priv, unsigned int preasso_sleep)
1940 {
1941         int ret;
1942
1943         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1944                 "Set Preasso Sleep 0x%08x\n", preasso_sleep);
1945
1946         ret = rda5890_generic_set_ulong(priv, WID_PREASSO_SLEEP, preasso_sleep);
1947         if (ret) {
1948                 goto out;
1949         }
1950
1951         RDA5890_DBGLAP(RDA5890_DA_WID, RDA5890_DL_TRACE,
1952                 "Set Preasso Sleep Done\n");
1953
1954 out:
1955         return ret;
1956 }
1957