Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
[cascardo/linux.git] / drivers / staging / wlags49_h2 / wl_netdev.c
1 /*******************************************************************************
2  * Agere Systems Inc.
3  * Wireless device driver for Linux (wlags49).
4  *
5  * Copyright (c) 1998-2003 Agere Systems Inc.
6  * All rights reserved.
7  *   http://www.agere.com
8  *
9  * Initially developed by TriplePoint, Inc.
10  *   http://www.triplepoint.com
11  *
12  *------------------------------------------------------------------------------
13  *
14  *   This file contains handler functions registered with the net_device
15  *   structure.
16  *
17  *------------------------------------------------------------------------------
18  *
19  * SOFTWARE LICENSE
20  *
21  * This software is provided subject to the following terms and conditions,
22  * which you should read carefully before using the software.  Using this
23  * software indicates your acceptance of these terms and conditions.  If you do
24  * not agree with these terms and conditions, do not use the software.
25  *
26  * Copyright © 2003 Agere Systems Inc.
27  * All rights reserved.
28  *
29  * Redistribution and use in source or binary forms, with or without
30  * modifications, are permitted provided that the following conditions are met:
31  *
32  * . Redistributions of source code must retain the above copyright notice, this
33  *    list of conditions and the following Disclaimer as comments in the code as
34  *    well as in the documentation and/or other materials provided with the
35  *    distribution.
36  *
37  * . Redistributions in binary form must reproduce the above copyright notice,
38  *    this list of conditions and the following Disclaimer in the documentation
39  *    and/or other materials provided with the distribution.
40  *
41  * . Neither the name of Agere Systems Inc. nor the names of the contributors
42  *    may be used to endorse or promote products derived from this software
43  *    without specific prior written permission.
44  *
45  * Disclaimer
46  *
47  * THIS SOFTWARE IS PROVIDED \93AS IS\94 AND ANY EXPRESS OR IMPLIED WARRANTIES,
48  * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
49  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
50  * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
51  * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
52  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
55  * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
57  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
58  * DAMAGE.
59  *
60  ******************************************************************************/
61
62 /*******************************************************************************
63  * include files
64  ******************************************************************************/
65 #include <wl_version.h>
66
67 #include <linux/module.h>
68 #include <linux/slab.h>
69 #include <linux/types.h>
70 #include <linux/kernel.h>
71 // #include <linux/sched.h>
72 // #include <linux/ptrace.h>
73 // #include <linux/slab.h>
74 // #include <linux/ctype.h>
75 // #include <linux/string.h>
76 //#include <linux/timer.h>
77 // #include <linux/interrupt.h>
78 // #include <linux/in.h>
79 // #include <linux/delay.h>
80 // #include <linux/skbuff.h>
81 // #include <asm/io.h>
82 // // #include <asm/bitops.h>
83
84 #include <linux/netdevice.h>
85 #include <linux/ethtool.h>
86 #include <linux/etherdevice.h>
87 // #include <linux/skbuff.h>
88 // #include <linux/if_arp.h>
89 // #include <linux/ioport.h>
90
91 #include <debug.h>
92
93 #include <hcf.h>
94 #include <dhf.h>
95 // #include <hcfdef.h>
96
97 #include <wl_if.h>
98 #include <wl_internal.h>
99 #include <wl_util.h>
100 #include <wl_priv.h>
101 #include <wl_main.h>
102 #include <wl_netdev.h>
103 #include <wl_wext.h>
104
105 #ifdef USE_PROFILE
106 #include <wl_profile.h>
107 #endif  /* USE_PROFILE */
108
109 #ifdef BUS_PCMCIA
110 #include <wl_cs.h>
111 #endif  /* BUS_PCMCIA */
112
113 #ifdef BUS_PCI
114 #include <wl_pci.h>
115 #endif  /* BUS_PCI */
116
117
118 #if HCF_ENCAP
119 #define MTU_MAX (HCF_MAX_MSG - ETH_HLEN - 8)
120 #else
121 #define MTU_MAX (HCF_MAX_MSG - ETH_HLEN)
122 #endif
123
124 //static int mtu = MTU_MAX;
125 //MODULE_PARM(mtu, "i");
126 //MODULE_PARM_DESC(mtu, "MTU");
127
128 /*******************************************************************************
129  * macros
130  ******************************************************************************/
131 #define BLOCK_INPUT(buf, len) \
132     desc->buf_addr = buf; \
133     desc->BUF_SIZE = len; \
134     status = hcf_rcv_msg(&(lp->hcfCtx), desc, 0)
135
136 #define BLOCK_INPUT_DMA(buf, len) memcpy( buf, desc_next->buf_addr, pktlen )
137
138 /*******************************************************************************
139  * function prototypes
140  ******************************************************************************/
141
142 /*******************************************************************************
143  *      wl_init()
144  *******************************************************************************
145  *
146  *  DESCRIPTION:
147  *
148  *      We never need to do anything when a "Wireless" device is "initialized"
149  *  by the net software, because we only register already-found cards.
150  *
151  *  PARAMETERS:
152  *
153  *      dev - a pointer to the device's net_device structure
154  *
155  *  RETURNS:
156  *
157  *      0 on success
158  *      errno value otherwise
159  *
160  ******************************************************************************/
161 int wl_init( struct net_device *dev )
162 {
163 //    unsigned long       flags;
164 //    struct wl_private   *lp = wl_priv(dev);
165
166     DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
167
168     /* Nothing to do, but grab the spinlock anyway just in case we ever need
169        this routine */
170 //  wl_lock( lp, &flags );
171 //  wl_unlock( lp, &flags );
172
173     return 0;
174 } // wl_init
175 /*============================================================================*/
176
177 /*******************************************************************************
178  *      wl_config()
179  *******************************************************************************
180  *
181  *  DESCRIPTION:
182  *
183  *      Implement the SIOCSIFMAP interface.
184  *
185  *  PARAMETERS:
186  *
187  *      dev - a pointer to the device's net_device structure
188  *      map - a pointer to the device's ifmap structure
189  *
190  *  RETURNS:
191  *
192  *      0 on success
193  *      errno otherwise
194  *
195  ******************************************************************************/
196 int wl_config( struct net_device *dev, struct ifmap *map )
197 {
198     DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
199     DBG_PARAM( DbgInfo, "map", "0x%p", map );
200
201     /* The only thing we care about here is a port change. Since this not needed,
202        ignore the request. */
203     DBG_TRACE(DbgInfo, "%s: %s called.\n", dev->name, __func__);
204
205     return 0;
206 } // wl_config
207 /*============================================================================*/
208
209 /*******************************************************************************
210  *      wl_stats()
211  *******************************************************************************
212  *
213  *  DESCRIPTION:
214  *
215  *      Return the current device statistics.
216  *
217  *  PARAMETERS:
218  *
219  *      dev - a pointer to the device's net_device structure
220  *
221  *  RETURNS:
222  *
223  *      a pointer to a net_device_stats structure containing the network
224  *      statistics.
225  *
226  ******************************************************************************/
227 struct net_device_stats *wl_stats( struct net_device *dev )
228 {
229 #ifdef USE_WDS
230     int                         count;
231 #endif  /* USE_WDS */
232     unsigned long               flags;
233     struct net_device_stats     *pStats;
234     struct wl_private           *lp = wl_priv(dev);
235
236     //DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
237
238     pStats = NULL;
239
240     wl_lock( lp, &flags );
241
242 #ifdef USE_RTS
243     if( lp->useRTS == 1 ) {
244         wl_unlock( lp, &flags );
245         return NULL;
246     }
247 #endif  /* USE_RTS */
248
249     /* Return the statistics for the appropriate device */
250 #ifdef USE_WDS
251
252     for( count = 0; count < NUM_WDS_PORTS; count++ ) {
253         if( dev == lp->wds_port[count].dev ) {
254             pStats = &( lp->wds_port[count].stats );
255         }
256     }
257
258 #endif  /* USE_WDS */
259
260     /* If pStats is still NULL, then the device is not a WDS port */
261     if( pStats == NULL ) {
262         pStats = &( lp->stats );
263     }
264
265     wl_unlock( lp, &flags );
266
267     return pStats;
268 } // wl_stats
269 /*============================================================================*/
270
271 /*******************************************************************************
272  *      wl_open()
273  *******************************************************************************
274  *
275  *  DESCRIPTION:
276  *
277  *      Open the device.
278  *
279  *  PARAMETERS:
280  *
281  *      dev - a pointer to the device's net_device structure
282  *
283  *  RETURNS:
284  *
285  *      0 on success
286  *      errno otherwise
287  *
288  ******************************************************************************/
289 int wl_open(struct net_device *dev)
290 {
291     int                 status = HCF_SUCCESS;
292     struct wl_private   *lp = wl_priv(dev);
293     unsigned long       flags;
294
295     wl_lock( lp, &flags );
296
297 #ifdef USE_RTS
298     if( lp->useRTS == 1 ) {
299         DBG_TRACE( DbgInfo, "Skipping device open, in RTS mode\n" );
300         wl_unlock( lp, &flags );
301         return -EIO;
302     }
303 #endif  /* USE_RTS */
304
305 #ifdef USE_PROFILE
306     parse_config( dev );
307 #endif
308
309     if( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
310         DBG_TRACE( DbgInfo, "Enabling Port 0\n" );
311         status = wl_enable( lp );
312
313         if( status != HCF_SUCCESS ) {
314             DBG_TRACE( DbgInfo, "Enable port 0 failed: 0x%x\n", status );
315         }
316     }
317
318     // Holding the lock too long, make a gap to allow other processes
319     wl_unlock(lp, &flags);
320     wl_lock( lp, &flags );
321
322     if ( strlen( lp->fw_image_filename ) ) {
323         DBG_TRACE( DbgInfo, ";???? Kludgy way to force a download\n" );
324         status = wl_go( lp );
325     } else {
326         status = wl_apply( lp );
327     }
328
329     // Holding the lock too long, make a gap to allow other processes
330     wl_unlock(lp, &flags);
331     wl_lock( lp, &flags );
332
333     if( status != HCF_SUCCESS ) {
334         // Unsuccessful, try reset of the card to recover
335         status = wl_reset( dev );
336     }
337
338     // Holding the lock too long, make a gap to allow other processes
339     wl_unlock(lp, &flags);
340     wl_lock( lp, &flags );
341
342     if( status == HCF_SUCCESS ) {
343         netif_carrier_on( dev );
344         WL_WDS_NETIF_CARRIER_ON( lp );
345
346         lp->is_handling_int = WL_HANDLING_INT; // Start handling interrupts
347         wl_act_int_on( lp );
348
349         netif_start_queue( dev );
350         WL_WDS_NETIF_START_QUEUE( lp );
351     } else {
352         wl_hcf_error( dev, status );            /* Report the error */
353         netif_device_detach( dev );             /* Stop the device and queue */
354     }
355
356     wl_unlock( lp, &flags );
357
358     return status;
359 } // wl_open
360 /*============================================================================*/
361
362 /*******************************************************************************
363  *      wl_close()
364  *******************************************************************************
365  *
366  *  DESCRIPTION:
367  *
368  *      Close the device.
369  *
370  *  PARAMETERS:
371  *
372  *      dev - a pointer to the device's net_device structure
373  *
374  *  RETURNS:
375  *
376  *      0 on success
377  *      errno otherwise
378  *
379  ******************************************************************************/
380 int wl_close( struct net_device *dev )
381 {
382     struct wl_private   *lp = wl_priv(dev);
383     unsigned long   flags;
384
385     DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
386
387     /* Mark the adapter as busy */
388     netif_stop_queue( dev );
389     WL_WDS_NETIF_STOP_QUEUE( lp );
390
391     netif_carrier_off( dev );
392     WL_WDS_NETIF_CARRIER_OFF( lp );
393
394     /* Shutdown the adapter:
395             Disable adapter interrupts
396             Stop Tx/Rx
397             Update statistics
398             Set low power mode
399     */
400
401     wl_lock( lp, &flags );
402
403     wl_act_int_off( lp );
404     lp->is_handling_int = WL_NOT_HANDLING_INT; // Stop handling interrupts
405
406 #ifdef USE_RTS
407     if( lp->useRTS == 1 ) {
408         DBG_TRACE( DbgInfo, "Skipping device close, in RTS mode\n" );
409         wl_unlock( lp, &flags );
410         return -EIO;
411     }
412 #endif  /* USE_RTS */
413
414     /* Disable the ports */
415     wl_disable( lp );
416
417     wl_unlock( lp, &flags );
418
419     return 0;
420 } // wl_close
421 /*============================================================================*/
422
423 static void wl_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
424 {
425     strlcpy(info->driver, DRIVER_NAME, sizeof(info->driver));
426     strlcpy(info->version, DRV_VERSION_STR, sizeof(info->version));
427 //      strlcpy(info.fw_version, priv->fw_name,
428 //      sizeof(info.fw_version));
429
430     if (dev->dev.parent) {
431         dev_set_name(dev->dev.parent, "%s", info->bus_info);
432         //strlcpy(info->bus_info, dev->dev.parent->bus_id,
433         //      sizeof(info->bus_info));
434     } else {
435         snprintf(info->bus_info, sizeof(info->bus_info),
436                 "PCMCIA FIXME");
437 //                  "PCMCIA 0x%lx", priv->hw.iobase);
438     }
439 } // wl_get_drvinfo
440
441 static struct ethtool_ops wl_ethtool_ops = {
442     .get_drvinfo = wl_get_drvinfo,
443     .get_link = ethtool_op_get_link,
444 };
445
446
447 /*******************************************************************************
448  *      wl_ioctl()
449  *******************************************************************************
450  *
451  *  DESCRIPTION:
452  *
453  *      The IOCTL handler for the device.
454  *
455  *  PARAMETERS:
456  *
457  *      dev - a pointer to the device's net_device struct.
458  *      rq  - a pointer to the IOCTL request buffer.
459  *      cmd - the IOCTL command code.
460  *
461  *  RETURNS:
462  *
463  *      0 on success
464  *      errno value otherwise
465  *
466  ******************************************************************************/
467 int wl_ioctl( struct net_device *dev, struct ifreq *rq, int cmd )
468 {
469     struct wl_private  *lp = wl_priv(dev);
470     unsigned long           flags;
471     int                     ret = 0;
472
473     DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
474     DBG_PARAM(DbgInfo, "rq", "0x%p", rq);
475     DBG_PARAM(DbgInfo, "cmd", "0x%04x", cmd);
476
477     wl_lock( lp, &flags );
478
479     wl_act_int_off( lp );
480
481 #ifdef USE_RTS
482     if( lp->useRTS == 1 ) {
483         /* Handle any RTS IOCTL here */
484         if( cmd == WL_IOCTL_RTS ) {
485             DBG_TRACE( DbgInfo, "IOCTL: WL_IOCTL_RTS\n" );
486             ret = wvlan_rts( (struct rtsreq *)rq, dev->base_addr );
487         } else {
488             DBG_TRACE( DbgInfo, "IOCTL not supported in RTS mode: 0x%X\n", cmd );
489             ret = -EOPNOTSUPP;
490         }
491
492         goto out_act_int_on_unlock;
493     }
494 #endif  /* USE_RTS */
495
496     /* Only handle UIL IOCTL requests when the UIL has the system blocked. */
497     if( !(( lp->flags & WVLAN2_UIL_BUSY ) && ( cmd != WVLAN2_IOCTL_UIL ))) {
498 #ifdef USE_UIL
499         struct uilreq  *urq = (struct uilreq *)rq;
500 #endif /* USE_UIL */
501
502         switch( cmd ) {
503                 // ================== Private IOCTLs (up to 16) ==================
504 #ifdef USE_UIL
505         case WVLAN2_IOCTL_UIL:
506              DBG_TRACE( DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL\n" );
507              ret = wvlan_uil( urq, lp );
508              break;
509 #endif  /* USE_UIL */
510
511         default:
512              DBG_TRACE(DbgInfo, "IOCTL CODE NOT SUPPORTED: 0x%X\n", cmd );
513              ret = -EOPNOTSUPP;
514              break;
515         }
516     } else {
517         DBG_WARNING( DbgInfo, "DEVICE IS BUSY, CANNOT PROCESS REQUEST\n" );
518         ret = -EBUSY;
519     }
520
521 #ifdef USE_RTS
522 out_act_int_on_unlock:
523 #endif  /* USE_RTS */
524     wl_act_int_on( lp );
525
526     wl_unlock( lp, &flags );
527
528     return ret;
529 } // wl_ioctl
530 /*============================================================================*/
531
532 #ifdef CONFIG_NET_POLL_CONTROLLER
533 void wl_poll(struct net_device *dev)
534 {
535     struct wl_private *lp = wl_priv(dev);
536     unsigned long flags;
537     struct pt_regs regs;
538
539     wl_lock( lp, &flags );
540     wl_isr(dev->irq, dev, &regs);
541     wl_unlock( lp, &flags );
542 }
543 #endif
544
545 /*******************************************************************************
546  *      wl_tx_timeout()
547  *******************************************************************************
548  *
549  *  DESCRIPTION:
550  *
551  *      The handler called when, for some reason, a Tx request is not completed.
552  *
553  *  PARAMETERS:
554  *
555  *      dev - a pointer to the device's net_device struct.
556  *
557  *  RETURNS:
558  *
559  *      N/A
560  *
561  ******************************************************************************/
562 void wl_tx_timeout( struct net_device *dev )
563 {
564 #ifdef USE_WDS
565     int                     count;
566 #endif  /* USE_WDS */
567     unsigned long           flags;
568     struct wl_private       *lp = wl_priv(dev);
569     struct net_device_stats *pStats = NULL;
570
571     DBG_WARNING( DbgInfo, "%s: Transmit timeout.\n", dev->name );
572
573     wl_lock( lp, &flags );
574
575 #ifdef USE_RTS
576     if( lp->useRTS == 1 ) {
577         DBG_TRACE( DbgInfo, "Skipping tx_timeout handler, in RTS mode\n" );
578         wl_unlock( lp, &flags );
579         return;
580     }
581 #endif  /* USE_RTS */
582
583     /* Figure out which device (the "root" device or WDS port) this timeout
584        is for */
585 #ifdef USE_WDS
586
587     for( count = 0; count < NUM_WDS_PORTS; count++ ) {
588         if( dev == lp->wds_port[count].dev ) {
589             pStats = &( lp->wds_port[count].stats );
590
591             /* Break the loop so that we can use the counter to access WDS
592                information in the private structure */
593             break;
594         }
595     }
596
597 #endif  /* USE_WDS */
598
599     /* If pStats is still NULL, then the device is not a WDS port */
600     if( pStats == NULL ) {
601         pStats = &( lp->stats );
602     }
603
604     /* Accumulate the timeout error */
605     pStats->tx_errors++;
606
607     wl_unlock( lp, &flags );
608 } // wl_tx_timeout
609 /*============================================================================*/
610
611 /*******************************************************************************
612  *      wl_send()
613  *******************************************************************************
614  *
615  *  DESCRIPTION:
616  *
617  *      The routine which performs data transmits.
618  *
619  *  PARAMETERS:
620  *
621  *      lp  - a pointer to the device's wl_private struct.
622  *
623  *  RETURNS:
624  *
625  *      0 on success
626  *      1 on error
627  *
628  ******************************************************************************/
629 int wl_send( struct wl_private *lp )
630 {
631
632     int                 status;
633     DESC_STRCT          *desc;
634     WVLAN_LFRAME        *txF = NULL;
635     struct list_head    *element;
636     int                 len;
637     /*------------------------------------------------------------------------*/
638
639     if( lp == NULL ) {
640         DBG_ERROR( DbgInfo, "Private adapter struct is NULL\n" );
641         return FALSE;
642     }
643     if( lp->dev == NULL ) {
644         DBG_ERROR( DbgInfo, "net_device struct in wl_private is NULL\n" );
645         return FALSE;
646     }
647
648     /* Check for the availability of FIDs; if none are available, don't take any
649        frames off the txQ */
650     if( lp->hcfCtx.IFB_RscInd == 0 ) {
651         return FALSE;
652     }
653
654     /* Reclaim the TxQ Elements and place them back on the free queue */
655     if( !list_empty( &( lp->txQ[0] ))) {
656         element = lp->txQ[0].next;
657
658         txF = (WVLAN_LFRAME * )list_entry( element, WVLAN_LFRAME, node );
659         if( txF != NULL ) {
660             lp->txF.skb  = txF->frame.skb;
661             lp->txF.port = txF->frame.port;
662
663             txF->frame.skb  = NULL;
664             txF->frame.port = 0;
665
666             list_del( &( txF->node ));
667             list_add( element, &( lp->txFree ));
668
669             lp->txQ_count--;
670
671             if( lp->txQ_count < TX_Q_LOW_WATER_MARK ) {
672                 if( lp->netif_queue_on == FALSE ) {
673                     DBG_TX( DbgInfo, "Kickstarting Q: %d\n", lp->txQ_count );
674                     netif_wake_queue( lp->dev );
675                     WL_WDS_NETIF_WAKE_QUEUE( lp );
676                     lp->netif_queue_on = TRUE;
677                 }
678             }
679         }
680     }
681
682     if( lp->txF.skb == NULL ) {
683         return FALSE;
684     }
685
686     /* If the device has resources (FIDs) available, then Tx the packet */
687     /* Format the TxRequest and send it to the adapter */
688     len = lp->txF.skb->len < ETH_ZLEN ? ETH_ZLEN : lp->txF.skb->len;
689
690     desc                    = &( lp->desc_tx );
691     desc->buf_addr          = lp->txF.skb->data;
692     desc->BUF_CNT           = len;
693     desc->next_desc_addr    = NULL;
694
695     status = hcf_send_msg( &( lp->hcfCtx ), desc, lp->txF.port );
696
697     if( status == HCF_SUCCESS ) {
698         lp->dev->trans_start = jiffies;
699
700         DBG_TX( DbgInfo, "Transmit...\n" );
701
702         if( lp->txF.port == HCF_PORT_0 ) {
703             lp->stats.tx_packets++;
704             lp->stats.tx_bytes += lp->txF.skb->len;
705         }
706
707 #ifdef USE_WDS
708         else
709         {
710             lp->wds_port[(( lp->txF.port >> 8 ) - 1)].stats.tx_packets++;
711             lp->wds_port[(( lp->txF.port >> 8 ) - 1)].stats.tx_bytes += lp->txF.skb->len;
712         }
713
714 #endif  /* USE_WDS */
715
716         /* Free the skb and perform queue cleanup, as the buffer was
717             transmitted successfully */
718         dev_kfree_skb( lp->txF.skb );
719
720         lp->txF.skb = NULL;
721         lp->txF.port = 0;
722     }
723
724     return TRUE;
725 } // wl_send
726 /*============================================================================*/
727
728 /*******************************************************************************
729  *      wl_tx()
730  *******************************************************************************
731  *
732  *  DESCRIPTION:
733  *
734  *      The Tx handler function for the network layer.
735  *
736  *  PARAMETERS:
737  *
738  *      skb - a pointer to the sk_buff structure containing the data to transfer.
739  *      dev - a pointer to the device's net_device structure.
740  *
741  *  RETURNS:
742  *
743  *      0 on success
744  *      1 on error
745  *
746  ******************************************************************************/
747 int wl_tx( struct sk_buff *skb, struct net_device *dev, int port )
748 {
749     unsigned long           flags;
750     struct wl_private       *lp = wl_priv(dev);
751     WVLAN_LFRAME            *txF = NULL;
752     struct list_head        *element;
753     /*------------------------------------------------------------------------*/
754
755     /* Grab the spinlock */
756     wl_lock( lp, &flags );
757
758     if( lp->flags & WVLAN2_UIL_BUSY ) {
759         DBG_WARNING( DbgInfo, "UIL has device blocked\n" );
760         /* Start dropping packets here??? */
761         wl_unlock( lp, &flags );
762         return 1;
763     }
764
765 #ifdef USE_RTS
766     if( lp->useRTS == 1 ) {
767         DBG_PRINT( "RTS: we're getting a Tx...\n" );
768         wl_unlock( lp, &flags );
769         return 1;
770     }
771 #endif  /* USE_RTS */
772
773     if( !lp->use_dma ) {
774         /* Get an element from the queue */
775         element = lp->txFree.next;
776         txF = (WVLAN_LFRAME *)list_entry( element, WVLAN_LFRAME, node );
777         if( txF == NULL ) {
778             DBG_ERROR( DbgInfo, "Problem with list_entry\n" );
779             wl_unlock( lp, &flags );
780             return 1;
781         }
782         /* Fill out the frame */
783         txF->frame.skb = skb;
784         txF->frame.port = port;
785         /* Move the frame to the txQ */
786         /* NOTE: Here's where we would do priority queueing */
787         list_move(&(txF->node), &(lp->txQ[0]));
788
789         lp->txQ_count++;
790         if( lp->txQ_count >= DEFAULT_NUM_TX_FRAMES ) {
791             DBG_TX( DbgInfo, "Q Full: %d\n", lp->txQ_count );
792             if( lp->netif_queue_on == TRUE ) {
793                 netif_stop_queue( lp->dev );
794                 WL_WDS_NETIF_STOP_QUEUE( lp );
795                 lp->netif_queue_on = FALSE;
796             }
797         }
798     }
799     wl_act_int_off( lp ); /* Disable Interrupts */
800
801     /* Send the data to the hardware using the appropriate method */
802 #ifdef ENABLE_DMA
803     if( lp->use_dma ) {
804         wl_send_dma( lp, skb, port );
805     }
806     else
807 #endif
808     {
809         wl_send( lp );
810     }
811     /* Re-enable Interrupts, release the spinlock and return */
812     wl_act_int_on( lp );
813     wl_unlock( lp, &flags );
814     return 0;
815 } // wl_tx
816 /*============================================================================*/
817
818 /*******************************************************************************
819  *      wl_rx()
820  *******************************************************************************
821  *
822  *  DESCRIPTION:
823  *
824  *      The routine which performs data reception.
825  *
826  *  PARAMETERS:
827  *
828  *      dev - a pointer to the device's net_device structure.
829  *
830  *  RETURNS:
831  *
832  *      0 on success
833  *      1 on error
834  *
835  ******************************************************************************/
836 int wl_rx(struct net_device *dev)
837 {
838     int                     port;
839     struct sk_buff          *skb;
840     struct wl_private       *lp = wl_priv(dev);
841     int                     status;
842     hcf_16                  pktlen;
843     hcf_16                  hfs_stat;
844     DESC_STRCT              *desc;
845     /*------------------------------------------------------------------------*/
846
847     DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
848
849     if(!( lp->flags & WVLAN2_UIL_BUSY )) {
850
851 #ifdef USE_RTS
852         if( lp->useRTS == 1 ) {
853             DBG_PRINT( "RTS: We're getting an Rx...\n" );
854             return -EIO;
855         }
856 #endif  /* USE_RTS */
857
858         /* Read the HFS_STAT register from the lookahead buffer */
859         hfs_stat = (hcf_16)(( lp->lookAheadBuf[HFS_STAT] ) |
860                             ( lp->lookAheadBuf[HFS_STAT + 1] << 8 ));
861
862         /* Make sure the frame isn't bad */
863         if(( hfs_stat & HFS_STAT_ERR ) != HCF_SUCCESS ) {
864             DBG_WARNING( DbgInfo, "HFS_STAT_ERROR (0x%x) in Rx Packet\n",
865                          lp->lookAheadBuf[HFS_STAT] );
866             return -EIO;
867         }
868
869         /* Determine what port this packet is for */
870         port = ( hfs_stat >> 8 ) & 0x0007;
871         DBG_RX( DbgInfo, "Rx frame for port %d\n", port );
872
873         pktlen = lp->hcfCtx.IFB_RxLen;
874         if (pktlen != 0) {
875             skb = ALLOC_SKB(pktlen);
876             if (skb != NULL) {
877                 /* Set the netdev based on the port */
878                 switch( port ) {
879 #ifdef USE_WDS
880                 case 1:
881                 case 2:
882                 case 3:
883                 case 4:
884                 case 5:
885                 case 6:
886                     skb->dev = lp->wds_port[port-1].dev;
887                     break;
888 #endif  /* USE_WDS */
889
890                 case 0:
891                 default:
892                     skb->dev = dev;
893                     break;
894                 }
895
896                 desc = &( lp->desc_rx );
897
898                 desc->next_desc_addr = NULL;
899
900 /*
901 #define BLOCK_INPUT(buf, len) \
902     desc->buf_addr = buf; \
903     desc->BUF_SIZE = len; \
904     status = hcf_rcv_msg(&(lp->hcfCtx), desc, 0)
905 */
906
907                 GET_PACKET( skb->dev, skb, pktlen );
908
909                 if( status == HCF_SUCCESS ) {
910                     netif_rx( skb );
911
912                     if( port == 0 ) {
913                         lp->stats.rx_packets++;
914                         lp->stats.rx_bytes += pktlen;
915                     }
916 #ifdef USE_WDS
917                     else
918                     {
919                         lp->wds_port[port-1].stats.rx_packets++;
920                         lp->wds_port[port-1].stats.rx_bytes += pktlen;
921                     }
922 #endif  /* USE_WDS */
923
924                     dev->last_rx = jiffies;
925
926 #ifdef WIRELESS_EXT
927 #ifdef WIRELESS_SPY
928                     if( lp->spydata.spy_number > 0 ) {
929                         char *srcaddr = skb->mac.raw + MAC_ADDR_SIZE;
930
931                         wl_spy_gather( dev, srcaddr );
932                     }
933 #endif /* WIRELESS_SPY */
934 #endif /* WIRELESS_EXT */
935                 } else {
936                     DBG_ERROR( DbgInfo, "Rx request to card FAILED\n" );
937
938                     if( port == 0 ) {
939                         lp->stats.rx_dropped++;
940                     }
941 #ifdef USE_WDS
942                     else
943                     {
944                         lp->wds_port[port-1].stats.rx_dropped++;
945                     }
946 #endif  /* USE_WDS */
947
948                     dev_kfree_skb( skb );
949                 }
950             } else {
951                 DBG_ERROR( DbgInfo, "Could not alloc skb\n" );
952
953                 if( port == 0 ) {
954                     lp->stats.rx_dropped++;
955                 }
956 #ifdef USE_WDS
957                 else
958                 {
959                     lp->wds_port[port-1].stats.rx_dropped++;
960                 }
961 #endif  /* USE_WDS */
962             }
963         }
964     }
965
966     return 0;
967 } // wl_rx
968 /*============================================================================*/
969
970 /*******************************************************************************
971  *      wl_multicast()
972  *******************************************************************************
973  *
974  *  DESCRIPTION:
975  *
976  *      Function to handle multicast packets
977  *
978  *  PARAMETERS:
979  *
980  *      dev - a pointer to the device's net_device structure.
981  *
982  *  RETURNS:
983  *
984  *      N/A
985  *
986  ******************************************************************************/
987 #ifdef NEW_MULTICAST
988
989 void wl_multicast( struct net_device *dev )
990 {
991 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA //;?should we return an error status in AP mode
992 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
993
994     int                 x;
995     struct netdev_hw_addr *ha;
996     struct wl_private   *lp = wl_priv(dev);
997     unsigned long       flags;
998
999     DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
1000
1001     if( !wl_adapter_is_open( dev ))
1002         return;
1003
1004 #if DBG
1005     if( DBG_FLAGS( DbgInfo ) & DBG_PARAM_ON ) {
1006         DBG_PRINT("  flags: %s%s%s\n",
1007             ( dev->flags & IFF_PROMISC ) ? "Promiscuous " : "",
1008             ( dev->flags & IFF_MULTICAST ) ? "Multicast " : "",
1009             ( dev->flags & IFF_ALLMULTI ) ? "All-Multicast" : "" );
1010
1011         DBG_PRINT( "  mc_count: %d\n", netdev_mc_count(dev));
1012
1013         netdev_for_each_mc_addr(ha, dev)
1014         DBG_PRINT("    %pM (%d)\n", ha->addr, dev->addr_len);
1015     }
1016 #endif /* DBG */
1017
1018     if(!( lp->flags & WVLAN2_UIL_BUSY )) {
1019
1020 #ifdef USE_RTS
1021         if( lp->useRTS == 1 ) {
1022             DBG_TRACE( DbgInfo, "Skipping multicast, in RTS mode\n" );
1023             return;
1024         }
1025 #endif  /* USE_RTS */
1026
1027         wl_lock( lp, &flags );
1028         wl_act_int_off( lp );
1029
1030                 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA  ) {
1031             if( dev->flags & IFF_PROMISC ) {
1032                 /* Enable promiscuous mode */
1033                 lp->ltvRecord.len       = 2;
1034                 lp->ltvRecord.typ       = CFG_PROMISCUOUS_MODE;
1035                 lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 1 );
1036                 DBG_PRINT( "Enabling Promiscuous mode (IFF_PROMISC)\n" );
1037                 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1038             }
1039             else if ((netdev_mc_count(dev) > HCF_MAX_MULTICAST) ||
1040                     ( dev->flags & IFF_ALLMULTI )) {
1041                 /* Shutting off this filter will enable all multicast frames to
1042                    be sent up from the device; however, this is a static RID, so
1043                    a call to wl_apply() is needed */
1044                 lp->ltvRecord.len       = 2;
1045                 lp->ltvRecord.typ       = CFG_CNF_RX_ALL_GROUP_ADDR;
1046                 lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0 );
1047                 DBG_PRINT( "Enabling all multicast mode (IFF_ALLMULTI)\n" );
1048                 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1049                 wl_apply( lp );
1050             }
1051             else if (!netdev_mc_empty(dev)) {
1052                 /* Set the multicast addresses */
1053                 lp->ltvRecord.len = ( netdev_mc_count(dev) * 3 ) + 1;
1054                 lp->ltvRecord.typ = CFG_GROUP_ADDR;
1055
1056                 x = 0;
1057                 netdev_for_each_mc_addr(ha, dev)
1058                     memcpy(&(lp->ltvRecord.u.u8[x++ * ETH_ALEN]),
1059                            ha->addr, ETH_ALEN);
1060                 DBG_PRINT( "Setting multicast list\n" );
1061                 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1062             } else {
1063                 /* Disable promiscuous mode */
1064                 lp->ltvRecord.len       = 2;
1065                 lp->ltvRecord.typ       = CFG_PROMISCUOUS_MODE;
1066                 lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 0 );
1067                 DBG_PRINT( "Disabling Promiscuous mode\n" );
1068                 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1069
1070                 /* Disable multicast mode */
1071                 lp->ltvRecord.len = 2;
1072                 lp->ltvRecord.typ = CFG_GROUP_ADDR;
1073                 DBG_PRINT( "Disabling Multicast mode\n" );
1074                 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1075
1076                 /* Turning on this filter will prevent all multicast frames from
1077                    being sent up from the device; however, this is a static RID,
1078                    so a call to wl_apply() is needed */
1079                 lp->ltvRecord.len       = 2;
1080                 lp->ltvRecord.typ       = CFG_CNF_RX_ALL_GROUP_ADDR;
1081                 lp->ltvRecord.u.u16[0]  = CNV_INT_TO_LITTLE( 1 );
1082                 DBG_PRINT( "Disabling all multicast mode (IFF_ALLMULTI)\n" );
1083                 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1084                 wl_apply( lp );
1085             }
1086         }
1087         wl_act_int_on( lp );
1088         wl_unlock( lp, &flags );
1089     }
1090 #endif /* HCF_STA */
1091 } // wl_multicast
1092 /*============================================================================*/
1093
1094 #else /* NEW_MULTICAST */
1095
1096 void wl_multicast( struct net_device *dev, int num_addrs, void *addrs )
1097 {
1098     DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
1099     DBG_PARAM( DbgInfo, "num_addrs", "%d", num_addrs );
1100     DBG_PARAM( DbgInfo, "addrs", "0x%p", addrs );
1101
1102 #error Obsolete set multicast interface!
1103 } // wl_multicast
1104 /*============================================================================*/
1105
1106 #endif /* NEW_MULTICAST */
1107
1108 static const struct net_device_ops wl_netdev_ops =
1109 {
1110     .ndo_start_xmit         = &wl_tx_port0,
1111
1112     .ndo_set_config         = &wl_config,
1113     .ndo_get_stats          = &wl_stats,
1114     .ndo_set_rx_mode        = &wl_multicast,
1115
1116     .ndo_init               = &wl_insert,
1117     .ndo_open               = &wl_adapter_open,
1118     .ndo_stop               = &wl_adapter_close,
1119     .ndo_do_ioctl           = &wl_ioctl,
1120
1121     .ndo_tx_timeout         = &wl_tx_timeout,
1122
1123 #ifdef CONFIG_NET_POLL_CONTROLLER
1124     .ndo_poll_controller    = wl_poll,
1125 #endif
1126 };
1127
1128 /*******************************************************************************
1129  *      wl_device_alloc()
1130  *******************************************************************************
1131  *
1132  *  DESCRIPTION:
1133  *
1134  *      Create instances of net_device and wl_private for the new adapter
1135  *  and register the device's entry points in the net_device structure.
1136  *
1137  *  PARAMETERS:
1138  *
1139  *      N/A
1140  *
1141  *  RETURNS:
1142  *
1143  *      a pointer to an allocated and initialized net_device struct for this
1144  *      device.
1145  *
1146  ******************************************************************************/
1147 struct net_device * wl_device_alloc( void )
1148 {
1149     struct net_device   *dev = NULL;
1150     struct wl_private   *lp = NULL;
1151
1152     /* Alloc a net_device struct */
1153     dev = alloc_etherdev(sizeof(struct wl_private));
1154     if (!dev)
1155         return NULL;
1156
1157     /* Initialize the 'next' pointer in the struct. Currently only used for PCI,
1158        but do it here just in case it's used for other buses in the future */
1159     lp = wl_priv(dev);
1160
1161
1162     /* Check MTU */
1163     if( dev->mtu > MTU_MAX )
1164     {
1165             DBG_WARNING( DbgInfo, "%s: MTU set too high, limiting to %d.\n",
1166                         dev->name, MTU_MAX );
1167         dev->mtu = MTU_MAX;
1168     }
1169
1170     /* Setup the function table in the device structure. */
1171
1172     dev->wireless_handlers = (struct iw_handler_def *)&wl_iw_handler_def;
1173     lp->wireless_data.spy_data = &lp->spy_data;
1174     dev->wireless_data = &lp->wireless_data;
1175
1176     dev->netdev_ops = &wl_netdev_ops;
1177
1178     dev->watchdog_timeo     = TX_TIMEOUT;
1179
1180     dev->ethtool_ops        = &wl_ethtool_ops;
1181
1182     netif_stop_queue( dev );
1183
1184     /* Allocate virtual devices for WDS support if needed */
1185     WL_WDS_DEVICE_ALLOC( lp );
1186
1187     return dev;
1188 } // wl_device_alloc
1189 /*============================================================================*/
1190
1191 /*******************************************************************************
1192  *      wl_device_dealloc()
1193  *******************************************************************************
1194  *
1195  *  DESCRIPTION:
1196  *
1197  *      Free instances of net_device and wl_private strcutres for an adapter
1198  *  and perform basic cleanup.
1199  *
1200  *  PARAMETERS:
1201  *
1202  *      dev - a pointer to the device's net_device structure.
1203  *
1204  *  RETURNS:
1205  *
1206  *      N/A
1207  *
1208  ******************************************************************************/
1209 void wl_device_dealloc( struct net_device *dev )
1210 {
1211 //    struct wl_private   *lp = wl_priv(dev);
1212
1213     /* Dealloc the WDS ports */
1214     WL_WDS_DEVICE_DEALLOC( lp );
1215
1216     free_netdev( dev );
1217 } // wl_device_dealloc
1218 /*============================================================================*/
1219
1220 /*******************************************************************************
1221  *      wl_tx_port0()
1222  *******************************************************************************
1223  *
1224  *  DESCRIPTION:
1225  *
1226  *      The handler routine for Tx over HCF_PORT_0.
1227  *
1228  *  PARAMETERS:
1229  *
1230  *      skb - a pointer to the sk_buff to transmit.
1231  *      dev - a pointer to a net_device structure representing HCF_PORT_0.
1232  *
1233  *  RETURNS:
1234  *
1235  *      N/A
1236  *
1237  ******************************************************************************/
1238 int wl_tx_port0( struct sk_buff *skb, struct net_device *dev )
1239 {
1240     DBG_TX( DbgInfo, "Tx on Port 0\n" );
1241
1242     return wl_tx( skb, dev, HCF_PORT_0 );
1243 #ifdef ENABLE_DMA
1244     return wl_tx_dma( skb, dev, HCF_PORT_0 );
1245 #endif
1246 } // wl_tx_port0
1247 /*============================================================================*/
1248
1249 #ifdef USE_WDS
1250
1251 /*******************************************************************************
1252  *      wl_tx_port1()
1253  *******************************************************************************
1254  *
1255  *  DESCRIPTION:
1256  *
1257  *      The handler routine for Tx over HCF_PORT_1.
1258  *
1259  *  PARAMETERS:
1260  *
1261  *      skb - a pointer to the sk_buff to transmit.
1262  *      dev - a pointer to a net_device structure representing HCF_PORT_1.
1263  *
1264  *  RETURNS:
1265  *
1266  *      N/A
1267  *
1268  ******************************************************************************/
1269 int wl_tx_port1( struct sk_buff *skb, struct net_device *dev )
1270 {
1271     DBG_TX( DbgInfo, "Tx on Port 1\n" );
1272     return wl_tx( skb, dev, HCF_PORT_1 );
1273 } // wl_tx_port1
1274 /*============================================================================*/
1275
1276 /*******************************************************************************
1277  *      wl_tx_port2()
1278  *******************************************************************************
1279  *
1280  *  DESCRIPTION:
1281  *
1282  *      The handler routine for Tx over HCF_PORT_2.
1283  *
1284  *  PARAMETERS:
1285  *
1286  *      skb - a pointer to the sk_buff to transmit.
1287  *      dev - a pointer to a net_device structure representing HCF_PORT_2.
1288  *
1289  *  RETURNS:
1290  *
1291  *      N/A
1292  *
1293  ******************************************************************************/
1294 int wl_tx_port2( struct sk_buff *skb, struct net_device *dev )
1295 {
1296     DBG_TX( DbgInfo, "Tx on Port 2\n" );
1297     return wl_tx( skb, dev, HCF_PORT_2 );
1298 } // wl_tx_port2
1299 /*============================================================================*/
1300
1301 /*******************************************************************************
1302  *      wl_tx_port3()
1303  *******************************************************************************
1304  *
1305  *  DESCRIPTION:
1306  *
1307  *      The handler routine for Tx over HCF_PORT_3.
1308  *
1309  *  PARAMETERS:
1310  *
1311  *      skb - a pointer to the sk_buff to transmit.
1312  *      dev - a pointer to a net_device structure representing HCF_PORT_3.
1313  *
1314  *  RETURNS:
1315  *
1316  *      N/A
1317  *
1318  ******************************************************************************/
1319 int wl_tx_port3( struct sk_buff *skb, struct net_device *dev )
1320 {
1321     DBG_TX( DbgInfo, "Tx on Port 3\n" );
1322     return wl_tx( skb, dev, HCF_PORT_3 );
1323 } // wl_tx_port3
1324 /*============================================================================*/
1325
1326 /*******************************************************************************
1327  *      wl_tx_port4()
1328  *******************************************************************************
1329  *
1330  *  DESCRIPTION:
1331  *
1332  *      The handler routine for Tx over HCF_PORT_4.
1333  *
1334  *  PARAMETERS:
1335  *
1336  *      skb - a pointer to the sk_buff to transmit.
1337  *      dev - a pointer to a net_device structure representing HCF_PORT_4.
1338  *
1339  *  RETURNS:
1340  *
1341  *      N/A
1342  *
1343  ******************************************************************************/
1344 int wl_tx_port4( struct sk_buff *skb, struct net_device *dev )
1345 {
1346     DBG_TX( DbgInfo, "Tx on Port 4\n" );
1347     return wl_tx( skb, dev, HCF_PORT_4 );
1348 } // wl_tx_port4
1349 /*============================================================================*/
1350
1351 /*******************************************************************************
1352  *      wl_tx_port5()
1353  *******************************************************************************
1354  *
1355  *  DESCRIPTION:
1356  *
1357  *      The handler routine for Tx over HCF_PORT_5.
1358  *
1359  *  PARAMETERS:
1360  *
1361  *      skb - a pointer to the sk_buff to transmit.
1362  *      dev - a pointer to a net_device structure representing HCF_PORT_5.
1363  *
1364  *  RETURNS:
1365  *
1366  *      N/A
1367  *
1368  ******************************************************************************/
1369 int wl_tx_port5( struct sk_buff *skb, struct net_device *dev )
1370 {
1371     DBG_TX( DbgInfo, "Tx on Port 5\n" );
1372     return wl_tx( skb, dev, HCF_PORT_5 );
1373 } // wl_tx_port5
1374 /*============================================================================*/
1375
1376 /*******************************************************************************
1377  *      wl_tx_port6()
1378  *******************************************************************************
1379  *
1380  *  DESCRIPTION:
1381  *
1382  *      The handler routine for Tx over HCF_PORT_6.
1383  *
1384  *  PARAMETERS:
1385  *
1386  *      skb - a pointer to the sk_buff to transmit.
1387  *      dev - a pointer to a net_device structure representing HCF_PORT_6.
1388  *
1389  *  RETURNS:
1390  *
1391  *      N/A
1392  *
1393  ******************************************************************************/
1394 int wl_tx_port6( struct sk_buff *skb, struct net_device *dev )
1395 {
1396     DBG_TX( DbgInfo, "Tx on Port 6\n" );
1397     return wl_tx( skb, dev, HCF_PORT_6 );
1398 } // wl_tx_port6
1399 /*============================================================================*/
1400
1401 /*******************************************************************************
1402  *      wl_wds_device_alloc()
1403  *******************************************************************************
1404  *
1405  *  DESCRIPTION:
1406  *
1407  *      Create instances of net_device to represent the WDS ports, and register
1408  *  the device's entry points in the net_device structure.
1409  *
1410  *  PARAMETERS:
1411  *
1412  *      lp  - a pointer to the device's private adapter structure
1413  *
1414  *  RETURNS:
1415  *
1416  *      N/A, but will place pointers to the allocated and initialized net_device
1417  *      structs in the private adapter structure.
1418  *
1419  ******************************************************************************/
1420 void wl_wds_device_alloc( struct wl_private *lp )
1421 {
1422     int count;
1423
1424     /* WDS support requires additional net_device structs to be allocated,
1425        so that user space apps can use these virtual devices to specify the
1426        port on which to Tx/Rx */
1427     for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1428         struct net_device *dev_wds = NULL;
1429
1430         dev_wds = kzalloc(sizeof(struct net_device), GFP_KERNEL);
1431         if (!dev_wds)
1432                 return;
1433
1434         ether_setup( dev_wds );
1435
1436         lp->wds_port[count].dev = dev_wds;
1437
1438         /* Re-use wl_init for all the devices, as it currently does nothing, but
1439            is required. Re-use the stats/tx_timeout handler for all as well; the
1440            WDS port which is requesting these operations can be determined by
1441            the net_device pointer. Set the private member of all devices to point
1442            to the same net_device struct; that way, all information gets
1443            funnelled through the one "real" net_device. Name the WDS ports
1444            "wds<n>" */
1445         lp->wds_port[count].dev->init           = &wl_init;
1446         lp->wds_port[count].dev->get_stats      = &wl_stats;
1447         lp->wds_port[count].dev->tx_timeout     = &wl_tx_timeout;
1448         lp->wds_port[count].dev->watchdog_timeo = TX_TIMEOUT;
1449         lp->wds_port[count].dev->priv           = lp;
1450
1451         sprintf( lp->wds_port[count].dev->name, "wds%d", count );
1452     }
1453
1454     /* Register the Tx handlers */
1455     lp->wds_port[0].dev->hard_start_xmit = &wl_tx_port1;
1456     lp->wds_port[1].dev->hard_start_xmit = &wl_tx_port2;
1457     lp->wds_port[2].dev->hard_start_xmit = &wl_tx_port3;
1458     lp->wds_port[3].dev->hard_start_xmit = &wl_tx_port4;
1459     lp->wds_port[4].dev->hard_start_xmit = &wl_tx_port5;
1460     lp->wds_port[5].dev->hard_start_xmit = &wl_tx_port6;
1461
1462     WL_WDS_NETIF_STOP_QUEUE( lp );
1463 } // wl_wds_device_alloc
1464 /*============================================================================*/
1465
1466 /*******************************************************************************
1467  *      wl_wds_device_dealloc()
1468  *******************************************************************************
1469  *
1470  *  DESCRIPTION:
1471  *
1472  *      Free instances of net_device structures used to support WDS.
1473  *
1474  *  PARAMETERS:
1475  *
1476  *      lp  - a pointer to the device's private adapter structure
1477  *
1478  *  RETURNS:
1479  *
1480  *      N/A
1481  *
1482  ******************************************************************************/
1483 void wl_wds_device_dealloc( struct wl_private *lp )
1484 {
1485     int count;
1486
1487     for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1488         struct net_device *dev_wds = NULL;
1489
1490         dev_wds = lp->wds_port[count].dev;
1491
1492         if( dev_wds != NULL ) {
1493             if( dev_wds->flags & IFF_UP ) {
1494                 dev_close( dev_wds );
1495                 dev_wds->flags &= ~( IFF_UP | IFF_RUNNING );
1496             }
1497
1498             free_netdev(dev_wds);
1499             lp->wds_port[count].dev = NULL;
1500         }
1501     }
1502 } // wl_wds_device_dealloc
1503 /*============================================================================*/
1504
1505 /*******************************************************************************
1506  *      wl_wds_netif_start_queue()
1507  *******************************************************************************
1508  *
1509  *  DESCRIPTION:
1510  *
1511  *      Used to start the netif queues of all the "virtual" network devices
1512  *      which represent the WDS ports.
1513  *
1514  *  PARAMETERS:
1515  *
1516  *      lp  - a pointer to the device's private adapter structure
1517  *
1518  *  RETURNS:
1519  *
1520  *      N/A
1521  *
1522  ******************************************************************************/
1523 void wl_wds_netif_start_queue( struct wl_private *lp )
1524 {
1525     int count;
1526     /*------------------------------------------------------------------------*/
1527
1528     if( lp != NULL ) {
1529         for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1530             if( lp->wds_port[count].is_registered &&
1531                 lp->wds_port[count].netif_queue_on == FALSE ) {
1532                 netif_start_queue( lp->wds_port[count].dev );
1533                 lp->wds_port[count].netif_queue_on = TRUE;
1534             }
1535         }
1536     }
1537 } // wl_wds_netif_start_queue
1538 /*============================================================================*/
1539
1540 /*******************************************************************************
1541  *      wl_wds_netif_stop_queue()
1542  *******************************************************************************
1543  *
1544  *  DESCRIPTION:
1545  *
1546  *      Used to stop the netif queues of all the "virtual" network devices
1547  *      which represent the WDS ports.
1548  *
1549  *  PARAMETERS:
1550  *
1551  *      lp  - a pointer to the device's private adapter structure
1552  *
1553  *  RETURNS:
1554  *
1555  *      N/A
1556  *
1557  ******************************************************************************/
1558 void wl_wds_netif_stop_queue( struct wl_private *lp )
1559 {
1560     int count;
1561     /*------------------------------------------------------------------------*/
1562
1563     if( lp != NULL ) {
1564         for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1565             if( lp->wds_port[count].is_registered &&
1566                 lp->wds_port[count].netif_queue_on == TRUE ) {
1567                 netif_stop_queue( lp->wds_port[count].dev );
1568                 lp->wds_port[count].netif_queue_on = FALSE;
1569             }
1570         }
1571     }
1572 } // wl_wds_netif_stop_queue
1573 /*============================================================================*/
1574
1575 /*******************************************************************************
1576  *      wl_wds_netif_wake_queue()
1577  *******************************************************************************
1578  *
1579  *  DESCRIPTION:
1580  *
1581  *      Used to wake the netif queues of all the "virtual" network devices
1582  *      which represent the WDS ports.
1583  *
1584  *  PARAMETERS:
1585  *
1586  *      lp  - a pointer to the device's private adapter structure
1587  *
1588  *  RETURNS:
1589  *
1590  *      N/A
1591  *
1592  ******************************************************************************/
1593 void wl_wds_netif_wake_queue( struct wl_private *lp )
1594 {
1595     int count;
1596     /*------------------------------------------------------------------------*/
1597
1598     if( lp != NULL ) {
1599         for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1600             if( lp->wds_port[count].is_registered &&
1601                 lp->wds_port[count].netif_queue_on == FALSE ) {
1602                 netif_wake_queue( lp->wds_port[count].dev );
1603                 lp->wds_port[count].netif_queue_on = TRUE;
1604             }
1605         }
1606     }
1607 } // wl_wds_netif_wake_queue
1608 /*============================================================================*/
1609
1610 /*******************************************************************************
1611  *      wl_wds_netif_carrier_on()
1612  *******************************************************************************
1613  *
1614  *  DESCRIPTION:
1615  *
1616  *      Used to signal the network layer that carrier is present on all of the
1617  *      "virtual" network devices which represent the WDS ports.
1618  *
1619  *  PARAMETERS:
1620  *
1621  *      lp  - a pointer to the device's private adapter structure
1622  *
1623  *  RETURNS:
1624  *
1625  *      N/A
1626  *
1627  ******************************************************************************/
1628 void wl_wds_netif_carrier_on( struct wl_private *lp )
1629 {
1630     int count;
1631     /*------------------------------------------------------------------------*/
1632
1633     if( lp != NULL ) {
1634         for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1635             if( lp->wds_port[count].is_registered ) {
1636                 netif_carrier_on( lp->wds_port[count].dev );
1637             }
1638         }
1639     }
1640 } // wl_wds_netif_carrier_on
1641 /*============================================================================*/
1642
1643 /*******************************************************************************
1644  *      wl_wds_netif_carrier_off()
1645  *******************************************************************************
1646  *
1647  *  DESCRIPTION:
1648  *
1649  *      Used to signal the network layer that carrier is NOT present on all of
1650  *      the "virtual" network devices which represent the WDS ports.
1651  *
1652  *  PARAMETERS:
1653  *
1654  *      lp  - a pointer to the device's private adapter structure
1655  *
1656  *  RETURNS:
1657  *
1658  *      N/A
1659  *
1660  ******************************************************************************/
1661 void wl_wds_netif_carrier_off( struct wl_private *lp )
1662 {
1663         int count;
1664
1665         if(lp != NULL) {
1666                 for(count = 0; count < NUM_WDS_PORTS; count++) {
1667                         if(lp->wds_port[count].is_registered)
1668                                 netif_carrier_off(lp->wds_port[count].dev);
1669                 }
1670         }
1671
1672 } // wl_wds_netif_carrier_off
1673 /*============================================================================*/
1674
1675 #endif  /* USE_WDS */
1676
1677 #ifdef ENABLE_DMA
1678 /*******************************************************************************
1679  *      wl_send_dma()
1680  *******************************************************************************
1681  *
1682  *  DESCRIPTION:
1683  *
1684  *      The routine which performs data transmits when using busmaster DMA.
1685  *
1686  *  PARAMETERS:
1687  *
1688  *      lp   - a pointer to the device's wl_private struct.
1689  *      skb  - a pointer to the network layer's data buffer.
1690  *      port - the Hermes port on which to transmit.
1691  *
1692  *  RETURNS:
1693  *
1694  *      0 on success
1695  *      1 on error
1696  *
1697  ******************************************************************************/
1698 int wl_send_dma( struct wl_private *lp, struct sk_buff *skb, int port )
1699 {
1700     int         len;
1701     DESC_STRCT *desc = NULL;
1702     DESC_STRCT *desc_next = NULL;
1703     /*------------------------------------------------------------------------*/
1704
1705     if( lp == NULL ) {
1706         DBG_ERROR( DbgInfo, "Private adapter struct is NULL\n" );
1707         return FALSE;
1708     }
1709
1710     if( lp->dev == NULL ) {
1711         DBG_ERROR( DbgInfo, "net_device struct in wl_private is NULL\n" );
1712         return FALSE;
1713     }
1714
1715     /* AGAIN, ALL THE QUEUEING DONE HERE IN I/O MODE IS NOT PERFORMED */
1716
1717     if( skb == NULL ) {
1718         DBG_WARNING (DbgInfo, "Nothing to send.\n");
1719         return FALSE;
1720     }
1721
1722     len = skb->len;
1723
1724     /* Get a free descriptor */
1725     desc = wl_pci_dma_get_tx_packet( lp );
1726
1727     if( desc == NULL ) {
1728         if( lp->netif_queue_on == TRUE ) {
1729             netif_stop_queue( lp->dev );
1730             WL_WDS_NETIF_STOP_QUEUE( lp );
1731             lp->netif_queue_on = FALSE;
1732
1733             dev_kfree_skb( skb );
1734             return 0;
1735         }
1736     }
1737
1738     SET_BUF_CNT( desc, /*HCF_DMA_FD_CNT*/HFS_ADDR_DEST );
1739     SET_BUF_SIZE( desc, HCF_DMA_TX_BUF1_SIZE );
1740
1741     desc_next = desc->next_desc_addr;
1742
1743     if( desc_next->buf_addr == NULL ) {
1744         DBG_ERROR( DbgInfo, "DMA descriptor buf_addr is NULL\n" );
1745         return FALSE;
1746     }
1747
1748     /* Copy the payload into the DMA packet */
1749     memcpy( desc_next->buf_addr, skb->data, len );
1750
1751     SET_BUF_CNT( desc_next, len );
1752     SET_BUF_SIZE( desc_next, HCF_MAX_PACKET_SIZE );
1753
1754     hcf_dma_tx_put( &( lp->hcfCtx ), desc, 0 );
1755
1756     /* Free the skb and perform queue cleanup, as the buffer was
1757             transmitted successfully */
1758     dev_kfree_skb( skb );
1759
1760     return TRUE;
1761 } // wl_send_dma
1762 /*============================================================================*/
1763
1764 /*******************************************************************************
1765  *      wl_rx_dma()
1766  *******************************************************************************
1767  *
1768  *  DESCRIPTION:
1769  *
1770  *      The routine which performs data reception when using busmaster DMA.
1771  *
1772  *  PARAMETERS:
1773  *
1774  *      dev - a pointer to the device's net_device structure.
1775  *
1776  *  RETURNS:
1777  *
1778  *      0 on success
1779  *      1 on error
1780  *
1781  ******************************************************************************/
1782 int wl_rx_dma( struct net_device *dev )
1783 {
1784     int                      port;
1785     hcf_16                   pktlen;
1786     hcf_16                   hfs_stat;
1787     struct sk_buff          *skb;
1788     struct wl_private       *lp = NULL;
1789     DESC_STRCT              *desc, *desc_next;
1790     //CFG_MB_INFO_RANGE2_STRCT x;
1791     /*------------------------------------------------------------------------*/
1792
1793     DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
1794
1795     if((( lp = dev->priv ) != NULL ) &&
1796         !( lp->flags & WVLAN2_UIL_BUSY )) {
1797
1798 #ifdef USE_RTS
1799         if( lp->useRTS == 1 ) {
1800             DBG_PRINT( "RTS: We're getting an Rx...\n" );
1801             return -EIO;
1802         }
1803 #endif  /* USE_RTS */
1804
1805         //if( lp->dma.status == 0 )
1806         //{
1807             desc = hcf_dma_rx_get( &( lp->hcfCtx ));
1808
1809             if( desc != NULL )
1810             {
1811                 /* Check and see if we rcvd. a WMP frame */
1812                 /*
1813                 if((( *(hcf_8 *)&desc->buf_addr[HFS_STAT] ) &
1814                     ( HFS_STAT_MSG_TYPE | HFS_STAT_ERR )) == HFS_STAT_WMP_MSG )
1815                 {
1816                     DBG_TRACE( DbgInfo, "Got a WMP frame\n" );
1817
1818                     x.len = sizeof( CFG_MB_INFO_RANGE2_STRCT ) / sizeof( hcf_16 );
1819                                     x.typ = CFG_MB_INFO;
1820                                     x.base_typ = CFG_WMP;
1821                                     x.frag_cnt = 2;
1822                                     x.frag_buf[0].frag_len  = GET_BUF_CNT( descp ) / sizeof( hcf_16 );
1823                                     x.frag_buf[0].frag_addr = (hcf_8 *) descp->buf_addr ;
1824                                     x.frag_buf[1].frag_len  = ( GET_BUF_CNT( descp->next_desc_addr ) + 1 ) / sizeof( hcf_16 );
1825                                     x.frag_buf[1].frag_addr = (hcf_8 *) descp->next_desc_addr->buf_addr ;
1826
1827                     hcf_put_info( &( lp->hcfCtx ), (LTVP)&x );
1828                 }
1829                 */
1830
1831                 desc_next = desc->next_desc_addr;
1832
1833                 /* Make sure the buffer isn't empty */
1834                 if( GET_BUF_CNT( desc ) == 0 ) {
1835                     DBG_WARNING( DbgInfo, "Buffer is empty!\n" );
1836
1837                     /* Give the descriptor back to the HCF */
1838                     hcf_dma_rx_put( &( lp->hcfCtx ), desc );
1839                     return -EIO;
1840                 }
1841
1842                 /* Read the HFS_STAT register from the lookahead buffer */
1843                 hfs_stat = (hcf_16)( desc->buf_addr[HFS_STAT/2] );
1844
1845                 /* Make sure the frame isn't bad */
1846                 if(( hfs_stat & HFS_STAT_ERR ) != HCF_SUCCESS )
1847                 {
1848                     DBG_WARNING( DbgInfo, "HFS_STAT_ERROR (0x%x) in Rx Packet\n",
1849                                 desc->buf_addr[HFS_STAT/2] );
1850
1851                     /* Give the descriptor back to the HCF */
1852                     hcf_dma_rx_put( &( lp->hcfCtx ), desc );
1853                     return -EIO;
1854                 }
1855
1856                 /* Determine what port this packet is for */
1857                 port = ( hfs_stat >> 8 ) & 0x0007;
1858                 DBG_RX( DbgInfo, "Rx frame for port %d\n", port );
1859
1860                 pktlen = GET_BUF_CNT(desc_next);
1861                 if (pktlen != 0) {
1862                     skb = ALLOC_SKB(pktlen);
1863                     if (skb != NULL) {
1864                         switch( port ) {
1865 #ifdef USE_WDS
1866                         case 1:
1867                         case 2:
1868                         case 3:
1869                         case 4:
1870                         case 5:
1871                         case 6:
1872                             skb->dev = lp->wds_port[port-1].dev;
1873                             break;
1874 #endif  /* USE_WDS */
1875
1876                         case 0:
1877                         default:
1878                             skb->dev = dev;
1879                             break;
1880                         }
1881
1882                         GET_PACKET_DMA( skb->dev, skb, pktlen );
1883
1884                         /* Give the descriptor back to the HCF */
1885                         hcf_dma_rx_put( &( lp->hcfCtx ), desc );
1886
1887                         netif_rx( skb );
1888
1889                         if( port == 0 ) {
1890                             lp->stats.rx_packets++;
1891                             lp->stats.rx_bytes += pktlen;
1892                         }
1893 #ifdef USE_WDS
1894                         else
1895                         {
1896                             lp->wds_port[port-1].stats.rx_packets++;
1897                             lp->wds_port[port-1].stats.rx_bytes += pktlen;
1898                         }
1899 #endif  /* USE_WDS */
1900
1901                         dev->last_rx = jiffies;
1902
1903                     } else {
1904                         DBG_ERROR( DbgInfo, "Could not alloc skb\n" );
1905
1906                         if( port == 0 )
1907                             {
1908                                 lp->stats.rx_dropped++;
1909                             }
1910 #ifdef USE_WDS
1911                         else
1912                         {
1913                             lp->wds_port[port-1].stats.rx_dropped++;
1914                         }
1915 #endif  /* USE_WDS */
1916                     }
1917                 }
1918             }
1919         //}
1920     }
1921
1922     return 0;
1923 } // wl_rx_dma
1924 /*============================================================================*/
1925 #endif  // ENABLE_DMA