1 #include "wilc_wlan_if.h"
3 #include "wilc_wfi_netdevice.h"
4 #include "wilc_wlan_cfg.h"
6 static CHIP_PS_STATE_T chip_ps_state = CHIP_WAKEDUP;
8 static inline void acquire_bus(struct wilc *wilc, BUS_ACQUIRE_T acquire)
10 mutex_lock(&wilc->hif_cs);
11 if (acquire == ACQUIRE_AND_WAKEUP)
15 static inline void release_bus(struct wilc *wilc, BUS_RELEASE_T release)
17 if (release == RELEASE_ALLOW_SLEEP)
18 chip_allow_sleep(wilc);
19 mutex_unlock(&wilc->hif_cs);
22 static void wilc_wlan_txq_remove(struct wilc *wilc, struct txq_entry_t *tqe)
24 if (tqe == wilc->txq_head) {
25 wilc->txq_head = tqe->next;
27 wilc->txq_head->prev = NULL;
28 } else if (tqe == wilc->txq_tail) {
29 wilc->txq_tail = (tqe->prev);
31 wilc->txq_tail->next = NULL;
33 tqe->prev->next = tqe->next;
34 tqe->next->prev = tqe->prev;
36 wilc->txq_entries -= 1;
39 static struct txq_entry_t *
40 wilc_wlan_txq_remove_from_head(struct net_device *dev)
42 struct txq_entry_t *tqe;
47 vif = netdev_priv(dev);
50 spin_lock_irqsave(&wilc->txq_spinlock, flags);
53 wilc->txq_head = tqe->next;
55 wilc->txq_head->prev = NULL;
57 wilc->txq_entries -= 1;
61 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
65 static void wilc_wlan_txq_add_to_tail(struct net_device *dev,
66 struct txq_entry_t *tqe)
72 vif = netdev_priv(dev);
75 spin_lock_irqsave(&wilc->txq_spinlock, flags);
77 if (!wilc->txq_head) {
84 tqe->prev = wilc->txq_tail;
85 wilc->txq_tail->next = tqe;
88 wilc->txq_entries += 1;
90 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
95 static int wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
96 struct txq_entry_t *tqe)
99 struct wilc *wilc = vif->wilc;
101 if (wilc_lock_timeout(wilc, &wilc->txq_add_to_head_cs,
105 spin_lock_irqsave(&wilc->txq_spinlock, flags);
107 if (!wilc->txq_head) {
110 wilc->txq_head = tqe;
111 wilc->txq_tail = tqe;
113 tqe->next = wilc->txq_head;
115 wilc->txq_head->prev = tqe;
116 wilc->txq_head = tqe;
118 wilc->txq_entries += 1;
120 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
121 up(&wilc->txq_add_to_head_cs);
122 up(&wilc->txq_event);
127 struct ack_session_info;
128 struct ack_session_info {
136 struct pending_acks_info {
139 struct txq_entry_t *txqe;
142 #define NOT_TCP_ACK (-1)
144 #define MAX_TCP_SESSION 25
145 #define MAX_PENDING_ACKS 256
146 static struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION];
147 static struct pending_acks_info pending_acks_info[MAX_PENDING_ACKS];
149 static u32 pending_base;
150 static u32 tcp_session;
151 static u32 pending_acks;
153 static inline int init_tcp_tracking(void)
158 static inline int add_tcp_session(u32 src_prt, u32 dst_prt, u32 seq)
160 if (tcp_session < 2 * MAX_TCP_SESSION) {
161 ack_session_info[tcp_session].seq_num = seq;
162 ack_session_info[tcp_session].bigger_ack_num = 0;
163 ack_session_info[tcp_session].src_port = src_prt;
164 ack_session_info[tcp_session].dst_port = dst_prt;
170 static inline int update_tcp_session(u32 index, u32 ack)
172 if (index < 2 * MAX_TCP_SESSION &&
173 ack > ack_session_info[index].bigger_ack_num)
174 ack_session_info[index].bigger_ack_num = ack;
178 static inline int add_tcp_pending_ack(u32 ack, u32 session_index,
179 struct txq_entry_t *txqe)
181 if (pending_base + pending_acks < MAX_PENDING_ACKS) {
182 pending_acks_info[pending_base + pending_acks].ack_num = ack;
183 pending_acks_info[pending_base + pending_acks].txqe = txqe;
184 pending_acks_info[pending_base + pending_acks].session_index = session_index;
185 txqe->tcp_pending_ack_idx = pending_base + pending_acks;
191 static inline void tcp_process(struct net_device *dev, struct txq_entry_t *tqe)
194 u8 *buffer = tqe->buffer;
195 unsigned short h_proto;
198 struct wilc_vif *vif;
201 vif = netdev_priv(dev);
204 spin_lock_irqsave(&wilc->txq_spinlock, flags);
206 eth_hdr_ptr = &buffer[0];
207 h_proto = ntohs(*((unsigned short *)ð_hdr_ptr[12]));
208 if (h_proto == ETH_P_IP) {
212 ip_hdr_ptr = &buffer[ETHERNET_HDR_LEN];
213 protocol = ip_hdr_ptr[9];
215 if (protocol == 0x06) {
217 u32 IHL, total_length, data_offset;
219 tcp_hdr_ptr = &ip_hdr_ptr[IP_HDR_LEN];
220 IHL = (ip_hdr_ptr[0] & 0xf) << 2;
221 total_length = ((u32)ip_hdr_ptr[2] << 8) +
223 data_offset = ((u32)tcp_hdr_ptr[12] & 0xf0) >> 2;
224 if (total_length == (IHL + data_offset)) {
227 seq_no = ((u32)tcp_hdr_ptr[4] << 24) +
228 ((u32)tcp_hdr_ptr[5] << 16) +
229 ((u32)tcp_hdr_ptr[6] << 8) +
232 ack_no = ((u32)tcp_hdr_ptr[8] << 24) +
233 ((u32)tcp_hdr_ptr[9] << 16) +
234 ((u32)tcp_hdr_ptr[10] << 8) +
235 (u32)tcp_hdr_ptr[11];
237 for (i = 0; i < tcp_session; i++) {
238 if (i < 2 * MAX_TCP_SESSION &&
239 ack_session_info[i].seq_num == seq_no) {
240 update_tcp_session(i, ack_no);
244 if (i == tcp_session)
245 add_tcp_session(0, 0, seq_no);
247 add_tcp_pending_ack(ack_no, i, tqe);
251 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
254 static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
256 struct wilc_vif *vif;
261 vif = netdev_priv(dev);
264 spin_lock_irqsave(&wilc->txq_spinlock, wilc->txq_spinlock_flags);
265 for (i = pending_base; i < (pending_base + pending_acks); i++) {
266 if (i >= MAX_PENDING_ACKS ||
267 pending_acks_info[i].session_index >= 2 * MAX_TCP_SESSION)
269 if (pending_acks_info[i].ack_num < ack_session_info[pending_acks_info[i].session_index].bigger_ack_num) {
270 struct txq_entry_t *tqe;
272 tqe = pending_acks_info[i].txqe;
274 wilc_wlan_txq_remove(wilc, tqe);
276 if (tqe->tx_complete_func)
277 tqe->tx_complete_func(tqe->priv,
287 if (pending_base == 0)
288 pending_base = MAX_TCP_SESSION;
292 spin_unlock_irqrestore(&wilc->txq_spinlock, wilc->txq_spinlock_flags);
294 while (dropped > 0) {
295 wilc_lock_timeout(wilc, &wilc->txq_event, 1);
304 void wilc_enable_tcp_ack_filter(bool value)
309 static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer,
312 struct txq_entry_t *tqe;
313 struct wilc *wilc = vif->wilc;
315 netdev_dbg(vif->ndev, "Adding config packet ...\n");
317 netdev_dbg(vif->ndev, "Return due to clear function\n");
318 up(&wilc->cfg_event);
322 tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
326 tqe->type = WILC_CFG_PKT;
327 tqe->buffer = buffer;
328 tqe->buffer_size = buffer_size;
329 tqe->tx_complete_func = NULL;
331 tqe->tcp_pending_ack_idx = NOT_TCP_ACK;
333 if (wilc_wlan_txq_add_to_head(vif, tqe))
338 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
339 u32 buffer_size, wilc_tx_complete_func_t func)
341 struct txq_entry_t *tqe;
342 struct wilc_vif *vif = netdev_priv(dev);
350 tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
354 tqe->type = WILC_NET_PKT;
355 tqe->buffer = buffer;
356 tqe->buffer_size = buffer_size;
357 tqe->tx_complete_func = func;
360 tqe->tcp_pending_ack_idx = NOT_TCP_ACK;
362 tcp_process(dev, tqe);
363 wilc_wlan_txq_add_to_tail(dev, tqe);
364 return wilc->txq_entries;
367 int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
368 u32 buffer_size, wilc_tx_complete_func_t func)
370 struct txq_entry_t *tqe;
371 struct wilc_vif *vif = netdev_priv(dev);
379 tqe = kmalloc(sizeof(*tqe), GFP_KERNEL);
383 tqe->type = WILC_MGMT_PKT;
384 tqe->buffer = buffer;
385 tqe->buffer_size = buffer_size;
386 tqe->tx_complete_func = func;
388 tqe->tcp_pending_ack_idx = NOT_TCP_ACK;
389 wilc_wlan_txq_add_to_tail(dev, tqe);
393 static struct txq_entry_t *wilc_wlan_txq_get_first(struct wilc *wilc)
395 struct txq_entry_t *tqe;
398 spin_lock_irqsave(&wilc->txq_spinlock, flags);
400 tqe = wilc->txq_head;
402 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
407 static struct txq_entry_t *wilc_wlan_txq_get_next(struct wilc *wilc,
408 struct txq_entry_t *tqe)
412 spin_lock_irqsave(&wilc->txq_spinlock, flags);
415 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
420 static int wilc_wlan_rxq_add(struct wilc *wilc, struct rxq_entry_t *rqe)
425 mutex_lock(&wilc->rxq_cs);
426 if (!wilc->rxq_head) {
428 wilc->rxq_head = rqe;
429 wilc->rxq_tail = rqe;
431 wilc->rxq_tail->next = rqe;
433 wilc->rxq_tail = rqe;
435 wilc->rxq_entries += 1;
436 mutex_unlock(&wilc->rxq_cs);
437 return wilc->rxq_entries;
440 static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
442 if (wilc->rxq_head) {
443 struct rxq_entry_t *rqe;
445 mutex_lock(&wilc->rxq_cs);
446 rqe = wilc->rxq_head;
447 wilc->rxq_head = wilc->rxq_head->next;
448 wilc->rxq_entries -= 1;
449 mutex_unlock(&wilc->rxq_cs);
455 void chip_allow_sleep(struct wilc *wilc)
459 wilc->hif_func->hif_read_reg(wilc, 0xf0, ®);
461 wilc->hif_func->hif_write_reg(wilc, 0xf0, reg & ~BIT(0));
462 wilc->hif_func->hif_write_reg(wilc, 0xfa, 0);
464 EXPORT_SYMBOL_GPL(chip_allow_sleep);
466 void chip_wakeup(struct wilc *wilc)
468 u32 reg, clk_status_reg;
470 if ((wilc->io_type & 0x1) == HIF_SPI) {
472 wilc->hif_func->hif_read_reg(wilc, 1, ®);
473 wilc->hif_func->hif_write_reg(wilc, 1, reg | BIT(1));
474 wilc->hif_func->hif_write_reg(wilc, 1, reg & ~BIT(1));
477 usleep_range(2 * 1000, 2 * 1000);
478 wilc_get_chipid(wilc, true);
479 } while (wilc_get_chipid(wilc, true) == 0);
480 } while (wilc_get_chipid(wilc, true) == 0);
481 } else if ((wilc->io_type & 0x1) == HIF_SDIO) {
482 wilc->hif_func->hif_write_reg(wilc, 0xfa, 1);
484 wilc->hif_func->hif_read_reg(wilc, 0xf0, ®);
486 wilc->hif_func->hif_write_reg(wilc, 0xf0,
488 wilc->hif_func->hif_read_reg(wilc, 0xf1,
491 while ((clk_status_reg & 0x1) == 0) {
492 usleep_range(2 * 1000, 2 * 1000);
494 wilc->hif_func->hif_read_reg(wilc, 0xf1,
497 if ((clk_status_reg & 0x1) == 0) {
498 wilc->hif_func->hif_write_reg(wilc, 0xf0,
501 } while ((clk_status_reg & 0x1) == 0);
504 if (chip_ps_state == CHIP_SLEEPING_MANUAL) {
505 if (wilc_get_chipid(wilc, false) < 0x1002b0) {
508 wilc->hif_func->hif_read_reg(wilc, 0x1e1c, &val32);
510 wilc->hif_func->hif_write_reg(wilc, 0x1e1c, val32);
512 wilc->hif_func->hif_read_reg(wilc, 0x1e9c, &val32);
514 wilc->hif_func->hif_write_reg(wilc, 0x1e9c, val32);
517 chip_ps_state = CHIP_WAKEDUP;
519 EXPORT_SYMBOL_GPL(chip_wakeup);
521 void wilc_chip_sleep_manually(struct wilc *wilc)
523 if (chip_ps_state != CHIP_WAKEDUP)
525 acquire_bus(wilc, ACQUIRE_ONLY);
527 chip_allow_sleep(wilc);
528 wilc->hif_func->hif_write_reg(wilc, 0x10a8, 1);
530 chip_ps_state = CHIP_SLEEPING_MANUAL;
531 release_bus(wilc, RELEASE_ONLY);
533 EXPORT_SYMBOL_GPL(wilc_chip_sleep_manually);
535 void host_wakeup_notify(struct wilc *wilc)
537 acquire_bus(wilc, ACQUIRE_ONLY);
538 wilc->hif_func->hif_write_reg(wilc, 0x10b0, 1);
539 release_bus(wilc, RELEASE_ONLY);
541 EXPORT_SYMBOL_GPL(host_wakeup_notify);
543 void host_sleep_notify(struct wilc *wilc)
545 acquire_bus(wilc, ACQUIRE_ONLY);
546 wilc->hif_func->hif_write_reg(wilc, 0x10ac, 1);
547 release_bus(wilc, RELEASE_ONLY);
549 EXPORT_SYMBOL_GPL(host_sleep_notify);
551 int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
559 struct txq_entry_t *tqe;
563 u32 vmm_table[WILC_VMM_TBL_SIZE];
564 struct wilc_vif *vif;
567 vif = netdev_priv(dev);
570 txb = wilc->tx_buffer;
576 wilc_lock_timeout(wilc, &wilc->txq_add_to_head_cs,
578 wilc_wlan_txq_filter_dup_tcp_ack(dev);
579 tqe = wilc_wlan_txq_get_first(wilc);
583 if (tqe && (i < (WILC_VMM_TBL_SIZE - 1))) {
584 if (tqe->type == WILC_CFG_PKT)
585 vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET;
587 else if (tqe->type == WILC_NET_PKT)
588 vmm_sz = ETH_ETHERNET_HDR_OFFSET;
591 vmm_sz = HOST_HDR_OFFSET;
593 vmm_sz += tqe->buffer_size;
596 vmm_sz = (vmm_sz + 4) & ~0x3;
598 if ((sum + vmm_sz) > LINUX_TX_SIZE)
601 vmm_table[i] = vmm_sz / 4;
602 if (tqe->type == WILC_CFG_PKT)
603 vmm_table[i] |= BIT(10);
604 vmm_table[i] = cpu_to_le32(vmm_table[i]);
608 tqe = wilc_wlan_txq_get_next(wilc, tqe);
618 acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
621 ret = wilc->hif_func->hif_read_reg(wilc,
627 if ((reg & 0x1) == 0) {
633 ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0);
637 } while (!wilc->quit);
644 ret = wilc->hif_func->hif_block_tx(wilc, WILC_VMM_TBL_RX_SHADOW_BASE, (u8 *)vmm_table, ((i + 1) * 4));
648 ret = wilc->hif_func->hif_write_reg(wilc,
655 ret = wilc->hif_func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, ®);
658 if ((reg >> 2) & 0x1) {
659 entries = ((reg >> 3) & 0x3f);
662 release_bus(wilc, RELEASE_ALLOW_SLEEP);
666 ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0);
674 ret = wilc->hif_func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, ®);
678 ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, reg);
691 ret = WILC_TX_ERR_NO_BUF;
695 release_bus(wilc, RELEASE_ALLOW_SLEEP);
700 tqe = wilc_wlan_txq_remove_from_head(dev);
701 if (tqe && (vmm_table[i] != 0)) {
702 u32 header, buffer_offset;
704 vmm_table[i] = cpu_to_le32(vmm_table[i]);
705 vmm_sz = (vmm_table[i] & 0x3ff);
707 header = (tqe->type << 31) |
708 (tqe->buffer_size << 15) |
710 if (tqe->type == WILC_MGMT_PKT)
715 header = cpu_to_le32(header);
716 memcpy(&txb[offset], &header, 4);
717 if (tqe->type == WILC_CFG_PKT) {
718 buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET;
719 } else if (tqe->type == WILC_NET_PKT) {
720 char *bssid = ((struct tx_complete_data *)(tqe->priv))->bssid;
722 buffer_offset = ETH_ETHERNET_HDR_OFFSET;
723 memcpy(&txb[offset + 4], bssid, 6);
725 buffer_offset = HOST_HDR_OFFSET;
728 memcpy(&txb[offset + buffer_offset],
729 tqe->buffer, tqe->buffer_size);
733 if (tqe->tx_complete_func)
734 tqe->tx_complete_func(tqe->priv,
736 if (tqe->tcp_pending_ack_idx != NOT_TCP_ACK &&
737 tqe->tcp_pending_ack_idx < MAX_PENDING_ACKS)
738 pending_acks_info[tqe->tcp_pending_ack_idx].txqe = NULL;
745 acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
747 ret = wilc->hif_func->hif_clear_int_ext(wilc, ENABLE_TX_VMM);
751 ret = wilc->hif_func->hif_block_tx_ext(wilc, 0, txb, offset);
757 release_bus(wilc, RELEASE_ALLOW_SLEEP);
761 up(&wilc->txq_add_to_head_cs);
764 *txq_count = wilc->txq_entries;
768 static void wilc_wlan_handle_rxq(struct wilc *wilc)
770 int offset = 0, size;
772 struct rxq_entry_t *rqe;
778 up(&wilc->cfg_event);
781 rqe = wilc_wlan_rxq_remove(wilc);
785 buffer = rqe->buffer;
786 size = rqe->buffer_size;
791 u32 pkt_len, pkt_offset, tp_len;
794 memcpy(&header, &buffer[offset], 4);
795 header = cpu_to_le32(header);
797 is_cfg_packet = (header >> 31) & 0x1;
798 pkt_offset = (header >> 22) & 0x1ff;
799 tp_len = (header >> 11) & 0x7ff;
800 pkt_len = header & 0x7ff;
802 if (pkt_len == 0 || tp_len == 0)
805 #define IS_MANAGMEMENT 0x100
806 #define IS_MANAGMEMENT_CALLBACK 0x080
807 #define IS_MGMT_STATUS_SUCCES 0x040
809 if (pkt_offset & IS_MANAGMEMENT) {
810 pkt_offset &= ~(IS_MANAGMEMENT |
811 IS_MANAGMEMENT_CALLBACK |
812 IS_MGMT_STATUS_SUCCES);
814 WILC_WFI_mgmt_rx(wilc, &buffer[offset + HOST_HDR_OFFSET], pkt_len);
816 if (!is_cfg_packet) {
818 wilc_frmw_to_linux(wilc,
824 struct wilc_cfg_rsp rsp;
826 wilc_wlan_cfg_indicate_rx(wilc, &buffer[pkt_offset + offset], pkt_len, &rsp);
827 if (rsp.type == WILC_CFG_RSP) {
828 if (wilc->cfg_seq_no == rsp.seq_no)
829 up(&wilc->cfg_event);
830 } else if (rsp.type == WILC_CFG_RSP_STATUS) {
831 wilc_mac_indicate(wilc, WILC_MAC_INDICATE_STATUS);
833 } else if (rsp.type == WILC_CFG_RSP_SCAN) {
834 wilc_mac_indicate(wilc, WILC_MAC_INDICATE_SCAN);
848 static void wilc_unknown_isr_ext(struct wilc *wilc)
850 wilc->hif_func->hif_clear_int_ext(wilc, 0);
853 static void wilc_pllupdate_isr_ext(struct wilc *wilc, u32 int_stats)
857 wilc->hif_func->hif_clear_int_ext(wilc, PLL_INT_CLR);
859 if (wilc->io_type == HIF_SDIO)
860 mdelay(WILC_PLL_TO_SDIO);
862 mdelay(WILC_PLL_TO_SPI);
864 while (!(ISWILC1000(wilc_get_chipid(wilc, true)) && --trials))
868 static void wilc_sleeptimer_isr_ext(struct wilc *wilc, u32 int_stats1)
870 wilc->hif_func->hif_clear_int_ext(wilc, SLEEP_INT_CLR);
873 static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status)
875 u32 offset = wilc->rx_buffer_offset;
880 struct rxq_entry_t *rqe;
882 size = (int_status & 0x7fff) << 2;
884 while (!size && retries < 10) {
885 wilc->hif_func->hif_read_size(wilc, &size);
886 size = (size & 0x7fff) << 2;
891 if (LINUX_RX_SIZE - offset < size)
895 buffer = &wilc->rx_buffer[offset];
899 wilc->hif_func->hif_clear_int_ext(wilc,
900 DATA_INT_CLR | ENABLE_RX_VMM);
901 ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size);
908 wilc->rx_buffer_offset = offset;
909 rqe = kmalloc(sizeof(*rqe), GFP_KERNEL);
911 rqe->buffer = buffer;
912 rqe->buffer_size = size;
913 wilc_wlan_rxq_add(wilc, rqe);
917 wilc_wlan_handle_rxq(wilc);
920 void wilc_handle_isr(struct wilc *wilc)
924 acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
925 wilc->hif_func->hif_read_int(wilc, &int_status);
927 if (int_status & PLL_INT_EXT)
928 wilc_pllupdate_isr_ext(wilc, int_status);
930 if (int_status & DATA_INT_EXT)
931 wilc_wlan_handle_isr_ext(wilc, int_status);
933 if (int_status & SLEEP_INT_EXT)
934 wilc_sleeptimer_isr_ext(wilc, int_status);
936 if (!(int_status & (ALL_INT_EXT)))
937 wilc_unknown_isr_ext(wilc);
939 release_bus(wilc, RELEASE_ALLOW_SLEEP);
941 EXPORT_SYMBOL_GPL(wilc_handle_isr);
943 int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
947 u32 addr, size, size2, blksz;
953 dma_buffer = kmalloc(blksz, GFP_KERNEL);
961 memcpy(&addr, &buffer[offset], 4);
962 memcpy(&size, &buffer[offset + 4], 4);
963 addr = cpu_to_le32(addr);
964 size = cpu_to_le32(size);
965 acquire_bus(wilc, ACQUIRE_ONLY);
967 while (((int)size) && (offset < buffer_size)) {
973 memcpy(dma_buffer, &buffer[offset], size2);
974 ret = wilc->hif_func->hif_block_tx(wilc, addr,
983 release_bus(wilc, RELEASE_ONLY);
989 } while (offset < buffer_size);
997 return (ret < 0) ? ret : 0;
1000 int wilc_wlan_start(struct wilc *wilc)
1006 if (wilc->io_type == HIF_SDIO) {
1009 } else if (wilc->io_type == HIF_SPI) {
1012 acquire_bus(wilc, ACQUIRE_ONLY);
1013 ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg);
1015 release_bus(wilc, RELEASE_ONLY);
1020 if (wilc->io_type == HIF_SDIO && wilc->dev_irq_num)
1021 reg |= WILC_HAVE_SDIO_IRQ_GPIO;
1023 #ifdef WILC_DISABLE_PMU
1025 reg |= WILC_HAVE_USE_PMU;
1028 #ifdef WILC_SLEEP_CLK_SRC_XO
1029 reg |= WILC_HAVE_SLEEP_CLK_SRC_XO;
1030 #elif defined WILC_SLEEP_CLK_SRC_RTC
1031 reg |= WILC_HAVE_SLEEP_CLK_SRC_RTC;
1034 #ifdef WILC_EXT_PA_INV_TX_RX
1035 reg |= WILC_HAVE_EXT_PA_INV_TX_RX;
1037 reg |= WILC_HAVE_USE_IRQ_AS_HOST_WAKE;
1038 reg |= WILC_HAVE_LEGACY_RF_SETTINGS;
1040 reg |= WILC_HAVE_XTAL_24;
1042 #ifdef DISABLE_WILC_UART
1043 reg |= WILC_HAVE_DISABLE_WILC_UART;
1046 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg);
1048 release_bus(wilc, RELEASE_ONLY);
1053 wilc->hif_func->hif_sync_ext(wilc, NUM_INT_EXT);
1055 ret = wilc->hif_func->hif_read_reg(wilc, 0x1000, &chipid);
1057 release_bus(wilc, RELEASE_ONLY);
1062 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®);
1063 if ((reg & BIT(10)) == BIT(10)) {
1065 wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1066 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®);
1070 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1071 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®);
1072 release_bus(wilc, RELEASE_ONLY);
1074 return (ret < 0) ? ret : 0;
1077 int wilc_wlan_stop(struct wilc *wilc)
1083 acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
1085 ret = wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®);
1087 release_bus(wilc, RELEASE_ALLOW_SLEEP);
1092 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1094 release_bus(wilc, RELEASE_ALLOW_SLEEP);
1099 ret = wilc->hif_func->hif_read_reg(wilc,
1100 WILC_GLB_RESET_0, ®);
1102 release_bus(wilc, RELEASE_ALLOW_SLEEP);
1106 if ((reg & BIT(10))) {
1108 ret = wilc->hif_func->hif_write_reg(wilc,
1113 ret = wilc->hif_func->hif_read_reg(wilc,
1117 release_bus(wilc, RELEASE_ALLOW_SLEEP);
1124 reg = (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(8) | BIT(9) | BIT(26) |
1125 BIT(29) | BIT(30) | BIT(31));
1127 wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1128 reg = (u32)~BIT(10);
1130 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1132 release_bus(wilc, RELEASE_ALLOW_SLEEP);
1137 void wilc_wlan_cleanup(struct net_device *dev)
1139 struct txq_entry_t *tqe;
1140 struct rxq_entry_t *rqe;
1143 struct wilc_vif *vif;
1146 vif = netdev_priv(dev);
1151 tqe = wilc_wlan_txq_remove_from_head(dev);
1154 if (tqe->tx_complete_func)
1155 tqe->tx_complete_func(tqe->priv, 0);
1160 rqe = wilc_wlan_rxq_remove(wilc);
1166 kfree(wilc->rx_buffer);
1167 wilc->rx_buffer = NULL;
1168 kfree(wilc->tx_buffer);
1169 wilc->tx_buffer = NULL;
1171 acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
1173 ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, ®);
1175 release_bus(wilc, RELEASE_ALLOW_SLEEP);
1177 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0,
1180 release_bus(wilc, RELEASE_ALLOW_SLEEP);
1182 release_bus(wilc, RELEASE_ALLOW_SLEEP);
1183 wilc->hif_func->hif_deinit(NULL);
1186 static int wilc_wlan_cfg_commit(struct wilc_vif *vif, int type,
1189 struct wilc *wilc = vif->wilc;
1190 struct wilc_cfg_frame *cfg = &wilc->cfg_frame;
1191 int total_len = wilc->cfg_frame_offset + 4 + DRIVER_HANDLER_SIZE;
1192 int seq_no = wilc->cfg_seq_no % 256;
1193 int driver_handler = (u32)drv_handler;
1195 if (type == WILC_CFG_SET)
1196 cfg->wid_header[0] = 'W';
1198 cfg->wid_header[0] = 'Q';
1199 cfg->wid_header[1] = seq_no;
1200 cfg->wid_header[2] = (u8)total_len;
1201 cfg->wid_header[3] = (u8)(total_len >> 8);
1202 cfg->wid_header[4] = (u8)driver_handler;
1203 cfg->wid_header[5] = (u8)(driver_handler >> 8);
1204 cfg->wid_header[6] = (u8)(driver_handler >> 16);
1205 cfg->wid_header[7] = (u8)(driver_handler >> 24);
1206 wilc->cfg_seq_no = seq_no;
1208 if (!wilc_wlan_txq_add_cfg_pkt(vif, &cfg->wid_header[0], total_len))
1214 int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u32 wid, u8 *buffer,
1215 u32 buffer_size, int commit, u32 drv_handler)
1219 struct wilc *wilc = vif->wilc;
1221 if (wilc->cfg_frame_in_use)
1225 wilc->cfg_frame_offset = 0;
1227 offset = wilc->cfg_frame_offset;
1228 ret_size = wilc_wlan_cfg_set_wid(wilc->cfg_frame.frame, offset,
1229 (u16)wid, buffer, buffer_size);
1231 wilc->cfg_frame_offset = offset;
1234 netdev_dbg(vif->ndev,
1235 "[WILC]PACKET Commit with sequence number %d\n",
1237 netdev_dbg(vif->ndev, "Processing cfg_set()\n");
1238 wilc->cfg_frame_in_use = 1;
1240 if (wilc_wlan_cfg_commit(vif, WILC_CFG_SET, drv_handler))
1243 if (wilc_lock_timeout(wilc, &wilc->cfg_event,
1244 CFG_PKTS_TIMEOUT)) {
1245 netdev_dbg(vif->ndev, "Set Timed Out\n");
1248 wilc->cfg_frame_in_use = 0;
1249 wilc->cfg_frame_offset = 0;
1250 wilc->cfg_seq_no += 1;
1256 int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u32 wid, int commit,
1261 struct wilc *wilc = vif->wilc;
1263 if (wilc->cfg_frame_in_use)
1267 wilc->cfg_frame_offset = 0;
1269 offset = wilc->cfg_frame_offset;
1270 ret_size = wilc_wlan_cfg_get_wid(wilc->cfg_frame.frame, offset,
1273 wilc->cfg_frame_offset = offset;
1276 wilc->cfg_frame_in_use = 1;
1278 if (wilc_wlan_cfg_commit(vif, WILC_CFG_QUERY, drv_handler))
1281 if (wilc_lock_timeout(wilc, &wilc->cfg_event,
1282 CFG_PKTS_TIMEOUT)) {
1283 netdev_dbg(vif->ndev, "Get Timed Out\n");
1286 wilc->cfg_frame_in_use = 0;
1287 wilc->cfg_frame_offset = 0;
1288 wilc->cfg_seq_no += 1;
1294 int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size)
1296 return wilc_wlan_cfg_get_wid_value((u16)wid, buffer, buffer_size);
1299 int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
1305 if (mode == GET_CFG) {
1306 for (i = 0; i < count; i++) {
1307 if (!wilc_wlan_cfg_get(vif, !i,
1315 for (i = 0; i < count; i++) {
1316 wids[i].size = wilc_wlan_cfg_get_val(wids[i].id,
1320 } else if (mode == SET_CFG) {
1321 for (i = 0; i < count; i++) {
1322 if (!wilc_wlan_cfg_set(vif, !i,
1337 static u32 init_chip(struct net_device *dev)
1341 struct wilc_vif *vif;
1344 vif = netdev_priv(dev);
1347 acquire_bus(wilc, ACQUIRE_ONLY);
1349 chipid = wilc_get_chipid(wilc, true);
1351 if ((chipid & 0xfff) != 0xa0) {
1352 ret = wilc->hif_func->hif_read_reg(wilc, 0x1118, ®);
1354 netdev_err(dev, "fail read reg 0x1118\n");
1358 ret = wilc->hif_func->hif_write_reg(wilc, 0x1118, reg);
1360 netdev_err(dev, "fail write reg 0x1118\n");
1363 ret = wilc->hif_func->hif_write_reg(wilc, 0xc0000, 0x71);
1365 netdev_err(dev, "fail write reg 0xc0000\n");
1370 release_bus(wilc, RELEASE_ONLY);
1375 u32 wilc_get_chipid(struct wilc *wilc, bool update)
1381 if (chipid == 0 || update) {
1382 wilc->hif_func->hif_read_reg(wilc, 0x1000, &tempchipid);
1383 wilc->hif_func->hif_read_reg(wilc, 0x13f4, &rfrevid);
1384 if (!ISWILC1000(tempchipid)) {
1388 if (tempchipid == 0x1002a0) {
1390 tempchipid = 0x1002a1;
1391 } else if (tempchipid == 0x1002b0) {
1393 tempchipid = 0x1002b1;
1394 else if (rfrevid != 0x3)
1395 tempchipid = 0x1002b2;
1398 chipid = tempchipid;
1403 int wilc_wlan_init(struct net_device *dev)
1406 struct wilc_vif *vif = netdev_priv(dev);
1413 if (!wilc->hif_func->hif_init(wilc, false)) {
1418 if (!wilc_wlan_cfg_init()) {
1423 if (!wilc->tx_buffer)
1424 wilc->tx_buffer = kmalloc(LINUX_TX_SIZE, GFP_KERNEL);
1426 if (!wilc->tx_buffer) {
1431 if (!wilc->rx_buffer)
1432 wilc->rx_buffer = kmalloc(LINUX_RX_SIZE, GFP_KERNEL);
1434 if (!wilc->rx_buffer) {
1439 if (!init_chip(dev)) {
1443 init_tcp_tracking();
1449 kfree(wilc->rx_buffer);
1450 wilc->rx_buffer = NULL;
1451 kfree(wilc->tx_buffer);
1452 wilc->tx_buffer = NULL;