GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / wlags49_h2 / wl_netdev.c
blob19f0118e78cab8fa3371d0a18ce6d46a4542e123
1 /*******************************************************************************
2 * Agere Systems Inc.
3 * Wireless device driver for Linux (wlags49).
5 * Copyright (c) 1998-2003 Agere Systems Inc.
6 * All rights reserved.
7 * http://www.agere.com
9 * Initially developed by TriplePoint, Inc.
10 * http://www.triplepoint.com
12 *------------------------------------------------------------------------------
14 * This file contains handler functions registered with the net_device
15 * structure.
17 *------------------------------------------------------------------------------
19 * SOFTWARE LICENSE
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.
26 * Copyright © 2003 Agere Systems Inc.
27 * All rights reserved.
29 * Redistribution and use in source or binary forms, with or without
30 * modifications, are permitted provided that the following conditions are met:
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.
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.
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.
45 * Disclaimer
47 * THIS SOFTWARE IS PROVIDED “AS IS” 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.
60 ******************************************************************************/
62 /*******************************************************************************
63 * include files
64 ******************************************************************************/
65 #include <wl_version.h>
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/system.h>
83 // #include <asm/bitops.h>
85 #include <linux/netdevice.h>
86 #include <linux/ethtool.h>
87 #include <linux/etherdevice.h>
88 // #include <linux/skbuff.h>
89 // #include <linux/if_arp.h>
90 // #include <linux/ioport.h>
92 #include <debug.h>
94 #include <hcf.h>
95 #include <dhf.h>
96 // #include <hcfdef.h>
98 #include <wl_if.h>
99 #include <wl_internal.h>
100 #include <wl_util.h>
101 #include <wl_priv.h>
102 #include <wl_main.h>
103 #include <wl_netdev.h>
104 #include <wl_wext.h>
106 #ifdef USE_PROFILE
107 #include <wl_profile.h>
108 #endif /* USE_PROFILE */
110 #ifdef BUS_PCMCIA
111 #include <wl_cs.h>
112 #endif /* BUS_PCMCIA */
114 #ifdef BUS_PCI
115 #include <wl_pci.h>
116 #endif /* BUS_PCI */
119 /*******************************************************************************
120 * global variables
121 ******************************************************************************/
122 #if DBG
123 extern dbg_info_t *DbgInfo;
124 #endif /* DBG */
127 #if HCF_ENCAP
128 #define MTU_MAX (HCF_MAX_MSG - ETH_HLEN - 8)
129 #else
130 #define MTU_MAX (HCF_MAX_MSG - ETH_HLEN)
131 #endif
133 //static int mtu = MTU_MAX;
134 //MODULE_PARM(mtu, "i");
135 //MODULE_PARM_DESC(mtu, "MTU");
137 /*******************************************************************************
138 * macros
139 ******************************************************************************/
140 #define BLOCK_INPUT(buf, len) \
141 desc->buf_addr = buf; \
142 desc->BUF_SIZE = len; \
143 status = hcf_rcv_msg(&(lp->hcfCtx), desc, 0)
145 #define BLOCK_INPUT_DMA(buf, len) memcpy( buf, desc_next->buf_addr, pktlen )
147 /*******************************************************************************
148 * function prototypes
149 ******************************************************************************/
151 /*******************************************************************************
152 * wl_init()
153 *******************************************************************************
155 * DESCRIPTION:
157 * We never need to do anything when a "Wireless" device is "initialized"
158 * by the net software, because we only register already-found cards.
160 * PARAMETERS:
162 * dev - a pointer to the device's net_device structure
164 * RETURNS:
166 * 0 on success
167 * errno value otherwise
169 ******************************************************************************/
170 int wl_init( struct net_device *dev )
172 // unsigned long flags;
173 // struct wl_private *lp = wl_priv(dev);
174 /*------------------------------------------------------------------------*/
176 DBG_FUNC( "wl_init" );
177 DBG_ENTER( DbgInfo );
179 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
181 /* Nothing to do, but grab the spinlock anyway just in case we ever need
182 this routine */
183 // wl_lock( lp, &flags );
184 // wl_unlock( lp, &flags );
186 DBG_LEAVE( DbgInfo );
187 return 0;
188 } // wl_init
189 /*============================================================================*/
191 /*******************************************************************************
192 * wl_config()
193 *******************************************************************************
195 * DESCRIPTION:
197 * Implement the SIOCSIFMAP interface.
199 * PARAMETERS:
201 * dev - a pointer to the device's net_device structure
202 * map - a pointer to the device's ifmap structure
204 * RETURNS:
206 * 0 on success
207 * errno otherwise
209 ******************************************************************************/
210 int wl_config( struct net_device *dev, struct ifmap *map )
212 DBG_FUNC( "wl_config" );
213 DBG_ENTER( DbgInfo );
215 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
216 DBG_PARAM( DbgInfo, "map", "0x%p", map );
218 /* The only thing we care about here is a port change. Since this not needed,
219 ignore the request. */
220 DBG_TRACE( DbgInfo, "%s: %s called.\n", dev->name, __FUNC__ );
222 DBG_LEAVE( DbgInfo );
223 return 0;
224 } // wl_config
225 /*============================================================================*/
227 /*******************************************************************************
228 * wl_stats()
229 *******************************************************************************
231 * DESCRIPTION:
233 * Return the current device statistics.
235 * PARAMETERS:
237 * dev - a pointer to the device's net_device structure
239 * RETURNS:
241 * a pointer to a net_device_stats structure containing the network
242 * statistics.
244 ******************************************************************************/
245 struct net_device_stats *wl_stats( struct net_device *dev )
247 #ifdef USE_WDS
248 int count;
249 #endif /* USE_WDS */
250 unsigned long flags;
251 struct net_device_stats *pStats;
252 struct wl_private *lp = wl_priv(dev);
253 /*------------------------------------------------------------------------*/
255 //DBG_FUNC( "wl_stats" );
256 //DBG_ENTER( DbgInfo );
257 //DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
259 pStats = NULL;
261 wl_lock( lp, &flags );
263 #ifdef USE_RTS
264 if( lp->useRTS == 1 ) {
265 wl_unlock( lp, &flags );
267 //DBG_LEAVE( DbgInfo );
268 return NULL;
270 #endif /* USE_RTS */
272 /* Return the statistics for the appropriate device */
273 #ifdef USE_WDS
275 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
276 if( dev == lp->wds_port[count].dev ) {
277 pStats = &( lp->wds_port[count].stats );
281 #endif /* USE_WDS */
283 /* If pStats is still NULL, then the device is not a WDS port */
284 if( pStats == NULL ) {
285 pStats = &( lp->stats );
288 wl_unlock( lp, &flags );
290 //DBG_LEAVE( DbgInfo );
292 return pStats;
293 } // wl_stats
294 /*============================================================================*/
296 /*******************************************************************************
297 * wl_open()
298 *******************************************************************************
300 * DESCRIPTION:
302 * Open the device.
304 * PARAMETERS:
306 * dev - a pointer to the device's net_device structure
308 * RETURNS:
310 * 0 on success
311 * errno otherwise
313 ******************************************************************************/
314 int wl_open(struct net_device *dev)
316 int status = HCF_SUCCESS;
317 struct wl_private *lp = wl_priv(dev);
318 unsigned long flags;
319 /*------------------------------------------------------------------------*/
321 DBG_FUNC( "wl_open" );
322 DBG_ENTER( DbgInfo );
324 wl_lock( lp, &flags );
326 #ifdef USE_RTS
327 if( lp->useRTS == 1 ) {
328 DBG_TRACE( DbgInfo, "Skipping device open, in RTS mode\n" );
329 wl_unlock( lp, &flags );
330 DBG_LEAVE( DbgInfo );
331 return -EIO;
333 #endif /* USE_RTS */
335 #ifdef USE_PROFILE
336 parse_config( dev );
337 #endif
339 if( lp->portState == WVLAN_PORT_STATE_DISABLED ) {
340 DBG_TRACE( DbgInfo, "Enabling Port 0\n" );
341 status = wl_enable( lp );
343 if( status != HCF_SUCCESS ) {
344 DBG_TRACE( DbgInfo, "Enable port 0 failed: 0x%x\n", status );
348 // Holding the lock too long, make a gap to allow other processes
349 wl_unlock(lp, &flags);
350 wl_lock( lp, &flags );
352 if ( strlen( lp->fw_image_filename ) ) {
353 DBG_TRACE( DbgInfo, ";???? Kludgy way to force a download\n" );
354 status = wl_go( lp );
355 } else {
356 status = wl_apply( lp );
359 // Holding the lock too long, make a gap to allow other processes
360 wl_unlock(lp, &flags);
361 wl_lock( lp, &flags );
363 if( status != HCF_SUCCESS ) {
364 // Unsuccessful, try reset of the card to recover
365 status = wl_reset( dev );
368 // Holding the lock too long, make a gap to allow other processes
369 wl_unlock(lp, &flags);
370 wl_lock( lp, &flags );
372 if( status == HCF_SUCCESS ) {
373 netif_carrier_on( dev );
374 WL_WDS_NETIF_CARRIER_ON( lp );
376 lp->is_handling_int = WL_HANDLING_INT; // Start handling interrupts
377 wl_act_int_on( lp );
379 netif_start_queue( dev );
380 WL_WDS_NETIF_START_QUEUE( lp );
381 } else {
382 wl_hcf_error( dev, status ); /* Report the error */
383 netif_device_detach( dev ); /* Stop the device and queue */
386 wl_unlock( lp, &flags );
388 DBG_LEAVE( DbgInfo );
389 return status;
390 } // wl_open
391 /*============================================================================*/
393 /*******************************************************************************
394 * wl_close()
395 *******************************************************************************
397 * DESCRIPTION:
399 * Close the device.
401 * PARAMETERS:
403 * dev - a pointer to the device's net_device structure
405 * RETURNS:
407 * 0 on success
408 * errno otherwise
410 ******************************************************************************/
411 int wl_close( struct net_device *dev )
413 struct wl_private *lp = wl_priv(dev);
414 unsigned long flags;
415 /*------------------------------------------------------------------------*/
417 DBG_FUNC("wl_close");
418 DBG_ENTER(DbgInfo);
419 DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
421 /* Mark the adapter as busy */
422 netif_stop_queue( dev );
423 WL_WDS_NETIF_STOP_QUEUE( lp );
425 netif_carrier_off( dev );
426 WL_WDS_NETIF_CARRIER_OFF( lp );
428 /* Shutdown the adapter:
429 Disable adapter interrupts
430 Stop Tx/Rx
431 Update statistics
432 Set low power mode
435 wl_lock( lp, &flags );
437 wl_act_int_off( lp );
438 lp->is_handling_int = WL_NOT_HANDLING_INT; // Stop handling interrupts
440 #ifdef USE_RTS
441 if( lp->useRTS == 1 ) {
442 DBG_TRACE( DbgInfo, "Skipping device close, in RTS mode\n" );
443 wl_unlock( lp, &flags );
444 DBG_LEAVE( DbgInfo );
445 return -EIO;
447 #endif /* USE_RTS */
449 /* Disable the ports */
450 wl_disable( lp );
452 wl_unlock( lp, &flags );
454 DBG_LEAVE( DbgInfo );
455 return 0;
456 } // wl_close
457 /*============================================================================*/
459 static void wl_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
461 strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
462 strncpy(info->version, DRV_VERSION_STR, sizeof(info->version) - 1);
463 // strncpy(info.fw_version, priv->fw_name,
464 // sizeof(info.fw_version) - 1);
466 if (dev->dev.parent) {
467 dev_set_name(dev->dev.parent, "%s", info->bus_info);
468 //strncpy(info->bus_info, dev->dev.parent->bus_id,
469 // sizeof(info->bus_info) - 1);
470 } else {
471 snprintf(info->bus_info, sizeof(info->bus_info) - 1,
472 "PCMCIA FIXME");
473 // "PCMCIA 0x%lx", priv->hw.iobase);
475 } // wl_get_drvinfo
477 static struct ethtool_ops wl_ethtool_ops = {
478 .get_drvinfo = wl_get_drvinfo,
479 .get_link = ethtool_op_get_link,
483 /*******************************************************************************
484 * wl_ioctl()
485 *******************************************************************************
487 * DESCRIPTION:
489 * The IOCTL handler for the device.
491 * PARAMETERS:
493 * dev - a pointer to the device's net_device struct.
494 * rq - a pointer to the IOCTL request buffer.
495 * cmd - the IOCTL command code.
497 * RETURNS:
499 * 0 on success
500 * errno value otherwise
502 ******************************************************************************/
503 int wl_ioctl( struct net_device *dev, struct ifreq *rq, int cmd )
505 struct wl_private *lp = wl_priv(dev);
506 unsigned long flags;
507 int ret = 0;
508 /*------------------------------------------------------------------------*/
510 DBG_FUNC( "wl_ioctl" );
511 DBG_ENTER(DbgInfo);
512 DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
513 DBG_PARAM(DbgInfo, "rq", "0x%p", rq);
514 DBG_PARAM(DbgInfo, "cmd", "0x%04x", cmd);
516 wl_lock( lp, &flags );
518 wl_act_int_off( lp );
520 #ifdef USE_RTS
521 if( lp->useRTS == 1 ) {
522 /* Handle any RTS IOCTL here */
523 if( cmd == WL_IOCTL_RTS ) {
524 DBG_TRACE( DbgInfo, "IOCTL: WL_IOCTL_RTS\n" );
525 ret = wvlan_rts( (struct rtsreq *)rq, dev->base_addr );
526 } else {
527 DBG_TRACE( DbgInfo, "IOCTL not supported in RTS mode: 0x%X\n", cmd );
528 ret = -EOPNOTSUPP;
531 goto out_act_int_on_unlock;
533 #endif /* USE_RTS */
535 /* Only handle UIL IOCTL requests when the UIL has the system blocked. */
536 if( !(( lp->flags & WVLAN2_UIL_BUSY ) && ( cmd != WVLAN2_IOCTL_UIL ))) {
537 #ifdef USE_UIL
538 struct uilreq *urq = (struct uilreq *)rq;
539 #endif /* USE_UIL */
541 switch( cmd ) {
542 // ================== Private IOCTLs (up to 16) ==================
543 #ifdef USE_UIL
544 case WVLAN2_IOCTL_UIL:
545 DBG_TRACE( DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL\n" );
546 ret = wvlan_uil( urq, lp );
547 break;
548 #endif /* USE_UIL */
550 default:
551 DBG_TRACE(DbgInfo, "IOCTL CODE NOT SUPPORTED: 0x%X\n", cmd );
552 ret = -EOPNOTSUPP;
553 break;
555 } else {
556 DBG_WARNING( DbgInfo, "DEVICE IS BUSY, CANNOT PROCESS REQUEST\n" );
557 ret = -EBUSY;
560 #ifdef USE_RTS
561 out_act_int_on_unlock:
562 #endif /* USE_RTS */
563 wl_act_int_on( lp );
565 wl_unlock( lp, &flags );
567 DBG_LEAVE( DbgInfo );
568 return ret;
569 } // wl_ioctl
570 /*============================================================================*/
572 #ifdef CONFIG_NET_POLL_CONTROLLER
573 void wl_poll(struct net_device *dev)
575 struct wl_private *lp = wl_priv(dev);
576 unsigned long flags;
577 struct pt_regs regs;
579 wl_lock( lp, &flags );
580 wl_isr(dev->irq, dev, &regs);
581 wl_unlock( lp, &flags );
583 #endif
585 /*******************************************************************************
586 * wl_tx_timeout()
587 *******************************************************************************
589 * DESCRIPTION:
591 * The handler called when, for some reason, a Tx request is not completed.
593 * PARAMETERS:
595 * dev - a pointer to the device's net_device struct.
597 * RETURNS:
599 * N/A
601 ******************************************************************************/
602 void wl_tx_timeout( struct net_device *dev )
604 #ifdef USE_WDS
605 int count;
606 #endif /* USE_WDS */
607 unsigned long flags;
608 struct wl_private *lp = wl_priv(dev);
609 struct net_device_stats *pStats = NULL;
610 /*------------------------------------------------------------------------*/
612 DBG_FUNC( "wl_tx_timeout" );
613 DBG_ENTER( DbgInfo );
615 DBG_WARNING( DbgInfo, "%s: Transmit timeout.\n", dev->name );
617 wl_lock( lp, &flags );
619 #ifdef USE_RTS
620 if( lp->useRTS == 1 ) {
621 DBG_TRACE( DbgInfo, "Skipping tx_timeout handler, in RTS mode\n" );
622 wl_unlock( lp, &flags );
624 DBG_LEAVE( DbgInfo );
625 return;
627 #endif /* USE_RTS */
629 /* Figure out which device (the "root" device or WDS port) this timeout
630 is for */
631 #ifdef USE_WDS
633 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
634 if( dev == lp->wds_port[count].dev ) {
635 pStats = &( lp->wds_port[count].stats );
637 /* Break the loop so that we can use the counter to access WDS
638 information in the private structure */
639 break;
643 #endif /* USE_WDS */
645 /* If pStats is still NULL, then the device is not a WDS port */
646 if( pStats == NULL ) {
647 pStats = &( lp->stats );
650 /* Accumulate the timeout error */
651 pStats->tx_errors++;
653 wl_unlock( lp, &flags );
655 DBG_LEAVE( DbgInfo );
656 return;
657 } // wl_tx_timeout
658 /*============================================================================*/
660 /*******************************************************************************
661 * wl_send()
662 *******************************************************************************
664 * DESCRIPTION:
666 * The routine which performs data transmits.
668 * PARAMETERS:
670 * lp - a pointer to the device's wl_private struct.
672 * RETURNS:
674 * 0 on success
675 * 1 on error
677 ******************************************************************************/
678 int wl_send( struct wl_private *lp )
681 int status;
682 DESC_STRCT *desc;
683 WVLAN_LFRAME *txF = NULL;
684 struct list_head *element;
685 int len;
686 /*------------------------------------------------------------------------*/
688 DBG_FUNC( "wl_send" );
690 if( lp == NULL ) {
691 DBG_ERROR( DbgInfo, "Private adapter struct is NULL\n" );
692 return FALSE;
694 if( lp->dev == NULL ) {
695 DBG_ERROR( DbgInfo, "net_device struct in wl_private is NULL\n" );
696 return FALSE;
699 /* Check for the availability of FIDs; if none are available, don't take any
700 frames off the txQ */
701 if( lp->hcfCtx.IFB_RscInd == 0 ) {
702 return FALSE;
705 /* Reclaim the TxQ Elements and place them back on the free queue */
706 if( !list_empty( &( lp->txQ[0] ))) {
707 element = lp->txQ[0].next;
709 txF = (WVLAN_LFRAME * )list_entry( element, WVLAN_LFRAME, node );
710 if( txF != NULL ) {
711 lp->txF.skb = txF->frame.skb;
712 lp->txF.port = txF->frame.port;
714 txF->frame.skb = NULL;
715 txF->frame.port = 0;
717 list_del( &( txF->node ));
718 list_add( element, &( lp->txFree ));
720 lp->txQ_count--;
722 if( lp->txQ_count < TX_Q_LOW_WATER_MARK ) {
723 if( lp->netif_queue_on == FALSE ) {
724 DBG_TX( DbgInfo, "Kickstarting Q: %d\n", lp->txQ_count );
725 netif_wake_queue( lp->dev );
726 WL_WDS_NETIF_WAKE_QUEUE( lp );
727 lp->netif_queue_on = TRUE;
733 if( lp->txF.skb == NULL ) {
734 return FALSE;
737 /* If the device has resources (FIDs) available, then Tx the packet */
738 /* Format the TxRequest and send it to the adapter */
739 len = lp->txF.skb->len < ETH_ZLEN ? ETH_ZLEN : lp->txF.skb->len;
741 desc = &( lp->desc_tx );
742 desc->buf_addr = lp->txF.skb->data;
743 desc->BUF_CNT = len;
744 desc->next_desc_addr = NULL;
746 status = hcf_send_msg( &( lp->hcfCtx ), desc, lp->txF.port );
748 if( status == HCF_SUCCESS ) {
749 lp->dev->trans_start = jiffies;
751 DBG_TX( DbgInfo, "Transmit...\n" );
753 if( lp->txF.port == HCF_PORT_0 ) {
754 lp->stats.tx_packets++;
755 lp->stats.tx_bytes += lp->txF.skb->len;
758 #ifdef USE_WDS
759 else
761 lp->wds_port[(( lp->txF.port >> 8 ) - 1)].stats.tx_packets++;
762 lp->wds_port[(( lp->txF.port >> 8 ) - 1)].stats.tx_bytes += lp->txF.skb->len;
765 #endif /* USE_WDS */
767 /* Free the skb and perform queue cleanup, as the buffer was
768 transmitted successfully */
769 dev_kfree_skb( lp->txF.skb );
771 lp->txF.skb = NULL;
772 lp->txF.port = 0;
775 return TRUE;
776 } // wl_send
777 /*============================================================================*/
779 /*******************************************************************************
780 * wl_tx()
781 *******************************************************************************
783 * DESCRIPTION:
785 * The Tx handler function for the network layer.
787 * PARAMETERS:
789 * skb - a pointer to the sk_buff structure containing the data to transfer.
790 * dev - a pointer to the device's net_device structure.
792 * RETURNS:
794 * 0 on success
795 * 1 on error
797 ******************************************************************************/
798 int wl_tx( struct sk_buff *skb, struct net_device *dev, int port )
800 unsigned long flags;
801 struct wl_private *lp = wl_priv(dev);
802 WVLAN_LFRAME *txF = NULL;
803 struct list_head *element;
804 /*------------------------------------------------------------------------*/
806 DBG_FUNC( "wl_tx" );
808 /* Grab the spinlock */
809 wl_lock( lp, &flags );
811 if( lp->flags & WVLAN2_UIL_BUSY ) {
812 DBG_WARNING( DbgInfo, "UIL has device blocked\n" );
813 /* Start dropping packets here??? */
814 wl_unlock( lp, &flags );
815 return 1;
818 #ifdef USE_RTS
819 if( lp->useRTS == 1 ) {
820 DBG_PRINT( "RTS: we're getting a Tx...\n" );
821 wl_unlock( lp, &flags );
822 return 1;
824 #endif /* USE_RTS */
826 if( !lp->use_dma ) {
827 /* Get an element from the queue */
828 element = lp->txFree.next;
829 txF = (WVLAN_LFRAME *)list_entry( element, WVLAN_LFRAME, node );
830 if( txF == NULL ) {
831 DBG_ERROR( DbgInfo, "Problem with list_entry\n" );
832 wl_unlock( lp, &flags );
833 return 1;
835 /* Fill out the frame */
836 txF->frame.skb = skb;
837 txF->frame.port = port;
838 /* Move the frame to the txQ */
839 /* NOTE: Here's where we would do priority queueing */
840 list_del( &( txF->node ));
841 list_add( &( txF->node ), &( lp->txQ[0] ));
843 lp->txQ_count++;
844 if( lp->txQ_count >= DEFAULT_NUM_TX_FRAMES ) {
845 DBG_TX( DbgInfo, "Q Full: %d\n", lp->txQ_count );
846 if( lp->netif_queue_on == TRUE ) {
847 netif_stop_queue( lp->dev );
848 WL_WDS_NETIF_STOP_QUEUE( lp );
849 lp->netif_queue_on = FALSE;
853 wl_act_int_off( lp ); /* Disable Interrupts */
855 /* Send the data to the hardware using the appropriate method */
856 #ifdef ENABLE_DMA
857 if( lp->use_dma ) {
858 wl_send_dma( lp, skb, port );
860 else
861 #endif
863 wl_send( lp );
865 /* Re-enable Interrupts, release the spinlock and return */
866 wl_act_int_on( lp );
867 wl_unlock( lp, &flags );
868 return 0;
869 } // wl_tx
870 /*============================================================================*/
872 /*******************************************************************************
873 * wl_rx()
874 *******************************************************************************
876 * DESCRIPTION:
878 * The routine which performs data reception.
880 * PARAMETERS:
882 * dev - a pointer to the device's net_device structure.
884 * RETURNS:
886 * 0 on success
887 * 1 on error
889 ******************************************************************************/
890 int wl_rx(struct net_device *dev)
892 int port;
893 struct sk_buff *skb;
894 struct wl_private *lp = wl_priv(dev);
895 int status;
896 hcf_16 pktlen;
897 hcf_16 hfs_stat;
898 DESC_STRCT *desc;
899 /*------------------------------------------------------------------------*/
901 DBG_FUNC("wl_rx")
902 DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
904 if(!( lp->flags & WVLAN2_UIL_BUSY )) {
906 #ifdef USE_RTS
907 if( lp->useRTS == 1 ) {
908 DBG_PRINT( "RTS: We're getting an Rx...\n" );
909 return -EIO;
911 #endif /* USE_RTS */
913 /* Read the HFS_STAT register from the lookahead buffer */
914 hfs_stat = (hcf_16)(( lp->lookAheadBuf[HFS_STAT] ) |
915 ( lp->lookAheadBuf[HFS_STAT + 1] << 8 ));
917 /* Make sure the frame isn't bad */
918 if(( hfs_stat & HFS_STAT_ERR ) != HCF_SUCCESS ) {
919 DBG_WARNING( DbgInfo, "HFS_STAT_ERROR (0x%x) in Rx Packet\n",
920 lp->lookAheadBuf[HFS_STAT] );
921 return -EIO;
924 /* Determine what port this packet is for */
925 port = ( hfs_stat >> 8 ) & 0x0007;
926 DBG_RX( DbgInfo, "Rx frame for port %d\n", port );
928 pktlen = lp->hcfCtx.IFB_RxLen;
929 if (pktlen != 0) {
930 skb = ALLOC_SKB(pktlen);
931 if (skb != NULL) {
932 /* Set the netdev based on the port */
933 switch( port ) {
934 #ifdef USE_WDS
935 case 1:
936 case 2:
937 case 3:
938 case 4:
939 case 5:
940 case 6:
941 skb->dev = lp->wds_port[port-1].dev;
942 break;
943 #endif /* USE_WDS */
945 case 0:
946 default:
947 skb->dev = dev;
948 break;
951 desc = &( lp->desc_rx );
953 desc->next_desc_addr = NULL;
956 #define BLOCK_INPUT(buf, len) \
957 desc->buf_addr = buf; \
958 desc->BUF_SIZE = len; \
959 status = hcf_rcv_msg(&(lp->hcfCtx), desc, 0)
962 GET_PACKET( skb->dev, skb, pktlen );
964 if( status == HCF_SUCCESS ) {
965 netif_rx( skb );
967 if( port == 0 ) {
968 lp->stats.rx_packets++;
969 lp->stats.rx_bytes += pktlen;
971 #ifdef USE_WDS
972 else
974 lp->wds_port[port-1].stats.rx_packets++;
975 lp->wds_port[port-1].stats.rx_bytes += pktlen;
977 #endif /* USE_WDS */
979 dev->last_rx = jiffies;
981 #ifdef WIRELESS_EXT
982 #ifdef WIRELESS_SPY
983 if( lp->spydata.spy_number > 0 ) {
984 char *srcaddr = skb->mac.raw + MAC_ADDR_SIZE;
986 wl_spy_gather( dev, srcaddr );
988 #endif /* WIRELESS_SPY */
989 #endif /* WIRELESS_EXT */
990 } else {
991 DBG_ERROR( DbgInfo, "Rx request to card FAILED\n" );
993 if( port == 0 ) {
994 lp->stats.rx_dropped++;
996 #ifdef USE_WDS
997 else
999 lp->wds_port[port-1].stats.rx_dropped++;
1001 #endif /* USE_WDS */
1003 dev_kfree_skb( skb );
1005 } else {
1006 DBG_ERROR( DbgInfo, "Could not alloc skb\n" );
1008 if( port == 0 ) {
1009 lp->stats.rx_dropped++;
1011 #ifdef USE_WDS
1012 else
1014 lp->wds_port[port-1].stats.rx_dropped++;
1016 #endif /* USE_WDS */
1021 return 0;
1022 } // wl_rx
1023 /*============================================================================*/
1025 /*******************************************************************************
1026 * wl_multicast()
1027 *******************************************************************************
1029 * DESCRIPTION:
1031 * Function to handle multicast packets
1033 * PARAMETERS:
1035 * dev - a pointer to the device's net_device structure.
1037 * RETURNS:
1039 * N/A
1041 ******************************************************************************/
1042 #ifdef NEW_MULTICAST
1044 void wl_multicast( struct net_device *dev )
1046 #if 1 //;? (HCF_TYPE) & HCF_TYPE_STA //;?should we return an error status in AP mode
1047 //;?seems reasonable that even an AP-only driver could afford this small additional footprint
1049 int x;
1050 struct netdev_hw_addr *ha;
1051 struct wl_private *lp = wl_priv(dev);
1052 unsigned long flags;
1053 /*------------------------------------------------------------------------*/
1055 DBG_FUNC( "wl_multicast" );
1056 DBG_ENTER( DbgInfo );
1057 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
1059 if( !wl_adapter_is_open( dev )) {
1060 DBG_LEAVE( DbgInfo );
1061 return;
1064 #if DBG
1065 if( DBG_FLAGS( DbgInfo ) & DBG_PARAM_ON ) {
1066 DBG_PRINT(" flags: %s%s%s\n",
1067 ( dev->flags & IFF_PROMISC ) ? "Promiscous " : "",
1068 ( dev->flags & IFF_MULTICAST ) ? "Multicast " : "",
1069 ( dev->flags & IFF_ALLMULTI ) ? "All-Multicast" : "" );
1071 DBG_PRINT( " mc_count: %d\n", netdev_mc_count(dev));
1073 netdev_for_each_mc_addr(ha, dev)
1074 DBG_PRINT(" %s (%d)\n", DbgHwAddr(ha->addr),
1075 dev->addr_len);
1077 #endif /* DBG */
1079 if(!( lp->flags & WVLAN2_UIL_BUSY )) {
1081 #ifdef USE_RTS
1082 if( lp->useRTS == 1 ) {
1083 DBG_TRACE( DbgInfo, "Skipping multicast, in RTS mode\n" );
1085 DBG_LEAVE( DbgInfo );
1086 return;
1088 #endif /* USE_RTS */
1090 wl_lock( lp, &flags );
1091 wl_act_int_off( lp );
1093 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1094 if( dev->flags & IFF_PROMISC ) {
1095 /* Enable promiscuous mode */
1096 lp->ltvRecord.len = 2;
1097 lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
1098 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 1 );
1099 DBG_PRINT( "Enabling Promiscuous mode (IFF_PROMISC)\n" );
1100 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1102 else if ((netdev_mc_count(dev) > HCF_MAX_MULTICAST) ||
1103 ( dev->flags & IFF_ALLMULTI )) {
1104 /* Shutting off this filter will enable all multicast frames to
1105 be sent up from the device; however, this is a static RID, so
1106 a call to wl_apply() is needed */
1107 lp->ltvRecord.len = 2;
1108 lp->ltvRecord.typ = CFG_CNF_RX_ALL_GROUP_ADDR;
1109 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1110 DBG_PRINT( "Enabling all multicast mode (IFF_ALLMULTI)\n" );
1111 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1112 wl_apply( lp );
1114 else if (!netdev_mc_empty(dev)) {
1115 /* Set the multicast addresses */
1116 lp->ltvRecord.len = ( netdev_mc_count(dev) * 3 ) + 1;
1117 lp->ltvRecord.typ = CFG_GROUP_ADDR;
1119 x = 0;
1120 netdev_for_each_mc_addr(ha, dev)
1121 memcpy(&(lp->ltvRecord.u.u8[x++ * ETH_ALEN]),
1122 ha->addr, ETH_ALEN);
1123 DBG_PRINT( "Setting multicast list\n" );
1124 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1125 } else {
1126 /* Disable promiscuous mode */
1127 lp->ltvRecord.len = 2;
1128 lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
1129 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1130 DBG_PRINT( "Disabling Promiscuous mode\n" );
1131 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1133 /* Disable multicast mode */
1134 lp->ltvRecord.len = 2;
1135 lp->ltvRecord.typ = CFG_GROUP_ADDR;
1136 DBG_PRINT( "Disabling Multicast mode\n" );
1137 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1139 /* Turning on this filter will prevent all multicast frames from
1140 being sent up from the device; however, this is a static RID,
1141 so a call to wl_apply() is needed */
1142 lp->ltvRecord.len = 2;
1143 lp->ltvRecord.typ = CFG_CNF_RX_ALL_GROUP_ADDR;
1144 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 1 );
1145 DBG_PRINT( "Disabling all multicast mode (IFF_ALLMULTI)\n" );
1146 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1147 wl_apply( lp );
1150 wl_act_int_on( lp );
1151 wl_unlock( lp, &flags );
1153 DBG_LEAVE( DbgInfo );
1154 #endif /* HCF_STA */
1155 } // wl_multicast
1156 /*============================================================================*/
1158 #else /* NEW_MULTICAST */
1160 void wl_multicast( struct net_device *dev, int num_addrs, void *addrs )
1162 DBG_FUNC( "wl_multicast");
1163 DBG_ENTER(DbgInfo);
1165 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
1166 DBG_PARAM( DbgInfo, "num_addrs", "%d", num_addrs );
1167 DBG_PARAM( DbgInfo, "addrs", "0x%p", addrs );
1169 #error Obsolete set multicast interface!
1171 DBG_LEAVE( DbgInfo );
1172 } // wl_multicast
1173 /*============================================================================*/
1175 #endif /* NEW_MULTICAST */
1177 static const struct net_device_ops wl_netdev_ops =
1179 .ndo_start_xmit = &wl_tx_port0,
1181 .ndo_set_config = &wl_config,
1182 .ndo_get_stats = &wl_stats,
1183 .ndo_set_multicast_list = &wl_multicast,
1185 .ndo_init = &wl_insert,
1186 .ndo_open = &wl_adapter_open,
1187 .ndo_stop = &wl_adapter_close,
1188 .ndo_do_ioctl = &wl_ioctl,
1190 .ndo_tx_timeout = &wl_tx_timeout,
1192 #ifdef CONFIG_NET_POLL_CONTROLLER
1193 .ndo_poll_controller = wl_poll,
1194 #endif
1197 /*******************************************************************************
1198 * wl_device_alloc()
1199 *******************************************************************************
1201 * DESCRIPTION:
1203 * Create instances of net_device and wl_private for the new adapter
1204 * and register the device's entry points in the net_device structure.
1206 * PARAMETERS:
1208 * N/A
1210 * RETURNS:
1212 * a pointer to an allocated and initialized net_device struct for this
1213 * device.
1215 ******************************************************************************/
1216 struct net_device * wl_device_alloc( void )
1218 struct net_device *dev = NULL;
1219 struct wl_private *lp = NULL;
1220 /*------------------------------------------------------------------------*/
1222 DBG_FUNC( "wl_device_alloc" );
1223 DBG_ENTER( DbgInfo );
1225 /* Alloc a net_device struct */
1226 dev = alloc_etherdev(sizeof(struct wl_private));
1227 if (!dev)
1228 return NULL;
1230 /* Initialize the 'next' pointer in the struct. Currently only used for PCI,
1231 but do it here just in case it's used for other buses in the future */
1232 lp = wl_priv(dev);
1235 /* Check MTU */
1236 if( dev->mtu > MTU_MAX )
1238 DBG_WARNING( DbgInfo, "%s: MTU set too high, limiting to %d.\n",
1239 dev->name, MTU_MAX );
1240 dev->mtu = MTU_MAX;
1243 /* Setup the function table in the device structure. */
1245 dev->wireless_handlers = (struct iw_handler_def *)&wl_iw_handler_def;
1246 lp->wireless_data.spy_data = &lp->spy_data;
1247 dev->wireless_data = &lp->wireless_data;
1249 dev->netdev_ops = &wl_netdev_ops;
1251 dev->watchdog_timeo = TX_TIMEOUT;
1253 dev->ethtool_ops = &wl_ethtool_ops;
1255 netif_stop_queue( dev );
1257 /* Allocate virutal devices for WDS support if needed */
1258 WL_WDS_DEVICE_ALLOC( lp );
1260 DBG_LEAVE( DbgInfo );
1261 return dev;
1262 } // wl_device_alloc
1263 /*============================================================================*/
1265 /*******************************************************************************
1266 * wl_device_dealloc()
1267 *******************************************************************************
1269 * DESCRIPTION:
1271 * Free instances of net_device and wl_private strcutres for an adapter
1272 * and perform basic cleanup.
1274 * PARAMETERS:
1276 * dev - a pointer to the device's net_device structure.
1278 * RETURNS:
1280 * N/A
1282 ******************************************************************************/
1283 void wl_device_dealloc( struct net_device *dev )
1285 // struct wl_private *lp = wl_priv(dev);
1286 /*------------------------------------------------------------------------*/
1288 DBG_FUNC( "wl_device_dealloc" );
1289 DBG_ENTER( DbgInfo );
1291 /* Dealloc the WDS ports */
1292 WL_WDS_DEVICE_DEALLOC( lp );
1294 free_netdev( dev );
1296 DBG_LEAVE( DbgInfo );
1297 return;
1298 } // wl_device_dealloc
1299 /*============================================================================*/
1301 /*******************************************************************************
1302 * wl_tx_port0()
1303 *******************************************************************************
1305 * DESCRIPTION:
1307 * The handler routine for Tx over HCF_PORT_0.
1309 * PARAMETERS:
1311 * skb - a pointer to the sk_buff to transmit.
1312 * dev - a pointer to a net_device structure representing HCF_PORT_0.
1314 * RETURNS:
1316 * N/A
1318 ******************************************************************************/
1319 int wl_tx_port0( struct sk_buff *skb, struct net_device *dev )
1321 DBG_TX( DbgInfo, "Tx on Port 0\n" );
1323 return wl_tx( skb, dev, HCF_PORT_0 );
1324 #ifdef ENABLE_DMA
1325 return wl_tx_dma( skb, dev, HCF_PORT_0 );
1326 #endif
1327 } // wl_tx_port0
1328 /*============================================================================*/
1330 #ifdef USE_WDS
1332 /*******************************************************************************
1333 * wl_tx_port1()
1334 *******************************************************************************
1336 * DESCRIPTION:
1338 * The handler routine for Tx over HCF_PORT_1.
1340 * PARAMETERS:
1342 * skb - a pointer to the sk_buff to transmit.
1343 * dev - a pointer to a net_device structure representing HCF_PORT_1.
1345 * RETURNS:
1347 * N/A
1349 ******************************************************************************/
1350 int wl_tx_port1( struct sk_buff *skb, struct net_device *dev )
1352 DBG_TX( DbgInfo, "Tx on Port 1\n" );
1353 return wl_tx( skb, dev, HCF_PORT_1 );
1354 } // wl_tx_port1
1355 /*============================================================================*/
1357 /*******************************************************************************
1358 * wl_tx_port2()
1359 *******************************************************************************
1361 * DESCRIPTION:
1363 * The handler routine for Tx over HCF_PORT_2.
1365 * PARAMETERS:
1367 * skb - a pointer to the sk_buff to transmit.
1368 * dev - a pointer to a net_device structure representing HCF_PORT_2.
1370 * RETURNS:
1372 * N/A
1374 ******************************************************************************/
1375 int wl_tx_port2( struct sk_buff *skb, struct net_device *dev )
1377 DBG_TX( DbgInfo, "Tx on Port 2\n" );
1378 return wl_tx( skb, dev, HCF_PORT_2 );
1379 } // wl_tx_port2
1380 /*============================================================================*/
1382 /*******************************************************************************
1383 * wl_tx_port3()
1384 *******************************************************************************
1386 * DESCRIPTION:
1388 * The handler routine for Tx over HCF_PORT_3.
1390 * PARAMETERS:
1392 * skb - a pointer to the sk_buff to transmit.
1393 * dev - a pointer to a net_device structure representing HCF_PORT_3.
1395 * RETURNS:
1397 * N/A
1399 ******************************************************************************/
1400 int wl_tx_port3( struct sk_buff *skb, struct net_device *dev )
1402 DBG_TX( DbgInfo, "Tx on Port 3\n" );
1403 return wl_tx( skb, dev, HCF_PORT_3 );
1404 } // wl_tx_port3
1405 /*============================================================================*/
1407 /*******************************************************************************
1408 * wl_tx_port4()
1409 *******************************************************************************
1411 * DESCRIPTION:
1413 * The handler routine for Tx over HCF_PORT_4.
1415 * PARAMETERS:
1417 * skb - a pointer to the sk_buff to transmit.
1418 * dev - a pointer to a net_device structure representing HCF_PORT_4.
1420 * RETURNS:
1422 * N/A
1424 ******************************************************************************/
1425 int wl_tx_port4( struct sk_buff *skb, struct net_device *dev )
1427 DBG_TX( DbgInfo, "Tx on Port 4\n" );
1428 return wl_tx( skb, dev, HCF_PORT_4 );
1429 } // wl_tx_port4
1430 /*============================================================================*/
1432 /*******************************************************************************
1433 * wl_tx_port5()
1434 *******************************************************************************
1436 * DESCRIPTION:
1438 * The handler routine for Tx over HCF_PORT_5.
1440 * PARAMETERS:
1442 * skb - a pointer to the sk_buff to transmit.
1443 * dev - a pointer to a net_device structure representing HCF_PORT_5.
1445 * RETURNS:
1447 * N/A
1449 ******************************************************************************/
1450 int wl_tx_port5( struct sk_buff *skb, struct net_device *dev )
1452 DBG_TX( DbgInfo, "Tx on Port 5\n" );
1453 return wl_tx( skb, dev, HCF_PORT_5 );
1454 } // wl_tx_port5
1455 /*============================================================================*/
1457 /*******************************************************************************
1458 * wl_tx_port6()
1459 *******************************************************************************
1461 * DESCRIPTION:
1463 * The handler routine for Tx over HCF_PORT_6.
1465 * PARAMETERS:
1467 * skb - a pointer to the sk_buff to transmit.
1468 * dev - a pointer to a net_device structure representing HCF_PORT_6.
1470 * RETURNS:
1472 * N/A
1474 ******************************************************************************/
1475 int wl_tx_port6( struct sk_buff *skb, struct net_device *dev )
1477 DBG_TX( DbgInfo, "Tx on Port 6\n" );
1478 return wl_tx( skb, dev, HCF_PORT_6 );
1479 } // wl_tx_port6
1480 /*============================================================================*/
1482 /*******************************************************************************
1483 * wl_wds_device_alloc()
1484 *******************************************************************************
1486 * DESCRIPTION:
1488 * Create instances of net_device to represent the WDS ports, and register
1489 * the device's entry points in the net_device structure.
1491 * PARAMETERS:
1493 * lp - a pointer to the device's private adapter structure
1495 * RETURNS:
1497 * N/A, but will place pointers to the allocated and initialized net_device
1498 * structs in the private adapter structure.
1500 ******************************************************************************/
1501 void wl_wds_device_alloc( struct wl_private *lp )
1503 int count;
1504 /*------------------------------------------------------------------------*/
1506 DBG_FUNC( "wl_wds_device_alloc" );
1507 DBG_ENTER( DbgInfo );
1509 /* WDS support requires additional net_device structs to be allocated,
1510 so that user space apps can use these virtual devices to specify the
1511 port on which to Tx/Rx */
1512 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1513 struct net_device *dev_wds = NULL;
1515 dev_wds = kmalloc( sizeof( struct net_device ), GFP_KERNEL );
1516 memset( dev_wds, 0, sizeof( struct net_device ));
1518 ether_setup( dev_wds );
1520 lp->wds_port[count].dev = dev_wds;
1522 /* Re-use wl_init for all the devices, as it currently does nothing, but
1523 is required. Re-use the stats/tx_timeout handler for all as well; the
1524 WDS port which is requesting these operations can be determined by
1525 the net_device pointer. Set the private member of all devices to point
1526 to the same net_device struct; that way, all information gets
1527 funnelled through the one "real" net_device. Name the WDS ports
1528 "wds<n>" */
1529 lp->wds_port[count].dev->init = &wl_init;
1530 lp->wds_port[count].dev->get_stats = &wl_stats;
1531 lp->wds_port[count].dev->tx_timeout = &wl_tx_timeout;
1532 lp->wds_port[count].dev->watchdog_timeo = TX_TIMEOUT;
1533 lp->wds_port[count].dev->priv = lp;
1535 sprintf( lp->wds_port[count].dev->name, "wds%d", count );
1538 /* Register the Tx handlers */
1539 lp->wds_port[0].dev->hard_start_xmit = &wl_tx_port1;
1540 lp->wds_port[1].dev->hard_start_xmit = &wl_tx_port2;
1541 lp->wds_port[2].dev->hard_start_xmit = &wl_tx_port3;
1542 lp->wds_port[3].dev->hard_start_xmit = &wl_tx_port4;
1543 lp->wds_port[4].dev->hard_start_xmit = &wl_tx_port5;
1544 lp->wds_port[5].dev->hard_start_xmit = &wl_tx_port6;
1546 WL_WDS_NETIF_STOP_QUEUE( lp );
1548 DBG_LEAVE( DbgInfo );
1549 return;
1550 } // wl_wds_device_alloc
1551 /*============================================================================*/
1553 /*******************************************************************************
1554 * wl_wds_device_dealloc()
1555 *******************************************************************************
1557 * DESCRIPTION:
1559 * Free instances of net_device structures used to support WDS.
1561 * PARAMETERS:
1563 * lp - a pointer to the device's private adapter structure
1565 * RETURNS:
1567 * N/A
1569 ******************************************************************************/
1570 void wl_wds_device_dealloc( struct wl_private *lp )
1572 int count;
1573 /*------------------------------------------------------------------------*/
1575 DBG_FUNC( "wl_wds_device_dealloc" );
1576 DBG_ENTER( DbgInfo );
1578 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1579 struct net_device *dev_wds = NULL;
1581 dev_wds = lp->wds_port[count].dev;
1583 if( dev_wds != NULL ) {
1584 if( dev_wds->flags & IFF_UP ) {
1585 dev_close( dev_wds );
1586 dev_wds->flags &= ~( IFF_UP | IFF_RUNNING );
1589 kfree( dev_wds );
1590 lp->wds_port[count].dev = NULL;
1594 DBG_LEAVE( DbgInfo );
1595 return;
1596 } // wl_wds_device_dealloc
1597 /*============================================================================*/
1599 /*******************************************************************************
1600 * wl_wds_netif_start_queue()
1601 *******************************************************************************
1603 * DESCRIPTION:
1605 * Used to start the netif queues of all the "virtual" network devices
1606 * which repesent the WDS ports.
1608 * PARAMETERS:
1610 * lp - a pointer to the device's private adapter structure
1612 * RETURNS:
1614 * N/A
1616 ******************************************************************************/
1617 void wl_wds_netif_start_queue( struct wl_private *lp )
1619 int count;
1620 /*------------------------------------------------------------------------*/
1622 if( lp != NULL ) {
1623 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1624 if( lp->wds_port[count].is_registered &&
1625 lp->wds_port[count].netif_queue_on == FALSE ) {
1626 netif_start_queue( lp->wds_port[count].dev );
1627 lp->wds_port[count].netif_queue_on = TRUE;
1632 return;
1633 } // wl_wds_netif_start_queue
1634 /*============================================================================*/
1636 /*******************************************************************************
1637 * wl_wds_netif_stop_queue()
1638 *******************************************************************************
1640 * DESCRIPTION:
1642 * Used to stop the netif queues of all the "virtual" network devices
1643 * which repesent the WDS ports.
1645 * PARAMETERS:
1647 * lp - a pointer to the device's private adapter structure
1649 * RETURNS:
1651 * N/A
1653 ******************************************************************************/
1654 void wl_wds_netif_stop_queue( struct wl_private *lp )
1656 int count;
1657 /*------------------------------------------------------------------------*/
1659 if( lp != NULL ) {
1660 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1661 if( lp->wds_port[count].is_registered &&
1662 lp->wds_port[count].netif_queue_on == TRUE ) {
1663 netif_stop_queue( lp->wds_port[count].dev );
1664 lp->wds_port[count].netif_queue_on = FALSE;
1669 return;
1670 } // wl_wds_netif_stop_queue
1671 /*============================================================================*/
1673 /*******************************************************************************
1674 * wl_wds_netif_wake_queue()
1675 *******************************************************************************
1677 * DESCRIPTION:
1679 * Used to wake the netif queues of all the "virtual" network devices
1680 * which repesent the WDS ports.
1682 * PARAMETERS:
1684 * lp - a pointer to the device's private adapter structure
1686 * RETURNS:
1688 * N/A
1690 ******************************************************************************/
1691 void wl_wds_netif_wake_queue( struct wl_private *lp )
1693 int count;
1694 /*------------------------------------------------------------------------*/
1696 if( lp != NULL ) {
1697 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1698 if( lp->wds_port[count].is_registered &&
1699 lp->wds_port[count].netif_queue_on == FALSE ) {
1700 netif_wake_queue( lp->wds_port[count].dev );
1701 lp->wds_port[count].netif_queue_on = TRUE;
1706 return;
1707 } // wl_wds_netif_wake_queue
1708 /*============================================================================*/
1710 /*******************************************************************************
1711 * wl_wds_netif_carrier_on()
1712 *******************************************************************************
1714 * DESCRIPTION:
1716 * Used to signal the network layer that carrier is present on all of the
1717 * "virtual" network devices which repesent the WDS ports.
1719 * PARAMETERS:
1721 * lp - a pointer to the device's private adapter structure
1723 * RETURNS:
1725 * N/A
1727 ******************************************************************************/
1728 void wl_wds_netif_carrier_on( struct wl_private *lp )
1730 int count;
1731 /*------------------------------------------------------------------------*/
1733 if( lp != NULL ) {
1734 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1735 if( lp->wds_port[count].is_registered ) {
1736 netif_carrier_on( lp->wds_port[count].dev );
1741 return;
1742 } // wl_wds_netif_carrier_on
1743 /*============================================================================*/
1745 /*******************************************************************************
1746 * wl_wds_netif_carrier_off()
1747 *******************************************************************************
1749 * DESCRIPTION:
1751 * Used to signal the network layer that carrier is NOT present on all of
1752 * the "virtual" network devices which repesent the WDS ports.
1754 * PARAMETERS:
1756 * lp - a pointer to the device's private adapter structure
1758 * RETURNS:
1760 * N/A
1762 ******************************************************************************/
1763 void wl_wds_netif_carrier_off( struct wl_private *lp )
1765 int count;
1766 /*------------------------------------------------------------------------*/
1768 if( lp != NULL ) {
1769 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1770 if( lp->wds_port[count].is_registered ) {
1771 netif_carrier_off( lp->wds_port[count].dev );
1776 return;
1777 } // wl_wds_netif_carrier_off
1778 /*============================================================================*/
1780 #endif /* USE_WDS */
1782 #ifdef ENABLE_DMA
1783 /*******************************************************************************
1784 * wl_send_dma()
1785 *******************************************************************************
1787 * DESCRIPTION:
1789 * The routine which performs data transmits when using busmaster DMA.
1791 * PARAMETERS:
1793 * lp - a pointer to the device's wl_private struct.
1794 * skb - a pointer to the network layer's data buffer.
1795 * port - the Hermes port on which to transmit.
1797 * RETURNS:
1799 * 0 on success
1800 * 1 on error
1802 ******************************************************************************/
1803 int wl_send_dma( struct wl_private *lp, struct sk_buff *skb, int port )
1805 int len;
1806 DESC_STRCT *desc = NULL;
1807 DESC_STRCT *desc_next = NULL;
1808 /*------------------------------------------------------------------------*/
1810 DBG_FUNC( "wl_send_dma" );
1812 if( lp == NULL )
1814 DBG_ERROR( DbgInfo, "Private adapter struct is NULL\n" );
1815 return FALSE;
1818 if( lp->dev == NULL )
1820 DBG_ERROR( DbgInfo, "net_device struct in wl_private is NULL\n" );
1821 return FALSE;
1824 /* AGAIN, ALL THE QUEUEING DONE HERE IN I/O MODE IS NOT PERFORMED */
1826 if( skb == NULL )
1828 DBG_WARNING (DbgInfo, "Nothing to send.\n");
1829 return FALSE;
1832 len = skb->len;
1834 /* Get a free descriptor */
1835 desc = wl_pci_dma_get_tx_packet( lp );
1837 if( desc == NULL )
1839 if( lp->netif_queue_on == TRUE ) {
1840 netif_stop_queue( lp->dev );
1841 WL_WDS_NETIF_STOP_QUEUE( lp );
1842 lp->netif_queue_on = FALSE;
1844 dev_kfree_skb( skb );
1845 return 0;
1849 SET_BUF_CNT( desc, /*HCF_DMA_FD_CNT*/HFS_ADDR_DEST );
1850 SET_BUF_SIZE( desc, HCF_DMA_TX_BUF1_SIZE );
1852 desc_next = desc->next_desc_addr;
1854 if( desc_next->buf_addr == NULL )
1856 DBG_ERROR( DbgInfo, "DMA descriptor buf_addr is NULL\n" );
1857 return FALSE;
1860 /* Copy the payload into the DMA packet */
1861 memcpy( desc_next->buf_addr, skb->data, len );
1863 SET_BUF_CNT( desc_next, len );
1864 SET_BUF_SIZE( desc_next, HCF_MAX_PACKET_SIZE );
1866 hcf_dma_tx_put( &( lp->hcfCtx ), desc, 0 );
1868 /* Free the skb and perform queue cleanup, as the buffer was
1869 transmitted successfully */
1870 dev_kfree_skb( skb );
1872 return TRUE;
1873 } // wl_send_dma
1874 /*============================================================================*/
1876 /*******************************************************************************
1877 * wl_rx_dma()
1878 *******************************************************************************
1880 * DESCRIPTION:
1882 * The routine which performs data reception when using busmaster DMA.
1884 * PARAMETERS:
1886 * dev - a pointer to the device's net_device structure.
1888 * RETURNS:
1890 * 0 on success
1891 * 1 on error
1893 ******************************************************************************/
1894 int wl_rx_dma( struct net_device *dev )
1896 int port;
1897 hcf_16 pktlen;
1898 hcf_16 hfs_stat;
1899 struct sk_buff *skb;
1900 struct wl_private *lp = NULL;
1901 DESC_STRCT *desc, *desc_next;
1902 //CFG_MB_INFO_RANGE2_STRCT x;
1903 /*------------------------------------------------------------------------*/
1905 DBG_FUNC("wl_rx")
1906 DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
1908 if((( lp = dev->priv ) != NULL ) &&
1909 !( lp->flags & WVLAN2_UIL_BUSY )) {
1911 #ifdef USE_RTS
1912 if( lp->useRTS == 1 ) {
1913 DBG_PRINT( "RTS: We're getting an Rx...\n" );
1914 return -EIO;
1916 #endif /* USE_RTS */
1918 //if( lp->dma.status == 0 )
1920 desc = hcf_dma_rx_get( &( lp->hcfCtx ));
1922 if( desc != NULL )
1924 /* Check and see if we rcvd. a WMP frame */
1926 if((( *(hcf_8 *)&desc->buf_addr[HFS_STAT] ) &
1927 ( HFS_STAT_MSG_TYPE | HFS_STAT_ERR )) == HFS_STAT_WMP_MSG )
1929 DBG_TRACE( DbgInfo, "Got a WMP frame\n" );
1931 x.len = sizeof( CFG_MB_INFO_RANGE2_STRCT ) / sizeof( hcf_16 );
1932 x.typ = CFG_MB_INFO;
1933 x.base_typ = CFG_WMP;
1934 x.frag_cnt = 2;
1935 x.frag_buf[0].frag_len = GET_BUF_CNT( descp ) / sizeof( hcf_16 );
1936 x.frag_buf[0].frag_addr = (hcf_8 *) descp->buf_addr ;
1937 x.frag_buf[1].frag_len = ( GET_BUF_CNT( descp->next_desc_addr ) + 1 ) / sizeof( hcf_16 );
1938 x.frag_buf[1].frag_addr = (hcf_8 *) descp->next_desc_addr->buf_addr ;
1940 hcf_put_info( &( lp->hcfCtx ), (LTVP)&x );
1944 desc_next = desc->next_desc_addr;
1946 /* Make sure the buffer isn't empty */
1947 if( GET_BUF_CNT( desc ) == 0 ) {
1948 DBG_WARNING( DbgInfo, "Buffer is empty!\n" );
1950 /* Give the descriptor back to the HCF */
1951 hcf_dma_rx_put( &( lp->hcfCtx ), desc );
1952 return -EIO;
1955 /* Read the HFS_STAT register from the lookahead buffer */
1956 hfs_stat = (hcf_16)( desc->buf_addr[HFS_STAT/2] );
1958 /* Make sure the frame isn't bad */
1959 if(( hfs_stat & HFS_STAT_ERR ) != HCF_SUCCESS )
1961 DBG_WARNING( DbgInfo, "HFS_STAT_ERROR (0x%x) in Rx Packet\n",
1962 desc->buf_addr[HFS_STAT/2] );
1964 /* Give the descriptor back to the HCF */
1965 hcf_dma_rx_put( &( lp->hcfCtx ), desc );
1966 return -EIO;
1969 /* Determine what port this packet is for */
1970 port = ( hfs_stat >> 8 ) & 0x0007;
1971 DBG_RX( DbgInfo, "Rx frame for port %d\n", port );
1973 pktlen = GET_BUF_CNT(desc_next);
1974 if (pktlen != 0) {
1975 skb = ALLOC_SKB(pktlen);
1976 if (skb != NULL) {
1977 switch( port ) {
1978 #ifdef USE_WDS
1979 case 1:
1980 case 2:
1981 case 3:
1982 case 4:
1983 case 5:
1984 case 6:
1985 skb->dev = lp->wds_port[port-1].dev;
1986 break;
1987 #endif /* USE_WDS */
1989 case 0:
1990 default:
1991 skb->dev = dev;
1992 break;
1995 GET_PACKET_DMA( skb->dev, skb, pktlen );
1997 /* Give the descriptor back to the HCF */
1998 hcf_dma_rx_put( &( lp->hcfCtx ), desc );
2000 netif_rx( skb );
2002 if( port == 0 ) {
2003 lp->stats.rx_packets++;
2004 lp->stats.rx_bytes += pktlen;
2006 #ifdef USE_WDS
2007 else
2009 lp->wds_port[port-1].stats.rx_packets++;
2010 lp->wds_port[port-1].stats.rx_bytes += pktlen;
2012 #endif /* USE_WDS */
2014 dev->last_rx = jiffies;
2016 } else {
2017 DBG_ERROR( DbgInfo, "Could not alloc skb\n" );
2019 if( port == 0 )
2021 lp->stats.rx_dropped++;
2023 #ifdef USE_WDS
2024 else
2026 lp->wds_port[port-1].stats.rx_dropped++;
2028 #endif /* USE_WDS */
2035 return 0;
2036 } // wl_rx_dma
2037 /*============================================================================*/
2038 #endif // ENABLE_DMA