1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
7 #include <linux/if_ether.h>
12 static inline bool is_wilc1000(u32 id
)
14 return (id
& 0xfffff000) == 0x100000;
17 static inline void acquire_bus(struct wilc
*wilc
, enum bus_acquire acquire
)
19 mutex_lock(&wilc
->hif_cs
);
20 if (acquire
== WILC_BUS_ACQUIRE_AND_WAKEUP
)
24 static inline void release_bus(struct wilc
*wilc
, enum bus_release release
)
26 if (release
== WILC_BUS_RELEASE_ALLOW_SLEEP
)
27 chip_allow_sleep(wilc
);
28 mutex_unlock(&wilc
->hif_cs
);
31 static void wilc_wlan_txq_remove(struct wilc
*wilc
, struct txq_entry_t
*tqe
)
34 wilc
->txq_entries
-= 1;
37 static struct txq_entry_t
*
38 wilc_wlan_txq_remove_from_head(struct net_device
*dev
)
40 struct txq_entry_t
*tqe
= NULL
;
42 struct wilc_vif
*vif
= netdev_priv(dev
);
43 struct wilc
*wilc
= vif
->wilc
;
45 spin_lock_irqsave(&wilc
->txq_spinlock
, flags
);
47 if (!list_empty(&wilc
->txq_head
.list
)) {
48 tqe
= list_first_entry(&wilc
->txq_head
.list
, struct txq_entry_t
,
51 wilc
->txq_entries
-= 1;
53 spin_unlock_irqrestore(&wilc
->txq_spinlock
, flags
);
57 static void wilc_wlan_txq_add_to_tail(struct net_device
*dev
,
58 struct txq_entry_t
*tqe
)
61 struct wilc_vif
*vif
= netdev_priv(dev
);
62 struct wilc
*wilc
= vif
->wilc
;
64 spin_lock_irqsave(&wilc
->txq_spinlock
, flags
);
66 list_add_tail(&tqe
->list
, &wilc
->txq_head
.list
);
67 wilc
->txq_entries
+= 1;
69 spin_unlock_irqrestore(&wilc
->txq_spinlock
, flags
);
71 complete(&wilc
->txq_event
);
74 static void wilc_wlan_txq_add_to_head(struct wilc_vif
*vif
,
75 struct txq_entry_t
*tqe
)
78 struct wilc
*wilc
= vif
->wilc
;
80 mutex_lock(&wilc
->txq_add_to_head_cs
);
82 spin_lock_irqsave(&wilc
->txq_spinlock
, flags
);
84 list_add(&tqe
->list
, &wilc
->txq_head
.list
);
85 wilc
->txq_entries
+= 1;
87 spin_unlock_irqrestore(&wilc
->txq_spinlock
, flags
);
88 mutex_unlock(&wilc
->txq_add_to_head_cs
);
89 complete(&wilc
->txq_event
);
92 #define NOT_TCP_ACK (-1)
94 static inline void add_tcp_session(struct wilc_vif
*vif
, u32 src_prt
,
97 struct tcp_ack_filter
*f
= &vif
->ack_filter
;
99 if (f
->tcp_session
< 2 * MAX_TCP_SESSION
) {
100 f
->ack_session_info
[f
->tcp_session
].seq_num
= seq
;
101 f
->ack_session_info
[f
->tcp_session
].bigger_ack_num
= 0;
102 f
->ack_session_info
[f
->tcp_session
].src_port
= src_prt
;
103 f
->ack_session_info
[f
->tcp_session
].dst_port
= dst_prt
;
108 static inline void update_tcp_session(struct wilc_vif
*vif
, u32 index
, u32 ack
)
110 struct tcp_ack_filter
*f
= &vif
->ack_filter
;
112 if (index
< 2 * MAX_TCP_SESSION
&&
113 ack
> f
->ack_session_info
[index
].bigger_ack_num
)
114 f
->ack_session_info
[index
].bigger_ack_num
= ack
;
117 static inline void add_tcp_pending_ack(struct wilc_vif
*vif
, u32 ack
,
119 struct txq_entry_t
*txqe
)
121 struct tcp_ack_filter
*f
= &vif
->ack_filter
;
122 u32 i
= f
->pending_base
+ f
->pending_acks_idx
;
124 if (i
< MAX_PENDING_ACKS
) {
125 f
->pending_acks
[i
].ack_num
= ack
;
126 f
->pending_acks
[i
].txqe
= txqe
;
127 f
->pending_acks
[i
].session_index
= session_index
;
129 f
->pending_acks_idx
++;
133 static inline void tcp_process(struct net_device
*dev
, struct txq_entry_t
*tqe
)
135 void *buffer
= tqe
->buffer
;
136 const struct ethhdr
*eth_hdr_ptr
= buffer
;
139 struct wilc_vif
*vif
= netdev_priv(dev
);
140 struct wilc
*wilc
= vif
->wilc
;
141 struct tcp_ack_filter
*f
= &vif
->ack_filter
;
142 const struct iphdr
*ip_hdr_ptr
;
143 const struct tcphdr
*tcp_hdr_ptr
;
144 u32 ihl
, total_length
, data_offset
;
146 spin_lock_irqsave(&wilc
->txq_spinlock
, flags
);
148 if (eth_hdr_ptr
->h_proto
!= htons(ETH_P_IP
))
151 ip_hdr_ptr
= buffer
+ ETH_HLEN
;
153 if (ip_hdr_ptr
->protocol
!= IPPROTO_TCP
)
156 ihl
= ip_hdr_ptr
->ihl
<< 2;
157 tcp_hdr_ptr
= buffer
+ ETH_HLEN
+ ihl
;
158 total_length
= ntohs(ip_hdr_ptr
->tot_len
);
160 data_offset
= tcp_hdr_ptr
->doff
<< 2;
161 if (total_length
== (ihl
+ data_offset
)) {
164 seq_no
= ntohl(tcp_hdr_ptr
->seq
);
165 ack_no
= ntohl(tcp_hdr_ptr
->ack_seq
);
166 for (i
= 0; i
< f
->tcp_session
; i
++) {
167 u32 j
= f
->ack_session_info
[i
].seq_num
;
169 if (i
< 2 * MAX_TCP_SESSION
&&
171 update_tcp_session(vif
, i
, ack_no
);
175 if (i
== f
->tcp_session
)
176 add_tcp_session(vif
, 0, 0, seq_no
);
178 add_tcp_pending_ack(vif
, ack_no
, i
, tqe
);
182 spin_unlock_irqrestore(&wilc
->txq_spinlock
, flags
);
185 static void wilc_wlan_txq_filter_dup_tcp_ack(struct net_device
*dev
)
187 struct wilc_vif
*vif
= netdev_priv(dev
);
188 struct wilc
*wilc
= vif
->wilc
;
189 struct tcp_ack_filter
*f
= &vif
->ack_filter
;
194 spin_lock_irqsave(&wilc
->txq_spinlock
, flags
);
195 for (i
= f
->pending_base
;
196 i
< (f
->pending_base
+ f
->pending_acks_idx
); i
++) {
200 if (i
>= MAX_PENDING_ACKS
)
203 index
= f
->pending_acks
[i
].session_index
;
205 if (index
>= 2 * MAX_TCP_SESSION
)
208 bigger_ack_num
= f
->ack_session_info
[index
].bigger_ack_num
;
210 if (f
->pending_acks
[i
].ack_num
< bigger_ack_num
) {
211 struct txq_entry_t
*tqe
;
213 tqe
= f
->pending_acks
[i
].txqe
;
215 wilc_wlan_txq_remove(wilc
, tqe
);
217 if (tqe
->tx_complete_func
)
218 tqe
->tx_complete_func(tqe
->priv
,
225 f
->pending_acks_idx
= 0;
228 if (f
->pending_base
== 0)
229 f
->pending_base
= MAX_TCP_SESSION
;
233 spin_unlock_irqrestore(&wilc
->txq_spinlock
, flags
);
235 while (dropped
> 0) {
236 wait_for_completion_timeout(&wilc
->txq_event
,
237 msecs_to_jiffies(1));
242 void wilc_enable_tcp_ack_filter(struct wilc_vif
*vif
, bool value
)
244 vif
->ack_filter
.enabled
= value
;
247 static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif
*vif
, u8
*buffer
,
250 struct txq_entry_t
*tqe
;
251 struct wilc
*wilc
= vif
->wilc
;
253 netdev_dbg(vif
->ndev
, "Adding config packet ...\n");
255 netdev_dbg(vif
->ndev
, "Return due to clear function\n");
256 complete(&wilc
->cfg_event
);
260 tqe
= kmalloc(sizeof(*tqe
), GFP_ATOMIC
);
264 tqe
->type
= WILC_CFG_PKT
;
265 tqe
->buffer
= buffer
;
266 tqe
->buffer_size
= buffer_size
;
267 tqe
->tx_complete_func
= NULL
;
269 tqe
->ack_idx
= NOT_TCP_ACK
;
272 wilc_wlan_txq_add_to_head(vif
, tqe
);
277 int wilc_wlan_txq_add_net_pkt(struct net_device
*dev
, void *priv
, u8
*buffer
,
279 void (*tx_complete_fn
)(void *, int))
281 struct txq_entry_t
*tqe
;
282 struct wilc_vif
*vif
= netdev_priv(dev
);
290 tqe
= kmalloc(sizeof(*tqe
), GFP_ATOMIC
);
294 tqe
->type
= WILC_NET_PKT
;
295 tqe
->buffer
= buffer
;
296 tqe
->buffer_size
= buffer_size
;
297 tqe
->tx_complete_func
= tx_complete_fn
;
301 tqe
->ack_idx
= NOT_TCP_ACK
;
302 if (vif
->ack_filter
.enabled
)
303 tcp_process(dev
, tqe
);
304 wilc_wlan_txq_add_to_tail(dev
, tqe
);
305 return wilc
->txq_entries
;
308 int wilc_wlan_txq_add_mgmt_pkt(struct net_device
*dev
, void *priv
, u8
*buffer
,
310 void (*tx_complete_fn
)(void *, int))
312 struct txq_entry_t
*tqe
;
313 struct wilc_vif
*vif
= netdev_priv(dev
);
321 tqe
= kmalloc(sizeof(*tqe
), GFP_ATOMIC
);
325 tqe
->type
= WILC_MGMT_PKT
;
326 tqe
->buffer
= buffer
;
327 tqe
->buffer_size
= buffer_size
;
328 tqe
->tx_complete_func
= tx_complete_fn
;
330 tqe
->ack_idx
= NOT_TCP_ACK
;
332 wilc_wlan_txq_add_to_tail(dev
, tqe
);
336 static struct txq_entry_t
*wilc_wlan_txq_get_first(struct wilc
*wilc
)
338 struct txq_entry_t
*tqe
= NULL
;
341 spin_lock_irqsave(&wilc
->txq_spinlock
, flags
);
343 if (!list_empty(&wilc
->txq_head
.list
))
344 tqe
= list_first_entry(&wilc
->txq_head
.list
, struct txq_entry_t
,
347 spin_unlock_irqrestore(&wilc
->txq_spinlock
, flags
);
352 static struct txq_entry_t
*wilc_wlan_txq_get_next(struct wilc
*wilc
,
353 struct txq_entry_t
*tqe
)
357 spin_lock_irqsave(&wilc
->txq_spinlock
, flags
);
359 if (!list_is_last(&tqe
->list
, &wilc
->txq_head
.list
))
360 tqe
= list_next_entry(tqe
, list
);
363 spin_unlock_irqrestore(&wilc
->txq_spinlock
, flags
);
368 static void wilc_wlan_rxq_add(struct wilc
*wilc
, struct rxq_entry_t
*rqe
)
373 mutex_lock(&wilc
->rxq_cs
);
374 list_add_tail(&rqe
->list
, &wilc
->rxq_head
.list
);
375 mutex_unlock(&wilc
->rxq_cs
);
378 static struct rxq_entry_t
*wilc_wlan_rxq_remove(struct wilc
*wilc
)
380 struct rxq_entry_t
*rqe
= NULL
;
382 mutex_lock(&wilc
->rxq_cs
);
383 if (!list_empty(&wilc
->rxq_head
.list
)) {
384 rqe
= list_first_entry(&wilc
->rxq_head
.list
, struct rxq_entry_t
,
386 list_del(&rqe
->list
);
388 mutex_unlock(&wilc
->rxq_cs
);
392 void chip_allow_sleep(struct wilc
*wilc
)
396 wilc
->hif_func
->hif_read_reg(wilc
, 0xf0, ®
);
398 wilc
->hif_func
->hif_write_reg(wilc
, 0xf0, reg
& ~BIT(0));
399 wilc
->hif_func
->hif_write_reg(wilc
, 0xfa, 0);
401 EXPORT_SYMBOL_GPL(chip_allow_sleep
);
403 void chip_wakeup(struct wilc
*wilc
)
405 u32 reg
, clk_status_reg
;
407 if ((wilc
->io_type
& 0x1) == WILC_HIF_SPI
) {
409 wilc
->hif_func
->hif_read_reg(wilc
, 1, ®
);
410 wilc
->hif_func
->hif_write_reg(wilc
, 1, reg
| BIT(1));
411 wilc
->hif_func
->hif_write_reg(wilc
, 1, reg
& ~BIT(1));
414 usleep_range(2000, 2500);
415 wilc_get_chipid(wilc
, true);
416 } while (wilc_get_chipid(wilc
, true) == 0);
417 } while (wilc_get_chipid(wilc
, true) == 0);
418 } else if ((wilc
->io_type
& 0x1) == WILC_HIF_SDIO
) {
419 wilc
->hif_func
->hif_write_reg(wilc
, 0xfa, 1);
420 usleep_range(200, 400);
421 wilc
->hif_func
->hif_read_reg(wilc
, 0xf0, ®
);
423 wilc
->hif_func
->hif_write_reg(wilc
, 0xf0,
425 wilc
->hif_func
->hif_read_reg(wilc
, 0xf1,
428 while ((clk_status_reg
& 0x1) == 0) {
429 usleep_range(2000, 2500);
431 wilc
->hif_func
->hif_read_reg(wilc
, 0xf1,
434 if ((clk_status_reg
& 0x1) == 0) {
435 wilc
->hif_func
->hif_write_reg(wilc
, 0xf0,
438 } while ((clk_status_reg
& 0x1) == 0);
441 if (wilc
->chip_ps_state
== WILC_CHIP_SLEEPING_MANUAL
) {
442 if (wilc_get_chipid(wilc
, false) < 0x1002b0) {
445 wilc
->hif_func
->hif_read_reg(wilc
, 0x1e1c, &val32
);
447 wilc
->hif_func
->hif_write_reg(wilc
, 0x1e1c, val32
);
449 wilc
->hif_func
->hif_read_reg(wilc
, 0x1e9c, &val32
);
451 wilc
->hif_func
->hif_write_reg(wilc
, 0x1e9c, val32
);
454 wilc
->chip_ps_state
= WILC_CHIP_WAKEDUP
;
456 EXPORT_SYMBOL_GPL(chip_wakeup
);
458 void host_wakeup_notify(struct wilc
*wilc
)
460 acquire_bus(wilc
, WILC_BUS_ACQUIRE_ONLY
);
461 wilc
->hif_func
->hif_write_reg(wilc
, 0x10b0, 1);
462 release_bus(wilc
, WILC_BUS_RELEASE_ONLY
);
464 EXPORT_SYMBOL_GPL(host_wakeup_notify
);
466 void host_sleep_notify(struct wilc
*wilc
)
468 acquire_bus(wilc
, WILC_BUS_ACQUIRE_ONLY
);
469 wilc
->hif_func
->hif_write_reg(wilc
, 0x10ac, 1);
470 release_bus(wilc
, WILC_BUS_RELEASE_ONLY
);
472 EXPORT_SYMBOL_GPL(host_sleep_notify
);
474 int wilc_wlan_handle_txq(struct wilc
*wilc
, u32
*txq_count
)
481 struct txq_entry_t
*tqe
;
485 u32 vmm_table
[WILC_VMM_TBL_SIZE
];
486 const struct wilc_hif_func
*func
;
487 u8
*txb
= wilc
->tx_buffer
;
488 struct net_device
*dev
;
489 struct wilc_vif
*vif
;
494 mutex_lock(&wilc
->txq_add_to_head_cs
);
495 tqe
= wilc_wlan_txq_get_first(wilc
);
498 dev
= tqe
->vif
->ndev
;
499 wilc_wlan_txq_filter_dup_tcp_ack(dev
);
502 while (tqe
&& (i
< (WILC_VMM_TBL_SIZE
- 1))) {
503 if (tqe
->type
== WILC_CFG_PKT
)
504 vmm_sz
= ETH_CONFIG_PKT_HDR_OFFSET
;
505 else if (tqe
->type
== WILC_NET_PKT
)
506 vmm_sz
= ETH_ETHERNET_HDR_OFFSET
;
508 vmm_sz
= HOST_HDR_OFFSET
;
510 vmm_sz
+= tqe
->buffer_size
;
513 vmm_sz
= (vmm_sz
+ 4) & ~0x3;
515 if ((sum
+ vmm_sz
) > WILC_TX_BUFF_SIZE
)
518 vmm_table
[i
] = vmm_sz
/ 4;
519 if (tqe
->type
== WILC_CFG_PKT
)
520 vmm_table
[i
] |= BIT(10);
521 cpu_to_le32s(&vmm_table
[i
]);
525 tqe
= wilc_wlan_txq_get_next(wilc
, tqe
);
532 acquire_bus(wilc
, WILC_BUS_ACQUIRE_AND_WAKEUP
);
534 func
= wilc
->hif_func
;
536 ret
= func
->hif_read_reg(wilc
, WILC_HOST_TX_CTRL
, ®
);
540 if ((reg
& 0x1) == 0)
546 ret
= func
->hif_write_reg(wilc
, WILC_HOST_TX_CTRL
, 0);
549 } while (!wilc
->quit
);
552 goto out_release_bus
;
556 ret
= func
->hif_block_tx(wilc
,
557 WILC_VMM_TBL_RX_SHADOW_BASE
,
563 ret
= func
->hif_write_reg(wilc
, WILC_HOST_VMM_CTL
, 0x2);
568 ret
= func
->hif_read_reg(wilc
, WILC_HOST_VMM_CTL
, ®
);
571 if ((reg
>> 2) & 0x1) {
572 entries
= ((reg
>> 3) & 0x3f);
575 release_bus(wilc
, WILC_BUS_RELEASE_ALLOW_SLEEP
);
578 ret
= func
->hif_write_reg(wilc
, WILC_HOST_VMM_CTL
, 0x0);
586 ret
= func
->hif_read_reg(wilc
, WILC_HOST_TX_CTRL
, ®
);
590 ret
= func
->hif_write_reg(wilc
, WILC_HOST_TX_CTRL
, reg
);
595 goto out_release_bus
;
599 * No VMM space available in firmware so retry to transmit
600 * the packet from tx queue.
602 ret
= WILC_VMM_ENTRY_FULL_RETRY
;
603 goto out_release_bus
;
606 release_bus(wilc
, WILC_BUS_RELEASE_ALLOW_SLEEP
);
611 u32 header
, buffer_offset
;
614 tqe
= wilc_wlan_txq_remove_from_head(dev
);
619 if (vmm_table
[i
] == 0)
622 le32_to_cpus(&vmm_table
[i
]);
623 vmm_sz
= (vmm_table
[i
] & 0x3ff);
625 header
= (tqe
->type
<< 31) |
626 (tqe
->buffer_size
<< 15) |
628 if (tqe
->type
== WILC_MGMT_PKT
)
633 cpu_to_le32s(&header
);
634 memcpy(&txb
[offset
], &header
, 4);
635 if (tqe
->type
== WILC_CFG_PKT
) {
636 buffer_offset
= ETH_CONFIG_PKT_HDR_OFFSET
;
637 } else if (tqe
->type
== WILC_NET_PKT
) {
638 bssid
= tqe
->vif
->bssid
;
639 buffer_offset
= ETH_ETHERNET_HDR_OFFSET
;
640 memcpy(&txb
[offset
+ 8], bssid
, 6);
642 buffer_offset
= HOST_HDR_OFFSET
;
645 memcpy(&txb
[offset
+ buffer_offset
],
646 tqe
->buffer
, tqe
->buffer_size
);
650 if (tqe
->tx_complete_func
)
651 tqe
->tx_complete_func(tqe
->priv
, tqe
->status
);
652 if (tqe
->ack_idx
!= NOT_TCP_ACK
&&
653 tqe
->ack_idx
< MAX_PENDING_ACKS
)
654 vif
->ack_filter
.pending_acks
[tqe
->ack_idx
].txqe
= NULL
;
658 acquire_bus(wilc
, WILC_BUS_ACQUIRE_AND_WAKEUP
);
660 ret
= func
->hif_clear_int_ext(wilc
, ENABLE_TX_VMM
);
662 goto out_release_bus
;
664 ret
= func
->hif_block_tx_ext(wilc
, 0, txb
, offset
);
667 release_bus(wilc
, WILC_BUS_RELEASE_ALLOW_SLEEP
);
670 mutex_unlock(&wilc
->txq_add_to_head_cs
);
673 *txq_count
= wilc
->txq_entries
;
677 static void wilc_wlan_handle_rx_buff(struct wilc
*wilc
, u8
*buffer
, int size
)
681 u32 pkt_len
, pkt_offset
, tp_len
;
686 buff_ptr
= buffer
+ offset
;
687 header
= get_unaligned_le32(buff_ptr
);
689 is_cfg_packet
= (header
>> 31) & 0x1;
690 pkt_offset
= (header
>> 22) & 0x1ff;
691 tp_len
= (header
>> 11) & 0x7ff;
692 pkt_len
= header
& 0x7ff;
694 if (pkt_len
== 0 || tp_len
== 0)
697 if (pkt_offset
& IS_MANAGMEMENT
) {
698 buff_ptr
+= HOST_HDR_OFFSET
;
699 wilc_wfi_mgmt_rx(wilc
, buff_ptr
, pkt_len
);
701 if (!is_cfg_packet
) {
703 wilc_frmw_to_host(wilc
, buff_ptr
,
704 pkt_len
, pkt_offset
);
707 struct wilc_cfg_rsp rsp
;
709 buff_ptr
+= pkt_offset
;
711 wilc_wlan_cfg_indicate_rx(wilc
, buff_ptr
,
714 if (rsp
.type
== WILC_CFG_RSP
) {
715 if (wilc
->cfg_seq_no
== rsp
.seq_no
)
716 complete(&wilc
->cfg_event
);
717 } else if (rsp
.type
== WILC_CFG_RSP_STATUS
) {
718 wilc_mac_indicate(wilc
);
723 } while (offset
< size
);
726 static void wilc_wlan_handle_rxq(struct wilc
*wilc
)
730 struct rxq_entry_t
*rqe
;
732 while (!wilc
->quit
) {
733 rqe
= wilc_wlan_rxq_remove(wilc
);
737 buffer
= rqe
->buffer
;
738 size
= rqe
->buffer_size
;
739 wilc_wlan_handle_rx_buff(wilc
, buffer
, size
);
744 complete(&wilc
->cfg_event
);
747 static void wilc_unknown_isr_ext(struct wilc
*wilc
)
749 wilc
->hif_func
->hif_clear_int_ext(wilc
, 0);
752 static void wilc_wlan_handle_isr_ext(struct wilc
*wilc
, u32 int_status
)
754 u32 offset
= wilc
->rx_buffer_offset
;
759 struct rxq_entry_t
*rqe
;
761 size
= (int_status
& 0x7fff) << 2;
763 while (!size
&& retries
< 10) {
764 wilc
->hif_func
->hif_read_size(wilc
, &size
);
765 size
= (size
& 0x7fff) << 2;
772 if (WILC_RX_BUFF_SIZE
- offset
< size
)
775 buffer
= &wilc
->rx_buffer
[offset
];
777 wilc
->hif_func
->hif_clear_int_ext(wilc
, DATA_INT_CLR
| ENABLE_RX_VMM
);
778 ret
= wilc
->hif_func
->hif_block_rx_ext(wilc
, 0, buffer
, size
);
783 wilc
->rx_buffer_offset
= offset
;
784 rqe
= kmalloc(sizeof(*rqe
), GFP_KERNEL
);
788 rqe
->buffer
= buffer
;
789 rqe
->buffer_size
= size
;
790 wilc_wlan_rxq_add(wilc
, rqe
);
791 wilc_wlan_handle_rxq(wilc
);
794 void wilc_handle_isr(struct wilc
*wilc
)
798 acquire_bus(wilc
, WILC_BUS_ACQUIRE_AND_WAKEUP
);
799 wilc
->hif_func
->hif_read_int(wilc
, &int_status
);
801 if (int_status
& DATA_INT_EXT
)
802 wilc_wlan_handle_isr_ext(wilc
, int_status
);
804 if (!(int_status
& (ALL_INT_EXT
)))
805 wilc_unknown_isr_ext(wilc
);
807 release_bus(wilc
, WILC_BUS_RELEASE_ALLOW_SLEEP
);
809 EXPORT_SYMBOL_GPL(wilc_handle_isr
);
811 int wilc_wlan_firmware_download(struct wilc
*wilc
, const u8
*buffer
,
815 u32 addr
, size
, size2
, blksz
;
821 dma_buffer
= kmalloc(blksz
, GFP_KERNEL
);
827 addr
= get_unaligned_le32(&buffer
[offset
]);
828 size
= get_unaligned_le32(&buffer
[offset
+ 4]);
829 acquire_bus(wilc
, WILC_BUS_ACQUIRE_ONLY
);
831 while (((int)size
) && (offset
< buffer_size
)) {
837 memcpy(dma_buffer
, &buffer
[offset
], size2
);
838 ret
= wilc
->hif_func
->hif_block_tx(wilc
, addr
,
847 release_bus(wilc
, WILC_BUS_RELEASE_ONLY
);
851 } while (offset
< buffer_size
);
860 int wilc_wlan_start(struct wilc
*wilc
)
866 if (wilc
->io_type
== WILC_HIF_SDIO
) {
869 } else if (wilc
->io_type
== WILC_HIF_SPI
) {
872 acquire_bus(wilc
, WILC_BUS_ACQUIRE_ONLY
);
873 ret
= wilc
->hif_func
->hif_write_reg(wilc
, WILC_VMM_CORE_CFG
, reg
);
875 release_bus(wilc
, WILC_BUS_RELEASE_ONLY
);
879 if (wilc
->io_type
== WILC_HIF_SDIO
&& wilc
->dev_irq_num
)
880 reg
|= WILC_HAVE_SDIO_IRQ_GPIO
;
882 ret
= wilc
->hif_func
->hif_write_reg(wilc
, WILC_GP_REG_1
, reg
);
884 release_bus(wilc
, WILC_BUS_RELEASE_ONLY
);
888 wilc
->hif_func
->hif_sync_ext(wilc
, NUM_INT_EXT
);
890 ret
= wilc
->hif_func
->hif_read_reg(wilc
, 0x1000, &chipid
);
892 release_bus(wilc
, WILC_BUS_RELEASE_ONLY
);
896 wilc
->hif_func
->hif_read_reg(wilc
, WILC_GLB_RESET_0
, ®
);
897 if ((reg
& BIT(10)) == BIT(10)) {
899 wilc
->hif_func
->hif_write_reg(wilc
, WILC_GLB_RESET_0
, reg
);
900 wilc
->hif_func
->hif_read_reg(wilc
, WILC_GLB_RESET_0
, ®
);
904 ret
= wilc
->hif_func
->hif_write_reg(wilc
, WILC_GLB_RESET_0
, reg
);
905 wilc
->hif_func
->hif_read_reg(wilc
, WILC_GLB_RESET_0
, ®
);
906 release_bus(wilc
, WILC_BUS_RELEASE_ONLY
);
911 int wilc_wlan_stop(struct wilc
*wilc
, struct wilc_vif
*vif
)
916 acquire_bus(wilc
, WILC_BUS_ACQUIRE_AND_WAKEUP
);
918 ret
= wilc
->hif_func
->hif_read_reg(wilc
, WILC_GP_REG_0
, ®
);
920 netdev_err(vif
->ndev
, "Error while reading reg\n");
921 release_bus(wilc
, WILC_BUS_RELEASE_ALLOW_SLEEP
);
925 ret
= wilc
->hif_func
->hif_write_reg(wilc
, WILC_GP_REG_0
,
926 (reg
| WILC_ABORT_REQ_BIT
));
928 netdev_err(vif
->ndev
, "Error while writing reg\n");
929 release_bus(wilc
, WILC_BUS_RELEASE_ALLOW_SLEEP
);
933 ret
= wilc
->hif_func
->hif_read_reg(wilc
, WILC_FW_HOST_COMM
, ®
);
935 netdev_err(vif
->ndev
, "Error while reading reg\n");
936 release_bus(wilc
, WILC_BUS_RELEASE_ALLOW_SLEEP
);
941 ret
= wilc
->hif_func
->hif_write_reg(wilc
, WILC_FW_HOST_COMM
, reg
);
943 netdev_err(vif
->ndev
, "Error while writing reg\n");
944 release_bus(wilc
, WILC_BUS_RELEASE_ALLOW_SLEEP
);
948 release_bus(wilc
, WILC_BUS_RELEASE_ALLOW_SLEEP
);
953 void wilc_wlan_cleanup(struct net_device
*dev
)
955 struct txq_entry_t
*tqe
;
956 struct rxq_entry_t
*rqe
;
957 struct wilc_vif
*vif
= netdev_priv(dev
);
958 struct wilc
*wilc
= vif
->wilc
;
961 while ((tqe
= wilc_wlan_txq_remove_from_head(dev
))) {
962 if (tqe
->tx_complete_func
)
963 tqe
->tx_complete_func(tqe
->priv
, 0);
967 while ((rqe
= wilc_wlan_rxq_remove(wilc
)))
970 kfree(wilc
->rx_buffer
);
971 wilc
->rx_buffer
= NULL
;
972 kfree(wilc
->tx_buffer
);
973 wilc
->tx_buffer
= NULL
;
974 wilc
->hif_func
->hif_deinit(NULL
);
977 static int wilc_wlan_cfg_commit(struct wilc_vif
*vif
, int type
,
980 struct wilc
*wilc
= vif
->wilc
;
981 struct wilc_cfg_frame
*cfg
= &wilc
->cfg_frame
;
982 int t_len
= wilc
->cfg_frame_offset
+ sizeof(struct wilc_cfg_cmd_hdr
);
984 if (type
== WILC_CFG_SET
)
985 cfg
->hdr
.cmd_type
= 'W';
987 cfg
->hdr
.cmd_type
= 'Q';
989 cfg
->hdr
.seq_no
= wilc
->cfg_seq_no
% 256;
990 cfg
->hdr
.total_len
= cpu_to_le16(t_len
);
991 cfg
->hdr
.driver_handler
= cpu_to_le32(drv_handler
);
992 wilc
->cfg_seq_no
= cfg
->hdr
.seq_no
;
994 if (!wilc_wlan_txq_add_cfg_pkt(vif
, (u8
*)&cfg
->hdr
, t_len
))
1000 int wilc_wlan_cfg_set(struct wilc_vif
*vif
, int start
, u16 wid
, u8
*buffer
,
1001 u32 buffer_size
, int commit
, u32 drv_handler
)
1005 struct wilc
*wilc
= vif
->wilc
;
1007 mutex_lock(&wilc
->cfg_cmd_lock
);
1010 wilc
->cfg_frame_offset
= 0;
1012 offset
= wilc
->cfg_frame_offset
;
1013 ret_size
= wilc_wlan_cfg_set_wid(wilc
->cfg_frame
.frame
, offset
,
1014 wid
, buffer
, buffer_size
);
1016 wilc
->cfg_frame_offset
= offset
;
1019 mutex_unlock(&wilc
->cfg_cmd_lock
);
1023 netdev_dbg(vif
->ndev
, "%s: seqno[%d]\n", __func__
, wilc
->cfg_seq_no
);
1025 if (wilc_wlan_cfg_commit(vif
, WILC_CFG_SET
, drv_handler
))
1028 if (!wait_for_completion_timeout(&wilc
->cfg_event
,
1029 WILC_CFG_PKTS_TIMEOUT
)) {
1030 netdev_dbg(vif
->ndev
, "%s: Timed Out\n", __func__
);
1034 wilc
->cfg_frame_offset
= 0;
1035 wilc
->cfg_seq_no
+= 1;
1036 mutex_unlock(&wilc
->cfg_cmd_lock
);
1041 int wilc_wlan_cfg_get(struct wilc_vif
*vif
, int start
, u16 wid
, int commit
,
1046 struct wilc
*wilc
= vif
->wilc
;
1048 mutex_lock(&wilc
->cfg_cmd_lock
);
1051 wilc
->cfg_frame_offset
= 0;
1053 offset
= wilc
->cfg_frame_offset
;
1054 ret_size
= wilc_wlan_cfg_get_wid(wilc
->cfg_frame
.frame
, offset
, wid
);
1056 wilc
->cfg_frame_offset
= offset
;
1059 mutex_unlock(&wilc
->cfg_cmd_lock
);
1063 if (wilc_wlan_cfg_commit(vif
, WILC_CFG_QUERY
, drv_handler
))
1066 if (!wait_for_completion_timeout(&wilc
->cfg_event
,
1067 WILC_CFG_PKTS_TIMEOUT
)) {
1068 netdev_dbg(vif
->ndev
, "%s: Timed Out\n", __func__
);
1071 wilc
->cfg_frame_offset
= 0;
1072 wilc
->cfg_seq_no
+= 1;
1073 mutex_unlock(&wilc
->cfg_cmd_lock
);
1078 int wilc_send_config_pkt(struct wilc_vif
*vif
, u8 mode
, struct wid
*wids
,
1083 u32 drv
= wilc_get_vif_idx(vif
);
1085 if (mode
== WILC_GET_CFG
) {
1086 for (i
= 0; i
< count
; i
++) {
1087 if (!wilc_wlan_cfg_get(vif
, !i
,
1095 for (i
= 0; i
< count
; i
++) {
1096 wids
[i
].size
= wilc_wlan_cfg_get_val(vif
->wilc
,
1101 } else if (mode
== WILC_SET_CFG
) {
1102 for (i
= 0; i
< count
; i
++) {
1103 if (!wilc_wlan_cfg_set(vif
, !i
,
1118 static int init_chip(struct net_device
*dev
)
1123 struct wilc_vif
*vif
= netdev_priv(dev
);
1124 struct wilc
*wilc
= vif
->wilc
;
1126 acquire_bus(wilc
, WILC_BUS_ACQUIRE_ONLY
);
1128 chipid
= wilc_get_chipid(wilc
, true);
1130 if ((chipid
& 0xfff) != 0xa0) {
1131 ret
= wilc
->hif_func
->hif_read_reg(wilc
, 0x1118, ®
);
1133 netdev_err(dev
, "fail read reg 0x1118\n");
1137 ret
= wilc
->hif_func
->hif_write_reg(wilc
, 0x1118, reg
);
1139 netdev_err(dev
, "fail write reg 0x1118\n");
1142 ret
= wilc
->hif_func
->hif_write_reg(wilc
, 0xc0000, 0x71);
1144 netdev_err(dev
, "fail write reg 0xc0000\n");
1150 release_bus(wilc
, WILC_BUS_RELEASE_ONLY
);
1155 u32
wilc_get_chipid(struct wilc
*wilc
, bool update
)
1161 if (chipid
== 0 || update
) {
1162 wilc
->hif_func
->hif_read_reg(wilc
, 0x1000, &tempchipid
);
1163 wilc
->hif_func
->hif_read_reg(wilc
, 0x13f4, &rfrevid
);
1164 if (!is_wilc1000(tempchipid
)) {
1168 if (tempchipid
== 0x1002a0) {
1170 tempchipid
= 0x1002a1;
1171 } else if (tempchipid
== 0x1002b0) {
1173 tempchipid
= 0x1002b1;
1174 else if (rfrevid
!= 0x3)
1175 tempchipid
= 0x1002b2;
1178 chipid
= tempchipid
;
1183 int wilc_wlan_init(struct net_device
*dev
)
1186 struct wilc_vif
*vif
= netdev_priv(dev
);
1193 if (wilc
->hif_func
->hif_init(wilc
, false)) {
1198 if (!wilc
->tx_buffer
)
1199 wilc
->tx_buffer
= kmalloc(WILC_TX_BUFF_SIZE
, GFP_KERNEL
);
1201 if (!wilc
->tx_buffer
) {
1206 if (!wilc
->rx_buffer
)
1207 wilc
->rx_buffer
= kmalloc(WILC_RX_BUFF_SIZE
, GFP_KERNEL
);
1209 if (!wilc
->rx_buffer
) {
1214 if (init_chip(dev
)) {
1223 kfree(wilc
->rx_buffer
);
1224 wilc
->rx_buffer
= NULL
;
1225 kfree(wilc
->tx_buffer
);
1226 wilc
->tx_buffer
= NULL
;