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 
wilc_debug(u32 flag,char * fmt,...)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*/
acquire_bus(BUS_ACQUIRE_T acquire)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 }
release_bus(BUS_RELEASE_T release)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 
wilc_wlan_txq_remove(struct txq_entry_t * tqe)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 
wilc_wlan_txq_remove_from_head(void)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 
wilc_wlan_txq_add_to_tail(struct txq_entry_t * tqe)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 
wilc_wlan_txq_add_to_head(struct txq_entry_t * tqe)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 
Init_TCP_tracking(void)292 static inline int Init_TCP_tracking(void)
293 {
294 
295 	return 0;
296 
297 }
add_TCP_track_session(u32 src_prt,u32 dst_prt,u32 seq)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 
Update_TCP_track_session(u32 index,u32 Ack)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 }
add_TCP_Pending_Ack(u32 Ack,u32 Session_index,struct txq_entry_t * txqe)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 }
remove_TCP_related(void)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 
tcp_process(struct net_device * dev,struct txq_entry_t * tqe)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 
wilc_wlan_txq_filter_dup_tcp_ack(struct net_device * dev)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 
Enable_TCP_ACK_Filter(bool value)464 void Enable_TCP_ACK_Filter(bool value)
465 {
466 	EnableTCPAckFilter = value;
467 }
468 
is_TCP_ACK_Filter_Enabled(void)469 bool is_TCP_ACK_Filter_Enabled(void)
470 {
471 	return EnableTCPAckFilter;
472 }
473 
wilc_wlan_txq_add_cfg_pkt(u8 * buffer,u32 buffer_size)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 
wilc_wlan_txq_add_net_pkt(struct net_device * dev,void * priv,u8 * buffer,u32 buffer_size,wilc_tx_complete_func_t func)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 
wilc_wlan_txq_add_mgmt_pkt(void * priv,u8 * buffer,u32 buffer_size,wilc_tx_complete_func_t func)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 
wilc_wlan_txq_get_first(void)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 
wilc_wlan_txq_get_next(struct wilc * wilc,struct txq_entry_t * tqe)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 
wilc_wlan_rxq_add(struct wilc * wilc,struct rxq_entry_t * rqe)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 
wilc_wlan_rxq_remove(struct wilc * wilc)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 
chip_allow_sleep(void)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 
chip_wakeup(void)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
chip_wakeup(void)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
chip_sleep_manually(u32 u32SleepTime)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  ********************************************/
wilc_wlan_handle_txq(struct net_device * dev,u32 * pu32TxqCount)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 
wilc_wlan_handle_rxq(struct wilc * wilc)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  ********************************************/
wilc_unknown_isr_ext(void)1247 static void wilc_unknown_isr_ext(void)
1248 {
1249 	g_wlan.hif_func.hif_clear_int_ext(0);
1250 }
wilc_pllupdate_isr_ext(u32 int_stats)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 
wilc_sleeptimer_isr_ext(u32 int_stats1)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 
wilc_wlan_handle_isr_ext(struct wilc * wilc,u32 int_status)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 
wilc_handle_isr(void * wilc)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  ********************************************/
wilc_wlan_firmware_download(const u8 * buffer,u32 buffer_size)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  ********************************************/
wilc_wlan_start(void)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 
wilc_wlan_global_reset(void)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 }
wilc_wlan_stop(void)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 
wilc_wlan_cleanup(struct net_device * dev)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 
wilc_wlan_cfg_commit(int type,u32 drvHandler)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 
wilc_wlan_cfg_set(int start,u32 wid,u8 * buffer,u32 buffer_size,int commit,u32 drvHandler)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 }
wilc_wlan_cfg_get(int start,u32 wid,int commit,u32 drvHandler)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 
wilc_wlan_cfg_get_val(u32 wid,u8 * buffer,u32 buffer_size)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 
wilc_bus_set_max_speed(void)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 
wilc_bus_set_default_speed(void)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 }
init_chip(void)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 
wilc_get_chipid(u8 update)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 
wilc_wlan_init(wilc_wlan_inp_t * inp)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 
Set_machw_change_vir_if(struct net_device * dev,bool bValue)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 }
2071