staging: wilc1000: remove variable rx_buffer_size
[firefly-linux-kernel-4.4.55.git] / drivers / staging / wilc1000 / wilc_wlan.c
1 /* ////////////////////////////////////////////////////////////////////////// */
2 /*  */
3 /* Copyright (c) Atmel Corporation.  All rights reserved. */
4 /*  */
5 /* Module Name:  wilc_wlan.c */
6 /*  */
7 /*  */
8 /* //////////////////////////////////////////////////////////////////////////// */
9
10 #include "wilc_wlan_if.h"
11 #include "wilc_wlan.h"
12
13 /********************************************
14  *
15  *      Global
16  *
17  ********************************************/
18 extern wilc_hif_func_t hif_sdio;
19 extern wilc_hif_func_t hif_spi;
20 extern wilc_cfg_func_t mac_cfg;
21 extern void WILC_WFI_mgmt_rx(u8 *buff, u32 size);
22 u32 wilc_get_chipid(u8 update);
23 u16 Set_machw_change_vir_if(bool bValue);
24
25
26
27 typedef struct {
28         int quit;
29
30         /**
31          *      input interface functions
32          **/
33         wilc_wlan_os_func_t os_func;
34         wilc_wlan_io_func_t io_func;
35
36         /**
37          *      host interface functions
38          **/
39         wilc_hif_func_t hif_func;
40
41         /**
42          *      configuration interface functions
43          **/
44         wilc_cfg_func_t cif_func;
45         int cfg_frame_in_use;
46         wilc_cfg_frame_t cfg_frame;
47         u32 cfg_frame_offset;
48         int cfg_seq_no;
49
50         /**
51          *      RX buffer
52          **/
53         #ifdef MEMORY_STATIC
54         u8 *rx_buffer;
55         u32 rx_buffer_offset;
56         #endif
57         /**
58          *      TX buffer
59          **/
60         u8 *tx_buffer;
61         u32 tx_buffer_offset;
62
63         /**
64          *      TX queue
65          **/
66         void *txq_lock;
67
68         unsigned long txq_spinlock_flags;
69
70         struct txq_entry_t *txq_head;
71         struct txq_entry_t *txq_tail;
72         int txq_entries;
73         int txq_exit;
74
75         /**
76          *      RX queue
77          **/
78         struct rxq_entry_t *rxq_head;
79         struct rxq_entry_t *rxq_tail;
80         int rxq_entries;
81         int rxq_exit;
82
83
84 } wilc_wlan_dev_t;
85
86 static wilc_wlan_dev_t g_wlan;
87
88 static inline void chip_allow_sleep(void);
89 static inline void chip_wakeup(void);
90 /********************************************
91  *
92  *      Debug
93  *
94  ********************************************/
95
96 static u32 dbgflag = N_INIT | N_ERR | N_INTR | N_TXQ | N_RXQ;
97
98 static void wilc_debug(u32 flag, char *fmt, ...)
99 {
100         char buf[256];
101         va_list args;
102
103         if (flag & dbgflag) {
104                 va_start(args, fmt);
105                 vsprintf(buf, fmt, args);
106                 va_end(args);
107
108                 linux_wlan_dbg(buf);
109         }
110 }
111
112 static CHIP_PS_STATE_T genuChipPSstate = CHIP_WAKEDUP;
113
114 /*acquire_bus() and release_bus() are made static inline functions*/
115 /*as a temporary workaround to fix a problem of receiving*/
116 /*unknown interrupt from FW*/
117 static inline void acquire_bus(BUS_ACQUIRE_T acquire)
118 {
119
120         mutex_lock(&g_linux_wlan->hif_cs);
121         #ifndef WILC_OPTIMIZE_SLEEP_INT
122         if (genuChipPSstate != CHIP_WAKEDUP)
123         #endif
124         {
125                 if (acquire == ACQUIRE_AND_WAKEUP)
126                         chip_wakeup();
127         }
128
129 }
130 static inline void release_bus(BUS_RELEASE_T release)
131 {
132         #ifdef WILC_OPTIMIZE_SLEEP_INT
133         if (release == RELEASE_ALLOW_SLEEP)
134                 chip_allow_sleep();
135         #endif
136         mutex_unlock(&g_linux_wlan->hif_cs);
137 }
138 /********************************************
139  *
140  *      Queue
141  *
142  ********************************************/
143
144 static void wilc_wlan_txq_remove(struct txq_entry_t *tqe)
145 {
146
147         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
148         /* unsigned long flags; */
149         if (tqe == p->txq_head) {
150
151                 p->txq_head = tqe->next;
152                 if (p->txq_head)
153                         p->txq_head->prev = NULL;
154
155
156         } else if (tqe == p->txq_tail)      {
157                 p->txq_tail = (tqe->prev);
158                 if (p->txq_tail)
159                         p->txq_tail->next = NULL;
160         } else {
161                 tqe->prev->next = tqe->next;
162                 tqe->next->prev = tqe->prev;
163         }
164         p->txq_entries -= 1;
165
166 }
167
168 static struct txq_entry_t *wilc_wlan_txq_remove_from_head(void)
169 {
170         struct txq_entry_t *tqe;
171         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
172         unsigned long flags;
173
174         spin_lock_irqsave(&g_linux_wlan->txq_spinlock, flags);
175         if (p->txq_head) {
176                 tqe = p->txq_head;
177                 p->txq_head = tqe->next;
178                 if (p->txq_head) {
179                         p->txq_head->prev = NULL;
180                 }
181                 p->txq_entries -= 1;
182
183
184
185
186         } else {
187                 tqe = NULL;
188         }
189         spin_unlock_irqrestore(&g_linux_wlan->txq_spinlock, flags);
190         return tqe;
191 }
192
193 static void wilc_wlan_txq_add_to_tail(struct txq_entry_t *tqe)
194 {
195         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
196         unsigned long flags;
197         spin_lock_irqsave(&g_linux_wlan->txq_spinlock, flags);
198
199         if (p->txq_head == NULL) {
200                 tqe->next = NULL;
201                 tqe->prev = NULL;
202                 p->txq_head = tqe;
203                 p->txq_tail = tqe;
204         } else {
205                 tqe->next = NULL;
206                 tqe->prev = p->txq_tail;
207                 p->txq_tail->next = tqe;
208                 p->txq_tail = tqe;
209         }
210         p->txq_entries += 1;
211         PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", p->txq_entries);
212
213         spin_unlock_irqrestore(&g_linux_wlan->txq_spinlock, flags);
214
215         /**
216          *      wake up TX queue
217          **/
218         PRINT_D(TX_DBG, "Wake the txq_handling\n");
219
220         up(&g_linux_wlan->txq_event);
221 }
222
223 static int wilc_wlan_txq_add_to_head(struct txq_entry_t *tqe)
224 {
225         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
226         unsigned long flags;
227         if (p->os_func.os_wait(&g_linux_wlan->txq_add_to_head_cs,
228                                CFG_PKTS_TIMEOUT))
229                 return -1;
230
231         spin_lock_irqsave(&g_linux_wlan->txq_spinlock, flags);
232
233         if (p->txq_head == NULL) {
234                 tqe->next = NULL;
235                 tqe->prev = NULL;
236                 p->txq_head = tqe;
237                 p->txq_tail = tqe;
238         } else {
239                 tqe->next = p->txq_head;
240                 tqe->prev = NULL;
241                 p->txq_head->prev = tqe;
242                 p->txq_head = tqe;
243         }
244         p->txq_entries += 1;
245         PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", p->txq_entries);
246
247         spin_unlock_irqrestore(&g_linux_wlan->txq_spinlock, flags);
248         up(&g_linux_wlan->txq_add_to_head_cs);
249
250
251         /**
252          *      wake up TX queue
253          **/
254         up(&g_linux_wlan->txq_event);
255         PRINT_D(TX_DBG, "Wake up the txq_handler\n");
256
257         return 0;
258
259 }
260
261 u32 Statisitcs_totalAcks = 0, Statisitcs_DroppedAcks = 0;
262
263 #ifdef  TCP_ACK_FILTER
264 struct Ack_session_info;
265 struct Ack_session_info {
266         u32 Ack_seq_num;
267         u32 Bigger_Ack_num;
268         u16 src_port;
269         u16 dst_port;
270         u16 status;
271 };
272
273 typedef struct {
274         u32 ack_num;
275         u32 Session_index;
276         struct txq_entry_t  *txqe;
277 } Pending_Acks_info_t /*Ack_info_t*/;
278
279
280
281
282 struct Ack_session_info *Free_head;
283 struct Ack_session_info *Alloc_head;
284
285 #define TCP_FIN_MASK            (1 << 0)
286 #define TCP_SYN_MASK            (1 << 1)
287 #define TCP_Ack_MASK            (1 << 4)
288 #define NOT_TCP_ACK                     (-1)
289
290 #define MAX_TCP_SESSION         25
291 #define MAX_PENDING_ACKS                256
292 struct Ack_session_info Acks_keep_track_info[2 * MAX_TCP_SESSION];
293 Pending_Acks_info_t Pending_Acks_info[MAX_PENDING_ACKS];
294
295 u32 PendingAcks_arrBase;
296 u32 Opened_TCP_session;
297 u32 Pending_Acks;
298
299
300
301 static inline int Init_TCP_tracking(void)
302 {
303
304         return 0;
305
306 }
307 static inline int add_TCP_track_session(u32 src_prt, u32 dst_prt, u32 seq)
308 {
309         Acks_keep_track_info[Opened_TCP_session].Ack_seq_num = seq;
310         Acks_keep_track_info[Opened_TCP_session].Bigger_Ack_num = 0;
311         Acks_keep_track_info[Opened_TCP_session].src_port = src_prt;
312         Acks_keep_track_info[Opened_TCP_session].dst_port = dst_prt;
313         Opened_TCP_session++;
314
315         PRINT_D(TCP_ENH, "TCP Session %d to Ack %d\n", Opened_TCP_session, seq);
316         return 0;
317 }
318
319 static inline int Update_TCP_track_session(u32 index, u32 Ack)
320 {
321
322         if (Ack > Acks_keep_track_info[index].Bigger_Ack_num) {
323                 Acks_keep_track_info[index].Bigger_Ack_num = Ack;
324         }
325         return 0;
326
327 }
328 static inline int add_TCP_Pending_Ack(u32 Ack, u32 Session_index, struct txq_entry_t  *txqe)
329 {
330         Statisitcs_totalAcks++;
331         if (Pending_Acks < MAX_PENDING_ACKS) {
332                 Pending_Acks_info[PendingAcks_arrBase + Pending_Acks].ack_num = Ack;
333                 Pending_Acks_info[PendingAcks_arrBase + Pending_Acks].txqe = txqe;
334                 Pending_Acks_info[PendingAcks_arrBase + Pending_Acks].Session_index = Session_index;
335                 txqe->tcp_PendingAck_index = PendingAcks_arrBase + Pending_Acks;
336                 Pending_Acks++;
337
338         } else {
339
340         }
341         return 0;
342 }
343 static inline int remove_TCP_related(void)
344 {
345         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
346         unsigned long flags;
347
348         spin_lock_irqsave(&g_linux_wlan->txq_spinlock, flags);
349
350         spin_unlock_irqrestore(&g_linux_wlan->txq_spinlock, flags);
351         return 0;
352 }
353
354 static inline int tcp_process(struct txq_entry_t *tqe)
355 {
356         int ret;
357         u8 *eth_hdr_ptr;
358         u8 *buffer = tqe->buffer;
359         unsigned short h_proto;
360         int i;
361         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
362         unsigned long flags;
363
364         spin_lock_irqsave(&g_linux_wlan->txq_spinlock, flags);
365
366         eth_hdr_ptr = &buffer[0];
367         h_proto = ntohs(*((unsigned short *)&eth_hdr_ptr[12]));
368         if (h_proto == 0x0800) { /* IP */
369                 u8 *ip_hdr_ptr;
370                 u8 protocol;
371
372                 ip_hdr_ptr = &buffer[ETHERNET_HDR_LEN];
373                 protocol = ip_hdr_ptr[9];
374
375
376                 if (protocol == 0x06) {
377                         u8 *tcp_hdr_ptr;
378                         u32 IHL, Total_Length, Data_offset;
379
380                         tcp_hdr_ptr = &ip_hdr_ptr[IP_HDR_LEN];
381                         IHL = (ip_hdr_ptr[0] & 0xf) << 2;
382                         Total_Length = (((u32)ip_hdr_ptr[2]) << 8) + ((u32)ip_hdr_ptr[3]);
383                         Data_offset = (((u32)tcp_hdr_ptr[12] & 0xf0) >> 2);
384                         if (Total_Length == (IHL + Data_offset)) { /*we want to recognize the clear Acks(packet only carry Ack infos not with data) so data size must be equal zero*/
385                                 u32 seq_no, Ack_no;
386
387                                 seq_no  = (((u32)tcp_hdr_ptr[4]) << 24) + (((u32)tcp_hdr_ptr[5]) << 16) + (((u32)tcp_hdr_ptr[6]) << 8) + ((u32)tcp_hdr_ptr[7]);
388
389                                 Ack_no  = (((u32)tcp_hdr_ptr[8]) << 24) + (((u32)tcp_hdr_ptr[9]) << 16) + (((u32)tcp_hdr_ptr[10]) << 8) + ((u32)tcp_hdr_ptr[11]);
390
391
392                                 for (i = 0; i < Opened_TCP_session; i++) {
393                                         if (Acks_keep_track_info[i].Ack_seq_num == seq_no) {
394                                                 Update_TCP_track_session(i, Ack_no);
395                                                 break;
396                                         }
397                                 }
398                                 if (i == Opened_TCP_session) {
399                                         add_TCP_track_session(0, 0, seq_no);
400                                 }
401                                 add_TCP_Pending_Ack(Ack_no, i, tqe);
402
403
404                         }
405
406                 } else {
407                         ret = 0;
408                 }
409         } else {
410                 ret = 0;
411         }
412         spin_unlock_irqrestore(&g_linux_wlan->txq_spinlock, flags);
413         return ret;
414 }
415
416
417 static int wilc_wlan_txq_filter_dup_tcp_ack(void)
418 {
419
420         u32 i = 0;
421         u32 Dropped = 0;
422         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
423
424         spin_lock_irqsave(&g_linux_wlan->txq_spinlock, p->txq_spinlock_flags);
425         for (i = PendingAcks_arrBase; i < (PendingAcks_arrBase + Pending_Acks); i++) {
426                 if (Pending_Acks_info[i].ack_num < Acks_keep_track_info[Pending_Acks_info[i].Session_index].Bigger_Ack_num) {
427                         struct txq_entry_t *tqe;
428
429                         PRINT_D(TCP_ENH, "DROP ACK: %u\n", Pending_Acks_info[i].ack_num);
430                         tqe = Pending_Acks_info[i].txqe;
431                         if (tqe) {
432                                 wilc_wlan_txq_remove(tqe);
433                                 Statisitcs_DroppedAcks++;
434                                 tqe->status = 1;                                /* mark the packet send */
435                                 if (tqe->tx_complete_func)
436                                         tqe->tx_complete_func(tqe->priv, tqe->status);
437                                 kfree(tqe);
438                                 Dropped++;
439                         }
440                 }
441         }
442         Pending_Acks = 0;
443         Opened_TCP_session = 0;
444
445         if (PendingAcks_arrBase == 0)
446                 PendingAcks_arrBase = MAX_TCP_SESSION;
447         else
448                 PendingAcks_arrBase = 0;
449
450
451         spin_unlock_irqrestore(&g_linux_wlan->txq_spinlock,
452                                p->txq_spinlock_flags);
453
454         while (Dropped > 0) {
455                 /*consume the semaphore count of the removed packet*/
456                 p->os_func.os_wait(&g_linux_wlan->txq_event, 1);
457                 Dropped--;
458         }
459
460         return 1;
461 }
462 #endif
463
464 bool EnableTCPAckFilter = false;
465
466 void Enable_TCP_ACK_Filter(bool value)
467 {
468         EnableTCPAckFilter = value;
469 }
470
471 bool is_TCP_ACK_Filter_Enabled(void)
472 {
473         return EnableTCPAckFilter;
474 }
475
476 static int wilc_wlan_txq_add_cfg_pkt(u8 *buffer, u32 buffer_size)
477 {
478         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
479         struct txq_entry_t *tqe;
480
481         PRINT_D(TX_DBG, "Adding config packet ...\n");
482         if (p->quit) {
483                 PRINT_D(TX_DBG, "Return due to clear function\n");
484                 up(&g_linux_wlan->cfg_event);
485                 return 0;
486         }
487
488         tqe = kmalloc(sizeof(struct txq_entry_t), GFP_ATOMIC);
489         if (tqe == NULL) {
490                 PRINT_ER("Failed to allocate memory\n");
491                 return 0;
492         }
493
494         tqe->type = WILC_CFG_PKT;
495         tqe->buffer = buffer;
496         tqe->buffer_size = buffer_size;
497         tqe->tx_complete_func = NULL;
498         tqe->priv = NULL;
499 #ifdef TCP_ACK_FILTER
500         tqe->tcp_PendingAck_index = NOT_TCP_ACK;
501 #endif
502         /**
503          *      Configuration packet always at the front
504          **/
505         PRINT_D(TX_DBG, "Adding the config packet at the Queue tail\n");
506
507         if (wilc_wlan_txq_add_to_head(tqe))
508                 return 0;
509         return 1;
510 }
511
512 static int wilc_wlan_txq_add_net_pkt(void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func)
513 {
514         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
515         struct txq_entry_t *tqe;
516
517         if (p->quit)
518                 return 0;
519
520         tqe = kmalloc(sizeof(struct txq_entry_t), GFP_ATOMIC);
521
522         if (tqe == NULL)
523                 return 0;
524         tqe->type = WILC_NET_PKT;
525         tqe->buffer = buffer;
526         tqe->buffer_size = buffer_size;
527         tqe->tx_complete_func = func;
528         tqe->priv = priv;
529
530         PRINT_D(TX_DBG, "Adding mgmt packet at the Queue tail\n");
531 #ifdef TCP_ACK_FILTER
532         tqe->tcp_PendingAck_index = NOT_TCP_ACK;
533         if (is_TCP_ACK_Filter_Enabled())
534                 tcp_process(tqe);
535 #endif
536         wilc_wlan_txq_add_to_tail(tqe);
537         /*return number of itemes in the queue*/
538         return p->txq_entries;
539 }
540
541 int wilc_wlan_txq_add_mgmt_pkt(void *priv, u8 *buffer, u32 buffer_size, wilc_tx_complete_func_t func)
542 {
543
544         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
545         struct txq_entry_t *tqe;
546
547         if (p->quit)
548                 return 0;
549
550         tqe = kmalloc(sizeof(struct txq_entry_t), GFP_KERNEL);
551
552         if (tqe == NULL)
553                 return 0;
554         tqe->type = WILC_MGMT_PKT;
555         tqe->buffer = buffer;
556         tqe->buffer_size = buffer_size;
557         tqe->tx_complete_func = func;
558         tqe->priv = priv;
559 #ifdef TCP_ACK_FILTER
560         tqe->tcp_PendingAck_index = NOT_TCP_ACK;
561 #endif
562         PRINT_D(TX_DBG, "Adding Network packet at the Queue tail\n");
563         wilc_wlan_txq_add_to_tail(tqe);
564         return 1;
565 }
566
567 static struct txq_entry_t *wilc_wlan_txq_get_first(void)
568 {
569         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
570         struct txq_entry_t *tqe;
571         unsigned long flags;
572
573         spin_lock_irqsave(&g_linux_wlan->txq_spinlock, flags);
574
575         tqe = p->txq_head;
576
577         spin_unlock_irqrestore(&g_linux_wlan->txq_spinlock, flags);
578
579
580         return tqe;
581 }
582
583 static struct txq_entry_t *wilc_wlan_txq_get_next(struct txq_entry_t *tqe)
584 {
585         unsigned long flags;
586         spin_lock_irqsave(&g_linux_wlan->txq_spinlock, flags);
587
588         tqe = tqe->next;
589         spin_unlock_irqrestore(&g_linux_wlan->txq_spinlock, flags);
590
591
592         return tqe;
593 }
594
595 static int wilc_wlan_rxq_add(struct rxq_entry_t *rqe)
596 {
597         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
598
599         if (p->quit)
600                 return 0;
601
602         mutex_lock(&g_linux_wlan->rxq_cs);
603         if (p->rxq_head == NULL) {
604                 PRINT_D(RX_DBG, "Add to Queue head\n");
605                 rqe->next = NULL;
606                 p->rxq_head = rqe;
607                 p->rxq_tail = rqe;
608         } else {
609                 PRINT_D(RX_DBG, "Add to Queue tail\n");
610                 p->rxq_tail->next = rqe;
611                 rqe->next = NULL;
612                 p->rxq_tail = rqe;
613         }
614         p->rxq_entries += 1;
615         PRINT_D(RX_DBG, "Number of queue entries: %d\n", p->rxq_entries);
616         mutex_unlock(&g_linux_wlan->rxq_cs);
617         return p->rxq_entries;
618 }
619
620 static struct rxq_entry_t *wilc_wlan_rxq_remove(void)
621 {
622         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
623
624         PRINT_D(RX_DBG, "Getting rxQ element\n");
625         if (p->rxq_head) {
626                 struct rxq_entry_t *rqe;
627
628                 mutex_lock(&g_linux_wlan->rxq_cs);
629                 rqe = p->rxq_head;
630                 p->rxq_head = p->rxq_head->next;
631                 p->rxq_entries -= 1;
632                 PRINT_D(RX_DBG, "RXQ entries decreased\n");
633                 mutex_unlock(&g_linux_wlan->rxq_cs);
634                 return rqe;
635         }
636         PRINT_D(RX_DBG, "Nothing to get from Q\n");
637         return NULL;
638 }
639
640
641 /********************************************
642  *
643  *      Power Save handle functions
644  *
645  ********************************************/
646
647
648
649 #ifdef WILC_OPTIMIZE_SLEEP_INT
650
651 static inline void chip_allow_sleep(void)
652 {
653         u32 reg = 0;
654
655         /* Clear bit 1 */
656         g_wlan.hif_func.hif_read_reg(0xf0, &reg);
657
658         g_wlan.hif_func.hif_write_reg(0xf0, reg & ~(1 << 0));
659 }
660
661 static inline void chip_wakeup(void)
662 {
663         u32 reg, clk_status_reg, trials = 0;
664         u32 sleep_time;
665
666         if ((g_wlan.io_func.io_type & 0x1) == HIF_SPI) {
667                 do {
668                         g_wlan.hif_func.hif_read_reg(1, &reg);
669                         /* Set bit 1 */
670                         g_wlan.hif_func.hif_write_reg(1, reg | (1 << 1));
671
672                         /* Clear bit 1*/
673                         g_wlan.hif_func.hif_write_reg(1, reg & ~(1 << 1));
674
675                         do {
676                                 /* Wait for the chip to stabilize*/
677                                 usleep_range(2 * 1000, 2 * 1000);
678                                 /* Make sure chip is awake. This is an extra step that can be removed */
679                                 /* later to avoid the bus access overhead */
680                                 if ((wilc_get_chipid(true) == 0)) {
681                                         wilc_debug(N_ERR, "Couldn't read chip id. Wake up failed\n");
682                                 }
683                         } while ((wilc_get_chipid(true) == 0) && ((++trials % 3) == 0));
684
685                 } while (wilc_get_chipid(true) == 0);
686         } else if ((g_wlan.io_func.io_type & 0x1) == HIF_SDIO)   {
687                 g_wlan.hif_func.hif_read_reg(0xf0, &reg);
688                 do {
689                         /* Set bit 1 */
690                         g_wlan.hif_func.hif_write_reg(0xf0, reg | (1 << 0));
691
692                         /* Check the clock status */
693                         g_wlan.hif_func.hif_read_reg(0xf1, &clk_status_reg);
694
695                         /* in case of clocks off, wait 2ms, and check it again. */
696                         /* if still off, wait for another 2ms, for a total wait of 6ms. */
697                         /* If still off, redo the wake up sequence */
698                         while (((clk_status_reg & 0x1) == 0) && (((++trials) % 3) == 0)) {
699                                 /* Wait for the chip to stabilize*/
700                                 usleep_range(2 * 1000, 2 * 1000);
701
702                                 /* Make sure chip is awake. This is an extra step that can be removed */
703                                 /* later to avoid the bus access overhead */
704                                 g_wlan.hif_func.hif_read_reg(0xf1, &clk_status_reg);
705
706                                 if ((clk_status_reg & 0x1) == 0) {
707                                         wilc_debug(N_ERR, "clocks still OFF. Wake up failed\n");
708                                 }
709                         }
710                         /* in case of failure, Reset the wakeup bit to introduce a new edge on the next loop */
711                         if ((clk_status_reg & 0x1) == 0) {
712                                 /* Reset bit 0 */
713                                 g_wlan.hif_func.hif_write_reg(0xf0, reg & (~(1 << 0)));
714                         }
715                 } while ((clk_status_reg & 0x1) == 0);
716         }
717
718
719         if (genuChipPSstate == CHIP_SLEEPING_MANUAL) {
720                 g_wlan.hif_func.hif_read_reg(0x1C0C, &reg);
721                 reg &= ~(1 << 0);
722                 g_wlan.hif_func.hif_write_reg(0x1C0C, reg);
723
724                 if (wilc_get_chipid(false) >= 0x1002b0) {
725                         /* Enable PALDO back right after wakeup */
726                         u32 val32;
727
728                         g_wlan.hif_func.hif_read_reg(0x1e1c, &val32);
729                         val32 |= (1 << 6);
730                         g_wlan.hif_func.hif_write_reg(0x1e1c, val32);
731
732                         g_wlan.hif_func.hif_read_reg(0x1e9c, &val32);
733                         val32 |= (1 << 6);
734                         g_wlan.hif_func.hif_write_reg(0x1e9c, val32);
735                 }
736         }
737         genuChipPSstate = CHIP_WAKEDUP;
738 }
739 #else
740 static inline void chip_wakeup(void)
741 {
742         u32 reg, trials = 0;
743
744         do {
745                 if ((g_wlan.io_func.io_type & 0x1) == HIF_SPI) {
746                         g_wlan.hif_func.hif_read_reg(1, &reg);
747                         /* Make sure bit 1 is 0 before we start. */
748                         g_wlan.hif_func.hif_write_reg(1, reg & ~(1 << 1));
749                         /* Set bit 1 */
750                         g_wlan.hif_func.hif_write_reg(1, reg | (1 << 1));
751                         /* Clear bit 1*/
752                         g_wlan.hif_func.hif_write_reg(1, reg  & ~(1 << 1));
753                 } else if ((g_wlan.io_func.io_type & 0x1) == HIF_SDIO)   {
754                         /* Make sure bit 0 is 0 before we start. */
755                         g_wlan.hif_func.hif_read_reg(0xf0, &reg);
756                         g_wlan.hif_func.hif_write_reg(0xf0, reg & ~(1 << 0));
757                         /* Set bit 1 */
758                         g_wlan.hif_func.hif_write_reg(0xf0, reg | (1 << 0));
759                         /* Clear bit 1 */
760                         g_wlan.hif_func.hif_write_reg(0xf0, reg  & ~(1 << 0));
761                 }
762
763                 do {
764                         /* Wait for the chip to stabilize*/
765                         mdelay(3);
766
767                         /* Make sure chip is awake. This is an extra step that can be removed */
768                         /* later to avoid the bus access overhead */
769                         if ((wilc_get_chipid(true) == 0)) {
770                                 wilc_debug(N_ERR, "Couldn't read chip id. Wake up failed\n");
771                         }
772                 } while ((wilc_get_chipid(true) == 0) && ((++trials % 3) == 0));
773
774         } while (wilc_get_chipid(true) == 0);
775
776         if (genuChipPSstate == CHIP_SLEEPING_MANUAL) {
777                 g_wlan.hif_func.hif_read_reg(0x1C0C, &reg);
778                 reg &= ~(1 << 0);
779                 g_wlan.hif_func.hif_write_reg(0x1C0C, reg);
780
781                 if (wilc_get_chipid(false) >= 0x1002b0) {
782                         /* Enable PALDO back right after wakeup */
783                         u32 val32;
784
785                         g_wlan.hif_func.hif_read_reg(0x1e1c, &val32);
786                         val32 |= (1 << 6);
787                         g_wlan.hif_func.hif_write_reg(0x1e1c, val32);
788
789                         g_wlan.hif_func.hif_read_reg(0x1e9c, &val32);
790                         val32 |= (1 << 6);
791                         g_wlan.hif_func.hif_write_reg(0x1e9c, val32);
792                 }
793         }
794         genuChipPSstate = CHIP_WAKEDUP;
795 }
796 #endif
797 void chip_sleep_manually(u32 u32SleepTime)
798 {
799         if (genuChipPSstate != CHIP_WAKEDUP) {
800                 /* chip is already sleeping. Do nothing */
801                 return;
802         }
803         acquire_bus(ACQUIRE_ONLY);
804
805 #ifdef WILC_OPTIMIZE_SLEEP_INT
806         chip_allow_sleep();
807 #endif
808
809         /* Trigger the manual sleep interrupt */
810         g_wlan.hif_func.hif_write_reg(0x10a8, 1);
811
812         genuChipPSstate = CHIP_SLEEPING_MANUAL;
813         release_bus(RELEASE_ONLY);
814
815 }
816
817
818 /********************************************
819  *
820  *      Tx, Rx queue handle functions
821  *
822  ********************************************/
823 static int wilc_wlan_handle_txq(u32 *pu32TxqCount)
824 {
825         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
826         int i, entries = 0;
827         u32 sum;
828         u32 reg;
829         u8 *txb = p->tx_buffer;
830         u32 offset = 0;
831         int vmm_sz = 0;
832         struct txq_entry_t *tqe;
833         int ret = 0;
834         int counter;
835         int timeout;
836         u32 vmm_table[WILC_VMM_TBL_SIZE];
837
838         p->txq_exit = 0;
839         do {
840                 if (p->quit)
841                         break;
842
843                 p->os_func.os_wait(&g_linux_wlan->txq_add_to_head_cs,
844                                    CFG_PKTS_TIMEOUT);
845 #ifdef  TCP_ACK_FILTER
846                 wilc_wlan_txq_filter_dup_tcp_ack();
847 #endif
848                 /**
849                  *      build the vmm list
850                  **/
851                 PRINT_D(TX_DBG, "Getting the head of the TxQ\n");
852                 tqe = wilc_wlan_txq_get_first();
853                 i = 0;
854                 sum = 0;
855                 do {
856                         /* if ((tqe != NULL) && (i < (8)) && */
857                         /* if ((tqe != NULL) && (i < (WILC_VMM_TBL_SIZE-1)) && */
858                         if ((tqe != NULL) && (i < (WILC_VMM_TBL_SIZE - 1)) /* reserve last entry to 0 */) {
859
860                                 if (tqe->type == WILC_CFG_PKT) {
861                                         vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET;
862                                 }
863                                 else if (tqe->type == WILC_NET_PKT) {
864                                         vmm_sz = ETH_ETHERNET_HDR_OFFSET;
865                                 }
866                                 else {
867                                         vmm_sz = HOST_HDR_OFFSET;
868                                 }
869                                 vmm_sz += tqe->buffer_size;
870                                 PRINT_D(TX_DBG, "VMM Size before alignment = %d\n", vmm_sz);
871                                 if (vmm_sz & 0x3) {                                                                                                     /* has to be word aligned */
872                                         vmm_sz = (vmm_sz + 4) & ~0x3;
873                                 }
874                                 if ((sum + vmm_sz) > LINUX_TX_SIZE) {
875                                         break;
876                                 }
877                                 PRINT_D(TX_DBG, "VMM Size AFTER alignment = %d\n", vmm_sz);
878                                 vmm_table[i] = vmm_sz / 4;                                                                                /* table take the word size */
879                                 PRINT_D(TX_DBG, "VMMTable entry size = %d\n", vmm_table[i]);
880
881                                 if (tqe->type == WILC_CFG_PKT) {
882                                         vmm_table[i] |= (1 << 10);
883                                         PRINT_D(TX_DBG, "VMMTable entry changed for CFG packet = %d\n", vmm_table[i]);
884                                 }
885 #ifdef BIG_ENDIAN
886                                 vmm_table[i] = BYTE_SWAP(vmm_table[i]);
887 #endif
888
889                                 i++;
890                                 sum += vmm_sz;
891                                 PRINT_D(TX_DBG, "sum = %d\n", sum);
892                                 tqe = wilc_wlan_txq_get_next(tqe);
893                         } else {
894                                 break;
895                         }
896                 } while (1);
897
898                 if (i == 0) {           /* nothing in the queue */
899                         PRINT_D(TX_DBG, "Nothing in TX-Q\n");
900                         break;
901                 } else {
902                         PRINT_D(TX_DBG, "Mark the last entry in VMM table - number of previous entries = %d\n", i);
903                         vmm_table[i] = 0x0;     /* mark the last element to 0 */
904                 }
905                 acquire_bus(ACQUIRE_AND_WAKEUP);
906                 counter = 0;
907                 do {
908
909                         ret = p->hif_func.hif_read_reg(WILC_HOST_TX_CTRL, &reg);
910                         if (!ret) {
911                                 wilc_debug(N_ERR, "[wilc txq]: fail can't read reg vmm_tbl_entry..\n");
912                                 break;
913                         }
914
915                         if ((reg & 0x1) == 0) {
916                                 /**
917                                  *      write to vmm table
918                                  **/
919                                 PRINT_D(TX_DBG, "Writing VMM table ... with Size = %d\n", ((i + 1) * 4));
920                                 break;
921                         } else {
922                                 counter++;
923                                 if (counter > 200) {
924                                         counter = 0;
925                                         PRINT_D(TX_DBG, "Looping in tx ctrl , forcce quit\n");
926                                         ret = p->hif_func.hif_write_reg(WILC_HOST_TX_CTRL, 0);
927                                         break;
928                                 }
929                                 /**
930                                  *      wait for vmm table is ready
931                                  **/
932                                 PRINT_WRN(GENERIC_DBG, "[wilc txq]: warn, vmm table not clear yet, wait...\n");
933                                 release_bus(RELEASE_ALLOW_SLEEP);
934                                 usleep_range(3000, 3000);
935                                 acquire_bus(ACQUIRE_AND_WAKEUP);
936                         }
937                 } while (!p->quit);
938
939                 if (!ret) {
940                         goto _end_;
941                 }
942
943                 timeout = 200;
944                 do {
945
946                         /**
947                          * write to vmm table
948                          **/
949                         ret = p->hif_func.hif_block_tx(WILC_VMM_TBL_RX_SHADOW_BASE, (u8 *)vmm_table, ((i + 1) * 4));
950                         if (!ret) {
951                                 wilc_debug(N_ERR, "ERR block TX of VMM table.\n");
952                                 break;
953                         }
954
955
956                         /**
957                          * interrupt firmware
958                          **/
959                         ret = p->hif_func.hif_write_reg(WILC_HOST_VMM_CTL, 0x2);
960                         if (!ret) {
961                                 wilc_debug(N_ERR, "[wilc txq]: fail can't write reg host_vmm_ctl..\n");
962                                 break;
963                         }
964
965                         /**
966                          *      wait for confirm...
967                          **/
968
969                         do {
970                                 ret = p->hif_func.hif_read_reg(WILC_HOST_VMM_CTL, &reg);
971                                 if (!ret) {
972                                         wilc_debug(N_ERR, "[wilc txq]: fail can't read reg host_vmm_ctl..\n");
973                                         break;
974                                 }
975                                 if ((reg >> 2) & 0x1) {
976                                         /**
977                                          *      Get the entries
978                                          **/
979                                         entries = ((reg >> 3) & 0x3f);
980                                         /* entries = ((reg>>3)&0x2f); */
981                                         break;
982                                 } else {
983                                         release_bus(RELEASE_ALLOW_SLEEP);
984                                         usleep_range(3000, 3000);
985                                         acquire_bus(ACQUIRE_AND_WAKEUP);
986                                         PRINT_WRN(GENERIC_DBG, "Can't get VMM entery - reg = %2x\n", reg);
987                                 }
988                         } while (--timeout);
989                         if (timeout <= 0) {
990                                 ret = p->hif_func.hif_write_reg(WILC_HOST_VMM_CTL, 0x0);
991                                 break;
992                         }
993
994                         if (!ret) {
995                                 break;
996                         }
997
998                         if (entries == 0) {
999                                 PRINT_WRN(GENERIC_DBG, "[wilc txq]: no more buffer in the chip (reg: %08x), retry later [[ %d, %x ]]\n", reg, i, vmm_table[i - 1]);
1000
1001                                 /* undo the transaction. */
1002                                 ret = p->hif_func.hif_read_reg(WILC_HOST_TX_CTRL, &reg);
1003                                 if (!ret) {
1004                                         wilc_debug(N_ERR, "[wilc txq]: fail can't read reg WILC_HOST_TX_CTRL..\n");
1005                                         break;
1006                                 }
1007                                 reg &= ~(1ul << 0);
1008                                 ret = p->hif_func.hif_write_reg(WILC_HOST_TX_CTRL, reg);
1009                                 if (!ret) {
1010                                         wilc_debug(N_ERR, "[wilc txq]: fail can't write reg WILC_HOST_TX_CTRL..\n");
1011                                         break;
1012                                 }
1013                                 break;
1014                         } else {
1015                                 break;
1016                         }
1017                 } while (1);
1018
1019                 if (!ret) {
1020                         goto _end_;
1021                 }
1022                 if (entries == 0) {
1023                         ret = WILC_TX_ERR_NO_BUF;
1024                         goto _end_;
1025                 }
1026
1027                 /* since copying data into txb takes some time, then
1028                  * allow the bus lock to be released let the RX task go. */
1029                 release_bus(RELEASE_ALLOW_SLEEP);
1030
1031                 /**
1032                  *      Copy data to the TX buffer
1033                  **/
1034                 offset = 0;
1035                 i = 0;
1036                 do {
1037                         tqe = wilc_wlan_txq_remove_from_head();
1038                         if (tqe != NULL && (vmm_table[i] != 0)) {
1039                                 u32 header, buffer_offset;
1040
1041 #ifdef BIG_ENDIAN
1042                                 vmm_table[i] = BYTE_SWAP(vmm_table[i]);
1043 #endif
1044                                 vmm_sz = (vmm_table[i] & 0x3ff);        /* in word unit */
1045                                 vmm_sz *= 4;
1046                                 header = (tqe->type << 31) | (tqe->buffer_size << 15) | vmm_sz;
1047                                 if (tqe->type == WILC_MGMT_PKT)
1048                                         header |= (1 << 30);
1049                                 else
1050                                         header &= ~(1 << 30);
1051
1052 #ifdef BIG_ENDIAN
1053                                 header = BYTE_SWAP(header);
1054 #endif
1055                                 memcpy(&txb[offset], &header, 4);
1056                                 if (tqe->type == WILC_CFG_PKT) {
1057                                         buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET;
1058                                 }
1059                                 else if (tqe->type == WILC_NET_PKT) {
1060                                         char *pBSSID = ((struct tx_complete_data *)(tqe->priv))->pBssid;
1061
1062                                         buffer_offset = ETH_ETHERNET_HDR_OFFSET;
1063                                         /* copy the bssid at the sart of the buffer */
1064                                         memcpy(&txb[offset + 4], pBSSID, 6);
1065                                 }
1066                                 else {
1067                                         buffer_offset = HOST_HDR_OFFSET;
1068                                 }
1069
1070                                 memcpy(&txb[offset + buffer_offset], tqe->buffer, tqe->buffer_size);
1071                                 offset += vmm_sz;
1072                                 i++;
1073                                 tqe->status = 1;                                /* mark the packet send */
1074                                 if (tqe->tx_complete_func)
1075                                         tqe->tx_complete_func(tqe->priv, tqe->status);
1076                                 #ifdef TCP_ACK_FILTER
1077                                 if (tqe->tcp_PendingAck_index != NOT_TCP_ACK) {
1078                                         Pending_Acks_info[tqe->tcp_PendingAck_index].txqe = NULL;
1079                                 }
1080                                 #endif
1081                                 kfree(tqe);
1082                         } else {
1083                                 break;
1084                         }
1085                 } while (--entries);
1086
1087                 /**
1088                  *      lock the bus
1089                  **/
1090                 acquire_bus(ACQUIRE_AND_WAKEUP);
1091
1092                 ret = p->hif_func.hif_clear_int_ext(ENABLE_TX_VMM);
1093                 if (!ret) {
1094                         wilc_debug(N_ERR, "[wilc txq]: fail can't start tx VMM ...\n");
1095                         goto _end_;
1096                 }
1097
1098                 /**
1099                  *      transfer
1100                  **/
1101                 ret = p->hif_func.hif_block_tx_ext(0, txb, offset);
1102                 if (!ret) {
1103                         wilc_debug(N_ERR, "[wilc txq]: fail can't block tx ext...\n");
1104                         goto _end_;
1105                 }
1106
1107 _end_:
1108
1109                 release_bus(RELEASE_ALLOW_SLEEP);
1110                 if (ret != 1)
1111                         break;
1112         } while (0);
1113         up(&g_linux_wlan->txq_add_to_head_cs);
1114
1115         p->txq_exit = 1;
1116         PRINT_D(TX_DBG, "THREAD: Exiting txq\n");
1117         /* return tx[]q count */
1118         *pu32TxqCount = p->txq_entries;
1119         return ret;
1120 }
1121
1122 static void wilc_wlan_handle_rxq(void)
1123 {
1124         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
1125         int offset = 0, size, has_packet = 0;
1126         u8 *buffer;
1127         struct rxq_entry_t *rqe;
1128
1129         p->rxq_exit = 0;
1130
1131
1132
1133
1134         do {
1135                 if (p->quit) {
1136                         PRINT_D(RX_DBG, "exit 1st do-while due to Clean_UP function\n");
1137                         up(&g_linux_wlan->cfg_event);
1138                         break;
1139                 }
1140                 rqe = wilc_wlan_rxq_remove();
1141                 if (rqe == NULL) {
1142                         PRINT_D(RX_DBG, "nothing in the queue - exit 1st do-while\n");
1143                         break;
1144                 }
1145                 buffer = rqe->buffer;
1146                 size = rqe->buffer_size;
1147                 PRINT_D(RX_DBG, "rxQ entery Size = %d - Address = %p\n", size, buffer);
1148                 offset = 0;
1149
1150
1151
1152                 do {
1153                         u32 header;
1154                         u32 pkt_len, pkt_offset, tp_len;
1155                         int is_cfg_packet;
1156
1157                         PRINT_D(RX_DBG, "In the 2nd do-while\n");
1158                         memcpy(&header, &buffer[offset], 4);
1159 #ifdef BIG_ENDIAN
1160                         header = BYTE_SWAP(header);
1161 #endif
1162                         PRINT_D(RX_DBG, "Header = %04x - Offset = %d\n", header, offset);
1163
1164
1165
1166                         is_cfg_packet = (header >> 31) & 0x1;
1167                         pkt_offset = (header >> 22) & 0x1ff;
1168                         tp_len = (header >> 11) & 0x7ff;
1169                         pkt_len = header & 0x7ff;
1170
1171                         if (pkt_len == 0 || tp_len == 0) {
1172                                 wilc_debug(N_RXQ, "[wilc rxq]: data corrupt, packet len or tp_len is 0 [%d][%d]\n", pkt_len, tp_len);
1173                                 break;
1174                         }
1175
1176 /*bug 3887: [AP] Allow Management frames to be passed to the host*/
1177                         #define IS_MANAGMEMENT                          0x100
1178                         #define IS_MANAGMEMENT_CALLBACK                 0x080
1179                         #define IS_MGMT_STATUS_SUCCES                   0x040
1180
1181
1182                         if (pkt_offset & IS_MANAGMEMENT) {
1183                                 /* reset mgmt indicator bit, to use pkt_offeset in furthur calculations */
1184                                 pkt_offset &= ~(IS_MANAGMEMENT | IS_MANAGMEMENT_CALLBACK | IS_MGMT_STATUS_SUCCES);
1185
1186                                 WILC_WFI_mgmt_rx(&buffer[offset + HOST_HDR_OFFSET], pkt_len);
1187                         }
1188                         /* BUG4530 fix */
1189                         else
1190                         {
1191
1192                                 if (!is_cfg_packet) {
1193                                         if (pkt_len > 0) {
1194                                                 frmw_to_linux(&buffer[offset],
1195                                                               pkt_len,
1196                                                               pkt_offset);
1197                                                 has_packet = 1;
1198                                         }
1199                                 } else {
1200                                         wilc_cfg_rsp_t rsp;
1201
1202
1203
1204                                         p->cif_func.rx_indicate(&buffer[pkt_offset + offset], pkt_len, &rsp);
1205                                         if (rsp.type == WILC_CFG_RSP) {
1206                                                 /**
1207                                                  *      wake up the waiting task...
1208                                                  **/
1209                                                 PRINT_D(RX_DBG, "p->cfg_seq_no = %d - rsp.seq_no = %d\n", p->cfg_seq_no, rsp.seq_no);
1210                                                 if (p->cfg_seq_no == rsp.seq_no) {
1211                                                         up(&g_linux_wlan->cfg_event);
1212                                                 }
1213                                         } else if (rsp.type == WILC_CFG_RSP_STATUS) {
1214                                                 /**
1215                                                  *      Call back to indicate status...
1216                                                  **/
1217                                                 linux_wlan_mac_indicate(WILC_MAC_INDICATE_STATUS);
1218
1219                                         } else if (rsp.type == WILC_CFG_RSP_SCAN) {
1220                                                 linux_wlan_mac_indicate(WILC_MAC_INDICATE_SCAN);
1221                                         }
1222                                 }
1223                         }
1224                         offset += tp_len;
1225                         if (offset >= size)
1226                                 break;
1227                 } while (1);
1228
1229
1230 #ifndef MEMORY_STATIC
1231                 kfree(buffer);
1232 #endif
1233                 kfree(rqe);
1234
1235                 if (has_packet) {
1236                         linux_wlan_rx_complete();
1237                 }
1238         } while (1);
1239
1240         p->rxq_exit = 1;
1241         PRINT_D(RX_DBG, "THREAD: Exiting RX thread\n");
1242 }
1243
1244 /********************************************
1245  *
1246  *      Fast DMA Isr
1247  *
1248  ********************************************/
1249 static void wilc_unknown_isr_ext(void)
1250 {
1251         g_wlan.hif_func.hif_clear_int_ext(0);
1252 }
1253 static void wilc_pllupdate_isr_ext(u32 int_stats)
1254 {
1255
1256         int trials = 10;
1257
1258         g_wlan.hif_func.hif_clear_int_ext(PLL_INT_CLR);
1259
1260         /* Waiting for PLL */
1261         mdelay(WILC_PLL_TO);
1262
1263         /* poll till read a valid data */
1264         while (!(ISWILC1000(wilc_get_chipid(true)) && --trials)) {
1265                 PRINT_D(TX_DBG, "PLL update retrying\n");
1266                 mdelay(1);
1267         }
1268 }
1269
1270 static void wilc_sleeptimer_isr_ext(u32 int_stats1)
1271 {
1272         g_wlan.hif_func.hif_clear_int_ext(SLEEP_INT_CLR);
1273 #ifndef WILC_OPTIMIZE_SLEEP_INT
1274         genuChipPSstate = CHIP_SLEEPING_AUTO;
1275 #endif
1276 }
1277
1278 static void wilc_wlan_handle_isr_ext(u32 int_status)
1279 {
1280         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
1281 #ifdef MEMORY_STATIC
1282         u32 offset = p->rx_buffer_offset;
1283 #endif
1284         u8 *buffer = NULL;
1285         u32 size;
1286         u32 retries = 0;
1287         int ret = 0;
1288         struct rxq_entry_t *rqe;
1289
1290
1291         /**
1292          *      Get the rx size
1293          **/
1294
1295         size = ((int_status & 0x7fff) << 2);
1296
1297         while (!size && retries < 10) {
1298                 u32 time = 0;
1299                 /*looping more secure*/
1300                 /*zero size make a crashe because the dma will not happen and that will block the firmware*/
1301                 wilc_debug(N_ERR, "RX Size equal zero ... Trying to read it again for %d time\n", time++);
1302                 p->hif_func.hif_read_size(&size);
1303                 size = ((size & 0x7fff) << 2);
1304                 retries++;
1305
1306         }
1307
1308         if (size > 0) {
1309 #ifdef MEMORY_STATIC
1310                 if (LINUX_RX_SIZE - offset < size)
1311                         offset = 0;
1312
1313                 if (p->rx_buffer)
1314                         buffer = &p->rx_buffer[offset];
1315                 else {
1316                         wilc_debug(N_ERR, "[wilc isr]: fail Rx Buffer is NULL...drop the packets (%d)\n", size);
1317                         goto _end_;
1318                 }
1319
1320 #else
1321                 buffer = kmalloc(size, GFP_KERNEL);
1322                 if (buffer == NULL) {
1323                         wilc_debug(N_ERR, "[wilc isr]: fail alloc host memory...drop the packets (%d)\n", size);
1324                         usleep_range(100 * 1000, 100 * 1000);
1325                         goto _end_;
1326                 }
1327 #endif
1328
1329                 /**
1330                  *      clear the chip's interrupt       after getting size some register getting corrupted after clear the interrupt
1331                  **/
1332                 p->hif_func.hif_clear_int_ext(DATA_INT_CLR | ENABLE_RX_VMM);
1333
1334
1335                 /**
1336                  * start transfer
1337                  **/
1338                 ret = p->hif_func.hif_block_rx_ext(0, buffer, size);
1339
1340                 if (!ret) {
1341                         wilc_debug(N_ERR, "[wilc isr]: fail block rx...\n");
1342                         goto _end_;
1343                 }
1344 _end_:
1345
1346
1347                 if (ret) {
1348 #ifdef MEMORY_STATIC
1349                         offset += size;
1350                         p->rx_buffer_offset = offset;
1351 #endif
1352                         /**
1353                          *      add to rx queue
1354                          **/
1355                         rqe = kmalloc(sizeof(struct rxq_entry_t), GFP_KERNEL);
1356                         if (rqe != NULL) {
1357                                 rqe->buffer = buffer;
1358                                 rqe->buffer_size = size;
1359                                 PRINT_D(RX_DBG, "rxq entery Size= %d - Address = %p\n", rqe->buffer_size, rqe->buffer);
1360                                 wilc_wlan_rxq_add(rqe);
1361                         }
1362                 } else {
1363 #ifndef MEMORY_STATIC
1364                         kfree(buffer);
1365 #endif
1366                 }
1367         }
1368         wilc_wlan_handle_rxq();
1369 }
1370
1371 void wilc_handle_isr(void)
1372 {
1373         u32 int_status;
1374
1375         acquire_bus(ACQUIRE_AND_WAKEUP);
1376         g_wlan.hif_func.hif_read_int(&int_status);
1377
1378         if (int_status & PLL_INT_EXT) {
1379                 wilc_pllupdate_isr_ext(int_status);
1380         }
1381         if (int_status & DATA_INT_EXT) {
1382                 wilc_wlan_handle_isr_ext(int_status);
1383         #ifndef WILC_OPTIMIZE_SLEEP_INT
1384                 /* Chip is up and talking*/
1385                 genuChipPSstate = CHIP_WAKEDUP;
1386         #endif
1387         }
1388         if (int_status & SLEEP_INT_EXT) {
1389                 wilc_sleeptimer_isr_ext(int_status);
1390         }
1391
1392         if (!(int_status & (ALL_INT_EXT))) {
1393 #ifdef WILC_SDIO
1394                 PRINT_D(TX_DBG, ">> UNKNOWN_INTERRUPT - 0x%08x\n", int_status);
1395 #endif
1396                 wilc_unknown_isr_ext();
1397         }
1398         release_bus(RELEASE_ALLOW_SLEEP);
1399 }
1400
1401 /********************************************
1402  *
1403  *      Firmware download
1404  *
1405  ********************************************/
1406 static int wilc_wlan_firmware_download(const u8 *buffer, u32 buffer_size)
1407 {
1408         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
1409         u32 offset;
1410         u32 addr, size, size2, blksz;
1411         u8 *dma_buffer;
1412         int ret = 0;
1413
1414         blksz = (1ul << 12);
1415         /* Allocate a DMA coherent  buffer. */
1416
1417         dma_buffer = kmalloc(blksz, GFP_KERNEL);
1418         if (dma_buffer == NULL) {
1419                 /*EIO   5*/
1420                 ret = -5;
1421                 PRINT_ER("Can't allocate buffer for firmware download IO error\n ");
1422                 goto _fail_1;
1423         }
1424
1425         PRINT_D(INIT_DBG, "Downloading firmware size = %d ...\n", buffer_size);
1426         /**
1427          *      load the firmware
1428          **/
1429         offset = 0;
1430         do {
1431                 memcpy(&addr, &buffer[offset], 4);
1432                 memcpy(&size, &buffer[offset + 4], 4);
1433 #ifdef BIG_ENDIAN
1434                 addr = BYTE_SWAP(addr);
1435                 size = BYTE_SWAP(size);
1436 #endif
1437                 acquire_bus(ACQUIRE_ONLY);
1438                 offset += 8;
1439                 while (((int)size) && (offset < buffer_size)) {
1440                         if (size <= blksz)
1441                                 size2 = size;
1442                         else
1443                                 size2 = blksz;
1444                         /* Copy firmware into a DMA coherent buffer */
1445                         memcpy(dma_buffer, &buffer[offset], size2);
1446                         ret = p->hif_func.hif_block_tx(addr, dma_buffer, size2);
1447                         if (!ret)
1448                                 break;
1449
1450                         addr += size2;
1451                         offset += size2;
1452                         size -= size2;
1453                 }
1454                 release_bus(RELEASE_ONLY);
1455
1456                 if (!ret) {
1457                         /*EIO   5*/
1458                         ret = -5;
1459                         PRINT_ER("Can't download firmware IO error\n ");
1460                         goto _fail_;
1461                 }
1462                 PRINT_D(INIT_DBG, "Offset = %d\n", offset);
1463         } while (offset < buffer_size);
1464
1465 _fail_:
1466
1467         kfree(dma_buffer);
1468
1469 _fail_1:
1470
1471         return (ret < 0) ? ret : 0;
1472 }
1473
1474 /********************************************
1475  *
1476  *      Common
1477  *
1478  ********************************************/
1479 static int wilc_wlan_start(void)
1480 {
1481         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
1482         u32 reg = 0;
1483         int ret;
1484         u32 chipid;
1485
1486         /**
1487          *      Set the host interface
1488          **/
1489         if (p->io_func.io_type == HIF_SDIO) {
1490                 reg = 0;
1491                 reg |= (1 << 3); /* bug 4456 and 4557 */
1492         } else if (p->io_func.io_type == HIF_SPI) {
1493                 reg = 1;
1494         }
1495         acquire_bus(ACQUIRE_ONLY);
1496         ret = p->hif_func.hif_write_reg(WILC_VMM_CORE_CFG, reg);
1497         if (!ret) {
1498                 wilc_debug(N_ERR, "[wilc start]: fail write reg vmm_core_cfg...\n");
1499                 release_bus(RELEASE_ONLY);
1500                 /* EIO  5*/
1501                 ret = -5;
1502                 return ret;
1503         }
1504         reg = 0;
1505 #ifdef WILC_SDIO_IRQ_GPIO
1506         reg |= WILC_HAVE_SDIO_IRQ_GPIO;
1507 #endif
1508
1509 #ifdef WILC_DISABLE_PMU
1510 #else
1511         reg |= WILC_HAVE_USE_PMU;
1512 #endif
1513
1514 #ifdef WILC_SLEEP_CLK_SRC_XO
1515         reg |= WILC_HAVE_SLEEP_CLK_SRC_XO;
1516 #elif defined WILC_SLEEP_CLK_SRC_RTC
1517         reg |= WILC_HAVE_SLEEP_CLK_SRC_RTC;
1518 #endif
1519
1520 #ifdef WILC_EXT_PA_INV_TX_RX
1521         reg |= WILC_HAVE_EXT_PA_INV_TX_RX;
1522 #endif
1523
1524         reg |= WILC_HAVE_LEGACY_RF_SETTINGS;
1525
1526
1527 /*Set oscillator frequency*/
1528 #ifdef XTAL_24
1529         reg |= WILC_HAVE_XTAL_24;
1530 #endif
1531
1532 /*Enable/Disable GPIO configuration for FW logs*/
1533 #ifdef DISABLE_WILC_UART
1534         reg |= WILC_HAVE_DISABLE_WILC_UART;
1535 #endif
1536
1537         ret = p->hif_func.hif_write_reg(WILC_GP_REG_1, reg);
1538         if (!ret) {
1539                 wilc_debug(N_ERR, "[wilc start]: fail write WILC_GP_REG_1 ...\n");
1540                 release_bus(RELEASE_ONLY);
1541                 /* EIO  5*/
1542                 ret = -5;
1543                 return ret;
1544         }
1545
1546         /**
1547          *      Bus related
1548          **/
1549         p->hif_func.hif_sync_ext(NUM_INT_EXT);
1550
1551         ret = p->hif_func.hif_read_reg(0x1000, &chipid);
1552         if (!ret) {
1553                 wilc_debug(N_ERR, "[wilc start]: fail read reg 0x1000 ...\n");
1554                 release_bus(RELEASE_ONLY);
1555                 /* EIO  5*/
1556                 ret = -5;
1557                 return ret;
1558         }
1559
1560         /**
1561          *      Go...
1562          **/
1563
1564
1565         p->hif_func.hif_read_reg(WILC_GLB_RESET_0, &reg);
1566         if ((reg & (1ul << 10)) == (1ul << 10)) {
1567                 reg &= ~(1ul << 10);
1568                 p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg);
1569                 p->hif_func.hif_read_reg(WILC_GLB_RESET_0, &reg);
1570         }
1571
1572         reg |= (1ul << 10);
1573         ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg);
1574         p->hif_func.hif_read_reg(WILC_GLB_RESET_0, &reg);
1575         release_bus(RELEASE_ONLY);
1576
1577         return (ret < 0) ? ret : 0;
1578 }
1579
1580 void wilc_wlan_global_reset(void)
1581 {
1582
1583         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
1584
1585         acquire_bus(ACQUIRE_AND_WAKEUP);
1586         p->hif_func.hif_write_reg(WILC_GLB_RESET_0, 0x0);
1587         release_bus(RELEASE_ONLY);
1588 }
1589 static int wilc_wlan_stop(void)
1590 {
1591         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
1592         u32 reg = 0;
1593         int ret;
1594         u8 timeout = 10;
1595         /**
1596          *      TODO: stop the firmware, need a re-download
1597          **/
1598         acquire_bus(ACQUIRE_AND_WAKEUP);
1599
1600         ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, &reg);
1601         if (!ret) {
1602                 PRINT_ER("Error while reading reg\n");
1603                 release_bus(RELEASE_ALLOW_SLEEP);
1604                 return ret;
1605         }
1606
1607         reg &= ~(1 << 10);
1608
1609
1610         ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg);
1611         if (!ret) {
1612                 PRINT_ER("Error while writing reg\n");
1613                 release_bus(RELEASE_ALLOW_SLEEP);
1614                 return ret;
1615         }
1616
1617
1618
1619         do {
1620                 ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, &reg);
1621                 if (!ret) {
1622                         PRINT_ER("Error while reading reg\n");
1623                         release_bus(RELEASE_ALLOW_SLEEP);
1624                         return ret;
1625                 }
1626                 PRINT_D(GENERIC_DBG, "Read RESET Reg %x : Retry%d\n", reg, timeout);
1627                 /*Workaround to ensure that the chip is actually reset*/
1628                 if ((reg & (1 << 10))) {
1629                         PRINT_D(GENERIC_DBG, "Bit 10 not reset : Retry %d\n", timeout);
1630                         reg &= ~(1 << 10);
1631                         ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg);
1632                         timeout--;
1633                 } else {
1634                         PRINT_D(GENERIC_DBG, "Bit 10 reset after : Retry %d\n", timeout);
1635                         ret = p->hif_func.hif_read_reg(WILC_GLB_RESET_0, &reg);
1636                         if (!ret) {
1637                                 PRINT_ER("Error while reading reg\n");
1638                                 release_bus(RELEASE_ALLOW_SLEEP);
1639                                 return ret;
1640                         }
1641                         PRINT_D(GENERIC_DBG, "Read RESET Reg %x : Retry%d\n", reg, timeout);
1642                         break;
1643                 }
1644
1645         } while (timeout);
1646         reg = ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 8) | (1 << 9) | (1 << 26) | (1 << 29) | (1 << 30) | (1 << 31)); /**/
1647         /**/
1648         p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg);                                 /**/
1649         reg = ~(1 << 10);                                                                                               /**/
1650         /**/
1651         ret = p->hif_func.hif_write_reg(WILC_GLB_RESET_0, reg);                                 /**/
1652 /******************************************************************************/
1653
1654         release_bus(RELEASE_ALLOW_SLEEP);
1655
1656         return ret;
1657 }
1658
1659 static void wilc_wlan_cleanup(void)
1660 {
1661         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
1662         struct txq_entry_t *tqe;
1663         struct rxq_entry_t *rqe;
1664         u32 reg = 0;
1665         int ret;
1666
1667         p->quit = 1;
1668         do {
1669                 tqe = wilc_wlan_txq_remove_from_head();
1670                 if (tqe == NULL)
1671                         break;
1672                 if (tqe->tx_complete_func)
1673                         tqe->tx_complete_func(tqe->priv, 0);
1674                 kfree(tqe);
1675         } while (1);
1676
1677         do {
1678                 rqe = wilc_wlan_rxq_remove();
1679                 if (rqe == NULL)
1680                         break;
1681 #ifndef MEMORY_STATIC
1682                 kfree(rqe->buffer);
1683 #endif
1684                 kfree(rqe);
1685         } while (1);
1686
1687         /**
1688          *      clean up buffer
1689          **/
1690
1691         #ifdef MEMORY_STATIC
1692         kfree(p->rx_buffer);
1693         p->rx_buffer = NULL;
1694         #endif
1695         kfree(p->tx_buffer);
1696
1697         acquire_bus(ACQUIRE_AND_WAKEUP);
1698
1699
1700         ret = p->hif_func.hif_read_reg(WILC_GP_REG_0, &reg);
1701         if (!ret) {
1702                 PRINT_ER("Error while reading reg\n");
1703                 release_bus(RELEASE_ALLOW_SLEEP);
1704         }
1705         PRINT_ER("Writing ABORT reg\n");
1706         ret = p->hif_func.hif_write_reg(WILC_GP_REG_0, (reg | ABORT_INT));
1707         if (!ret) {
1708                 PRINT_ER("Error while writing reg\n");
1709                 release_bus(RELEASE_ALLOW_SLEEP);
1710         }
1711         release_bus(RELEASE_ALLOW_SLEEP);
1712         /**
1713          *      io clean up
1714          **/
1715         p->hif_func.hif_deinit(NULL);
1716
1717 }
1718
1719 static int wilc_wlan_cfg_commit(int type, u32 drvHandler)
1720 {
1721         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
1722         wilc_cfg_frame_t *cfg = &p->cfg_frame;
1723         int total_len = p->cfg_frame_offset + 4 + DRIVER_HANDLER_SIZE;
1724         int seq_no = p->cfg_seq_no % 256;
1725         int driver_handler = (u32)drvHandler;
1726
1727
1728         /**
1729          *      Set up header
1730          **/
1731         if (type == WILC_CFG_SET) {             /* Set */
1732                 cfg->wid_header[0] = 'W';
1733         } else {                                        /* Query */
1734                 cfg->wid_header[0] = 'Q';
1735         }
1736         cfg->wid_header[1] = seq_no;    /* sequence number */
1737         cfg->wid_header[2] = (u8)total_len;
1738         cfg->wid_header[3] = (u8)(total_len >> 8);
1739         cfg->wid_header[4] = (u8)driver_handler;
1740         cfg->wid_header[5] = (u8)(driver_handler >> 8);
1741         cfg->wid_header[6] = (u8)(driver_handler >> 16);
1742         cfg->wid_header[7] = (u8)(driver_handler >> 24);
1743         p->cfg_seq_no = seq_no;
1744
1745         /**
1746          *      Add to TX queue
1747          **/
1748
1749         if (!wilc_wlan_txq_add_cfg_pkt(&cfg->wid_header[0], total_len))
1750                 return -1;
1751
1752         return 0;
1753 }
1754
1755 static int wilc_wlan_cfg_set(int start, u32 wid, u8 *buffer, u32 buffer_size, int commit, u32 drvHandler)
1756 {
1757         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
1758         u32 offset;
1759         int ret_size;
1760
1761
1762         if (p->cfg_frame_in_use)
1763                 return 0;
1764
1765         if (start)
1766                 p->cfg_frame_offset = 0;
1767
1768         offset = p->cfg_frame_offset;
1769         ret_size = p->cif_func.cfg_wid_set(p->cfg_frame.frame, offset, (u16)wid, buffer, buffer_size);
1770         offset += ret_size;
1771         p->cfg_frame_offset = offset;
1772
1773         if (commit) {
1774                 PRINT_D(TX_DBG, "[WILC]PACKET Commit with sequence number %d\n", p->cfg_seq_no);
1775                 PRINT_D(RX_DBG, "Processing cfg_set()\n");
1776                 p->cfg_frame_in_use = 1;
1777
1778                 if (wilc_wlan_cfg_commit(WILC_CFG_SET, drvHandler))
1779                         ret_size = 0;
1780
1781                 if (p->os_func.os_wait(&g_linux_wlan->cfg_event,
1782                                        CFG_PKTS_TIMEOUT)) {
1783                         PRINT_D(TX_DBG, "Set Timed Out\n");
1784                         ret_size = 0;
1785                 }
1786                 p->cfg_frame_in_use = 0;
1787                 p->cfg_frame_offset = 0;
1788                 p->cfg_seq_no += 1;
1789
1790         }
1791
1792         return ret_size;
1793 }
1794 static int wilc_wlan_cfg_get(int start, u32 wid, int commit, u32 drvHandler)
1795 {
1796         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
1797         u32 offset;
1798         int ret_size;
1799
1800
1801         if (p->cfg_frame_in_use)
1802                 return 0;
1803
1804         if (start)
1805                 p->cfg_frame_offset = 0;
1806
1807         offset = p->cfg_frame_offset;
1808         ret_size = p->cif_func.cfg_wid_get(p->cfg_frame.frame, offset, (u16)wid);
1809         offset += ret_size;
1810         p->cfg_frame_offset = offset;
1811
1812         if (commit) {
1813                 p->cfg_frame_in_use = 1;
1814
1815                 if (wilc_wlan_cfg_commit(WILC_CFG_QUERY, drvHandler))
1816                         ret_size = 0;
1817
1818
1819                 if (p->os_func.os_wait(&g_linux_wlan->cfg_event,
1820                                        CFG_PKTS_TIMEOUT)) {
1821                         PRINT_D(TX_DBG, "Get Timed Out\n");
1822                         ret_size = 0;
1823                 }
1824                 PRINT_D(GENERIC_DBG, "[WILC]Get Response received\n");
1825                 p->cfg_frame_in_use = 0;
1826                 p->cfg_frame_offset = 0;
1827                 p->cfg_seq_no += 1;
1828         }
1829
1830         return ret_size;
1831 }
1832
1833 static int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size)
1834 {
1835         wilc_wlan_dev_t *p = (wilc_wlan_dev_t *)&g_wlan;
1836         int ret;
1837
1838         ret = p->cif_func.cfg_wid_get_val((u16)wid, buffer, buffer_size);
1839
1840         return ret;
1841 }
1842
1843 void wilc_bus_set_max_speed(void)
1844 {
1845
1846         /* Increase bus speed to max possible.  */
1847         g_wlan.hif_func.hif_set_max_bus_speed();
1848 }
1849
1850 void wilc_bus_set_default_speed(void)
1851 {
1852
1853         /* Restore bus speed to default.  */
1854         g_wlan.hif_func.hif_set_default_bus_speed();
1855 }
1856 u32 init_chip(void)
1857 {
1858         u32 chipid;
1859         u32 reg, ret = 0;
1860
1861         acquire_bus(ACQUIRE_ONLY);
1862
1863         chipid = wilc_get_chipid(true);
1864
1865
1866
1867         if ((chipid & 0xfff) != 0xa0) {
1868                 /**
1869                  * Avoid booting from boot ROM. Make sure that Drive IRQN [SDIO platform]
1870                  * or SD_DAT3 [SPI platform] to ?1?
1871                  **/
1872                 /* Set cortus reset register to register control. */
1873                 ret = g_wlan.hif_func.hif_read_reg(0x1118, &reg);
1874                 if (!ret) {
1875                         wilc_debug(N_ERR, "[wilc start]: fail read reg 0x1118 ...\n");
1876                         return ret;
1877                 }
1878                 reg |= (1 << 0);
1879                 ret = g_wlan.hif_func.hif_write_reg(0x1118, reg);
1880                 if (!ret) {
1881                         wilc_debug(N_ERR, "[wilc start]: fail write reg 0x1118 ...\n");
1882                         return ret;
1883                 }
1884                 /**
1885                  * Write branch intruction to IRAM (0x71 trap) at location 0xFFFF0000
1886                  * (Cortus map) or C0000 (AHB map).
1887                  **/
1888                 ret = g_wlan.hif_func.hif_write_reg(0xc0000, 0x71);
1889                 if (!ret) {
1890                         wilc_debug(N_ERR, "[wilc start]: fail write reg 0xc0000 ...\n");
1891                         return ret;
1892                 }
1893         }
1894
1895         release_bus(RELEASE_ONLY);
1896
1897         return ret;
1898
1899 }
1900
1901 u32 wilc_get_chipid(u8 update)
1902 {
1903         static u32 chipid;
1904         /* SDIO can't read into global variables */
1905         /* Use this variable as a temp, then copy to the global */
1906         u32 tempchipid = 0;
1907         u32 rfrevid;
1908
1909         if (chipid == 0 || update != 0) {
1910                 g_wlan.hif_func.hif_read_reg(0x1000, &tempchipid);
1911                 g_wlan.hif_func.hif_read_reg(0x13f4, &rfrevid);
1912                 if (!ISWILC1000(tempchipid)) {
1913                         chipid = 0;
1914                         goto _fail_;
1915                 }
1916                 if (tempchipid == 0x1002a0) {
1917                         if (rfrevid == 0x1) { /* 1002A0 */
1918                         } else { /* if (rfrevid == 0x2) */   /* 1002A1 */
1919                                 tempchipid = 0x1002a1;
1920                         }
1921                 } else if (tempchipid == 0x1002b0) {
1922                         if (rfrevid == 3) { /* 1002B0 */
1923                         } else if (rfrevid == 4) { /* 1002B1 */
1924                                 tempchipid = 0x1002b1;
1925                         } else { /* if(rfrevid == 5) */   /* 1002B2 */
1926                                 tempchipid = 0x1002b2;
1927                         }
1928                 } else {
1929                 }
1930
1931                 chipid = tempchipid;
1932         }
1933 _fail_:
1934         return chipid;
1935 }
1936
1937 #ifdef COMPLEMENT_BOOT
1938 u8 core_11b_ready(void)
1939 {
1940         u32 reg_val;
1941
1942         acquire_bus(ACQUIRE_ONLY);
1943         g_wlan.hif_func.hif_write_reg(0x16082c, 1);
1944         g_wlan.hif_func.hif_write_reg(0x161600, 0x90);
1945         g_wlan.hif_func.hif_read_reg(0x161600, &reg_val);
1946         release_bus(RELEASE_ONLY);
1947
1948         if (reg_val == 0x90)
1949                 return 0;
1950         else
1951                 return 1;
1952 }
1953 #endif
1954
1955 int wilc_wlan_init(wilc_wlan_inp_t *inp, wilc_wlan_oup_t *oup)
1956 {
1957
1958         int ret = 0;
1959
1960         PRINT_D(INIT_DBG, "Initializing WILC_Wlan ...\n");
1961
1962         memset((void *)&g_wlan, 0, sizeof(wilc_wlan_dev_t));
1963
1964         /**
1965          *      store the input
1966          **/
1967         memcpy((void *)&g_wlan.os_func, (void *)&inp->os_func, sizeof(wilc_wlan_os_func_t));
1968         memcpy((void *)&g_wlan.io_func, (void *)&inp->io_func, sizeof(wilc_wlan_io_func_t));
1969         g_wlan.txq_lock = inp->os_context.txq_critical_section;
1970         /***
1971          *      host interface init
1972          **/
1973         if ((inp->io_func.io_type & 0x1) == HIF_SDIO) {
1974                 if (!hif_sdio.hif_init(inp, wilc_debug)) {
1975                         /* EIO  5 */
1976                         ret = -5;
1977                         goto _fail_;
1978                 }
1979                 memcpy((void *)&g_wlan.hif_func, &hif_sdio, sizeof(wilc_hif_func_t));
1980         } else {
1981                 if ((inp->io_func.io_type & 0x1) == HIF_SPI) {
1982                         /**
1983                          *      TODO:
1984                          **/
1985                         if (!hif_spi.hif_init(inp, wilc_debug)) {
1986                                 /* EIO  5 */
1987                                 ret = -5;
1988                                 goto _fail_;
1989                         }
1990                         memcpy((void *)&g_wlan.hif_func, &hif_spi, sizeof(wilc_hif_func_t));
1991                 } else {
1992                         /* EIO  5 */
1993                         ret = -5;
1994                         goto _fail_;
1995                 }
1996         }
1997
1998         /***
1999          *      mac interface init
2000          **/
2001         if (!mac_cfg.cfg_init(wilc_debug)) {
2002                 /* ENOBUFS      105 */
2003                 ret = -105;
2004                 goto _fail_;
2005         }
2006         memcpy((void *)&g_wlan.cif_func, &mac_cfg, sizeof(wilc_cfg_func_t));
2007
2008
2009         /**
2010          *      alloc tx, rx buffer
2011          **/
2012         if (g_wlan.tx_buffer == NULL)
2013                 g_wlan.tx_buffer = kmalloc(LINUX_TX_SIZE, GFP_KERNEL);
2014         PRINT_D(TX_DBG, "g_wlan.tx_buffer = %p\n", g_wlan.tx_buffer);
2015
2016         if (g_wlan.tx_buffer == NULL) {
2017                 /* ENOBUFS      105 */
2018                 ret = -105;
2019                 PRINT_ER("Can't allocate Tx Buffer");
2020                 goto _fail_;
2021         }
2022
2023 /* rx_buffer is not used unless we activate USE_MEM STATIC which is not applicable, allocating such memory is useless*/
2024 #if defined (MEMORY_STATIC)
2025         if (g_wlan.rx_buffer == NULL)
2026                 g_wlan.rx_buffer = kmalloc(LINUX_RX_SIZE, GFP_KERNEL);
2027         PRINT_D(TX_DBG, "g_wlan.rx_buffer =%p\n", g_wlan.rx_buffer);
2028         if (g_wlan.rx_buffer == NULL) {
2029                 /* ENOBUFS      105 */
2030                 ret = -105;
2031                 PRINT_ER("Can't allocate Rx Buffer");
2032                 goto _fail_;
2033         }
2034 #endif
2035
2036         /**
2037          *      export functions
2038          **/
2039         oup->wlan_firmware_download = wilc_wlan_firmware_download;
2040         oup->wlan_start = wilc_wlan_start;
2041         oup->wlan_stop = wilc_wlan_stop;
2042         oup->wlan_add_to_tx_que = wilc_wlan_txq_add_net_pkt;
2043         oup->wlan_handle_tx_que = wilc_wlan_handle_txq;
2044         oup->wlan_handle_rx_isr = wilc_handle_isr;
2045         oup->wlan_cleanup = wilc_wlan_cleanup;
2046         oup->wlan_cfg_set = wilc_wlan_cfg_set;
2047         oup->wlan_cfg_get = wilc_wlan_cfg_get;
2048         oup->wlan_cfg_get_value = wilc_wlan_cfg_get_val;
2049
2050         oup->wlan_add_mgmt_to_tx_que = wilc_wlan_txq_add_mgmt_pkt;
2051
2052         if (!init_chip()) {
2053                 /* EIO  5 */
2054                 ret = -5;
2055                 goto _fail_;
2056         }
2057 #ifdef  TCP_ACK_FILTER
2058         Init_TCP_tracking();
2059 #endif
2060
2061         return 1;
2062
2063 _fail_:
2064
2065   #ifdef MEMORY_STATIC
2066         kfree(g_wlan.rx_buffer);
2067         g_wlan.rx_buffer = NULL;
2068   #endif
2069         kfree(g_wlan.tx_buffer);
2070         g_wlan.tx_buffer = NULL;
2071
2072         return ret;
2073
2074 }
2075
2076 u16 Set_machw_change_vir_if(bool bValue)
2077 {
2078         u16 ret;
2079         u32 reg;
2080
2081         /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
2082         mutex_lock(&g_linux_wlan->hif_cs);
2083         ret = (&g_wlan)->hif_func.hif_read_reg(WILC_CHANGING_VIR_IF, &reg);
2084         if (!ret) {
2085                 PRINT_ER("Error while Reading reg WILC_CHANGING_VIR_IF\n");
2086         }
2087
2088         if (bValue)
2089                 reg |= BIT(31);
2090         else
2091                 reg &= ~BIT(31);
2092
2093         ret = (&g_wlan)->hif_func.hif_write_reg(WILC_CHANGING_VIR_IF, reg);
2094
2095         if (!ret) {
2096                 PRINT_ER("Error while writing reg WILC_CHANGING_VIR_IF\n");
2097         }
2098         mutex_unlock(&g_linux_wlan->hif_cs);
2099
2100         return ret;
2101 }