2 * @file wilc_wfi_netdevice.c
3 * @brief File Operations OS wrapper functionality
5 * @sa wilc_wfi_netdevice.h
12 #include "wilc_wfi_cfgoperations.h"
13 #include "host_interface.h"
16 MODULE_AUTHOR("Mai Daftedar");
17 MODULE_LICENSE("Dual BSD/GPL");
20 struct net_device
*WILC_WFI_devs
[2];
23 * Transmitter lockup simulation, normally disabled.
26 module_param(lockup
, int, 0);
28 static int timeout
= WILC_WFI_TIMEOUT
;
29 module_param(timeout
, int, 0);
32 * Do we run in NAPI mode?
35 module_param(use_napi
, int, 0);
39 * A structure representing an in-flight packet.
41 struct WILC_WFI_packet
{
42 struct WILC_WFI_packet
*next
;
43 struct net_device
*dev
;
45 u8 data
[ETH_DATA_LEN
];
51 module_param(pool_size
, int, 0);
54 static void WILC_WFI_TxTimeout(struct net_device
*dev
);
55 static void (*WILC_WFI_Interrupt
)(int, void *, struct pt_regs
*);
58 * @brief WILC_WFI_SetupPool
59 * @details Set up a device's packet pool.
60 * @param[in] struct net_device *dev : Network Device Pointer
66 void WILC_WFI_SetupPool(struct net_device
*dev
)
68 struct WILC_WFI_priv
*priv
= netdev_priv(dev
);
70 struct WILC_WFI_packet
*pkt
;
73 for (i
= 0; i
< pool_size
; i
++) {
74 pkt
= kmalloc (sizeof (struct WILC_WFI_packet
), GFP_KERNEL
);
76 PRINT_D(RX_DBG
, "Ran out of memory allocating packet pool\n");
80 pkt
->next
= priv
->ppool
;
86 * @brief WILC_WFI_TearDownPool
87 * @details Internal cleanup function that's called after the network device
88 * driver is unregistered
89 * @param[in] struct net_device *dev : Network Device Driver
95 void WILC_WFI_TearDownPool(struct net_device
*dev
)
97 struct WILC_WFI_priv
*priv
= netdev_priv(dev
);
98 struct WILC_WFI_packet
*pkt
;
100 while ((pkt
= priv
->ppool
)) {
101 priv
->ppool
= pkt
->next
;
103 /* FIXME - in-flight packets ? */
108 * @brief WILC_WFI_GetTxBuffer
109 * @details Buffer/pool management
110 * @param[in] net_device *dev : Network Device Driver Structure
111 * @return struct WILC_WFI_packet
116 struct WILC_WFI_packet
*WILC_WFI_GetTxBuffer(struct net_device
*dev
)
118 struct WILC_WFI_priv
*priv
= netdev_priv(dev
);
120 struct WILC_WFI_packet
*pkt
;
122 spin_lock_irqsave(&priv
->lock
, flags
);
124 priv
->ppool
= pkt
->next
;
125 if (priv
->ppool
== NULL
) {
126 PRINT_INFO(RX_DBG
, "Pool empty\n");
127 netif_stop_queue(dev
);
129 spin_unlock_irqrestore(&priv
->lock
, flags
);
133 * @brief WILC_WFI_ReleaseBuffer
134 * @details Buffer/pool management
135 * @param[in] WILC_WFI_packet *pkt : Structure holding in-flight packet
141 void WILC_WFI_ReleaseBuffer(struct WILC_WFI_packet
*pkt
)
144 struct WILC_WFI_priv
*priv
= netdev_priv(pkt
->dev
);
146 spin_lock_irqsave(&priv
->lock
, flags
);
147 pkt
->next
= priv
->ppool
;
149 spin_unlock_irqrestore(&priv
->lock
, flags
);
150 if (netif_queue_stopped(pkt
->dev
) && pkt
->next
== NULL
)
151 netif_wake_queue(pkt
->dev
);
155 * @brief WILC_WFI_EnqueueBuf
156 * @details Enqueuing packets in an RX buffer queue
157 * @param[in] WILC_WFI_packet *pkt : Structure holding in-flight packet
158 * @param[in] net_device *dev : Network Device Driver Structure
164 void WILC_WFI_EnqueueBuf(struct net_device
*dev
, struct WILC_WFI_packet
*pkt
)
167 struct WILC_WFI_priv
*priv
= netdev_priv(dev
);
169 spin_lock_irqsave(&priv
->lock
, flags
);
170 pkt
->next
= priv
->rx_queue
; /* FIXME - misorders packets */
171 priv
->rx_queue
= pkt
;
172 spin_unlock_irqrestore(&priv
->lock
, flags
);
176 * @brief WILC_WFI_DequeueBuf
177 * @details Dequeuing packets from the RX buffer queue
178 * @param[in] net_device *dev : Network Device Driver Structure
179 * @return WILC_WFI_packet *pkt : Structure holding in-flight pac
184 struct WILC_WFI_packet
*WILC_WFI_DequeueBuf(struct net_device
*dev
)
186 struct WILC_WFI_priv
*priv
= netdev_priv(dev
);
187 struct WILC_WFI_packet
*pkt
;
190 spin_lock_irqsave(&priv
->lock
, flags
);
191 pkt
= priv
->rx_queue
;
193 priv
->rx_queue
= pkt
->next
;
194 spin_unlock_irqrestore(&priv
->lock
, flags
);
198 * @brief WILC_WFI_RxInts
199 * @details Enable and disable receive interrupts.
200 * @param[in] net_device *dev : Network Device Driver Structure
201 * @param[in] enable : Enable/Disable flag
207 static void WILC_WFI_RxInts(struct net_device
*dev
, int enable
)
209 struct WILC_WFI_priv
*priv
= netdev_priv(dev
);
210 priv
->rx_int_enabled
= enable
;
214 * @brief WILC_WFI_Open
215 * @details Open Network Device Driver, called when the network
216 * interface is opened. It starts the interface's transmit queue.
217 * @param[in] net_device *dev : Network Device Driver Structure
218 * @param[in] enable : Enable/Disable flag
219 * @return int : Returns 0 upon success.
224 int WILC_WFI_Open(struct net_device
*dev
)
226 /* request_region(), request_irq(), .... (like fops->open) */
228 * Assign the hardware address of the board: use "\0SNULx", where
229 * x is 0 or 1. The first byte is '\0' to avoid being a multicast
230 * address (the first byte of multicast addrs is odd).
232 memcpy(dev
->dev_addr
, "\0WLAN0", ETH_ALEN
);
233 if (dev
== WILC_WFI_devs
[1])
234 dev
->dev_addr
[ETH_ALEN
- 1]++; /* \0SNUL1 */
236 WILC_WFI_InitHostInt(dev
);
237 netif_start_queue(dev
);
241 * @brief WILC_WFI_Release
242 * @details Release Network Device Driver, called when the network
243 * interface is stopped or brought down. This function marks
244 * the network driver as not being able to transmit
245 * @param[in] net_device *dev : Network Device Driver Structure
246 * @return int : Return 0 on Success.
251 int WILC_WFI_Release(struct net_device
*dev
)
253 /* release ports, irq and such -- like fops->close */
255 netif_stop_queue(dev
); /* can't transmit any more */
260 * @brief WILC_WFI_Config
261 * @details Configuration changes (passed on by ifconfig)
262 * @param[in] net_device *dev : Network Device Driver Structure
263 * @param[in] struct ifmap *map : Contains the ioctl implementation for the
265 * @return int : Return 0 on Success.
270 int WILC_WFI_Config(struct net_device
*dev
, struct ifmap
*map
)
272 if (dev
->flags
& IFF_UP
) /* can't act on a running interface */
275 /* Don't allow changing the I/O address */
276 if (map
->base_addr
!= dev
->base_addr
) {
277 PRINT_D(RX_DBG
, KERN_WARNING
"WILC_WFI: Can't change I/O address\n");
281 /* Allow changing the IRQ */
282 if (map
->irq
!= dev
->irq
) {
284 /* request_irq() is delayed to open-time */
287 /* ignore other fields */
292 * @details Receive a packet: retrieve, encapsulate and pass over to upper
294 * @param[in] net_device *dev : Network Device Driver Structure
295 * @param[in] WILC_WFI_packet :
301 void WILC_WFI_Rx(struct net_device
*dev
, struct WILC_WFI_packet
*pkt
)
305 struct WILC_WFI_priv
*priv
= netdev_priv(dev
);
308 * The packet has been retrieved from the transmission
309 * medium. Build an skb around it, so upper layers can handle it
313 skb
= dev_alloc_skb(pkt
->datalen
+ 2);
315 if (printk_ratelimit())
316 PRINT_D(RX_DBG
, "WILC_WFI rx: low on mem - packet dropped\n");
317 priv
->stats
.rx_dropped
++;
320 skb_reserve(skb
, 2); /* align IP on 16B boundary */
321 memcpy(skb_put(skb
, pkt
->datalen
), pkt
->data
, pkt
->datalen
);
323 if (priv
->monitor_flag
) {
324 PRINT_INFO(RX_DBG
, "In monitor device name %s\n", dev
->name
);
325 priv
= wiphy_priv(priv
->dev
->ieee80211_ptr
->wiphy
);
326 PRINT_D(RX_DBG
, "VALUE PASSED IN OF HRWD %p\n", priv
->hWILCWFIDrv
);
327 /* host_int_get_rssi(priv->hWILCWFIDrv, &(rssi)); */
329 for (i
= 14; i
< skb
->len
; i
++)
330 PRINT_INFO(RX_DBG
, "RXdata[%d] %02x\n", i
, skb
->data
[i
]);
332 WILC_WFI_monitor_rx(dev
, skb
);
340 * @brief WILC_WFI_Poll
341 * @details The poll implementation
342 * @param[in] struct napi_struct *napi :
343 * @param[in] int budget :
344 * @return int : Return 0 on Success.
349 static int WILC_WFI_Poll(struct napi_struct
*napi
, int budget
)
353 struct WILC_WFI_priv
*priv
= container_of(napi
, struct WILC_WFI_priv
, napi
);
354 struct net_device
*dev
= priv
->dev
;
355 struct WILC_WFI_packet
*pkt
;
357 while (npackets
< budget
&& priv
->rx_queue
) {
358 pkt
= WILC_WFI_DequeueBuf(dev
);
359 skb
= dev_alloc_skb(pkt
->datalen
+ 2);
361 if (printk_ratelimit())
362 PRINT_D(RX_DBG
, "WILC_WFI: packet dropped\n");
363 priv
->stats
.rx_dropped
++;
364 WILC_WFI_ReleaseBuffer(pkt
);
367 skb_reserve(skb
, 2); /* align IP on 16B boundary */
368 memcpy(skb_put(skb
, pkt
->datalen
), pkt
->data
, pkt
->datalen
);
370 skb
->protocol
= eth_type_trans(skb
, dev
);
371 skb
->ip_summed
= CHECKSUM_UNNECESSARY
; /* don't check it */
372 netif_receive_skb(skb
);
375 WILC_WFI_update_stats(priv
->dev
->ieee80211_ptr
->wiphy
, pkt
->datalen
, WILC_WFI_RX_PKT
);
376 WILC_WFI_ReleaseBuffer(pkt
);
378 /* If we processed all packets, we're done; tell the kernel and re-enable ints */
379 if (npackets
< budget
) {
381 WILC_WFI_RxInts(dev
, 1);
387 * @brief WILC_WFI_Poll
388 * @details The typical interrupt entry point
389 * @param[in] struct napi_struct *napi :
390 * @param[in] int budget :
391 * @return int : Return 0 on Success.
396 static void WILC_WFI_RegularInterrupt(int irq
, void *dev_id
, struct pt_regs
*regs
)
399 struct WILC_WFI_priv
*priv
;
400 struct WILC_WFI_packet
*pkt
= NULL
;
402 * As usual, check the "device" pointer to be sure it is
403 * really interrupting.
404 * Then assign "struct device *dev"
406 struct net_device
*dev
= (struct net_device
*)dev_id
;
407 /* ... and check with hw if it's really ours */
413 /* Lock the device */
414 priv
= netdev_priv(dev
);
415 spin_lock(&priv
->lock
);
417 /* retrieve statusword: real netdevices use I/O instructions */
418 statusword
= priv
->status
;
420 if (statusword
& WILC_WFI_RX_INTR
) {
421 /* send it to WILC_WFI_rx for handling */
422 pkt
= priv
->rx_queue
;
424 priv
->rx_queue
= pkt
->next
;
425 WILC_WFI_Rx(dev
, pkt
);
428 if (statusword
& WILC_WFI_TX_INTR
) {
429 /* a transmission is over: free the skb */
430 WILC_WFI_update_stats(priv
->dev
->ieee80211_ptr
->wiphy
, priv
->tx_packetlen
, WILC_WFI_TX_PKT
);
431 dev_kfree_skb(priv
->skb
);
434 /* Unlock the device and we are done */
435 spin_unlock(&priv
->lock
);
437 WILC_WFI_ReleaseBuffer(pkt
); /* Do this outside the lock! */
441 * @brief WILC_WFI_NapiInterrupt
442 * @details A NAPI interrupt handler
445 * @param[in] pt_regs:
451 static void WILC_WFI_NapiInterrupt(int irq
, void *dev_id
, struct pt_regs
*regs
)
454 struct WILC_WFI_priv
*priv
;
457 * As usual, check the "device" pointer for shared handlers.
458 * Then assign "struct device *dev"
460 struct net_device
*dev
= (struct net_device
*)dev_id
;
461 /* ... and check with hw if it's really ours */
467 /* Lock the device */
468 priv
= netdev_priv(dev
);
469 spin_lock(&priv
->lock
);
471 /* retrieve statusword: real netdevices use I/O instructions */
472 statusword
= priv
->status
;
474 if (statusword
& WILC_WFI_RX_INTR
) {
475 WILC_WFI_RxInts(dev
, 0); /* Disable further interrupts */
476 napi_schedule(&priv
->napi
);
478 if (statusword
& WILC_WFI_TX_INTR
) {
479 /* a transmission is over: free the skb */
481 WILC_WFI_update_stats(priv
->dev
->ieee80211_ptr
->wiphy
, priv
->tx_packetlen
, WILC_WFI_TX_PKT
);
482 dev_kfree_skb(priv
->skb
);
485 /* Unlock the device and we are done */
486 spin_unlock(&priv
->lock
);
492 * @details Transmit a packet (low level interface)
495 * @param[in] net_device *dev:
501 void WILC_WFI_HwTx(char *buf
, int len
, struct net_device
*dev
)
504 * This function deals with hw details. This interface loops
505 * back the packet to the other WILC_WFI interface (if any).
506 * In other words, this function implements the WILC_WFI behaviour,
507 * while all other procedures are rather device-independent
510 struct net_device
*dest
;
511 struct WILC_WFI_priv
*priv
;
513 struct WILC_WFI_packet
*tx_buffer
;
516 /* I am paranoid. Ain't I? */
517 if (len
< sizeof(struct ethhdr
) + sizeof(struct iphdr
)) {
518 PRINT_D(RX_DBG
, "WILC_WFI: Hmm... packet too short (%i octets)\n",
523 if (0) { /* enable this conditional to look at the data */
525 PRINT_D(RX_DBG
, "len is %i", len
);
526 for (i
= 14; i
< len
; i
++)
527 PRINT_D(RX_DBG
, "TXdata[%d] %02x\n", i
, buf
[i
] & 0xff);
528 /* PRINT_D(RX_DBG, "\n"); */
531 * Ethhdr is 14 bytes, but the kernel arranges for iphdr
532 * to be aligned (i.e., ethhdr is unaligned)
534 ih
= (struct iphdr
*)(buf
+ sizeof(struct ethhdr
));
538 ((u8
*)saddr
)[2] ^= 1; /* change the third octet (class C) */
539 ((u8
*)daddr
)[2] ^= 1;
541 ih
->check
= 0; /* and rebuild the checksum (ip needs it) */
542 ih
->check
= ip_fast_csum((unsigned char *)ih
, ih
->ihl
);
545 if (dev
== WILC_WFI_devs
[0])
546 PRINT_D(RX_DBG
, "%08x:%05i --> %08x:%05i\n",
547 ntohl(ih
->saddr
), ntohs(((struct tcphdr
*)(ih
+ 1))->source
),
548 ntohl(ih
->daddr
), ntohs(((struct tcphdr
*)(ih
+ 1))->dest
));
550 PRINT_D(RX_DBG
, "%08x:%05i <-- %08x:%05i\n",
551 ntohl(ih
->daddr
), ntohs(((struct tcphdr
*)(ih
+ 1))->dest
),
552 ntohl(ih
->saddr
), ntohs(((struct tcphdr
*)(ih
+ 1))->source
));
555 * Ok, now the packet is ready for transmission: first simulate a
556 * receive interrupt on the twin device, then a
557 * transmission-done on the transmitting device
559 dest
= WILC_WFI_devs
[dev
== WILC_WFI_devs
[0] ? 1 : 0];
560 priv
= netdev_priv(dest
);
562 tx_buffer
= WILC_WFI_GetTxBuffer(dev
);
563 tx_buffer
->datalen
= len
;
564 memcpy(tx_buffer
->data
, buf
, len
);
565 WILC_WFI_EnqueueBuf(dest
, tx_buffer
);
566 if (priv
->rx_int_enabled
) {
567 priv
->status
|= WILC_WFI_RX_INTR
;
568 WILC_WFI_Interrupt(0, dest
, NULL
);
571 priv
= netdev_priv(dev
);
572 priv
->tx_packetlen
= len
;
573 priv
->tx_packetdata
= buf
;
574 priv
->status
|= WILC_WFI_TX_INTR
;
575 if (lockup
&& ((priv
->stats
.tx_packets
+ 1) % lockup
) == 0) {
576 /* Simulate a dropped transmit interrupt */
577 netif_stop_queue(dev
);
578 PRINT_D(RX_DBG
, "Simulate lockup at %ld, txp %ld\n", jiffies
,
579 (unsigned long) priv
->stats
.tx_packets
);
581 WILC_WFI_Interrupt(0, dev
, NULL
);
587 * @details Transmit a packet (called by the kernel)
588 * @param[in] sk_buff *skb:
589 * @param[in] net_device *dev:
595 int WILC_WFI_Tx(struct sk_buff
*skb
, struct net_device
*dev
)
598 char *data
, shortpkt
[ETH_ZLEN
];
599 struct WILC_WFI_priv
*priv
= netdev_priv(dev
);
601 /* priv = wiphy_priv(priv->dev->ieee80211_ptr->wiphy); */
603 /* if(priv->monitor_flag) */
604 /* mac80211_hwsim_monitor_rx(skb); */
610 if (len
< ETH_ZLEN
) {
611 memset(shortpkt
, 0, ETH_ZLEN
);
612 memcpy(shortpkt
, skb
->data
, skb
->len
);
616 dev
->trans_start
= jiffies
; /* save the timestamp */
618 /* Remember the skb, so we can free it at interrupt time */
621 /* actual deliver of data is device-specific, and not shown here */
622 WILC_WFI_HwTx(data
, len
, dev
);
624 return 0; /* Our simple device can not fail */
628 * @brief WILC_WFI_TxTimeout
629 * @details Deal with a transmit timeout.
630 * @param[in] net_device *dev:
636 void WILC_WFI_TxTimeout(struct net_device
*dev
)
638 struct WILC_WFI_priv
*priv
= netdev_priv(dev
);
640 PRINT_D(RX_DBG
, "Transmit timeout at %ld, latency %ld\n", jiffies
,
641 jiffies
- dev
->trans_start
);
642 /* Simulate a transmission interrupt to get things moving */
643 priv
->status
= WILC_WFI_TX_INTR
;
644 WILC_WFI_Interrupt(0, dev
, NULL
);
645 priv
->stats
.tx_errors
++;
646 netif_wake_queue(dev
);
651 * @brief WILC_WFI_Ioctl
652 * @details Ioctl commands
653 * @param[in] net_device *dev:
654 * @param[in] ifreq *rq
656 * @return int : Return 0 on Success
661 int WILC_WFI_Ioctl(struct net_device
*dev
, struct ifreq
*rq
, int cmd
)
663 PRINT_D(RX_DBG
, "ioctl\n");
668 * @brief WILC_WFI_Stat
669 * @details Return statistics to the caller
670 * @param[in] net_device *dev:
671 * @return WILC_WFI_Stats : Return net_device_stats stucture with the
672 * network device driver private data contents.
677 struct net_device_stats
*WILC_WFI_Stats(struct net_device
*dev
)
679 struct WILC_WFI_priv
*priv
= netdev_priv(dev
);
684 * @brief WILC_WFI_RebuildHeader
685 * @details This function is called to fill up an eth header, since arp is not
686 * available on the interface
687 * @param[in] sk_buff *skb:
688 * @return int : Return 0 on Success
693 int WILC_WFI_RebuildHeader(struct sk_buff
*skb
)
695 struct ethhdr
*eth
= (struct ethhdr
*) skb
->data
;
696 struct net_device
*dev
= skb
->dev
;
698 memcpy(eth
->h_source
, dev
->dev_addr
, dev
->addr_len
);
699 memcpy(eth
->h_dest
, dev
->dev_addr
, dev
->addr_len
);
700 eth
->h_dest
[ETH_ALEN
- 1] ^= 0x01; /* dest is us xor 1 */
704 * @brief WILC_WFI_RebuildHeader
705 * @details This function is called to fill up an eth header, since arp is not
706 * available on the interface
707 * @param[in] sk_buff *skb:
708 * @param[in] struct net_device *dev:
709 * @param[in] unsigned short type:
710 * @param[in] const void *saddr,
711 * @param[in] const void *daddr:
712 * @param[in] unsigned int len
713 * @return int : Return 0 on Success
718 int WILC_WFI_Header(struct sk_buff
*skb
, struct net_device
*dev
,
719 unsigned short type
, const void *daddr
, const void *saddr
,
722 struct ethhdr
*eth
= (struct ethhdr
*)skb_push(skb
, ETH_HLEN
);
724 eth
->h_proto
= htons(type
);
725 memcpy(eth
->h_source
, saddr
? saddr
: dev
->dev_addr
, dev
->addr_len
);
726 memcpy(eth
->h_dest
, daddr
? daddr
: dev
->dev_addr
, dev
->addr_len
);
727 eth
->h_dest
[ETH_ALEN
- 1] ^= 0x01; /* dest is us xor 1 */
728 return dev
->hard_header_len
;
732 * @brief WILC_WFI_ChangeMtu
733 * @details The "change_mtu" method is usually not needed.
734 * If you need it, it must be like this.
735 * @param[in] net_device *dev : Network Device Driver Structure
736 * @param[in] new_mtu :
737 * @return int : Returns 0 on Success.
742 int WILC_WFI_ChangeMtu(struct net_device
*dev
, int new_mtu
)
745 struct WILC_WFI_priv
*priv
= netdev_priv(dev
);
746 spinlock_t
*lock
= &priv
->lock
;
749 if ((new_mtu
< 68) || (new_mtu
> 1500))
752 * Do anything you need, and the accept the value
754 spin_lock_irqsave(lock
, flags
);
756 spin_unlock_irqrestore(lock
, flags
);
757 return 0; /* success */
760 static const struct header_ops WILC_WFI_header_ops
= {
761 .create
= WILC_WFI_Header
,
762 .rebuild
= WILC_WFI_RebuildHeader
,
763 .cache
= NULL
, /* disable caching */
767 static const struct net_device_ops WILC_WFI_netdev_ops
= {
768 .ndo_open
= WILC_WFI_Open
,
769 .ndo_stop
= WILC_WFI_Release
,
770 .ndo_set_config
= WILC_WFI_Config
,
771 .ndo_start_xmit
= WILC_WFI_Tx
,
772 .ndo_do_ioctl
= WILC_WFI_Ioctl
,
773 .ndo_get_stats
= WILC_WFI_Stats
,
774 .ndo_change_mtu
= WILC_WFI_ChangeMtu
,
775 .ndo_tx_timeout
= WILC_WFI_TxTimeout
,
779 * @brief WILC_WFI_Init
780 * @details The init function (sometimes called probe).
781 * It is invoked by register_netdev()
782 * @param[in] net_device *dev:
788 void WILC_WFI_Init(struct net_device
*dev
)
790 struct WILC_WFI_priv
*priv
;
794 * Then, assign other fields in dev, using ether_setup() and some
797 ether_setup(dev
); /* assign some of the fields */
798 /* 1- Allocate space */
800 dev
->netdev_ops
= &WILC_WFI_netdev_ops
;
801 dev
->header_ops
= &WILC_WFI_header_ops
;
802 dev
->watchdog_timeo
= timeout
;
803 /* keep the default flags, just add NOARP */
804 dev
->flags
|= IFF_NOARP
;
805 dev
->features
|= NETIF_F_NO_CSUM
;
807 * Then, initialize the priv field. This encloses the statistics
808 * and a few private fields.
810 priv
= netdev_priv(dev
);
811 memset(priv
, 0, sizeof(struct WILC_WFI_priv
));
813 netif_napi_add(dev
, &priv
->napi
, WILC_WFI_Poll
, 2);
814 /* The last parameter above is the NAPI "weight". */
815 spin_lock_init(&priv
->lock
);
816 WILC_WFI_RxInts(dev
, 1); /* enable receive interrupts */
817 WILC_WFI_SetupPool(dev
);
821 * @brief WILC_WFI_Stat
822 * @details Return statistics to the caller
823 * @param[in] net_device *dev:
824 * @return WILC_WFI_Stats : Return net_device_stats stucture with the
825 * network device driver private data contents.
831 void WILC_WFI_Cleanup(void)
834 struct WILC_WFI_priv
*priv
[2];
836 /*if(hwsim_mon!=NULL)
838 * PRINT_D(RX_DBG, "Freeing monitor interface\n");
839 * unregister_netdev(hwsim_mon);
840 * free_netdev(hwsim_mon);
842 for (i
= 0; i
< 2; i
++) {
843 priv
[i
] = netdev_priv(WILC_WFI_devs
[i
]);
845 if (WILC_WFI_devs
[i
]) {
846 PRINT_D(RX_DBG
, "Unregistering\n");
847 unregister_netdev(WILC_WFI_devs
[i
]);
848 WILC_WFI_TearDownPool(WILC_WFI_devs
[i
]);
849 free_netdev(WILC_WFI_devs
[i
]);
850 PRINT_D(RX_DBG
, "[NETDEV]Stopping interface\n");
851 WILC_WFI_DeInitHostInt(WILC_WFI_devs
[i
]);
852 WILC_WFI_WiphyFree(WILC_WFI_devs
[i
]);
856 /* unregister_netdev(hwsim_mon); */
857 WILC_WFI_deinit_mon_interface();
862 void StartConfigSim(void);
871 * @brief WILC_WFI_Stat
872 * @details Return statistics to the caller
873 * @param[in] net_device *dev:
874 * @return WILC_WFI_Stats : Return net_device_stats stucture with the
875 * network device driver private data contents.
880 int WILC_WFI_InitModule(void)
883 int result
, i
, ret
= -ENOMEM
;
884 struct WILC_WFI_priv
*priv
[2], *netpriv
;
885 struct wireless_dev
*wdev
;
886 WILC_WFI_Interrupt
= use_napi
? WILC_WFI_NapiInterrupt
: WILC_WFI_RegularInterrupt
;
889 for (i
= 0; i
< 2; i
++) {
891 /* Allocate the net devices */
892 WILC_WFI_devs
[i
] = alloc_netdev(sizeof(struct WILC_WFI_priv
), "wlan%d",
894 if (WILC_WFI_devs
[i
] == NULL
)
896 /* priv[i] = netdev_priv(WILC_WFI_devs[i]); */
898 wdev
= WILC_WFI_WiphyRegister(WILC_WFI_devs
[i
]);
899 WILC_WFI_devs
[i
]->ieee80211_ptr
= wdev
;
900 netpriv
= netdev_priv(WILC_WFI_devs
[i
]);
901 netpriv
->dev
->ieee80211_ptr
= wdev
;
902 netpriv
->dev
->ml_priv
= netpriv
;
903 wdev
->netdev
= netpriv
->dev
;
905 /*Registering the net device*/
906 result
= register_netdev(WILC_WFI_devs
[i
]);
908 PRINT_D(RX_DBG
, "WILC_WFI: error %i registering device \"%s\"\n",
909 result
, WILC_WFI_devs
[i
]->name
);
915 /*init atmel driver */
916 priv
[0] = netdev_priv(WILC_WFI_devs
[0]);
917 priv
[1] = netdev_priv(WILC_WFI_devs
[1]);
919 if (priv
[1]->dev
->ieee80211_ptr
->wiphy
->interface_modes
&& BIT(NL80211_IFTYPE_MONITOR
)) {
920 /* snprintf(buf, IFNAMSIZ, "mon.%s", priv[1]->dev->name); */
921 /* WILC_WFI_init_mon_interface(); */
922 /* priv[1]->monitor_flag = 1; */
925 priv
[0]->bCfgScanning
= false;
926 priv
[0]->u32RcvdChCount
= 0;
928 WILC_memset(priv
[0]->au8AssociatedBss
, 0xFF, ETH_ALEN
);
931 /* ret = host_int_init(&priv[0]->hWILCWFIDrv); */
932 /*copy handle to the other driver*/
933 /* priv[1]->hWILCWFIDrv = priv[0]->hWILCWFIDrv; */
935 PRINT_ER("Error Init Driver\n");
948 module_init(WILC_WFI_InitModule
);
949 module_exit(WILC_WFI_Cleanup
);