~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/staging/wlags49_h2/wl_netdev.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 ļæ½AS ISļæ½ AND ANY EXPRESS OR IMPLIED WARRANTIES,
 
48
 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
 
49
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
 
50
 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
 
51
 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
 
52
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
53
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
54
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 
55
 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
 
56
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 
57
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 
58
 * DAMAGE.
 
59
 *
 
60
 ******************************************************************************/
 
61
 
 
62
/*******************************************************************************
 
63
 * include files
 
64
 ******************************************************************************/
 
65
#include <wl_version.h>
 
66
 
 
67
#include <linux/module.h>
 
68
#include <linux/slab.h>
 
69
#include <linux/types.h>
 
70
#include <linux/kernel.h>
 
71
// #include <linux/sched.h>
 
72
// #include <linux/ptrace.h>
 
73
// #include <linux/slab.h>
 
74
// #include <linux/ctype.h>
 
75
// #include <linux/string.h>
 
76
//#include <linux/timer.h>
 
77
// #include <linux/interrupt.h>
 
78
// #include <linux/in.h>
 
79
// #include <linux/delay.h>
 
80
// #include <linux/skbuff.h>
 
81
// #include <asm/io.h>
 
82
// #include <asm/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
 
123
extern 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
 ******************************************************************************/
 
170
int 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
 ******************************************************************************/
 
210
int wl_config( struct net_device *dev, struct ifmap *map )
 
211
{
 
212
    DBG_FUNC( "wl_config" );
 
213
    DBG_ENTER( DbgInfo );
 
214
 
 
215
    DBG_PARAM( DbgInfo, "dev", "%s (0x%p)", dev->name, dev );
 
216
    DBG_PARAM( DbgInfo, "map", "0x%p", map );
 
217
 
 
218
    /* The only thing we care about here is a port change. Since this not needed,
 
219
       ignore the request. */
 
220
    DBG_TRACE(DbgInfo, "%s: %s called.\n", dev->name, __func__);
 
221
 
 
222
    DBG_LEAVE( DbgInfo );
 
223
    return 0;
 
224
} // wl_config
 
225
/*============================================================================*/
 
226
 
 
227
/*******************************************************************************
 
228
 *      wl_stats()
 
229
 *******************************************************************************
 
230
 *
 
231
 *  DESCRIPTION:
 
232
 *
 
233
 *      Return the current device statistics.
 
234
 *
 
235
 *  PARAMETERS:
 
236
 *
 
237
 *      dev - a pointer to the device's net_device structure
 
238
 *
 
239
 *  RETURNS:
 
240
 *
 
241
 *      a pointer to a net_device_stats structure containing the network
 
242
 *      statistics.
 
243
 *
 
244
 ******************************************************************************/
 
245
struct 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
 ******************************************************************************/
 
314
int 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 ) {
 
364
        // Unsuccessful, try reset of the card to recover
 
365
        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
 ******************************************************************************/
 
411
int 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
 
 
459
static void wl_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 
460
{
 
461
    strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
 
462
    strncpy(info->version, DRV_VERSION_STR, sizeof(info->version) - 1);
 
463
//      strncpy(info.fw_version, priv->fw_name,
 
464
//      sizeof(info.fw_version) - 1);
 
465
 
 
466
    if (dev->dev.parent) {
 
467
        dev_set_name(dev->dev.parent, "%s", info->bus_info);
 
468
        //strncpy(info->bus_info, dev->dev.parent->bus_id,
 
469
        //      sizeof(info->bus_info) - 1);
 
470
    } else {
 
471
        snprintf(info->bus_info, sizeof(info->bus_info) - 1,
 
472
                "PCMCIA FIXME");
 
473
//                  "PCMCIA 0x%lx", priv->hw.iobase);
 
474
    }
 
475
} // wl_get_drvinfo
 
476
 
 
477
static 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
 ******************************************************************************/
 
503
int 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
 
561
out_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
 
573
void 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
 ******************************************************************************/
 
602
void 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
 ******************************************************************************/
 
678
int 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
 ******************************************************************************/
 
798
int 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
 ******************************************************************************/
 
890
int 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
 
 
928
        pktlen = lp->hcfCtx.IFB_RxLen;
 
929
        if (pktlen != 0) {
 
930
            skb = ALLOC_SKB(pktlen);
 
931
            if (skb != NULL) {
 
932
                /* Set the netdev based on the port */
 
933
                switch( port ) {
 
934
#ifdef USE_WDS
 
935
                case 1:
 
936
                case 2:
 
937
                case 3:
 
938
                case 4:
 
939
                case 5:
 
940
                case 6:
 
941
                    skb->dev = lp->wds_port[port-1].dev;
 
942
                    break;
 
943
#endif  /* USE_WDS */
 
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
 
 
1044
void 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;
 
1050
    struct netdev_hw_addr *ha;
 
1051
    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
 
 
1071
        DBG_PRINT( "  mc_count: %d\n", netdev_mc_count(dev));
 
1072
 
 
1073
        netdev_for_each_mc_addr(ha, dev)
 
1074
        DBG_PRINT("    %pM (%d)\n", ha->addr, dev->addr_len);
 
1075
    }
 
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
            }
 
1101
            else if ((netdev_mc_count(dev) > HCF_MAX_MULTICAST) ||
 
1102
                    ( 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
            }
 
1113
            else if (!netdev_mc_empty(dev)) {
 
1114
                /* Set the multicast addresses */
 
1115
                lp->ltvRecord.len = ( netdev_mc_count(dev) * 3 ) + 1;
 
1116
                lp->ltvRecord.typ = CFG_GROUP_ADDR;
 
1117
 
 
1118
                x = 0;
 
1119
                netdev_for_each_mc_addr(ha, dev)
 
1120
                    memcpy(&(lp->ltvRecord.u.u8[x++ * ETH_ALEN]),
 
1121
                           ha->addr, ETH_ALEN);
 
1122
                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
 
 
1159
void 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
 
 
1176
static 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,
 
1182
    .ndo_set_rx_mode        = &wl_multicast,
 
1183
 
 
1184
    .ndo_init               = &wl_insert,
 
1185
    .ndo_open               = &wl_adapter_open,
 
1186
    .ndo_stop               = &wl_adapter_close,
 
1187
    .ndo_do_ioctl           = &wl_ioctl,
 
1188
 
 
1189
    .ndo_tx_timeout         = &wl_tx_timeout,
 
1190
 
 
1191
#ifdef CONFIG_NET_POLL_CONTROLLER
 
1192
    .ndo_poll_controller    = wl_poll,
 
1193
#endif
 
1194
};
 
1195
 
 
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
 ******************************************************************************/
 
1215
struct 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
 
 
1248
    dev->netdev_ops = &wl_netdev_ops;
 
1249
 
 
1250
    dev->watchdog_timeo     = TX_TIMEOUT;
 
1251
 
 
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
 ******************************************************************************/
 
1282
void 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
 ******************************************************************************/
 
1318
int 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
 ******************************************************************************/
 
1349
int 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
 ******************************************************************************/
 
1374
int 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
 ******************************************************************************/
 
1399
int 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
 ******************************************************************************/
 
1424
int 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
 ******************************************************************************/
 
1449
int 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
 ******************************************************************************/
 
1474
int 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
 ******************************************************************************/
 
1500
void 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
 ******************************************************************************/
 
1569
void 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
 
 
1588
            free_netdev(dev_wds);
 
1589
            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
 ******************************************************************************/
 
1616
void 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
 ******************************************************************************/
 
1653
void 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
 ******************************************************************************/
 
1690
void 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
 ******************************************************************************/
 
1727
void 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
 ******************************************************************************/
 
1762
void 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
 ******************************************************************************/
 
1802
int 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
 ******************************************************************************/
 
1893
int 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
 
 
1907
    if((( lp = dev->priv ) != NULL ) &&
 
1908
        !( lp->flags & WVLAN2_UIL_BUSY )) {
 
1909
 
 
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
 
 
1972
                pktlen = GET_BUF_CNT(desc_next);
 
1973
                if (pktlen != 0) {
 
1974
                    skb = ALLOC_SKB(pktlen);
 
1975
                    if (skb != NULL) {
 
1976
                        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