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