• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <linux/completion.h>
2 #include "wilc_wlan_if.h"
3 #include "wilc_wlan.h"
4 #include "wilc_wfi_netdevice.h"
5 #include "wilc_wlan_cfg.h"
6 
7 static CHIP_PS_STATE_T chip_ps_state = CHIP_WAKEDUP;
8 
acquire_bus(struct wilc * wilc,BUS_ACQUIRE_T acquire)9 static inline void acquire_bus(struct wilc *wilc, BUS_ACQUIRE_T acquire)
10 {
11 	mutex_lock(&wilc->hif_cs);
12 	if (acquire == ACQUIRE_AND_WAKEUP)
13 		chip_wakeup(wilc);
14 }
15 
release_bus(struct wilc * wilc,BUS_RELEASE_T release)16 static inline void release_bus(struct wilc *wilc, BUS_RELEASE_T release)
17 {
18 	if (release == RELEASE_ALLOW_SLEEP)
19 		chip_allow_sleep(wilc);
20 	mutex_unlock(&wilc->hif_cs);
21 }
22 
wilc_wlan_txq_remove(struct wilc * wilc,struct txq_entry_t * tqe)23 static void wilc_wlan_txq_remove(struct wilc *wilc, struct txq_entry_t *tqe)
24 {
25 	if (tqe == wilc->txq_head) {
26 		wilc->txq_head = tqe->next;
27 		if (wilc->txq_head)
28 			wilc->txq_head->prev = NULL;
29 	} else if (tqe == wilc->txq_tail) {
30 		wilc->txq_tail = (tqe->prev);
31 		if (wilc->txq_tail)
32 			wilc->txq_tail->next = NULL;
33 	} else {
34 		tqe->prev->next = tqe->next;
35 		tqe->next->prev = tqe->prev;
36 	}
37 	wilc->txq_entries -= 1;
38 }
39 
40 static struct txq_entry_t *
wilc_wlan_txq_remove_from_head(struct net_device * dev)41 wilc_wlan_txq_remove_from_head(struct net_device *dev)
42 {
43 	struct txq_entry_t *tqe;
44 	unsigned long flags;
45 	struct wilc_vif *vif;
46 	struct wilc *wilc;
47 
48 	vif = netdev_priv(dev);
49 	wilc = vif->wilc;
50 
51 	spin_lock_irqsave(&wilc->txq_spinlock, flags);
52 	if (wilc->txq_head) {
53 		tqe = wilc->txq_head;
54 		wilc->txq_head = tqe->next;
55 		if (wilc->txq_head)
56 			wilc->txq_head->prev = NULL;
57 
58 		wilc->txq_entries -= 1;
59 	} else {
60 		tqe = NULL;
61 	}
62 	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
63 	return tqe;
64 }
65 
wilc_wlan_txq_add_to_tail(struct net_device * dev,struct txq_entry_t * tqe)66 static void wilc_wlan_txq_add_to_tail(struct net_device *dev,
67 				      struct txq_entry_t *tqe)
68 {
69 	unsigned long flags;
70 	struct wilc_vif *vif;
71 	struct wilc *wilc;
72 
73 	vif = netdev_priv(dev);
74 	wilc = vif->wilc;
75 
76 	spin_lock_irqsave(&wilc->txq_spinlock, flags);
77 
78 	if (!wilc->txq_head) {
79 		tqe->next = NULL;
80 		tqe->prev = NULL;
81 		wilc->txq_head = tqe;
82 		wilc->txq_tail = tqe;
83 	} else {
84 		tqe->next = NULL;
85 		tqe->prev = wilc->txq_tail;
86 		wilc->txq_tail->next = tqe;
87 		wilc->txq_tail = tqe;
88 	}
89 	wilc->txq_entries += 1;
90 
91 	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
92 
93 	complete(&wilc->txq_event);
94 }
95 
wilc_wlan_txq_add_to_head(struct wilc_vif * vif,struct txq_entry_t * tqe)96 static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
97 				     struct txq_entry_t *tqe)
98 {
99 	unsigned long flags;
100 	struct wilc *wilc = vif->wilc;
101 
102 	mutex_lock(&wilc->txq_add_to_head_cs);
103 
104 	spin_lock_irqsave(&wilc->txq_spinlock, flags);
105 
106 	if (!wilc->txq_head) {
107 		tqe->next = NULL;
108 		tqe->prev = NULL;
109 		wilc->txq_head = tqe;
110 		wilc->txq_tail = tqe;
111 	} else {
112 		tqe->next = wilc->txq_head;
113 		tqe->prev = NULL;
114 		wilc->txq_head->prev = tqe;
115 		wilc->txq_head = tqe;
116 	}
117 	wilc->txq_entries += 1;
118 
119 	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
120 	mutex_unlock(&wilc->txq_add_to_head_cs);
121 	complete(&wilc->txq_event);
122 
123 	return 0;
124 }
125 
126 struct ack_session_info;
127 struct ack_session_info {
128 	u32 seq_num;
129 	u32 bigger_ack_num;
130 	u16 src_port;
131 	u16 dst_port;
132 	u16 status;
133 };
134 
135 struct pending_acks_info {
136 	u32 ack_num;
137 	u32 session_index;
138 	struct txq_entry_t  *txqe;
139 };
140 
141 #define NOT_TCP_ACK			(-1)
142 
143 #define MAX_TCP_SESSION		25
144 #define MAX_PENDING_ACKS		256
145 static struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION];
146 static struct pending_acks_info pending_acks_info[MAX_PENDING_ACKS];
147 
148 static u32 pending_base;
149 static u32 tcp_session;
150 static u32 pending_acks;
151 
add_tcp_session(u32 src_prt,u32 dst_prt,u32 seq)152 static inline int add_tcp_session(u32 src_prt, u32 dst_prt, u32 seq)
153 {
154 	if (tcp_session < 2 * MAX_TCP_SESSION) {
155 		ack_session_info[tcp_session].seq_num = seq;
156 		ack_session_info[tcp_session].bigger_ack_num = 0;
157 		ack_session_info[tcp_session].src_port = src_prt;
158 		ack_session_info[tcp_session].dst_port = dst_prt;
159 		tcp_session++;
160 	}
161 	return 0;
162 }
163 
update_tcp_session(u32 index,u32 ack)164 static inline int update_tcp_session(u32 index, u32 ack)
165 {
166 	if (index < 2 * MAX_TCP_SESSION &&
167 	    ack > ack_session_info[index].bigger_ack_num)
168 		ack_session_info[index].bigger_ack_num = ack;
169 	return 0;
170 }
171 
add_tcp_pending_ack(u32 ack,u32 session_index,struct txq_entry_t * txqe)172 static inline int add_tcp_pending_ack(u32 ack, u32 session_index,
173 				      struct txq_entry_t *txqe)
174 {
175 	if (pending_base + pending_acks < MAX_PENDING_ACKS) {
176 		pending_acks_info[pending_base + pending_acks].ack_num = ack;
177 		pending_acks_info[pending_base + pending_acks].txqe = txqe;
178 		pending_acks_info[pending_base + pending_acks].session_index = session_index;
179 		txqe->tcp_pending_ack_idx = pending_base + pending_acks;
180 		pending_acks++;
181 	}
182 	return 0;
183 }
184 
tcp_process(struct net_device * dev,struct txq_entry_t * tqe)185 static inline void tcp_process(struct net_device *dev, struct txq_entry_t *tqe)
186 {
187 	u8 *eth_hdr_ptr;
188 	u8 *buffer = tqe->buffer;
189 	unsigned short h_proto;
190 	int i;
191 	unsigned long flags;
192 	struct wilc_vif *vif;
193 	struct wilc *wilc;
194 
195 	vif = netdev_priv(dev);
196 	wilc = vif->wilc;
197 
198 	spin_lock_irqsave(&wilc->txq_spinlock, flags);
199 
200 	eth_hdr_ptr = &buffer[0];
201 	h_proto = ntohs(*((unsigned short *)&eth_hdr_ptr[12]));
202 	if (h_proto == ETH_P_IP) {
203 		u8 *ip_hdr_ptr;
204 		u8 protocol;
205 
206 		ip_hdr_ptr = &buffer[ETHERNET_HDR_LEN];
207 		protocol = ip_hdr_ptr[9];
208 
209 		if (protocol == 0x06) {
210 			u8 *tcp_hdr_ptr;
211 			u32 IHL, total_length, data_offset;
212 
213 			tcp_hdr_ptr = &ip_hdr_ptr[IP_HDR_LEN];
214 			IHL = (ip_hdr_ptr[0] & 0xf) << 2;
215 			total_length = ((u32)ip_hdr_ptr[2] << 8) +
216 					(u32)ip_hdr_ptr[3];
217 			data_offset = ((u32)tcp_hdr_ptr[12] & 0xf0) >> 2;
218 			if (total_length == (IHL + data_offset)) {
219 				u32 seq_no, ack_no;
220 
221 				seq_no = ((u32)tcp_hdr_ptr[4] << 24) +
222 					 ((u32)tcp_hdr_ptr[5] << 16) +
223 					 ((u32)tcp_hdr_ptr[6] << 8) +
224 					 (u32)tcp_hdr_ptr[7];
225 
226 				ack_no = ((u32)tcp_hdr_ptr[8] << 24) +
227 					 ((u32)tcp_hdr_ptr[9] << 16) +
228 					 ((u32)tcp_hdr_ptr[10] << 8) +
229 					 (u32)tcp_hdr_ptr[11];
230 
231 				for (i = 0; i < tcp_session; i++) {
232 					if (i < 2 * MAX_TCP_SESSION &&
233 					    ack_session_info[i].seq_num == seq_no) {
234 						update_tcp_session(i, ack_no);
235 						break;
236 					}
237 				}
238 				if (i == tcp_session)
239 					add_tcp_session(0, 0, seq_no);
240 
241 				add_tcp_pending_ack(ack_no, i, tqe);
242 			}
243 		}
244 	}
245 	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
246 }
247 
wilc_wlan_txq_filter_dup_tcp_ack(struct net_device * dev)248 static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
249 {
250 	struct wilc_vif *vif;
251 	struct wilc *wilc;
252 	u32 i = 0;
253 	u32 dropped = 0;
254 
255 	vif = netdev_priv(dev);
256 	wilc = vif->wilc;
257 
258 	spin_lock_irqsave(&wilc->txq_spinlock, wilc->txq_spinlock_flags);
259 	for (i = pending_base; i < (pending_base + pending_acks); i++) {
260 		if (i >= MAX_PENDING_ACKS ||
261 		    pending_acks_info[i].session_index >= 2 * MAX_TCP_SESSION)
262 			break;
263 		if (pending_acks_info[i].ack_num < ack_session_info[pending_acks_info[i].session_index].bigger_ack_num) {
264 			struct txq_entry_t *tqe;
265 
266 			tqe = pending_acks_info[i].txqe;
267 			if (tqe) {
268 				wilc_wlan_txq_remove(wilc, tqe);
269 				tqe->status = 1;
270 				if (tqe->tx_complete_func)
271 					tqe->tx_complete_func(tqe->priv,
272 							      tqe->status);
273 				kfree(tqe);
274 				dropped++;
275 			}
276 		}
277 	}
278 	pending_acks = 0;
279 	tcp_session = 0;
280 
281 	if (pending_base == 0)
282 		pending_base = MAX_TCP_SESSION;
283 	else
284 		pending_base = 0;
285 
286 	spin_unlock_irqrestore(&wilc->txq_spinlock, wilc->txq_spinlock_flags);
287 
288 	while (dropped > 0) {
289 		wait_for_completion_timeout(&wilc->txq_event,
290 					    msecs_to_jiffies(1));
291 		dropped--;
292 	}
293 
294 	return 1;
295 }
296 
297 static bool enabled;
298 
wilc_enable_tcp_ack_filter(bool value)299 void wilc_enable_tcp_ack_filter(bool value)
300 {
301 	enabled = value;
302 }
303 
wilc_wlan_txq_add_cfg_pkt(struct wilc_vif * vif,u8 * buffer,u32 buffer_size)304 static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer,
305 				     u32 buffer_size)
306 {
307 	struct txq_entry_t *tqe;
308 	struct wilc *wilc = vif->wilc;
309 
310 	netdev_dbg(vif->ndev, "Adding config packet ...\n");
311 	if (wilc->quit) {
312 		netdev_dbg(vif->ndev, "Return due to clear function\n");
313 		complete(&wilc->cfg_event);
314 		return 0;
315 	}
316 
317 	tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
318 	if (!tqe)
319 		return 0;
320 
321 	tqe->type = WILC_CFG_PKT;
322 	tqe->buffer = buffer;
323 	tqe->buffer_size = buffer_size;
324 	tqe->tx_complete_func = NULL;
325 	tqe->priv = NULL;
326 	tqe->tcp_pending_ack_idx = NOT_TCP_ACK;
327 
328 	if (wilc_wlan_txq_add_to_head(vif, tqe)) {
329 		kfree(tqe);
330 		return 0;
331 	}
332 
333 	return 1;
334 }
335 
wilc_wlan_txq_add_net_pkt(struct net_device * dev,void * priv,u8 * buffer,u32 buffer_size,wilc_tx_complete_func_t func)336 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
337 			      u32 buffer_size, wilc_tx_complete_func_t func)
338 {
339 	struct txq_entry_t *tqe;
340 	struct wilc_vif *vif = netdev_priv(dev);
341 	struct wilc *wilc;
342 
343 	wilc = vif->wilc;
344 
345 	if (wilc->quit)
346 		return 0;
347 
348 	tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
349 
350 	if (!tqe)
351 		return 0;
352 	tqe->type = WILC_NET_PKT;
353 	tqe->buffer = buffer;
354 	tqe->buffer_size = buffer_size;
355 	tqe->tx_complete_func = func;
356 	tqe->priv = priv;
357 
358 	tqe->tcp_pending_ack_idx = NOT_TCP_ACK;
359 	if (enabled)
360 		tcp_process(dev, tqe);
361 	wilc_wlan_txq_add_to_tail(dev, tqe);
362 	return wilc->txq_entries;
363 }
364 
wilc_wlan_txq_add_mgmt_pkt(struct net_device * dev,void * priv,u8 * buffer,u32 buffer_size,wilc_tx_complete_func_t func)365 int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
366 			       u32 buffer_size, wilc_tx_complete_func_t func)
367 {
368 	struct txq_entry_t *tqe;
369 	struct wilc_vif *vif = netdev_priv(dev);
370 	struct wilc *wilc;
371 
372 	wilc = vif->wilc;
373 
374 	if (wilc->quit)
375 		return 0;
376 
377 	tqe = kmalloc(sizeof(*tqe), GFP_KERNEL);
378 
379 	if (!tqe)
380 		return 0;
381 	tqe->type = WILC_MGMT_PKT;
382 	tqe->buffer = buffer;
383 	tqe->buffer_size = buffer_size;
384 	tqe->tx_complete_func = func;
385 	tqe->priv = priv;
386 	tqe->tcp_pending_ack_idx = NOT_TCP_ACK;
387 	wilc_wlan_txq_add_to_tail(dev, tqe);
388 	return 1;
389 }
390 
wilc_wlan_txq_get_first(struct wilc * wilc)391 static struct txq_entry_t *wilc_wlan_txq_get_first(struct wilc *wilc)
392 {
393 	struct txq_entry_t *tqe;
394 	unsigned long flags;
395 
396 	spin_lock_irqsave(&wilc->txq_spinlock, flags);
397 
398 	tqe = wilc->txq_head;
399 
400 	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
401 
402 	return tqe;
403 }
404 
wilc_wlan_txq_get_next(struct wilc * wilc,struct txq_entry_t * tqe)405 static struct txq_entry_t *wilc_wlan_txq_get_next(struct wilc *wilc,
406 						  struct txq_entry_t *tqe)
407 {
408 	unsigned long flags;
409 
410 	spin_lock_irqsave(&wilc->txq_spinlock, flags);
411 
412 	tqe = tqe->next;
413 	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
414 
415 	return tqe;
416 }
417 
wilc_wlan_rxq_add(struct wilc * wilc,struct rxq_entry_t * rqe)418 static int wilc_wlan_rxq_add(struct wilc *wilc, struct rxq_entry_t *rqe)
419 {
420 	if (wilc->quit)
421 		return 0;
422 
423 	mutex_lock(&wilc->rxq_cs);
424 	if (!wilc->rxq_head) {
425 		rqe->next = NULL;
426 		wilc->rxq_head = rqe;
427 		wilc->rxq_tail = rqe;
428 	} else {
429 		wilc->rxq_tail->next = rqe;
430 		rqe->next = NULL;
431 		wilc->rxq_tail = rqe;
432 	}
433 	wilc->rxq_entries += 1;
434 	mutex_unlock(&wilc->rxq_cs);
435 	return wilc->rxq_entries;
436 }
437 
wilc_wlan_rxq_remove(struct wilc * wilc)438 static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
439 {
440 	if (wilc->rxq_head) {
441 		struct rxq_entry_t *rqe;
442 
443 		mutex_lock(&wilc->rxq_cs);
444 		rqe = wilc->rxq_head;
445 		wilc->rxq_head = wilc->rxq_head->next;
446 		wilc->rxq_entries -= 1;
447 		mutex_unlock(&wilc->rxq_cs);
448 		return rqe;
449 	}
450 	return NULL;
451 }
452 
chip_allow_sleep(struct wilc * wilc)453 void chip_allow_sleep(struct wilc *wilc)
454 {
455 	u32 reg = 0;
456 
457 	wilc->hif_func->hif_read_reg(wilc, 0xf0, &reg);
458 
459 	wilc->hif_func->hif_write_reg(wilc, 0xf0, reg & ~BIT(0));
460 	wilc->hif_func->hif_write_reg(wilc, 0xfa, 0);
461 }
462 EXPORT_SYMBOL_GPL(chip_allow_sleep);
463 
chip_wakeup(struct wilc * wilc)464 void chip_wakeup(struct wilc *wilc)
465 {
466 	u32 reg, clk_status_reg;
467 
468 	if ((wilc->io_type & 0x1) == HIF_SPI) {
469 		do {
470 			wilc->hif_func->hif_read_reg(wilc, 1, &reg);
471 			wilc->hif_func->hif_write_reg(wilc, 1, reg | BIT(1));
472 			wilc->hif_func->hif_write_reg(wilc, 1, reg & ~BIT(1));
473 
474 			do {
475 				usleep_range(2 * 1000, 2 * 1000);
476 				wilc_get_chipid(wilc, true);
477 			} while (wilc_get_chipid(wilc, true) == 0);
478 		} while (wilc_get_chipid(wilc, true) == 0);
479 	} else if ((wilc->io_type & 0x1) == HIF_SDIO)	 {
480 		wilc->hif_func->hif_write_reg(wilc, 0xfa, 1);
481 		udelay(200);
482 		wilc->hif_func->hif_read_reg(wilc, 0xf0, &reg);
483 		do {
484 			wilc->hif_func->hif_write_reg(wilc, 0xf0,
485 						      reg | BIT(0));
486 			wilc->hif_func->hif_read_reg(wilc, 0xf1,
487 						     &clk_status_reg);
488 
489 			while ((clk_status_reg & 0x1) == 0) {
490 				usleep_range(2 * 1000, 2 * 1000);
491 
492 				wilc->hif_func->hif_read_reg(wilc, 0xf1,
493 							     &clk_status_reg);
494 			}
495 			if ((clk_status_reg & 0x1) == 0) {
496 				wilc->hif_func->hif_write_reg(wilc, 0xf0,
497 							      reg & (~BIT(0)));
498 			}
499 		} while ((clk_status_reg & 0x1) == 0);
500 	}
501 
502 	if (chip_ps_state == CHIP_SLEEPING_MANUAL) {
503 		if (wilc_get_chipid(wilc, false) < 0x1002b0) {
504 			u32 val32;
505 
506 			wilc->hif_func->hif_read_reg(wilc, 0x1e1c, &val32);
507 			val32 |= BIT(6);
508 			wilc->hif_func->hif_write_reg(wilc, 0x1e1c, val32);
509 
510 			wilc->hif_func->hif_read_reg(wilc, 0x1e9c, &val32);
511 			val32 |= BIT(6);
512 			wilc->hif_func->hif_write_reg(wilc, 0x1e9c, val32);
513 		}
514 	}
515 	chip_ps_state = CHIP_WAKEDUP;
516 }
517 EXPORT_SYMBOL_GPL(chip_wakeup);
518 
wilc_chip_sleep_manually(struct wilc * wilc)519 void wilc_chip_sleep_manually(struct wilc *wilc)
520 {
521 	if (chip_ps_state != CHIP_WAKEDUP)
522 		return;
523 	acquire_bus(wilc, ACQUIRE_ONLY);
524 
525 	chip_allow_sleep(wilc);
526 	wilc->hif_func->hif_write_reg(wilc, 0x10a8, 1);
527 
528 	chip_ps_state = CHIP_SLEEPING_MANUAL;
529 	release_bus(wilc, RELEASE_ONLY);
530 }
531 EXPORT_SYMBOL_GPL(wilc_chip_sleep_manually);
532 
host_wakeup_notify(struct wilc * wilc)533 void host_wakeup_notify(struct wilc *wilc)
534 {
535 	acquire_bus(wilc, ACQUIRE_ONLY);
536 	wilc->hif_func->hif_write_reg(wilc, 0x10b0, 1);
537 	release_bus(wilc, RELEASE_ONLY);
538 }
539 EXPORT_SYMBOL_GPL(host_wakeup_notify);
540 
host_sleep_notify(struct wilc * wilc)541 void host_sleep_notify(struct wilc *wilc)
542 {
543 	acquire_bus(wilc, ACQUIRE_ONLY);
544 	wilc->hif_func->hif_write_reg(wilc, 0x10ac, 1);
545 	release_bus(wilc, RELEASE_ONLY);
546 }
547 EXPORT_SYMBOL_GPL(host_sleep_notify);
548 
wilc_wlan_handle_txq(struct net_device * dev,u32 * txq_count)549 int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
550 {
551 	int i, entries = 0;
552 	u32 sum;
553 	u32 reg;
554 	u8 *txb;
555 	u32 offset = 0;
556 	int vmm_sz = 0;
557 	struct txq_entry_t *tqe;
558 	int ret = 0;
559 	int counter;
560 	int timeout;
561 	u32 vmm_table[WILC_VMM_TBL_SIZE];
562 	struct wilc_vif *vif;
563 	struct wilc *wilc;
564 
565 	vif = netdev_priv(dev);
566 	wilc = vif->wilc;
567 
568 	txb = wilc->tx_buffer;
569 	wilc->txq_exit = 0;
570 	do {
571 		if (wilc->quit)
572 			break;
573 
574 		mutex_lock(&wilc->txq_add_to_head_cs);
575 		wilc_wlan_txq_filter_dup_tcp_ack(dev);
576 		tqe = wilc_wlan_txq_get_first(wilc);
577 		i = 0;
578 		sum = 0;
579 		do {
580 			if (tqe && (i < (WILC_VMM_TBL_SIZE - 1))) {
581 				if (tqe->type == WILC_CFG_PKT)
582 					vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET;
583 
584 				else if (tqe->type == WILC_NET_PKT)
585 					vmm_sz = ETH_ETHERNET_HDR_OFFSET;
586 
587 				else
588 					vmm_sz = HOST_HDR_OFFSET;
589 
590 				vmm_sz += tqe->buffer_size;
591 
592 				if (vmm_sz & 0x3)
593 					vmm_sz = (vmm_sz + 4) & ~0x3;
594 
595 				if ((sum + vmm_sz) > LINUX_TX_SIZE)
596 					break;
597 
598 				vmm_table[i] = vmm_sz / 4;
599 				if (tqe->type == WILC_CFG_PKT)
600 					vmm_table[i] |= BIT(10);
601 				vmm_table[i] = cpu_to_le32(vmm_table[i]);
602 
603 				i++;
604 				sum += vmm_sz;
605 				tqe = wilc_wlan_txq_get_next(wilc, tqe);
606 			} else {
607 				break;
608 			}
609 		} while (1);
610 
611 		if (i == 0)
612 			break;
613 		vmm_table[i] = 0x0;
614 
615 		acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
616 		counter = 0;
617 		do {
618 			ret = wilc->hif_func->hif_read_reg(wilc,
619 							   WILC_HOST_TX_CTRL,
620 							   &reg);
621 			if (!ret)
622 				break;
623 
624 			if ((reg & 0x1) == 0)
625 				break;
626 
627 			counter++;
628 			if (counter > 200) {
629 				counter = 0;
630 				ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0);
631 				break;
632 			}
633 		} while (!wilc->quit);
634 
635 		if (!ret)
636 			goto _end_;
637 
638 		timeout = 200;
639 		do {
640 			ret = wilc->hif_func->hif_block_tx(wilc, WILC_VMM_TBL_RX_SHADOW_BASE, (u8 *)vmm_table, ((i + 1) * 4));
641 			if (!ret)
642 				break;
643 
644 			ret = wilc->hif_func->hif_write_reg(wilc,
645 							    WILC_HOST_VMM_CTL,
646 							    0x2);
647 			if (!ret)
648 				break;
649 
650 			do {
651 				ret = wilc->hif_func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, &reg);
652 				if (!ret)
653 					break;
654 				if ((reg >> 2) & 0x1) {
655 					entries = ((reg >> 3) & 0x3f);
656 					break;
657 				}
658 				release_bus(wilc, RELEASE_ALLOW_SLEEP);
659 			} while (--timeout);
660 			if (timeout <= 0) {
661 				ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0);
662 				break;
663 			}
664 
665 			if (!ret)
666 				break;
667 
668 			if (entries == 0) {
669 				ret = wilc->hif_func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, &reg);
670 				if (!ret)
671 					break;
672 				reg &= ~BIT(0);
673 				ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, reg);
674 				if (!ret)
675 					break;
676 				break;
677 			}
678 			break;
679 		} while (1);
680 
681 		if (!ret)
682 			goto _end_;
683 
684 		if (entries == 0) {
685 			ret = WILC_TX_ERR_NO_BUF;
686 			goto _end_;
687 		}
688 
689 		release_bus(wilc, RELEASE_ALLOW_SLEEP);
690 
691 		offset = 0;
692 		i = 0;
693 		do {
694 			tqe = wilc_wlan_txq_remove_from_head(dev);
695 			if (tqe && (vmm_table[i] != 0)) {
696 				u32 header, buffer_offset;
697 
698 				vmm_table[i] = cpu_to_le32(vmm_table[i]);
699 				vmm_sz = (vmm_table[i] & 0x3ff);
700 				vmm_sz *= 4;
701 				header = (tqe->type << 31) |
702 					 (tqe->buffer_size << 15) |
703 					 vmm_sz;
704 				if (tqe->type == WILC_MGMT_PKT)
705 					header |= BIT(30);
706 				else
707 					header &= ~BIT(30);
708 
709 				header = cpu_to_le32(header);
710 				memcpy(&txb[offset], &header, 4);
711 				if (tqe->type == WILC_CFG_PKT) {
712 					buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET;
713 				} else if (tqe->type == WILC_NET_PKT) {
714 					char *bssid = ((struct tx_complete_data *)(tqe->priv))->bssid;
715 
716 					buffer_offset = ETH_ETHERNET_HDR_OFFSET;
717 					memcpy(&txb[offset + 8], bssid, 6);
718 				} else {
719 					buffer_offset = HOST_HDR_OFFSET;
720 				}
721 
722 				memcpy(&txb[offset + buffer_offset],
723 				       tqe->buffer, tqe->buffer_size);
724 				offset += vmm_sz;
725 				i++;
726 				tqe->status = 1;
727 				if (tqe->tx_complete_func)
728 					tqe->tx_complete_func(tqe->priv,
729 							      tqe->status);
730 				if (tqe->tcp_pending_ack_idx != NOT_TCP_ACK &&
731 				    tqe->tcp_pending_ack_idx < MAX_PENDING_ACKS)
732 					pending_acks_info[tqe->tcp_pending_ack_idx].txqe = NULL;
733 				kfree(tqe);
734 			} else {
735 				break;
736 			}
737 		} while (--entries);
738 
739 		acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
740 
741 		ret = wilc->hif_func->hif_clear_int_ext(wilc, ENABLE_TX_VMM);
742 		if (!ret)
743 			goto _end_;
744 
745 		ret = wilc->hif_func->hif_block_tx_ext(wilc, 0, txb, offset);
746 		if (!ret)
747 			goto _end_;
748 
749 _end_:
750 
751 		release_bus(wilc, RELEASE_ALLOW_SLEEP);
752 		if (ret != 1)
753 			break;
754 	} while (0);
755 	mutex_unlock(&wilc->txq_add_to_head_cs);
756 
757 	wilc->txq_exit = 1;
758 	*txq_count = wilc->txq_entries;
759 	return ret;
760 }
761 
wilc_wlan_handle_rxq(struct wilc * wilc)762 static void wilc_wlan_handle_rxq(struct wilc *wilc)
763 {
764 	int offset = 0, size;
765 	u8 *buffer;
766 	struct rxq_entry_t *rqe;
767 
768 	wilc->rxq_exit = 0;
769 
770 	do {
771 		if (wilc->quit) {
772 			complete(&wilc->cfg_event);
773 			break;
774 		}
775 		rqe = wilc_wlan_rxq_remove(wilc);
776 		if (!rqe)
777 			break;
778 
779 		buffer = rqe->buffer;
780 		size = rqe->buffer_size;
781 		offset = 0;
782 
783 		do {
784 			u32 header;
785 			u32 pkt_len, pkt_offset, tp_len;
786 			int is_cfg_packet;
787 
788 			memcpy(&header, &buffer[offset], 4);
789 			header = cpu_to_le32(header);
790 
791 			is_cfg_packet = (header >> 31) & 0x1;
792 			pkt_offset = (header >> 22) & 0x1ff;
793 			tp_len = (header >> 11) & 0x7ff;
794 			pkt_len = header & 0x7ff;
795 
796 			if (pkt_len == 0 || tp_len == 0)
797 				break;
798 
799 			#define IS_MANAGMEMENT				0x100
800 			#define IS_MANAGMEMENT_CALLBACK			0x080
801 			#define IS_MGMT_STATUS_SUCCES			0x040
802 
803 			if (pkt_offset & IS_MANAGMEMENT) {
804 				pkt_offset &= ~(IS_MANAGMEMENT |
805 						IS_MANAGMEMENT_CALLBACK |
806 						IS_MGMT_STATUS_SUCCES);
807 
808 				WILC_WFI_mgmt_rx(wilc, &buffer[offset + HOST_HDR_OFFSET], pkt_len);
809 			} else {
810 				if (!is_cfg_packet) {
811 					if (pkt_len > 0) {
812 						wilc_frmw_to_linux(wilc,
813 								   &buffer[offset],
814 								   pkt_len,
815 								   pkt_offset);
816 					}
817 				} else {
818 					struct wilc_cfg_rsp rsp;
819 
820 					wilc_wlan_cfg_indicate_rx(wilc, &buffer[pkt_offset + offset], pkt_len, &rsp);
821 					if (rsp.type == WILC_CFG_RSP) {
822 						if (wilc->cfg_seq_no == rsp.seq_no)
823 							complete(&wilc->cfg_event);
824 					} else if (rsp.type == WILC_CFG_RSP_STATUS) {
825 						wilc_mac_indicate(wilc, WILC_MAC_INDICATE_STATUS);
826 
827 					} else if (rsp.type == WILC_CFG_RSP_SCAN) {
828 						wilc_mac_indicate(wilc, WILC_MAC_INDICATE_SCAN);
829 					}
830 				}
831 			}
832 			offset += tp_len;
833 			if (offset >= size)
834 				break;
835 		} while (1);
836 		kfree(rqe);
837 	} while (1);
838 
839 	wilc->rxq_exit = 1;
840 }
841 
wilc_unknown_isr_ext(struct wilc * wilc)842 static void wilc_unknown_isr_ext(struct wilc *wilc)
843 {
844 	wilc->hif_func->hif_clear_int_ext(wilc, 0);
845 }
846 
wilc_pllupdate_isr_ext(struct wilc * wilc,u32 int_stats)847 static void wilc_pllupdate_isr_ext(struct wilc *wilc, u32 int_stats)
848 {
849 	int trials = 10;
850 
851 	wilc->hif_func->hif_clear_int_ext(wilc, PLL_INT_CLR);
852 
853 	if (wilc->io_type == HIF_SDIO)
854 		mdelay(WILC_PLL_TO_SDIO);
855 	else
856 		mdelay(WILC_PLL_TO_SPI);
857 
858 	while (!(ISWILC1000(wilc_get_chipid(wilc, true)) && --trials))
859 		mdelay(1);
860 }
861 
wilc_sleeptimer_isr_ext(struct wilc * wilc,u32 int_stats1)862 static void wilc_sleeptimer_isr_ext(struct wilc *wilc, u32 int_stats1)
863 {
864 	wilc->hif_func->hif_clear_int_ext(wilc, SLEEP_INT_CLR);
865 }
866 
wilc_wlan_handle_isr_ext(struct wilc * wilc,u32 int_status)867 static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status)
868 {
869 	u32 offset = wilc->rx_buffer_offset;
870 	u8 *buffer = NULL;
871 	u32 size;
872 	u32 retries = 0;
873 	int ret = 0;
874 	struct rxq_entry_t *rqe;
875 
876 	size = (int_status & 0x7fff) << 2;
877 
878 	while (!size && retries < 10) {
879 		wilc->hif_func->hif_read_size(wilc, &size);
880 		size = (size & 0x7fff) << 2;
881 		retries++;
882 	}
883 
884 	if (size > 0) {
885 		if (LINUX_RX_SIZE - offset < size)
886 			offset = 0;
887 
888 		if (wilc->rx_buffer)
889 			buffer = &wilc->rx_buffer[offset];
890 		else
891 			goto _end_;
892 
893 		wilc->hif_func->hif_clear_int_ext(wilc,
894 					      DATA_INT_CLR | ENABLE_RX_VMM);
895 		ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size);
896 
897 _end_:
898 		if (ret) {
899 			offset += size;
900 			wilc->rx_buffer_offset = offset;
901 			rqe = kmalloc(sizeof(*rqe), GFP_KERNEL);
902 			if (rqe) {
903 				rqe->buffer = buffer;
904 				rqe->buffer_size = size;
905 				wilc_wlan_rxq_add(wilc, rqe);
906 			}
907 		}
908 	}
909 	wilc_wlan_handle_rxq(wilc);
910 }
911 
wilc_handle_isr(struct wilc * wilc)912 void wilc_handle_isr(struct wilc *wilc)
913 {
914 	u32 int_status;
915 
916 	acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
917 	wilc->hif_func->hif_read_int(wilc, &int_status);
918 
919 	if (int_status & PLL_INT_EXT)
920 		wilc_pllupdate_isr_ext(wilc, int_status);
921 
922 	if (int_status & DATA_INT_EXT)
923 		wilc_wlan_handle_isr_ext(wilc, int_status);
924 
925 	if (int_status & SLEEP_INT_EXT)
926 		wilc_sleeptimer_isr_ext(wilc, int_status);
927 
928 	if (!(int_status & (ALL_INT_EXT)))
929 		wilc_unknown_isr_ext(wilc);
930 
931 	release_bus(wilc, RELEASE_ALLOW_SLEEP);
932 }
933 EXPORT_SYMBOL_GPL(wilc_handle_isr);
934 
wilc_wlan_firmware_download(struct wilc * wilc,const u8 * buffer,u32 buffer_size)935 int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
936 				u32 buffer_size)
937 {
938 	u32 offset;
939 	u32 addr, size, size2, blksz;
940 	u8 *dma_buffer;
941 	int ret = 0;
942 
943 	blksz = BIT(12);
944 
945 	dma_buffer = kmalloc(blksz, GFP_KERNEL);
946 	if (!dma_buffer)
947 		return -EIO;
948 
949 	offset = 0;
950 	do {
951 		memcpy(&addr, &buffer[offset], 4);
952 		memcpy(&size, &buffer[offset + 4], 4);
953 		addr = cpu_to_le32(addr);
954 		size = cpu_to_le32(size);
955 		acquire_bus(wilc, ACQUIRE_ONLY);
956 		offset += 8;
957 		while (((int)size) && (offset < buffer_size)) {
958 			if (size <= blksz)
959 				size2 = size;
960 			else
961 				size2 = blksz;
962 
963 			memcpy(dma_buffer, &buffer[offset], size2);
964 			ret = wilc->hif_func->hif_block_tx(wilc, addr,
965 							   dma_buffer, size2);
966 			if (!ret)
967 				break;
968 
969 			addr += size2;
970 			offset += size2;
971 			size -= size2;
972 		}
973 		release_bus(wilc, RELEASE_ONLY);
974 
975 		if (!ret) {
976 			ret = -EIO;
977 			goto _fail_;
978 		}
979 	} while (offset < buffer_size);
980 
981 _fail_:
982 
983 	kfree(dma_buffer);
984 
985 	return (ret < 0) ? ret : 0;
986 }
987 
wilc_wlan_start(struct wilc * wilc)988 int wilc_wlan_start(struct wilc *wilc)
989 {
990 	u32 reg = 0;
991 	int ret;
992 	u32 chipid;
993 
994 	if (wilc->io_type == HIF_SDIO) {
995 		reg = 0;
996 		reg |= BIT(3);
997 	} else if (wilc->io_type == HIF_SPI) {
998 		reg = 1;
999 	}
1000 	acquire_bus(wilc, ACQUIRE_ONLY);
1001 	ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg);
1002 	if (!ret) {
1003 		release_bus(wilc, RELEASE_ONLY);
1004 		return -EIO;
1005 	}
1006 	reg = 0;
1007 	if (wilc->io_type == HIF_SDIO && wilc->dev_irq_num)
1008 		reg |= WILC_HAVE_SDIO_IRQ_GPIO;
1009 
1010 #ifdef WILC_DISABLE_PMU
1011 #else
1012 	reg |= WILC_HAVE_USE_PMU;
1013 #endif
1014 
1015 #ifdef WILC_SLEEP_CLK_SRC_XO
1016 	reg |= WILC_HAVE_SLEEP_CLK_SRC_XO;
1017 #elif defined WILC_SLEEP_CLK_SRC_RTC
1018 	reg |= WILC_HAVE_SLEEP_CLK_SRC_RTC;
1019 #endif
1020 
1021 #ifdef WILC_EXT_PA_INV_TX_RX
1022 	reg |= WILC_HAVE_EXT_PA_INV_TX_RX;
1023 #endif
1024 	reg |= WILC_HAVE_USE_IRQ_AS_HOST_WAKE;
1025 	reg |= WILC_HAVE_LEGACY_RF_SETTINGS;
1026 #ifdef XTAL_24
1027 	reg |= WILC_HAVE_XTAL_24;
1028 #endif
1029 #ifdef DISABLE_WILC_UART
1030 	reg |= WILC_HAVE_DISABLE_WILC_UART;
1031 #endif
1032 
1033 	ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg);
1034 	if (!ret) {
1035 		release_bus(wilc, RELEASE_ONLY);
1036 		return -EIO;
1037 	}
1038 
1039 	wilc->hif_func->hif_sync_ext(wilc, NUM_INT_EXT);
1040 
1041 	ret = wilc->hif_func->hif_read_reg(wilc, 0x1000, &chipid);
1042 	if (!ret) {
1043 		release_bus(wilc, RELEASE_ONLY);
1044 		return -EIO;
1045 	}
1046 
1047 	wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
1048 	if ((reg & BIT(10)) == BIT(10)) {
1049 		reg &= ~BIT(10);
1050 		wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1051 		wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
1052 	}
1053 
1054 	reg |= BIT(10);
1055 	ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1056 	wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
1057 	release_bus(wilc, RELEASE_ONLY);
1058 
1059 	return (ret < 0) ? ret : 0;
1060 }
1061 
wilc_wlan_stop(struct wilc * wilc)1062 int wilc_wlan_stop(struct wilc *wilc)
1063 {
1064 	u32 reg = 0;
1065 	int ret;
1066 	u8 timeout = 10;
1067 
1068 	acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
1069 
1070 	ret = wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
1071 	if (!ret) {
1072 		release_bus(wilc, RELEASE_ALLOW_SLEEP);
1073 		return ret;
1074 	}
1075 
1076 	reg &= ~BIT(10);
1077 	ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1078 	if (!ret) {
1079 		release_bus(wilc, RELEASE_ALLOW_SLEEP);
1080 		return ret;
1081 	}
1082 
1083 	do {
1084 		ret = wilc->hif_func->hif_read_reg(wilc,
1085 						   WILC_GLB_RESET_0, &reg);
1086 		if (!ret) {
1087 			release_bus(wilc, RELEASE_ALLOW_SLEEP);
1088 			return ret;
1089 		}
1090 
1091 		if ((reg & BIT(10))) {
1092 			reg &= ~BIT(10);
1093 			ret = wilc->hif_func->hif_write_reg(wilc,
1094 							    WILC_GLB_RESET_0,
1095 							    reg);
1096 			timeout--;
1097 		} else {
1098 			ret = wilc->hif_func->hif_read_reg(wilc,
1099 							   WILC_GLB_RESET_0,
1100 							   &reg);
1101 			if (!ret) {
1102 				release_bus(wilc, RELEASE_ALLOW_SLEEP);
1103 				return ret;
1104 			}
1105 			break;
1106 		}
1107 
1108 	} while (timeout);
1109 	reg = (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(8) | BIT(9) | BIT(26) |
1110 	       BIT(29) | BIT(30) | BIT(31));
1111 
1112 	wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1113 	reg = (u32)~BIT(10);
1114 
1115 	ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1116 
1117 	release_bus(wilc, RELEASE_ALLOW_SLEEP);
1118 
1119 	return ret;
1120 }
1121 
wilc_wlan_cleanup(struct net_device * dev)1122 void wilc_wlan_cleanup(struct net_device *dev)
1123 {
1124 	struct txq_entry_t *tqe;
1125 	struct rxq_entry_t *rqe;
1126 	u32 reg = 0;
1127 	int ret;
1128 	struct wilc_vif *vif;
1129 	struct wilc *wilc;
1130 
1131 	vif = netdev_priv(dev);
1132 	wilc = vif->wilc;
1133 
1134 	wilc->quit = 1;
1135 	do {
1136 		tqe = wilc_wlan_txq_remove_from_head(dev);
1137 		if (!tqe)
1138 			break;
1139 		if (tqe->tx_complete_func)
1140 			tqe->tx_complete_func(tqe->priv, 0);
1141 		kfree(tqe);
1142 	} while (1);
1143 
1144 	do {
1145 		rqe = wilc_wlan_rxq_remove(wilc);
1146 		if (!rqe)
1147 			break;
1148 		kfree(rqe);
1149 	} while (1);
1150 
1151 	kfree(wilc->rx_buffer);
1152 	wilc->rx_buffer = NULL;
1153 	kfree(wilc->tx_buffer);
1154 	wilc->tx_buffer = NULL;
1155 
1156 	acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
1157 
1158 	ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, &reg);
1159 	if (!ret)
1160 		release_bus(wilc, RELEASE_ALLOW_SLEEP);
1161 
1162 	ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0,
1163 					(reg | ABORT_INT));
1164 	if (!ret)
1165 		release_bus(wilc, RELEASE_ALLOW_SLEEP);
1166 
1167 	release_bus(wilc, RELEASE_ALLOW_SLEEP);
1168 	wilc->hif_func->hif_deinit(NULL);
1169 }
1170 
wilc_wlan_cfg_commit(struct wilc_vif * vif,int type,u32 drv_handler)1171 static int wilc_wlan_cfg_commit(struct wilc_vif *vif, int type,
1172 				u32 drv_handler)
1173 {
1174 	struct wilc *wilc = vif->wilc;
1175 	struct wilc_cfg_frame *cfg = &wilc->cfg_frame;
1176 	int total_len = wilc->cfg_frame_offset + 4 + DRIVER_HANDLER_SIZE;
1177 	int seq_no = wilc->cfg_seq_no % 256;
1178 	int driver_handler = (u32)drv_handler;
1179 
1180 	if (type == WILC_CFG_SET)
1181 		cfg->wid_header[0] = 'W';
1182 	else
1183 		cfg->wid_header[0] = 'Q';
1184 	cfg->wid_header[1] = seq_no;
1185 	cfg->wid_header[2] = (u8)total_len;
1186 	cfg->wid_header[3] = (u8)(total_len >> 8);
1187 	cfg->wid_header[4] = (u8)driver_handler;
1188 	cfg->wid_header[5] = (u8)(driver_handler >> 8);
1189 	cfg->wid_header[6] = (u8)(driver_handler >> 16);
1190 	cfg->wid_header[7] = (u8)(driver_handler >> 24);
1191 	wilc->cfg_seq_no = seq_no;
1192 
1193 	if (!wilc_wlan_txq_add_cfg_pkt(vif, &cfg->wid_header[0], total_len))
1194 		return -1;
1195 
1196 	return 0;
1197 }
1198 
wilc_wlan_cfg_set(struct wilc_vif * vif,int start,u16 wid,u8 * buffer,u32 buffer_size,int commit,u32 drv_handler)1199 int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer,
1200 		      u32 buffer_size, int commit, u32 drv_handler)
1201 {
1202 	u32 offset;
1203 	int ret_size;
1204 	struct wilc *wilc = vif->wilc;
1205 
1206 	if (wilc->cfg_frame_in_use)
1207 		return 0;
1208 
1209 	if (start)
1210 		wilc->cfg_frame_offset = 0;
1211 
1212 	offset = wilc->cfg_frame_offset;
1213 	ret_size = wilc_wlan_cfg_set_wid(wilc->cfg_frame.frame, offset,
1214 					 wid, buffer, buffer_size);
1215 	offset += ret_size;
1216 	wilc->cfg_frame_offset = offset;
1217 
1218 	if (commit) {
1219 		netdev_dbg(vif->ndev,
1220 			   "[WILC]PACKET Commit with sequence number %d\n",
1221 			   wilc->cfg_seq_no);
1222 		netdev_dbg(vif->ndev, "Processing cfg_set()\n");
1223 		wilc->cfg_frame_in_use = 1;
1224 
1225 		if (wilc_wlan_cfg_commit(vif, WILC_CFG_SET, drv_handler))
1226 			ret_size = 0;
1227 
1228 		if (!wait_for_completion_timeout(&wilc->cfg_event,
1229 						 msecs_to_jiffies(CFG_PKTS_TIMEOUT))) {
1230 			netdev_dbg(vif->ndev, "Set Timed Out\n");
1231 			ret_size = 0;
1232 		}
1233 
1234 		wilc->cfg_frame_in_use = 0;
1235 		wilc->cfg_frame_offset = 0;
1236 		wilc->cfg_seq_no += 1;
1237 	}
1238 
1239 	return ret_size;
1240 }
1241 
wilc_wlan_cfg_get(struct wilc_vif * vif,int start,u16 wid,int commit,u32 drv_handler)1242 int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit,
1243 		      u32 drv_handler)
1244 {
1245 	u32 offset;
1246 	int ret_size;
1247 	struct wilc *wilc = vif->wilc;
1248 
1249 	if (wilc->cfg_frame_in_use)
1250 		return 0;
1251 
1252 	if (start)
1253 		wilc->cfg_frame_offset = 0;
1254 
1255 	offset = wilc->cfg_frame_offset;
1256 	ret_size = wilc_wlan_cfg_get_wid(wilc->cfg_frame.frame, offset, wid);
1257 	offset += ret_size;
1258 	wilc->cfg_frame_offset = offset;
1259 
1260 	if (commit) {
1261 		wilc->cfg_frame_in_use = 1;
1262 
1263 		if (wilc_wlan_cfg_commit(vif, WILC_CFG_QUERY, drv_handler))
1264 			ret_size = 0;
1265 
1266 		if (!wait_for_completion_timeout(&wilc->cfg_event,
1267 					msecs_to_jiffies(CFG_PKTS_TIMEOUT))) {
1268 			netdev_dbg(vif->ndev, "Get Timed Out\n");
1269 			ret_size = 0;
1270 		}
1271 		wilc->cfg_frame_in_use = 0;
1272 		wilc->cfg_frame_offset = 0;
1273 		wilc->cfg_seq_no += 1;
1274 	}
1275 
1276 	return ret_size;
1277 }
1278 
wilc_wlan_cfg_get_val(u16 wid,u8 * buffer,u32 buffer_size)1279 int wilc_wlan_cfg_get_val(u16 wid, u8 *buffer, u32 buffer_size)
1280 {
1281 	return wilc_wlan_cfg_get_wid_value(wid, buffer, buffer_size);
1282 }
1283 
wilc_send_config_pkt(struct wilc_vif * vif,u8 mode,struct wid * wids,u32 count,u32 drv)1284 int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
1285 			 u32 count, u32 drv)
1286 {
1287 	int i;
1288 	int ret = 0;
1289 
1290 	if (mode == GET_CFG) {
1291 		for (i = 0; i < count; i++) {
1292 			if (!wilc_wlan_cfg_get(vif, !i,
1293 					       wids[i].id,
1294 					       (i == count - 1),
1295 					       drv)) {
1296 				ret = -ETIMEDOUT;
1297 				break;
1298 			}
1299 		}
1300 		for (i = 0; i < count; i++) {
1301 			wids[i].size = wilc_wlan_cfg_get_val(wids[i].id,
1302 							     wids[i].val,
1303 							     wids[i].size);
1304 		}
1305 	} else if (mode == SET_CFG) {
1306 		for (i = 0; i < count; i++) {
1307 			if (!wilc_wlan_cfg_set(vif, !i,
1308 					       wids[i].id,
1309 					       wids[i].val,
1310 					       wids[i].size,
1311 					       (i == count - 1),
1312 					       drv)) {
1313 				ret = -ETIMEDOUT;
1314 				break;
1315 			}
1316 		}
1317 	}
1318 
1319 	return ret;
1320 }
1321 
init_chip(struct net_device * dev)1322 static u32 init_chip(struct net_device *dev)
1323 {
1324 	u32 chipid;
1325 	u32 reg, ret = 0;
1326 	struct wilc_vif *vif;
1327 	struct wilc *wilc;
1328 
1329 	vif = netdev_priv(dev);
1330 	wilc = vif->wilc;
1331 
1332 	acquire_bus(wilc, ACQUIRE_ONLY);
1333 
1334 	chipid = wilc_get_chipid(wilc, true);
1335 
1336 	if ((chipid & 0xfff) != 0xa0) {
1337 		ret = wilc->hif_func->hif_read_reg(wilc, 0x1118, &reg);
1338 		if (!ret) {
1339 			netdev_err(dev, "fail read reg 0x1118\n");
1340 			return ret;
1341 		}
1342 		reg |= BIT(0);
1343 		ret = wilc->hif_func->hif_write_reg(wilc, 0x1118, reg);
1344 		if (!ret) {
1345 			netdev_err(dev, "fail write reg 0x1118\n");
1346 			return ret;
1347 		}
1348 		ret = wilc->hif_func->hif_write_reg(wilc, 0xc0000, 0x71);
1349 		if (!ret) {
1350 			netdev_err(dev, "fail write reg 0xc0000\n");
1351 			return ret;
1352 		}
1353 	}
1354 
1355 	release_bus(wilc, RELEASE_ONLY);
1356 
1357 	return ret;
1358 }
1359 
wilc_get_chipid(struct wilc * wilc,bool update)1360 u32 wilc_get_chipid(struct wilc *wilc, bool update)
1361 {
1362 	static u32 chipid;
1363 	u32 tempchipid = 0;
1364 	u32 rfrevid = 0;
1365 
1366 	if (chipid == 0 || update) {
1367 		wilc->hif_func->hif_read_reg(wilc, 0x1000, &tempchipid);
1368 		wilc->hif_func->hif_read_reg(wilc, 0x13f4, &rfrevid);
1369 		if (!ISWILC1000(tempchipid)) {
1370 			chipid = 0;
1371 			return chipid;
1372 		}
1373 		if (tempchipid == 0x1002a0) {
1374 			if (rfrevid != 0x1)
1375 				tempchipid = 0x1002a1;
1376 		} else if (tempchipid == 0x1002b0) {
1377 			if (rfrevid == 0x4)
1378 				tempchipid = 0x1002b1;
1379 			else if (rfrevid != 0x3)
1380 				tempchipid = 0x1002b2;
1381 		}
1382 
1383 		chipid = tempchipid;
1384 	}
1385 	return chipid;
1386 }
1387 
wilc_wlan_init(struct net_device * dev)1388 int wilc_wlan_init(struct net_device *dev)
1389 {
1390 	int ret = 0;
1391 	struct wilc_vif *vif = netdev_priv(dev);
1392 	struct wilc *wilc;
1393 
1394 	wilc = vif->wilc;
1395 
1396 	wilc->quit = 0;
1397 
1398 	if (!wilc->hif_func->hif_init(wilc, false)) {
1399 		ret = -EIO;
1400 		goto _fail_;
1401 	}
1402 
1403 	if (!wilc_wlan_cfg_init()) {
1404 		ret = -ENOBUFS;
1405 		goto _fail_;
1406 	}
1407 
1408 	if (!wilc->tx_buffer)
1409 		wilc->tx_buffer = kmalloc(LINUX_TX_SIZE, GFP_KERNEL);
1410 
1411 	if (!wilc->tx_buffer) {
1412 		ret = -ENOBUFS;
1413 		goto _fail_;
1414 	}
1415 
1416 	if (!wilc->rx_buffer)
1417 		wilc->rx_buffer = kmalloc(LINUX_RX_SIZE, GFP_KERNEL);
1418 
1419 	if (!wilc->rx_buffer) {
1420 		ret = -ENOBUFS;
1421 		goto _fail_;
1422 	}
1423 
1424 	if (!init_chip(dev)) {
1425 		ret = -EIO;
1426 		goto _fail_;
1427 	}
1428 
1429 	return 1;
1430 
1431 _fail_:
1432 
1433 	kfree(wilc->rx_buffer);
1434 	wilc->rx_buffer = NULL;
1435 	kfree(wilc->tx_buffer);
1436 	wilc->tx_buffer = NULL;
1437 
1438 	return ret;
1439 }
1440