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