blob: 9c16f5478a75b04678b7e7ba7da9ea0000973259 [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 *
Al Virod36b6912011-12-29 17:09:01 -050026 * Copyright © 2003 Agere Systems Inc.
Henk de Groot68c0bdf2009-09-27 11:12:52 +020027 * 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 *
Al Virod36b6912011-12-29 17:09:01 -050047 * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
Henk de Groot68c0bdf2009-09-27 11:12:52 +020048 * 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. */
David Kilroy8bf90532011-10-01 09:43:48 +0100220 DBG_TRACE(DbgInfo, "%s: %s called.\n", dev->name, __func__);
Henk de Groot68c0bdf2009-09-27 11:12:52 +0200221
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
Henk de Groot68c0bdf2009-09-27 11:12:52 +0200466 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);
Henk de Groot68c0bdf2009-09-27 11:12:52 +0200470 } else {
471 snprintf(info->bus_info, sizeof(info->bus_info) - 1,
472 "PCMCIA FIXME");
473// "PCMCIA 0x%lx", priv->hw.iobase);
474 }
475} // wl_get_drvinfo
476
477static struct ethtool_ops wl_ethtool_ops = {
478 .get_drvinfo = wl_get_drvinfo,
479 .get_link = ethtool_op_get_link,
480};
481
482
483/*******************************************************************************
484 * wl_ioctl()
485 *******************************************************************************
486 *
487 * DESCRIPTION:
488 *
489 * The IOCTL handler for the device.
490 *
491 * PARAMETERS:
492 *
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.
496 *
497 * RETURNS:
498 *
499 * 0 on success
500 * errno value otherwise
501 *
502 ******************************************************************************/
503int wl_ioctl( struct net_device *dev, struct ifreq *rq, int cmd )
504{
505 struct wl_private *lp = wl_priv(dev);
506 unsigned long flags;
507 int ret = 0;
508 /*------------------------------------------------------------------------*/
509
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);
515
516 wl_lock( lp, &flags );
517
518 wl_act_int_off( lp );
519
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;
529 }
530
531 goto out_act_int_on_unlock;
532 }
533#endif /* USE_RTS */
534
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 */
540
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 */
549
550 default:
551 DBG_TRACE(DbgInfo, "IOCTL CODE NOT SUPPORTED: 0x%X\n", cmd );
552 ret = -EOPNOTSUPP;
553 break;
554 }
555 } else {
556 DBG_WARNING( DbgInfo, "DEVICE IS BUSY, CANNOT PROCESS REQUEST\n" );
557 ret = -EBUSY;
558 }
559
560#ifdef USE_RTS
561out_act_int_on_unlock:
562#endif /* USE_RTS */
563 wl_act_int_on( lp );
564
565 wl_unlock( lp, &flags );
566
567 DBG_LEAVE( DbgInfo );
568 return ret;
569} // wl_ioctl
570/*============================================================================*/
571
572#ifdef CONFIG_NET_POLL_CONTROLLER
573void wl_poll(struct net_device *dev)
574{
575 struct wl_private *lp = wl_priv(dev);
576 unsigned long flags;
577 struct pt_regs regs;
578
579 wl_lock( lp, &flags );
580 wl_isr(dev->irq, dev, &regs);
581 wl_unlock( lp, &flags );
582}
583#endif
584
585/*******************************************************************************
586 * wl_tx_timeout()
587 *******************************************************************************
588 *
589 * DESCRIPTION:
590 *
591 * The handler called when, for some reason, a Tx request is not completed.
592 *
593 * PARAMETERS:
594 *
595 * dev - a pointer to the device's net_device struct.
596 *
597 * RETURNS:
598 *
599 * N/A
600 *
601 ******************************************************************************/
602void wl_tx_timeout( struct net_device *dev )
603{
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 /*------------------------------------------------------------------------*/
611
612 DBG_FUNC( "wl_tx_timeout" );
613 DBG_ENTER( DbgInfo );
614
615 DBG_WARNING( DbgInfo, "%s: Transmit timeout.\n", dev->name );
616
617 wl_lock( lp, &flags );
618
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 );
623
624 DBG_LEAVE( DbgInfo );
625 return;
626 }
627#endif /* USE_RTS */
628
629 /* Figure out which device (the "root" device or WDS port) this timeout
630 is for */
631#ifdef USE_WDS
632
633 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
634 if( dev == lp->wds_port[count].dev ) {
635 pStats = &( lp->wds_port[count].stats );
636
637 /* Break the loop so that we can use the counter to access WDS
638 information in the private structure */
639 break;
640 }
641 }
642
643#endif /* USE_WDS */
644
645 /* If pStats is still NULL, then the device is not a WDS port */
646 if( pStats == NULL ) {
647 pStats = &( lp->stats );
648 }
649
650 /* Accumulate the timeout error */
651 pStats->tx_errors++;
652
653 wl_unlock( lp, &flags );
654
655 DBG_LEAVE( DbgInfo );
656 return;
657} // wl_tx_timeout
658/*============================================================================*/
659
660/*******************************************************************************
661 * wl_send()
662 *******************************************************************************
663 *
664 * DESCRIPTION:
665 *
666 * The routine which performs data transmits.
667 *
668 * PARAMETERS:
669 *
670 * lp - a pointer to the device's wl_private struct.
671 *
672 * RETURNS:
673 *
674 * 0 on success
675 * 1 on error
676 *
677 ******************************************************************************/
678int wl_send( struct wl_private *lp )
679{
680
681 int status;
682 DESC_STRCT *desc;
683 WVLAN_LFRAME *txF = NULL;
684 struct list_head *element;
685 int len;
686 /*------------------------------------------------------------------------*/
687
688 DBG_FUNC( "wl_send" );
689
690 if( lp == NULL ) {
691 DBG_ERROR( DbgInfo, "Private adapter struct is NULL\n" );
692 return FALSE;
693 }
694 if( lp->dev == NULL ) {
695 DBG_ERROR( DbgInfo, "net_device struct in wl_private is NULL\n" );
696 return FALSE;
697 }
698
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;
703 }
704
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;
708
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;
713
714 txF->frame.skb = NULL;
715 txF->frame.port = 0;
716
717 list_del( &( txF->node ));
718 list_add( element, &( lp->txFree ));
719
720 lp->txQ_count--;
721
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;
728 }
729 }
730 }
731 }
732
733 if( lp->txF.skb == NULL ) {
734 return FALSE;
735 }
736
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;
740
741 desc = &( lp->desc_tx );
742 desc->buf_addr = lp->txF.skb->data;
743 desc->BUF_CNT = len;
744 desc->next_desc_addr = NULL;
745
746 status = hcf_send_msg( &( lp->hcfCtx ), desc, lp->txF.port );
747
748 if( status == HCF_SUCCESS ) {
749 lp->dev->trans_start = jiffies;
750
751 DBG_TX( DbgInfo, "Transmit...\n" );
752
753 if( lp->txF.port == HCF_PORT_0 ) {
754 lp->stats.tx_packets++;
755 lp->stats.tx_bytes += lp->txF.skb->len;
756 }
757
758#ifdef USE_WDS
759 else
760 {
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;
763 }
764
765#endif /* USE_WDS */
766
767 /* Free the skb and perform queue cleanup, as the buffer was
768 transmitted successfully */
769 dev_kfree_skb( lp->txF.skb );
770
771 lp->txF.skb = NULL;
772 lp->txF.port = 0;
773 }
774
775 return TRUE;
776} // wl_send
777/*============================================================================*/
778
779/*******************************************************************************
780 * wl_tx()
781 *******************************************************************************
782 *
783 * DESCRIPTION:
784 *
785 * The Tx handler function for the network layer.
786 *
787 * PARAMETERS:
788 *
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.
791 *
792 * RETURNS:
793 *
794 * 0 on success
795 * 1 on error
796 *
797 ******************************************************************************/
798int wl_tx( struct sk_buff *skb, struct net_device *dev, int port )
799{
800 unsigned long flags;
801 struct wl_private *lp = wl_priv(dev);
802 WVLAN_LFRAME *txF = NULL;
803 struct list_head *element;
804 /*------------------------------------------------------------------------*/
805
806 DBG_FUNC( "wl_tx" );
807
808 /* Grab the spinlock */
809 wl_lock( lp, &flags );
810
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;
816 }
817
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;
823 }
824#endif /* USE_RTS */
825
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;
834 }
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] ));
842
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;
850 }
851 }
852 }
853 wl_act_int_off( lp ); /* Disable Interrupts */
854
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 );
859 }
860 else
861#endif
862 {
863 wl_send( lp );
864 }
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/*============================================================================*/
871
872/*******************************************************************************
873 * wl_rx()
874 *******************************************************************************
875 *
876 * DESCRIPTION:
877 *
878 * The routine which performs data reception.
879 *
880 * PARAMETERS:
881 *
882 * dev - a pointer to the device's net_device structure.
883 *
884 * RETURNS:
885 *
886 * 0 on success
887 * 1 on error
888 *
889 ******************************************************************************/
890int wl_rx(struct net_device *dev)
891{
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 /*------------------------------------------------------------------------*/
900
901 DBG_FUNC("wl_rx")
902 DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
903
904 if(!( lp->flags & WVLAN2_UIL_BUSY )) {
905
906#ifdef USE_RTS
907 if( lp->useRTS == 1 ) {
908 DBG_PRINT( "RTS: We're getting an Rx...\n" );
909 return -EIO;
910 }
911#endif /* USE_RTS */
912
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 ));
916
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;
922 }
923
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 );
927
Joe Perches491dbc82010-03-24 22:17:07 -0700928 pktlen = lp->hcfCtx.IFB_RxLen;
929 if (pktlen != 0) {
930 skb = ALLOC_SKB(pktlen);
931 if (skb != NULL) {
Henk de Groot68c0bdf2009-09-27 11:12:52 +0200932 /* 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 */
944
945 case 0:
946 default:
947 skb->dev = dev;
948 break;
949 }
950
951 desc = &( lp->desc_rx );
952
953 desc->next_desc_addr = NULL;
954
955/*
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)
960*/
961
962 GET_PACKET( skb->dev, skb, pktlen );
963
964 if( status == HCF_SUCCESS ) {
965 netif_rx( skb );
966
967 if( port == 0 ) {
968 lp->stats.rx_packets++;
969 lp->stats.rx_bytes += pktlen;
970 }
971#ifdef USE_WDS
972 else
973 {
974 lp->wds_port[port-1].stats.rx_packets++;
975 lp->wds_port[port-1].stats.rx_bytes += pktlen;
976 }
977#endif /* USE_WDS */
978
979 dev->last_rx = jiffies;
980
981#ifdef WIRELESS_EXT
982#ifdef WIRELESS_SPY
983 if( lp->spydata.spy_number > 0 ) {
984 char *srcaddr = skb->mac.raw + MAC_ADDR_SIZE;
985
986 wl_spy_gather( dev, srcaddr );
987 }
988#endif /* WIRELESS_SPY */
989#endif /* WIRELESS_EXT */
990 } else {
991 DBG_ERROR( DbgInfo, "Rx request to card FAILED\n" );
992
993 if( port == 0 ) {
994 lp->stats.rx_dropped++;
995 }
996#ifdef USE_WDS
997 else
998 {
999 lp->wds_port[port-1].stats.rx_dropped++;
1000 }
1001#endif /* USE_WDS */
1002
1003 dev_kfree_skb( skb );
1004 }
1005 } else {
1006 DBG_ERROR( DbgInfo, "Could not alloc skb\n" );
1007
1008 if( port == 0 ) {
1009 lp->stats.rx_dropped++;
1010 }
1011#ifdef USE_WDS
1012 else
1013 {
1014 lp->wds_port[port-1].stats.rx_dropped++;
1015 }
1016#endif /* USE_WDS */
1017 }
1018 }
1019 }
1020
1021 return 0;
1022} // wl_rx
1023/*============================================================================*/
1024
1025/*******************************************************************************
1026 * wl_multicast()
1027 *******************************************************************************
1028 *
1029 * DESCRIPTION:
1030 *
1031 * Function to handle multicast packets
1032 *
1033 * PARAMETERS:
1034 *
1035 * dev - a pointer to the device's net_device structure.
1036 *
1037 * RETURNS:
1038 *
1039 * N/A
1040 *
1041 ******************************************************************************/
1042#ifdef NEW_MULTICAST
1043
1044void wl_multicast( struct net_device *dev )
1045{
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
1048
1049 int x;
Jiri Pirko22bedad32010-04-01 21:22:57 +00001050 struct netdev_hw_addr *ha;
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001051 struct wl_private *lp = wl_priv(dev);
1052 unsigned long flags;
1053 /*------------------------------------------------------------------------*/
1054
1055 DBG_FUNC( "wl_multicast" );
1056 DBG_ENTER( DbgInfo );
1057 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
1058
1059 if( !wl_adapter_is_open( dev )) {
1060 DBG_LEAVE( DbgInfo );
1061 return;
1062 }
1063
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" : "" );
1070
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001071 DBG_PRINT( " mc_count: %d\n", netdev_mc_count(dev));
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001072
Jiri Pirko22bedad32010-04-01 21:22:57 +00001073 netdev_for_each_mc_addr(ha, dev)
Andy Shevchenko2b6d83d2010-10-16 13:11:12 +03001074 DBG_PRINT(" %pM (%d)\n", ha->addr, dev->addr_len);
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001075 }
1076#endif /* DBG */
1077
1078 if(!( lp->flags & WVLAN2_UIL_BUSY )) {
1079
1080#ifdef USE_RTS
1081 if( lp->useRTS == 1 ) {
1082 DBG_TRACE( DbgInfo, "Skipping multicast, in RTS mode\n" );
1083
1084 DBG_LEAVE( DbgInfo );
1085 return;
1086 }
1087#endif /* USE_RTS */
1088
1089 wl_lock( lp, &flags );
1090 wl_act_int_off( lp );
1091
1092 if ( CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_STA ) {
1093 if( dev->flags & IFF_PROMISC ) {
1094 /* Enable promiscuous mode */
1095 lp->ltvRecord.len = 2;
1096 lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
1097 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 1 );
1098 DBG_PRINT( "Enabling Promiscuous mode (IFF_PROMISC)\n" );
1099 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1100 }
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001101 else if ((netdev_mc_count(dev) > HCF_MAX_MULTICAST) ||
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001102 ( dev->flags & IFF_ALLMULTI )) {
1103 /* Shutting off this filter will enable all multicast frames to
1104 be sent up from the device; however, this is a static RID, so
1105 a call to wl_apply() is needed */
1106 lp->ltvRecord.len = 2;
1107 lp->ltvRecord.typ = CFG_CNF_RX_ALL_GROUP_ADDR;
1108 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1109 DBG_PRINT( "Enabling all multicast mode (IFF_ALLMULTI)\n" );
1110 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1111 wl_apply( lp );
1112 }
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001113 else if (!netdev_mc_empty(dev)) {
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001114 /* Set the multicast addresses */
Jiri Pirko4cd24ea2010-02-08 04:30:35 +00001115 lp->ltvRecord.len = ( netdev_mc_count(dev) * 3 ) + 1;
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001116 lp->ltvRecord.typ = CFG_GROUP_ADDR;
1117
Jiri Pirkod5907942010-02-18 05:10:14 +00001118 x = 0;
Jiri Pirko22bedad32010-04-01 21:22:57 +00001119 netdev_for_each_mc_addr(ha, dev)
Jiri Pirkod5907942010-02-18 05:10:14 +00001120 memcpy(&(lp->ltvRecord.u.u8[x++ * ETH_ALEN]),
Jiri Pirko22bedad32010-04-01 21:22:57 +00001121 ha->addr, ETH_ALEN);
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001122 DBG_PRINT( "Setting multicast list\n" );
1123 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1124 } else {
1125 /* Disable promiscuous mode */
1126 lp->ltvRecord.len = 2;
1127 lp->ltvRecord.typ = CFG_PROMISCUOUS_MODE;
1128 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 0 );
1129 DBG_PRINT( "Disabling Promiscuous mode\n" );
1130 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1131
1132 /* Disable multicast mode */
1133 lp->ltvRecord.len = 2;
1134 lp->ltvRecord.typ = CFG_GROUP_ADDR;
1135 DBG_PRINT( "Disabling Multicast mode\n" );
1136 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1137
1138 /* Turning on this filter will prevent all multicast frames from
1139 being sent up from the device; however, this is a static RID,
1140 so a call to wl_apply() is needed */
1141 lp->ltvRecord.len = 2;
1142 lp->ltvRecord.typ = CFG_CNF_RX_ALL_GROUP_ADDR;
1143 lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( 1 );
1144 DBG_PRINT( "Disabling all multicast mode (IFF_ALLMULTI)\n" );
1145 hcf_put_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1146 wl_apply( lp );
1147 }
1148 }
1149 wl_act_int_on( lp );
1150 wl_unlock( lp, &flags );
1151 }
1152 DBG_LEAVE( DbgInfo );
1153#endif /* HCF_STA */
1154} // wl_multicast
1155/*============================================================================*/
1156
1157#else /* NEW_MULTICAST */
1158
1159void wl_multicast( struct net_device *dev, int num_addrs, void *addrs )
1160{
1161 DBG_FUNC( "wl_multicast");
1162 DBG_ENTER(DbgInfo);
1163
1164 DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
1165 DBG_PARAM( DbgInfo, "num_addrs", "%d", num_addrs );
1166 DBG_PARAM( DbgInfo, "addrs", "0x%p", addrs );
1167
1168#error Obsolete set multicast interface!
1169
1170 DBG_LEAVE( DbgInfo );
1171} // wl_multicast
1172/*============================================================================*/
1173
1174#endif /* NEW_MULTICAST */
1175
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001176static const struct net_device_ops wl_netdev_ops =
1177{
1178 .ndo_start_xmit = &wl_tx_port0,
1179
1180 .ndo_set_config = &wl_config,
1181 .ndo_get_stats = &wl_stats,
Jiri Pirkoafc4b132011-08-16 06:29:01 +00001182 .ndo_set_rx_mode = &wl_multicast,
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001183
1184 .ndo_init = &wl_insert,
1185 .ndo_open = &wl_adapter_open,
1186 .ndo_stop = &wl_adapter_close,
1187 .ndo_do_ioctl = &wl_ioctl,
1188
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001189 .ndo_tx_timeout = &wl_tx_timeout,
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001190
1191#ifdef CONFIG_NET_POLL_CONTROLLER
1192 .ndo_poll_controller = wl_poll,
1193#endif
1194};
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001195
1196/*******************************************************************************
1197 * wl_device_alloc()
1198 *******************************************************************************
1199 *
1200 * DESCRIPTION:
1201 *
1202 * Create instances of net_device and wl_private for the new adapter
1203 * and register the device's entry points in the net_device structure.
1204 *
1205 * PARAMETERS:
1206 *
1207 * N/A
1208 *
1209 * RETURNS:
1210 *
1211 * a pointer to an allocated and initialized net_device struct for this
1212 * device.
1213 *
1214 ******************************************************************************/
1215struct net_device * wl_device_alloc( void )
1216{
1217 struct net_device *dev = NULL;
1218 struct wl_private *lp = NULL;
1219 /*------------------------------------------------------------------------*/
1220
1221 DBG_FUNC( "wl_device_alloc" );
1222 DBG_ENTER( DbgInfo );
1223
1224 /* Alloc a net_device struct */
1225 dev = alloc_etherdev(sizeof(struct wl_private));
1226 if (!dev)
1227 return NULL;
1228
1229 /* Initialize the 'next' pointer in the struct. Currently only used for PCI,
1230 but do it here just in case it's used for other buses in the future */
1231 lp = wl_priv(dev);
1232
1233
1234 /* Check MTU */
1235 if( dev->mtu > MTU_MAX )
1236 {
1237 DBG_WARNING( DbgInfo, "%s: MTU set too high, limiting to %d.\n",
1238 dev->name, MTU_MAX );
1239 dev->mtu = MTU_MAX;
1240 }
1241
1242 /* Setup the function table in the device structure. */
1243
1244 dev->wireless_handlers = (struct iw_handler_def *)&wl_iw_handler_def;
1245 lp->wireless_data.spy_data = &lp->spy_data;
1246 dev->wireless_data = &lp->wireless_data;
1247
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001248 dev->netdev_ops = &wl_netdev_ops;
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001249
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001250 dev->watchdog_timeo = TX_TIMEOUT;
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001251
1252 dev->ethtool_ops = &wl_ethtool_ops;
1253
1254 netif_stop_queue( dev );
1255
1256 /* Allocate virutal devices for WDS support if needed */
1257 WL_WDS_DEVICE_ALLOC( lp );
1258
1259 DBG_LEAVE( DbgInfo );
1260 return dev;
1261} // wl_device_alloc
1262/*============================================================================*/
1263
1264/*******************************************************************************
1265 * wl_device_dealloc()
1266 *******************************************************************************
1267 *
1268 * DESCRIPTION:
1269 *
1270 * Free instances of net_device and wl_private strcutres for an adapter
1271 * and perform basic cleanup.
1272 *
1273 * PARAMETERS:
1274 *
1275 * dev - a pointer to the device's net_device structure.
1276 *
1277 * RETURNS:
1278 *
1279 * N/A
1280 *
1281 ******************************************************************************/
1282void wl_device_dealloc( struct net_device *dev )
1283{
1284// struct wl_private *lp = wl_priv(dev);
1285 /*------------------------------------------------------------------------*/
1286
1287 DBG_FUNC( "wl_device_dealloc" );
1288 DBG_ENTER( DbgInfo );
1289
1290 /* Dealloc the WDS ports */
1291 WL_WDS_DEVICE_DEALLOC( lp );
1292
1293 free_netdev( dev );
1294
1295 DBG_LEAVE( DbgInfo );
1296 return;
1297} // wl_device_dealloc
1298/*============================================================================*/
1299
1300/*******************************************************************************
1301 * wl_tx_port0()
1302 *******************************************************************************
1303 *
1304 * DESCRIPTION:
1305 *
1306 * The handler routine for Tx over HCF_PORT_0.
1307 *
1308 * PARAMETERS:
1309 *
1310 * skb - a pointer to the sk_buff to transmit.
1311 * dev - a pointer to a net_device structure representing HCF_PORT_0.
1312 *
1313 * RETURNS:
1314 *
1315 * N/A
1316 *
1317 ******************************************************************************/
1318int wl_tx_port0( struct sk_buff *skb, struct net_device *dev )
1319{
1320 DBG_TX( DbgInfo, "Tx on Port 0\n" );
1321
1322 return wl_tx( skb, dev, HCF_PORT_0 );
1323#ifdef ENABLE_DMA
1324 return wl_tx_dma( skb, dev, HCF_PORT_0 );
1325#endif
1326} // wl_tx_port0
1327/*============================================================================*/
1328
1329#ifdef USE_WDS
1330
1331/*******************************************************************************
1332 * wl_tx_port1()
1333 *******************************************************************************
1334 *
1335 * DESCRIPTION:
1336 *
1337 * The handler routine for Tx over HCF_PORT_1.
1338 *
1339 * PARAMETERS:
1340 *
1341 * skb - a pointer to the sk_buff to transmit.
1342 * dev - a pointer to a net_device structure representing HCF_PORT_1.
1343 *
1344 * RETURNS:
1345 *
1346 * N/A
1347 *
1348 ******************************************************************************/
1349int wl_tx_port1( struct sk_buff *skb, struct net_device *dev )
1350{
1351 DBG_TX( DbgInfo, "Tx on Port 1\n" );
1352 return wl_tx( skb, dev, HCF_PORT_1 );
1353} // wl_tx_port1
1354/*============================================================================*/
1355
1356/*******************************************************************************
1357 * wl_tx_port2()
1358 *******************************************************************************
1359 *
1360 * DESCRIPTION:
1361 *
1362 * The handler routine for Tx over HCF_PORT_2.
1363 *
1364 * PARAMETERS:
1365 *
1366 * skb - a pointer to the sk_buff to transmit.
1367 * dev - a pointer to a net_device structure representing HCF_PORT_2.
1368 *
1369 * RETURNS:
1370 *
1371 * N/A
1372 *
1373 ******************************************************************************/
1374int wl_tx_port2( struct sk_buff *skb, struct net_device *dev )
1375{
1376 DBG_TX( DbgInfo, "Tx on Port 2\n" );
1377 return wl_tx( skb, dev, HCF_PORT_2 );
1378} // wl_tx_port2
1379/*============================================================================*/
1380
1381/*******************************************************************************
1382 * wl_tx_port3()
1383 *******************************************************************************
1384 *
1385 * DESCRIPTION:
1386 *
1387 * The handler routine for Tx over HCF_PORT_3.
1388 *
1389 * PARAMETERS:
1390 *
1391 * skb - a pointer to the sk_buff to transmit.
1392 * dev - a pointer to a net_device structure representing HCF_PORT_3.
1393 *
1394 * RETURNS:
1395 *
1396 * N/A
1397 *
1398 ******************************************************************************/
1399int wl_tx_port3( struct sk_buff *skb, struct net_device *dev )
1400{
1401 DBG_TX( DbgInfo, "Tx on Port 3\n" );
1402 return wl_tx( skb, dev, HCF_PORT_3 );
1403} // wl_tx_port3
1404/*============================================================================*/
1405
1406/*******************************************************************************
1407 * wl_tx_port4()
1408 *******************************************************************************
1409 *
1410 * DESCRIPTION:
1411 *
1412 * The handler routine for Tx over HCF_PORT_4.
1413 *
1414 * PARAMETERS:
1415 *
1416 * skb - a pointer to the sk_buff to transmit.
1417 * dev - a pointer to a net_device structure representing HCF_PORT_4.
1418 *
1419 * RETURNS:
1420 *
1421 * N/A
1422 *
1423 ******************************************************************************/
1424int wl_tx_port4( struct sk_buff *skb, struct net_device *dev )
1425{
1426 DBG_TX( DbgInfo, "Tx on Port 4\n" );
1427 return wl_tx( skb, dev, HCF_PORT_4 );
1428} // wl_tx_port4
1429/*============================================================================*/
1430
1431/*******************************************************************************
1432 * wl_tx_port5()
1433 *******************************************************************************
1434 *
1435 * DESCRIPTION:
1436 *
1437 * The handler routine for Tx over HCF_PORT_5.
1438 *
1439 * PARAMETERS:
1440 *
1441 * skb - a pointer to the sk_buff to transmit.
1442 * dev - a pointer to a net_device structure representing HCF_PORT_5.
1443 *
1444 * RETURNS:
1445 *
1446 * N/A
1447 *
1448 ******************************************************************************/
1449int wl_tx_port5( struct sk_buff *skb, struct net_device *dev )
1450{
1451 DBG_TX( DbgInfo, "Tx on Port 5\n" );
1452 return wl_tx( skb, dev, HCF_PORT_5 );
1453} // wl_tx_port5
1454/*============================================================================*/
1455
1456/*******************************************************************************
1457 * wl_tx_port6()
1458 *******************************************************************************
1459 *
1460 * DESCRIPTION:
1461 *
1462 * The handler routine for Tx over HCF_PORT_6.
1463 *
1464 * PARAMETERS:
1465 *
1466 * skb - a pointer to the sk_buff to transmit.
1467 * dev - a pointer to a net_device structure representing HCF_PORT_6.
1468 *
1469 * RETURNS:
1470 *
1471 * N/A
1472 *
1473 ******************************************************************************/
1474int wl_tx_port6( struct sk_buff *skb, struct net_device *dev )
1475{
1476 DBG_TX( DbgInfo, "Tx on Port 6\n" );
1477 return wl_tx( skb, dev, HCF_PORT_6 );
1478} // wl_tx_port6
1479/*============================================================================*/
1480
1481/*******************************************************************************
1482 * wl_wds_device_alloc()
1483 *******************************************************************************
1484 *
1485 * DESCRIPTION:
1486 *
1487 * Create instances of net_device to represent the WDS ports, and register
1488 * the device's entry points in the net_device structure.
1489 *
1490 * PARAMETERS:
1491 *
1492 * lp - a pointer to the device's private adapter structure
1493 *
1494 * RETURNS:
1495 *
1496 * N/A, but will place pointers to the allocated and initialized net_device
1497 * structs in the private adapter structure.
1498 *
1499 ******************************************************************************/
1500void wl_wds_device_alloc( struct wl_private *lp )
1501{
1502 int count;
1503 /*------------------------------------------------------------------------*/
1504
1505 DBG_FUNC( "wl_wds_device_alloc" );
1506 DBG_ENTER( DbgInfo );
1507
1508 /* WDS support requires additional net_device structs to be allocated,
1509 so that user space apps can use these virtual devices to specify the
1510 port on which to Tx/Rx */
1511 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1512 struct net_device *dev_wds = NULL;
1513
1514 dev_wds = kmalloc( sizeof( struct net_device ), GFP_KERNEL );
1515 memset( dev_wds, 0, sizeof( struct net_device ));
1516
1517 ether_setup( dev_wds );
1518
1519 lp->wds_port[count].dev = dev_wds;
1520
1521 /* Re-use wl_init for all the devices, as it currently does nothing, but
1522 is required. Re-use the stats/tx_timeout handler for all as well; the
1523 WDS port which is requesting these operations can be determined by
1524 the net_device pointer. Set the private member of all devices to point
1525 to the same net_device struct; that way, all information gets
1526 funnelled through the one "real" net_device. Name the WDS ports
1527 "wds<n>" */
1528 lp->wds_port[count].dev->init = &wl_init;
1529 lp->wds_port[count].dev->get_stats = &wl_stats;
1530 lp->wds_port[count].dev->tx_timeout = &wl_tx_timeout;
1531 lp->wds_port[count].dev->watchdog_timeo = TX_TIMEOUT;
1532 lp->wds_port[count].dev->priv = lp;
1533
1534 sprintf( lp->wds_port[count].dev->name, "wds%d", count );
1535 }
1536
1537 /* Register the Tx handlers */
1538 lp->wds_port[0].dev->hard_start_xmit = &wl_tx_port1;
1539 lp->wds_port[1].dev->hard_start_xmit = &wl_tx_port2;
1540 lp->wds_port[2].dev->hard_start_xmit = &wl_tx_port3;
1541 lp->wds_port[3].dev->hard_start_xmit = &wl_tx_port4;
1542 lp->wds_port[4].dev->hard_start_xmit = &wl_tx_port5;
1543 lp->wds_port[5].dev->hard_start_xmit = &wl_tx_port6;
1544
1545 WL_WDS_NETIF_STOP_QUEUE( lp );
1546
1547 DBG_LEAVE( DbgInfo );
1548 return;
1549} // wl_wds_device_alloc
1550/*============================================================================*/
1551
1552/*******************************************************************************
1553 * wl_wds_device_dealloc()
1554 *******************************************************************************
1555 *
1556 * DESCRIPTION:
1557 *
1558 * Free instances of net_device structures used to support WDS.
1559 *
1560 * PARAMETERS:
1561 *
1562 * lp - a pointer to the device's private adapter structure
1563 *
1564 * RETURNS:
1565 *
1566 * N/A
1567 *
1568 ******************************************************************************/
1569void wl_wds_device_dealloc( struct wl_private *lp )
1570{
1571 int count;
1572 /*------------------------------------------------------------------------*/
1573
1574 DBG_FUNC( "wl_wds_device_dealloc" );
1575 DBG_ENTER( DbgInfo );
1576
1577 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1578 struct net_device *dev_wds = NULL;
1579
1580 dev_wds = lp->wds_port[count].dev;
1581
1582 if( dev_wds != NULL ) {
1583 if( dev_wds->flags & IFF_UP ) {
1584 dev_close( dev_wds );
1585 dev_wds->flags &= ~( IFF_UP | IFF_RUNNING );
1586 }
1587
Vasiliy Kulikovb37e0c62010-09-28 21:08:11 +04001588 free_netdev(dev_wds);
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001589 lp->wds_port[count].dev = NULL;
1590 }
1591 }
1592
1593 DBG_LEAVE( DbgInfo );
1594 return;
1595} // wl_wds_device_dealloc
1596/*============================================================================*/
1597
1598/*******************************************************************************
1599 * wl_wds_netif_start_queue()
1600 *******************************************************************************
1601 *
1602 * DESCRIPTION:
1603 *
1604 * Used to start the netif queues of all the "virtual" network devices
1605 * which repesent the WDS ports.
1606 *
1607 * PARAMETERS:
1608 *
1609 * lp - a pointer to the device's private adapter structure
1610 *
1611 * RETURNS:
1612 *
1613 * N/A
1614 *
1615 ******************************************************************************/
1616void wl_wds_netif_start_queue( struct wl_private *lp )
1617{
1618 int count;
1619 /*------------------------------------------------------------------------*/
1620
1621 if( lp != NULL ) {
1622 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1623 if( lp->wds_port[count].is_registered &&
1624 lp->wds_port[count].netif_queue_on == FALSE ) {
1625 netif_start_queue( lp->wds_port[count].dev );
1626 lp->wds_port[count].netif_queue_on = TRUE;
1627 }
1628 }
1629 }
1630
1631 return;
1632} // wl_wds_netif_start_queue
1633/*============================================================================*/
1634
1635/*******************************************************************************
1636 * wl_wds_netif_stop_queue()
1637 *******************************************************************************
1638 *
1639 * DESCRIPTION:
1640 *
1641 * Used to stop the netif queues of all the "virtual" network devices
1642 * which repesent the WDS ports.
1643 *
1644 * PARAMETERS:
1645 *
1646 * lp - a pointer to the device's private adapter structure
1647 *
1648 * RETURNS:
1649 *
1650 * N/A
1651 *
1652 ******************************************************************************/
1653void wl_wds_netif_stop_queue( struct wl_private *lp )
1654{
1655 int count;
1656 /*------------------------------------------------------------------------*/
1657
1658 if( lp != NULL ) {
1659 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1660 if( lp->wds_port[count].is_registered &&
1661 lp->wds_port[count].netif_queue_on == TRUE ) {
1662 netif_stop_queue( lp->wds_port[count].dev );
1663 lp->wds_port[count].netif_queue_on = FALSE;
1664 }
1665 }
1666 }
1667
1668 return;
1669} // wl_wds_netif_stop_queue
1670/*============================================================================*/
1671
1672/*******************************************************************************
1673 * wl_wds_netif_wake_queue()
1674 *******************************************************************************
1675 *
1676 * DESCRIPTION:
1677 *
1678 * Used to wake the netif queues of all the "virtual" network devices
1679 * which repesent the WDS ports.
1680 *
1681 * PARAMETERS:
1682 *
1683 * lp - a pointer to the device's private adapter structure
1684 *
1685 * RETURNS:
1686 *
1687 * N/A
1688 *
1689 ******************************************************************************/
1690void wl_wds_netif_wake_queue( struct wl_private *lp )
1691{
1692 int count;
1693 /*------------------------------------------------------------------------*/
1694
1695 if( lp != NULL ) {
1696 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1697 if( lp->wds_port[count].is_registered &&
1698 lp->wds_port[count].netif_queue_on == FALSE ) {
1699 netif_wake_queue( lp->wds_port[count].dev );
1700 lp->wds_port[count].netif_queue_on = TRUE;
1701 }
1702 }
1703 }
1704
1705 return;
1706} // wl_wds_netif_wake_queue
1707/*============================================================================*/
1708
1709/*******************************************************************************
1710 * wl_wds_netif_carrier_on()
1711 *******************************************************************************
1712 *
1713 * DESCRIPTION:
1714 *
1715 * Used to signal the network layer that carrier is present on all of the
1716 * "virtual" network devices which repesent the WDS ports.
1717 *
1718 * PARAMETERS:
1719 *
1720 * lp - a pointer to the device's private adapter structure
1721 *
1722 * RETURNS:
1723 *
1724 * N/A
1725 *
1726 ******************************************************************************/
1727void wl_wds_netif_carrier_on( struct wl_private *lp )
1728{
1729 int count;
1730 /*------------------------------------------------------------------------*/
1731
1732 if( lp != NULL ) {
1733 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1734 if( lp->wds_port[count].is_registered ) {
1735 netif_carrier_on( lp->wds_port[count].dev );
1736 }
1737 }
1738 }
1739
1740 return;
1741} // wl_wds_netif_carrier_on
1742/*============================================================================*/
1743
1744/*******************************************************************************
1745 * wl_wds_netif_carrier_off()
1746 *******************************************************************************
1747 *
1748 * DESCRIPTION:
1749 *
1750 * Used to signal the network layer that carrier is NOT present on all of
1751 * the "virtual" network devices which repesent the WDS ports.
1752 *
1753 * PARAMETERS:
1754 *
1755 * lp - a pointer to the device's private adapter structure
1756 *
1757 * RETURNS:
1758 *
1759 * N/A
1760 *
1761 ******************************************************************************/
1762void wl_wds_netif_carrier_off( struct wl_private *lp )
1763{
1764 int count;
1765 /*------------------------------------------------------------------------*/
1766
1767 if( lp != NULL ) {
1768 for( count = 0; count < NUM_WDS_PORTS; count++ ) {
1769 if( lp->wds_port[count].is_registered ) {
1770 netif_carrier_off( lp->wds_port[count].dev );
1771 }
1772 }
1773 }
1774
1775 return;
1776} // wl_wds_netif_carrier_off
1777/*============================================================================*/
1778
1779#endif /* USE_WDS */
1780
1781#ifdef ENABLE_DMA
1782/*******************************************************************************
1783 * wl_send_dma()
1784 *******************************************************************************
1785 *
1786 * DESCRIPTION:
1787 *
1788 * The routine which performs data transmits when using busmaster DMA.
1789 *
1790 * PARAMETERS:
1791 *
1792 * lp - a pointer to the device's wl_private struct.
1793 * skb - a pointer to the network layer's data buffer.
1794 * port - the Hermes port on which to transmit.
1795 *
1796 * RETURNS:
1797 *
1798 * 0 on success
1799 * 1 on error
1800 *
1801 ******************************************************************************/
1802int wl_send_dma( struct wl_private *lp, struct sk_buff *skb, int port )
1803{
1804 int len;
1805 DESC_STRCT *desc = NULL;
1806 DESC_STRCT *desc_next = NULL;
1807 /*------------------------------------------------------------------------*/
1808
1809 DBG_FUNC( "wl_send_dma" );
1810
1811 if( lp == NULL )
1812 {
1813 DBG_ERROR( DbgInfo, "Private adapter struct is NULL\n" );
1814 return FALSE;
1815 }
1816
1817 if( lp->dev == NULL )
1818 {
1819 DBG_ERROR( DbgInfo, "net_device struct in wl_private is NULL\n" );
1820 return FALSE;
1821 }
1822
1823 /* AGAIN, ALL THE QUEUEING DONE HERE IN I/O MODE IS NOT PERFORMED */
1824
1825 if( skb == NULL )
1826 {
1827 DBG_WARNING (DbgInfo, "Nothing to send.\n");
1828 return FALSE;
1829 }
1830
1831 len = skb->len;
1832
1833 /* Get a free descriptor */
1834 desc = wl_pci_dma_get_tx_packet( lp );
1835
1836 if( desc == NULL )
1837 {
1838 if( lp->netif_queue_on == TRUE ) {
1839 netif_stop_queue( lp->dev );
1840 WL_WDS_NETIF_STOP_QUEUE( lp );
1841 lp->netif_queue_on = FALSE;
1842
1843 dev_kfree_skb( skb );
1844 return 0;
1845 }
1846 }
1847
1848 SET_BUF_CNT( desc, /*HCF_DMA_FD_CNT*/HFS_ADDR_DEST );
1849 SET_BUF_SIZE( desc, HCF_DMA_TX_BUF1_SIZE );
1850
1851 desc_next = desc->next_desc_addr;
1852
1853 if( desc_next->buf_addr == NULL )
1854 {
1855 DBG_ERROR( DbgInfo, "DMA descriptor buf_addr is NULL\n" );
1856 return FALSE;
1857 }
1858
1859 /* Copy the payload into the DMA packet */
1860 memcpy( desc_next->buf_addr, skb->data, len );
1861
1862 SET_BUF_CNT( desc_next, len );
1863 SET_BUF_SIZE( desc_next, HCF_MAX_PACKET_SIZE );
1864
1865 hcf_dma_tx_put( &( lp->hcfCtx ), desc, 0 );
1866
1867 /* Free the skb and perform queue cleanup, as the buffer was
1868 transmitted successfully */
1869 dev_kfree_skb( skb );
1870
1871 return TRUE;
1872} // wl_send_dma
1873/*============================================================================*/
1874
1875/*******************************************************************************
1876 * wl_rx_dma()
1877 *******************************************************************************
1878 *
1879 * DESCRIPTION:
1880 *
1881 * The routine which performs data reception when using busmaster DMA.
1882 *
1883 * PARAMETERS:
1884 *
1885 * dev - a pointer to the device's net_device structure.
1886 *
1887 * RETURNS:
1888 *
1889 * 0 on success
1890 * 1 on error
1891 *
1892 ******************************************************************************/
1893int wl_rx_dma( struct net_device *dev )
1894{
1895 int port;
1896 hcf_16 pktlen;
1897 hcf_16 hfs_stat;
1898 struct sk_buff *skb;
1899 struct wl_private *lp = NULL;
1900 DESC_STRCT *desc, *desc_next;
1901 //CFG_MB_INFO_RANGE2_STRCT x;
1902 /*------------------------------------------------------------------------*/
1903
1904 DBG_FUNC("wl_rx")
1905 DBG_PARAM(DbgInfo, "dev", "%s (0x%p)", dev->name, dev);
1906
Kulikov Vasiliyc755a822010-06-29 14:16:25 +04001907 if((( lp = dev->priv ) != NULL ) &&
1908 !( lp->flags & WVLAN2_UIL_BUSY )) {
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001909
1910#ifdef USE_RTS
1911 if( lp->useRTS == 1 ) {
1912 DBG_PRINT( "RTS: We're getting an Rx...\n" );
1913 return -EIO;
1914 }
1915#endif /* USE_RTS */
1916
1917 //if( lp->dma.status == 0 )
1918 //{
1919 desc = hcf_dma_rx_get( &( lp->hcfCtx ));
1920
1921 if( desc != NULL )
1922 {
1923 /* Check and see if we rcvd. a WMP frame */
1924 /*
1925 if((( *(hcf_8 *)&desc->buf_addr[HFS_STAT] ) &
1926 ( HFS_STAT_MSG_TYPE | HFS_STAT_ERR )) == HFS_STAT_WMP_MSG )
1927 {
1928 DBG_TRACE( DbgInfo, "Got a WMP frame\n" );
1929
1930 x.len = sizeof( CFG_MB_INFO_RANGE2_STRCT ) / sizeof( hcf_16 );
1931 x.typ = CFG_MB_INFO;
1932 x.base_typ = CFG_WMP;
1933 x.frag_cnt = 2;
1934 x.frag_buf[0].frag_len = GET_BUF_CNT( descp ) / sizeof( hcf_16 );
1935 x.frag_buf[0].frag_addr = (hcf_8 *) descp->buf_addr ;
1936 x.frag_buf[1].frag_len = ( GET_BUF_CNT( descp->next_desc_addr ) + 1 ) / sizeof( hcf_16 );
1937 x.frag_buf[1].frag_addr = (hcf_8 *) descp->next_desc_addr->buf_addr ;
1938
1939 hcf_put_info( &( lp->hcfCtx ), (LTVP)&x );
1940 }
1941 */
1942
1943 desc_next = desc->next_desc_addr;
1944
1945 /* Make sure the buffer isn't empty */
1946 if( GET_BUF_CNT( desc ) == 0 ) {
1947 DBG_WARNING( DbgInfo, "Buffer is empty!\n" );
1948
1949 /* Give the descriptor back to the HCF */
1950 hcf_dma_rx_put( &( lp->hcfCtx ), desc );
1951 return -EIO;
1952 }
1953
1954 /* Read the HFS_STAT register from the lookahead buffer */
1955 hfs_stat = (hcf_16)( desc->buf_addr[HFS_STAT/2] );
1956
1957 /* Make sure the frame isn't bad */
1958 if(( hfs_stat & HFS_STAT_ERR ) != HCF_SUCCESS )
1959 {
1960 DBG_WARNING( DbgInfo, "HFS_STAT_ERROR (0x%x) in Rx Packet\n",
1961 desc->buf_addr[HFS_STAT/2] );
1962
1963 /* Give the descriptor back to the HCF */
1964 hcf_dma_rx_put( &( lp->hcfCtx ), desc );
1965 return -EIO;
1966 }
1967
1968 /* Determine what port this packet is for */
1969 port = ( hfs_stat >> 8 ) & 0x0007;
1970 DBG_RX( DbgInfo, "Rx frame for port %d\n", port );
1971
Joe Perches491dbc82010-03-24 22:17:07 -07001972 pktlen = GET_BUF_CNT(desc_next);
1973 if (pktlen != 0) {
1974 skb = ALLOC_SKB(pktlen);
1975 if (skb != NULL) {
Henk de Groot68c0bdf2009-09-27 11:12:52 +02001976 switch( port ) {
1977#ifdef USE_WDS
1978 case 1:
1979 case 2:
1980 case 3:
1981 case 4:
1982 case 5:
1983 case 6:
1984 skb->dev = lp->wds_port[port-1].dev;
1985 break;
1986#endif /* USE_WDS */
1987
1988 case 0:
1989 default:
1990 skb->dev = dev;
1991 break;
1992 }
1993
1994 GET_PACKET_DMA( skb->dev, skb, pktlen );
1995
1996 /* Give the descriptor back to the HCF */
1997 hcf_dma_rx_put( &( lp->hcfCtx ), desc );
1998
1999 netif_rx( skb );
2000
2001 if( port == 0 ) {
2002 lp->stats.rx_packets++;
2003 lp->stats.rx_bytes += pktlen;
2004 }
2005#ifdef USE_WDS
2006 else
2007 {
2008 lp->wds_port[port-1].stats.rx_packets++;
2009 lp->wds_port[port-1].stats.rx_bytes += pktlen;
2010 }
2011#endif /* USE_WDS */
2012
2013 dev->last_rx = jiffies;
2014
2015 } else {
2016 DBG_ERROR( DbgInfo, "Could not alloc skb\n" );
2017
2018 if( port == 0 )
2019 {
2020 lp->stats.rx_dropped++;
2021 }
2022#ifdef USE_WDS
2023 else
2024 {
2025 lp->wds_port[port-1].stats.rx_dropped++;
2026 }
2027#endif /* USE_WDS */
2028 }
2029 }
2030 }
2031 //}
2032 }
2033
2034 return 0;
2035} // wl_rx_dma
2036/*============================================================================*/
2037#endif // ENABLE_DMA