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