OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [message/] [fusion/] [mptlan.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *  linux/drivers/message/fusion/mptlan.c
3
 *      IP Over Fibre Channel device driver.
4
 *      For use with PCI chip/adapter(s):
5
 *          LSIFC9xx/LSI409xx Fibre Channel
6
 *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
7
 *
8
 *  Credits:
9
 *      This driver would not exist if not for Alan Cox's development
10
 *      of the linux i2o driver.
11
 *
12
 *      Special thanks goes to the I2O LAN driver people at the
13
 *      University of Helsinki, who, unbeknownst to them, provided
14
 *      the inspiration and initial structure for this driver.
15
 *
16
 *      A huge debt of gratitude is owed to David S. Miller (DaveM)
17
 *      for fixing much of the stupid and broken stuff in the early
18
 *      driver while porting to sparc64 platform.  THANK YOU!
19
 *
20
 *      A really huge debt of gratitude is owed to Eddie C. Dost
21
 *      for gobs of hard work fixing and optimizing LAN code.
22
 *      THANK YOU!
23
 *
24
 *      (see also mptbase.c)
25
 *
26
 *  Copyright (c) 2000-2002 LSI Logic Corporation
27
 *  Originally By: Noah Romer
28
 *
29
 *  $Id: mptlan.c,v 1.1.1.1 2004-04-15 02:27:38 phoenix Exp $
30
 */
31
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
32
/*
33
    This program is free software; you can redistribute it and/or modify
34
    it under the terms of the GNU General Public License as published by
35
    the Free Software Foundation; version 2 of the License.
36
 
37
    This program is distributed in the hope that it will be useful,
38
    but WITHOUT ANY WARRANTY; without even the implied warranty of
39
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
40
    GNU General Public License for more details.
41
 
42
    NO WARRANTY
43
    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
44
    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
45
    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
46
    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
47
    solely responsible for determining the appropriateness of using and
48
    distributing the Program and assumes all risks associated with its
49
    exercise of rights under this Agreement, including but not limited to
50
    the risks and costs of program errors, damage to or loss of data,
51
    programs or equipment, and unavailability or interruption of operations.
52
 
53
    DISCLAIMER OF LIABILITY
54
    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
55
    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56
    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
57
    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
58
    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
59
    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
60
    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
61
 
62
    You should have received a copy of the GNU General Public License
63
    along with this program; if not, write to the Free Software
64
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
65
*/
66
 
67
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
68
/*
69
 * Define statements used for debugging
70
 */
71
//#define MPT_LAN_IO_DEBUG
72
 
73
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
74
 
75
#include "mptlan.h"
76
#include <linux/init.h>
77
#include <linux/module.h>
78
#include <linux/fs.h>
79
 
80
#define MYNAM           "mptlan"
81
 
82
MODULE_LICENSE("GPL");
83
 
84
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
85
/*
86
 * MPT LAN message sizes without variable part.
87
 */
88
#define MPT_LAN_RECEIVE_POST_REQUEST_SIZE \
89
        (sizeof(LANReceivePostRequest_t) - sizeof(SGE_MPI_UNION))
90
 
91
#define MPT_LAN_TRANSACTION32_SIZE \
92
        (sizeof(SGETransaction32_t) - sizeof(u32))
93
 
94
/*
95
 *  Fusion MPT LAN private structures
96
 */
97
 
98
struct NAA_Hosed {
99
        u16 NAA;
100
        u8 ieee[FC_ALEN];
101
        struct NAA_Hosed *next;
102
};
103
 
104
struct BufferControl {
105
        struct sk_buff  *skb;
106
        dma_addr_t      dma;
107
        unsigned int    len;
108
};
109
 
110
struct mpt_lan_priv {
111
        MPT_ADAPTER *mpt_dev;
112
        u8 pnum; /* Port number in the IOC. This is not a Unix network port! */
113
 
114
        atomic_t buckets_out;           /* number of unused buckets on IOC */
115
        int bucketthresh;               /* Send more when this many left */
116
 
117
        int *mpt_txfidx; /* Free Tx Context list */
118
        int mpt_txfidx_tail;
119
        spinlock_t txfidx_lock;
120
 
121
        int *mpt_rxfidx; /* Free Rx Context list */
122
        int mpt_rxfidx_tail;
123
        spinlock_t rxfidx_lock;
124
 
125
        struct BufferControl *RcvCtl;   /* Receive BufferControl structs */
126
        struct BufferControl *SendCtl;  /* Send BufferControl structs */
127
 
128
        int max_buckets_out;            /* Max buckets to send to IOC */
129
        int tx_max_out;                 /* IOC's Tx queue len */
130
 
131
        u32 total_posted;
132
        u32 total_received;
133
        struct net_device_stats stats;  /* Per device statistics */
134
 
135
        struct mpt_work_struct post_buckets_task;
136
        unsigned long post_buckets_active;
137
};
138
 
139
struct mpt_lan_ohdr {
140
        u16     dtype;
141
        u8      daddr[FC_ALEN];
142
        u16     stype;
143
        u8      saddr[FC_ALEN];
144
};
145
 
146
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
147
 
148
/*
149
 *  Forward protos...
150
 */
151
static int  lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
152
                       MPT_FRAME_HDR *reply);
153
static int  mpt_lan_open(struct net_device *dev);
154
static int  mpt_lan_reset(struct net_device *dev);
155
static int  mpt_lan_close(struct net_device *dev);
156
static void mpt_lan_post_receive_buckets(void *dev_id);
157
static void mpt_lan_wake_post_buckets_task(struct net_device *dev,
158
                                           int priority);
159
static int  mpt_lan_receive_post_turbo(struct net_device *dev, u32 tmsg);
160
static int  mpt_lan_receive_post_reply(struct net_device *dev,
161
                                       LANReceivePostReply_t *pRecvRep);
162
static int  mpt_lan_send_turbo(struct net_device *dev, u32 tmsg);
163
static int  mpt_lan_send_reply(struct net_device *dev,
164
                               LANSendReply_t *pSendRep);
165
static int  mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
166
static int  mpt_lan_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
167
static unsigned short mpt_lan_type_trans(struct sk_buff *skb,
168
                                         struct net_device *dev);
169
 
170
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
171
/*
172
 *  Fusion MPT LAN private data
173
 */
174
static int LanCtx = -1;
175
 
176
static u32 max_buckets_out = 127;
177
static u32 tx_max_out_p = 127 - 16;
178
 
179
static struct net_device *mpt_landev[MPT_MAX_ADAPTERS+1];
180
 
181
#ifdef QLOGIC_NAA_WORKAROUND
182
static struct NAA_Hosed *mpt_bad_naa = NULL;
183
rwlock_t bad_naa_lock;
184
#endif
185
 
186
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
187
/*
188
 * Fusion MPT LAN external data
189
 */
190
extern int mpt_lan_index;
191
 
192
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
193
/**
194
 *      lan_reply - Handle all data sent from the hardware.
195
 *      @ioc: Pointer to MPT_ADAPTER structure
196
 *      @mf: Pointer to original MPT request frame (NULL if TurboReply)
197
 *      @reply: Pointer to MPT reply frame
198
 *
199
 *      Returns 1 indicating original alloc'd request frame ptr
200
 *      should be freed, or 0 if it shouldn't.
201
 */
202
static int
203
lan_reply (MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
204
{
205
        struct net_device *dev = mpt_landev[ioc->id];
206
        int FreeReqFrame = 0;
207
 
208
        dioprintk((KERN_INFO MYNAM ": %s/%s: Got reply.\n",
209
                  IOC_AND_NETDEV_NAMES_s_s(dev)));
210
 
211
//      dioprintk((KERN_INFO MYNAM "@lan_reply: mf = %p, reply = %p\n",
212
//                      mf, reply));
213
 
214
        if (mf == NULL) {
215
                u32 tmsg = CAST_PTR_TO_U32(reply);
216
 
217
                dioprintk((KERN_INFO MYNAM ": %s/%s: @lan_reply, tmsg %08x\n",
218
                                IOC_AND_NETDEV_NAMES_s_s(dev),
219
                                tmsg));
220
 
221
                switch (GET_LAN_FORM(tmsg)) {
222
 
223
                // NOTE!  (Optimization) First case here is now caught in
224
                //  mptbase.c::mpt_interrupt() routine and callcack here
225
                //  is now skipped for this case!  20001218 -sralston
226
#if 0
227
                case LAN_REPLY_FORM_MESSAGE_CONTEXT:
228
//                      dioprintk((KERN_INFO MYNAM "/lan_reply: "
229
//                                "MessageContext turbo reply received\n"));
230
                        FreeReqFrame = 1;
231
                        break;
232
#endif
233
 
234
                case LAN_REPLY_FORM_SEND_SINGLE:
235
//                      dioprintk((MYNAM "/lan_reply: "
236
//                                "calling mpt_lan_send_reply (turbo)\n"));
237
 
238
                        // Potential BUG here?  -sralston
239
                        //      FreeReqFrame = mpt_lan_send_turbo(dev, tmsg);
240
                        //  If/when mpt_lan_send_turbo would return 1 here,
241
                        //  calling routine (mptbase.c|mpt_interrupt)
242
                        //  would Oops because mf has already been set
243
                        //  to NULL.  So after return from this func,
244
                        //  mpt_interrupt() will attempt to put (NULL) mf ptr
245
                        //  item back onto its adapter FreeQ - Oops!:-(
246
                        //  It's Ok, since mpt_lan_send_turbo() *currently*
247
                        //  always returns 0, but..., just in case:
248
 
249
                        (void) mpt_lan_send_turbo(dev, tmsg);
250
                        FreeReqFrame = 0;
251
 
252
                        break;
253
 
254
                case LAN_REPLY_FORM_RECEIVE_SINGLE:
255
//                      dioprintk((KERN_INFO MYNAM "@lan_reply: "
256
//                                "rcv-Turbo = %08x\n", tmsg));
257
                        mpt_lan_receive_post_turbo(dev, tmsg);
258
                        break;
259
 
260
                default:
261
                        printk (KERN_ERR MYNAM "/lan_reply: Got a turbo reply "
262
                                "that I don't know what to do with\n");
263
 
264
                        /* CHECKME!  Hmmm...  FreeReqFrame is 0 here; is that right? */
265
 
266
                        break;
267
                }
268
 
269
                return FreeReqFrame;
270
        }
271
 
272
//      msg = (u32 *) reply;
273
//      dioprintk((KERN_INFO MYNAM "@lan_reply: msg = %08x %08x %08x %08x\n",
274
//                le32_to_cpu(msg[0]), le32_to_cpu(msg[1]),
275
//                le32_to_cpu(msg[2]), le32_to_cpu(msg[3])));
276
//      dioprintk((KERN_INFO MYNAM "@lan_reply: Function = %02xh\n",
277
//                reply->u.hdr.Function));
278
 
279
        switch (reply->u.hdr.Function) {
280
 
281
        case MPI_FUNCTION_LAN_SEND:
282
        {
283
                LANSendReply_t *pSendRep;
284
 
285
                pSendRep = (LANSendReply_t *) reply;
286
                FreeReqFrame = mpt_lan_send_reply(dev, pSendRep);
287
                break;
288
        }
289
 
290
        case MPI_FUNCTION_LAN_RECEIVE:
291
        {
292
                LANReceivePostReply_t *pRecvRep;
293
 
294
                pRecvRep = (LANReceivePostReply_t *) reply;
295
                if (pRecvRep->NumberOfContexts) {
296
                        mpt_lan_receive_post_reply(dev, pRecvRep);
297
                        if (!(pRecvRep->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY))
298
                                FreeReqFrame = 1;
299
                } else
300
                        dioprintk((KERN_INFO MYNAM "@lan_reply: zero context "
301
                                  "ReceivePostReply received.\n"));
302
                break;
303
        }
304
 
305
        case MPI_FUNCTION_LAN_RESET:
306
                /* Just a default reply. Might want to check it to
307
                 * make sure that everything went ok.
308
                 */
309
                FreeReqFrame = 1;
310
                break;
311
 
312
        case MPI_FUNCTION_EVENT_NOTIFICATION:
313
        case MPI_FUNCTION_EVENT_ACK:
314
                /* UPDATE!  20010120 -sralston
315
                 *  _EVENT_NOTIFICATION should NOT come down this path any more.
316
                 *  Should be routed to mpt_lan_event_process(), but just in case...
317
                 */
318
                FreeReqFrame = 1;
319
                break;
320
 
321
        default:
322
                printk (KERN_ERR MYNAM "/lan_reply: Got a non-turbo "
323
                        "reply that I don't know what to do with\n");
324
 
325
                /* CHECKME!  Hmmm...  FreeReqFrame is 0 here; is that right? */
326
                FreeReqFrame = 1;
327
 
328
                break;
329
        }
330
 
331
        return FreeReqFrame;
332
}
333
 
334
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
335
static int
336
mpt_lan_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
337
{
338
        struct net_device *dev = mpt_landev[ioc->id];
339
        struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
340
 
341
        dlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to LAN driver!\n",
342
                        reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
343
                        reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
344
 
345
        if (priv->mpt_rxfidx == NULL)
346
                return (1);
347
 
348
        if (reset_phase == MPT_IOC_SETUP_RESET) {
349
                ;
350
        } else if (reset_phase == MPT_IOC_PRE_RESET) {
351
                int i;
352
                unsigned long flags;
353
 
354
                netif_stop_queue(dev);
355
 
356
                dlprintk ((KERN_INFO "mptlan/ioc_reset: called netif_stop_queue for %s.\n", dev->name));
357
 
358
                atomic_set(&priv->buckets_out, 0);
359
 
360
                /* Reset Rx Free Tail index and re-populate the queue. */
361
                spin_lock_irqsave(&priv->rxfidx_lock, flags);
362
                priv->mpt_rxfidx_tail = -1;
363
                for (i = 0; i < priv->max_buckets_out; i++)
364
                        priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i;
365
                spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
366
        } else {
367
                mpt_lan_post_receive_buckets(dev);
368
                netif_wake_queue(dev);
369
        }
370
 
371
        return 1;
372
}
373
 
374
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
375
static int
376
mpt_lan_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
377
{
378
        dlprintk((KERN_INFO MYNAM ": MPT event routed to LAN driver!\n"));
379
 
380
        switch (le32_to_cpu(pEvReply->Event)) {
381
        case MPI_EVENT_NONE:                            /* 00 */
382
        case MPI_EVENT_LOG_DATA:                        /* 01 */
383
        case MPI_EVENT_STATE_CHANGE:                    /* 02 */
384
        case MPI_EVENT_UNIT_ATTENTION:                  /* 03 */
385
        case MPI_EVENT_IOC_BUS_RESET:                   /* 04 */
386
        case MPI_EVENT_EXT_BUS_RESET:                   /* 05 */
387
        case MPI_EVENT_RESCAN:                          /* 06 */
388
                /* Ok, do we need to do anything here? As far as
389
                   I can tell, this is when a new device gets added
390
                   to the loop. */
391
        case MPI_EVENT_LINK_STATUS_CHANGE:              /* 07 */
392
        case MPI_EVENT_LOOP_STATE_CHANGE:               /* 08 */
393
        case MPI_EVENT_LOGOUT:                          /* 09 */
394
        case MPI_EVENT_EVENT_CHANGE:                    /* 0A */
395
        default:
396
                break;
397
        }
398
 
399
        /*
400
         *  NOTE: pEvent->AckRequired handling now done in mptbase.c;
401
         *  Do NOT do it here now!
402
         */
403
 
404
        return 1;
405
}
406
 
407
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
408
static int
409
mpt_lan_open(struct net_device *dev)
410
{
411
        struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
412
        int i;
413
 
414
        if (mpt_lan_reset(dev) != 0) {
415
                MPT_ADAPTER *mpt_dev = priv->mpt_dev;
416
 
417
                printk (KERN_WARNING MYNAM "/lan_open: lan_reset failed.");
418
 
419
                if (mpt_dev->active)
420
                        printk ("The ioc is active. Perhaps it needs to be"
421
                                " reset?\n");
422
                else
423
                        printk ("The ioc in inactive, most likely in the "
424
                                "process of being reset. Please try again in "
425
                                "a moment.\n");
426
        }
427
 
428
        priv->mpt_txfidx = kmalloc(priv->tx_max_out * sizeof(int), GFP_KERNEL);
429
        if (priv->mpt_txfidx == NULL)
430
                goto out;
431
        priv->mpt_txfidx_tail = -1;
432
 
433
        priv->SendCtl = kmalloc(priv->tx_max_out * sizeof(struct BufferControl),
434
                                GFP_KERNEL);
435
        if (priv->SendCtl == NULL)
436
                goto out_mpt_txfidx;
437
        for (i = 0; i < priv->tx_max_out; i++) {
438
                memset(&priv->SendCtl[i], 0, sizeof(struct BufferControl));
439
                priv->mpt_txfidx[++priv->mpt_txfidx_tail] = i;
440
        }
441
 
442
        dlprintk((KERN_INFO MYNAM "@lo: Finished initializing SendCtl\n"));
443
 
444
        priv->mpt_rxfidx = kmalloc(priv->max_buckets_out * sizeof(int),
445
                                   GFP_KERNEL);
446
        if (priv->mpt_rxfidx == NULL)
447
                goto out_SendCtl;
448
        priv->mpt_rxfidx_tail = -1;
449
 
450
        priv->RcvCtl = kmalloc(priv->max_buckets_out *
451
                                                sizeof(struct BufferControl),
452
                               GFP_KERNEL);
453
        if (priv->RcvCtl == NULL)
454
                goto out_mpt_rxfidx;
455
        for (i = 0; i < priv->max_buckets_out; i++) {
456
                memset(&priv->RcvCtl[i], 0, sizeof(struct BufferControl));
457
                priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i;
458
        }
459
 
460
/**/    dlprintk((KERN_INFO MYNAM "/lo: txfidx contains - "));
461
/**/    for (i = 0; i < priv->tx_max_out; i++)
462
/**/            dlprintk((" %xh", priv->mpt_txfidx[i]));
463
/**/    dlprintk(("\n"));
464
 
465
        dlprintk((KERN_INFO MYNAM "/lo: Finished initializing RcvCtl\n"));
466
 
467
        mpt_lan_post_receive_buckets(dev);
468
        printk(KERN_INFO MYNAM ": %s/%s: interface up & active\n",
469
                        IOC_AND_NETDEV_NAMES_s_s(dev));
470
 
471
        if (mpt_event_register(LanCtx, mpt_lan_event_process) != 0) {
472
                printk (KERN_WARNING MYNAM "/lo: Unable to register for Event"
473
                        " Notifications. This is a bad thing! We're not going "
474
                        "to go ahead, but I'd be leery of system stability at "
475
                        "this point.\n");
476
        }
477
 
478
        netif_start_queue(dev);
479
        dlprintk((KERN_INFO MYNAM "/lo: Done.\n"));
480
 
481
        return 0;
482
out_mpt_rxfidx:
483
        kfree(priv->mpt_rxfidx);
484
        priv->mpt_rxfidx = NULL;
485
out_SendCtl:
486
        kfree(priv->SendCtl);
487
        priv->SendCtl = NULL;
488
out_mpt_txfidx:
489
        kfree(priv->mpt_txfidx);
490
        priv->mpt_txfidx = NULL;
491
out:    return -ENOMEM;
492
}
493
 
494
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
495
/* Send a LanReset message to the FW. This should result in the FW returning
496
   any buckets it still has. */
497
static int
498
mpt_lan_reset(struct net_device *dev)
499
{
500
        MPT_FRAME_HDR *mf;
501
        LANResetRequest_t *pResetReq;
502
        struct mpt_lan_priv *priv = (struct mpt_lan_priv *)dev->priv;
503
 
504
        mf = mpt_get_msg_frame(LanCtx, priv->mpt_dev->id);
505
 
506
        if (mf == NULL) {
507
/*              dlprintk((KERN_ERR MYNAM "/reset: Evil funkiness abounds! "
508
                "Unable to allocate a request frame.\n"));
509
*/
510
                return -1;
511
        }
512
 
513
        pResetReq = (LANResetRequest_t *) mf;
514
 
515
        pResetReq->Function     = MPI_FUNCTION_LAN_RESET;
516
        pResetReq->ChainOffset  = 0;
517
        pResetReq->Reserved     = 0;
518
        pResetReq->PortNumber   = priv->pnum;
519
        pResetReq->MsgFlags     = 0;
520
        pResetReq->Reserved2    = 0;
521
 
522
        mpt_put_msg_frame(LanCtx, priv->mpt_dev->id, mf);
523
 
524
        return 0;
525
}
526
 
527
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
528
static int
529
mpt_lan_close(struct net_device *dev)
530
{
531
        struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
532
        MPT_ADAPTER *mpt_dev = priv->mpt_dev;
533
        unsigned int timeout;
534
        int i;
535
 
536
        dlprintk((KERN_INFO MYNAM ": mpt_lan_close called\n"));
537
 
538
        mpt_event_deregister(LanCtx);
539
 
540
        dlprintk((KERN_INFO MYNAM ":lan_close: Posted %d buckets "
541
                  "since driver was loaded, %d still out\n",
542
                  priv->total_posted,atomic_read(&priv->buckets_out)));
543
 
544
        netif_stop_queue(dev);
545
 
546
        mpt_lan_reset(dev);
547
 
548
        timeout = 2 * HZ;
549
        while (atomic_read(&priv->buckets_out) && --timeout) {
550
                set_current_state(TASK_INTERRUPTIBLE);
551
                schedule_timeout(1);
552
        }
553
 
554
        for (i = 0; i < priv->max_buckets_out; i++) {
555
                if (priv->RcvCtl[i].skb != NULL) {
556
/**/                    dlprintk((KERN_INFO MYNAM "/lan_close: bucket %05x "
557
/**/                              "is still out\n", i));
558
                        pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[i].dma,
559
                                         priv->RcvCtl[i].len,
560
                                         PCI_DMA_FROMDEVICE);
561
                        dev_kfree_skb(priv->RcvCtl[i].skb);
562
                }
563
        }
564
 
565
        kfree (priv->RcvCtl);
566
        kfree (priv->mpt_rxfidx);
567
 
568
        for (i = 0; i < priv->tx_max_out; i++) {
569
                if (priv->SendCtl[i].skb != NULL) {
570
                        pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[i].dma,
571
                                         priv->SendCtl[i].len,
572
                                         PCI_DMA_TODEVICE);
573
                        dev_kfree_skb(priv->SendCtl[i].skb);
574
                }
575
        }
576
 
577
        kfree(priv->SendCtl);
578
        kfree(priv->mpt_txfidx);
579
 
580
        atomic_set(&priv->buckets_out, 0);
581
 
582
        printk(KERN_INFO MYNAM ": %s/%s: interface down & inactive\n",
583
                        IOC_AND_NETDEV_NAMES_s_s(dev));
584
 
585
        return 0;
586
}
587
 
588
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
589
static struct net_device_stats *
590
mpt_lan_get_stats(struct net_device *dev)
591
{
592
        struct mpt_lan_priv *priv = (struct mpt_lan_priv *)dev->priv;
593
 
594
        return (struct net_device_stats *) &priv->stats;
595
}
596
 
597
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
598
static int
599
mpt_lan_change_mtu(struct net_device *dev, int new_mtu)
600
{
601
        if ((new_mtu < MPT_LAN_MIN_MTU) || (new_mtu > MPT_LAN_MAX_MTU))
602
                return -EINVAL;
603
        dev->mtu = new_mtu;
604
        return 0;
605
}
606
 
607
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
608
/* Tx timeout handler. */
609
static void
610
mpt_lan_tx_timeout(struct net_device *dev)
611
{
612
        struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
613
        MPT_ADAPTER *mpt_dev = priv->mpt_dev;
614
 
615
        if (mpt_dev->active) {
616
                dlprintk (("mptlan/tx_timeout: calling netif_wake_queue for %s.\n", dev->name));
617
                netif_wake_queue(dev);
618
        }
619
}
620
 
621
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
622
//static inline int
623
static int
624
mpt_lan_send_turbo(struct net_device *dev, u32 tmsg)
625
{
626
        struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
627
        MPT_ADAPTER *mpt_dev = priv->mpt_dev;
628
        struct sk_buff *sent;
629
        unsigned long flags;
630
        u32 ctx;
631
 
632
        ctx = GET_LAN_BUFFER_CONTEXT(tmsg);
633
        sent = priv->SendCtl[ctx].skb;
634
 
635
        priv->stats.tx_packets++;
636
        priv->stats.tx_bytes += sent->len;
637
 
638
        dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, skb %p sent.\n",
639
                        IOC_AND_NETDEV_NAMES_s_s(dev),
640
                        __FUNCTION__, sent));
641
 
642
        priv->SendCtl[ctx].skb = NULL;
643
        pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[ctx].dma,
644
                         priv->SendCtl[ctx].len, PCI_DMA_TODEVICE);
645
        dev_kfree_skb_irq(sent);
646
 
647
        spin_lock_irqsave(&priv->txfidx_lock, flags);
648
        priv->mpt_txfidx[++priv->mpt_txfidx_tail] = ctx;
649
        spin_unlock_irqrestore(&priv->txfidx_lock, flags);
650
 
651
        netif_wake_queue(dev);
652
        return 0;
653
}
654
 
655
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
656
static int
657
mpt_lan_send_reply(struct net_device *dev, LANSendReply_t *pSendRep)
658
{
659
        struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
660
        MPT_ADAPTER *mpt_dev = priv->mpt_dev;
661
        struct sk_buff *sent;
662
        unsigned long flags;
663
        int FreeReqFrame = 0;
664
        u32 *pContext;
665
        u32 ctx;
666
        u8 count;
667
 
668
        count = pSendRep->NumberOfContexts;
669
 
670
        dioprintk((KERN_INFO MYNAM ": send_reply: IOCStatus: %04x\n",
671
                 le16_to_cpu(pSendRep->IOCStatus)));
672
 
673
        /* Add check for Loginfo Flag in IOCStatus */
674
 
675
        switch (le16_to_cpu(pSendRep->IOCStatus) & MPI_IOCSTATUS_MASK) {
676
        case MPI_IOCSTATUS_SUCCESS:
677
                priv->stats.tx_packets += count;
678
                break;
679
 
680
        case MPI_IOCSTATUS_LAN_CANCELED:
681
        case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED:
682
                break;
683
 
684
        case MPI_IOCSTATUS_INVALID_SGL:
685
                priv->stats.tx_errors += count;
686
                printk (KERN_ERR MYNAM ": %s/%s: ERROR - Invalid SGL sent to IOC!\n",
687
                                IOC_AND_NETDEV_NAMES_s_s(dev));
688
                goto out;
689
 
690
        default:
691
                priv->stats.tx_errors += count;
692
                break;
693
        }
694
 
695
        pContext = &pSendRep->BufferContext;
696
 
697
        spin_lock_irqsave(&priv->txfidx_lock, flags);
698
        while (count > 0) {
699
                ctx = GET_LAN_BUFFER_CONTEXT(le32_to_cpu(*pContext));
700
 
701
                sent = priv->SendCtl[ctx].skb;
702
                priv->stats.tx_bytes += sent->len;
703
 
704
                dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, skb %p sent.\n",
705
                                IOC_AND_NETDEV_NAMES_s_s(dev),
706
                                __FUNCTION__, sent));
707
 
708
                priv->SendCtl[ctx].skb = NULL;
709
                pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[ctx].dma,
710
                                 priv->SendCtl[ctx].len, PCI_DMA_TODEVICE);
711
                dev_kfree_skb_irq(sent);
712
 
713
                priv->mpt_txfidx[++priv->mpt_txfidx_tail] = ctx;
714
 
715
                pContext++;
716
                count--;
717
        }
718
        spin_unlock_irqrestore(&priv->txfidx_lock, flags);
719
 
720
out:
721
        if (!(pSendRep->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY))
722
                FreeReqFrame = 1;
723
 
724
        netif_wake_queue(dev);
725
        return FreeReqFrame;
726
}
727
 
728
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
729
static int
730
mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
731
{
732
        struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
733
        MPT_ADAPTER *mpt_dev = priv->mpt_dev;
734
        MPT_FRAME_HDR *mf;
735
        LANSendRequest_t *pSendReq;
736
        SGETransaction32_t *pTrans;
737
        SGESimple64_t *pSimple;
738
        dma_addr_t dma;
739
        unsigned long flags;
740
        int ctx;
741
        u16 cur_naa = 0x1000;
742
 
743
        dioprintk((KERN_INFO MYNAM ": %s called, skb_addr = %p\n",
744
                        __FUNCTION__, skb));
745
 
746
        spin_lock_irqsave(&priv->txfidx_lock, flags);
747
        if (priv->mpt_txfidx_tail < 0) {
748
                netif_stop_queue(dev);
749
                spin_unlock_irqrestore(&priv->txfidx_lock, flags);
750
 
751
                printk (KERN_ERR "%s: no tx context available: %u\n",
752
                        __FUNCTION__, priv->mpt_txfidx_tail);
753
                return 1;
754
        }
755
 
756
        mf = mpt_get_msg_frame(LanCtx, mpt_dev->id);
757
        if (mf == NULL) {
758
                netif_stop_queue(dev);
759
                spin_unlock_irqrestore(&priv->txfidx_lock, flags);
760
 
761
                printk (KERN_ERR "%s: Unable to alloc request frame\n",
762
                        __FUNCTION__);
763
                return 1;
764
        }
765
 
766
        ctx = priv->mpt_txfidx[priv->mpt_txfidx_tail--];
767
        spin_unlock_irqrestore(&priv->txfidx_lock, flags);
768
 
769
//      dioprintk((KERN_INFO MYNAM ": %s/%s: Creating new msg frame (send).\n",
770
//                      IOC_AND_NETDEV_NAMES_s_s(dev)));
771
 
772
        pSendReq = (LANSendRequest_t *) mf;
773
 
774
        /* Set the mac.raw pointer, since this apparently isn't getting
775
         * done before we get the skb. Pull the data pointer past the mac data.
776
         */
777
        skb->mac.raw = skb->data;
778
        skb_pull(skb, 12);
779
 
780
        dma = pci_map_single(mpt_dev->pcidev, skb->data, skb->len,
781
                             PCI_DMA_TODEVICE);
782
 
783
        priv->SendCtl[ctx].skb = skb;
784
        priv->SendCtl[ctx].dma = dma;
785
        priv->SendCtl[ctx].len = skb->len;
786
 
787
        /* Message Header */
788
        pSendReq->Reserved    = 0;
789
        pSendReq->Function    = MPI_FUNCTION_LAN_SEND;
790
        pSendReq->ChainOffset = 0;
791
        pSendReq->Reserved2   = 0;
792
        pSendReq->MsgFlags    = 0;
793
        pSendReq->PortNumber  = priv->pnum;
794
 
795
        /* Transaction Context Element */
796
        pTrans = (SGETransaction32_t *) pSendReq->SG_List;
797
 
798
        /* No Flags, 8 bytes of Details, 32bit Context (bloody turbo replies) */
799
        pTrans->ContextSize   = sizeof(u32);
800
        pTrans->DetailsLength = 2 * sizeof(u32);
801
        pTrans->Flags         = 0;
802
        pTrans->TransactionContext[0] = cpu_to_le32(ctx);
803
 
804
//      dioprintk((KERN_INFO MYNAM ": %s/%s: BC = %08x, skb = %p, buff = %p\n",
805
//                      IOC_AND_NETDEV_NAMES_s_s(dev),
806
//                      ctx, skb, skb->data));
807
 
808
#ifdef QLOGIC_NAA_WORKAROUND
809
{
810
        struct NAA_Hosed *nh;
811
 
812
        /* Munge the NAA for Tx packets to QLogic boards, which don't follow
813
           RFC 2625. The longer I look at this, the more my opinion of Qlogic
814
           drops. */
815
        read_lock_irq(&bad_naa_lock);
816
        for (nh = mpt_bad_naa; nh != NULL; nh=nh->next) {
817
                if ((nh->ieee[0] == skb->mac.raw[0]) &&
818
                    (nh->ieee[1] == skb->mac.raw[1]) &&
819
                    (nh->ieee[2] == skb->mac.raw[2]) &&
820
                    (nh->ieee[3] == skb->mac.raw[3]) &&
821
                    (nh->ieee[4] == skb->mac.raw[4]) &&
822
                    (nh->ieee[5] == skb->mac.raw[5])) {
823
                        cur_naa = nh->NAA;
824
                        dlprintk ((KERN_INFO "mptlan/sdu_send: using NAA value "
825
                                  "= %04x.\n", cur_naa));
826
                        break;
827
                }
828
        }
829
        read_unlock_irq(&bad_naa_lock);
830
}
831
#endif
832
 
833
        pTrans->TransactionDetails[0] = cpu_to_le32((cur_naa         << 16) |
834
                                                    (skb->mac.raw[0] <<  8) |
835
                                                    (skb->mac.raw[1] <<  0));
836
        pTrans->TransactionDetails[1] = cpu_to_le32((skb->mac.raw[2] << 24) |
837
                                                    (skb->mac.raw[3] << 16) |
838
                                                    (skb->mac.raw[4] <<  8) |
839
                                                    (skb->mac.raw[5] <<  0));
840
 
841
        pSimple = (SGESimple64_t *) &pTrans->TransactionDetails[2];
842
 
843
        /* If we ever decide to send more than one Simple SGE per LANSend, then
844
           we will need to make sure that LAST_ELEMENT only gets set on the
845
           last one. Otherwise, bad voodoo and evil funkiness will commence. */
846
        pSimple->FlagsLength = cpu_to_le32(
847
                        ((MPI_SGE_FLAGS_LAST_ELEMENT |
848
                          MPI_SGE_FLAGS_END_OF_BUFFER |
849
                          MPI_SGE_FLAGS_SIMPLE_ELEMENT |
850
                          MPI_SGE_FLAGS_SYSTEM_ADDRESS |
851
                          MPI_SGE_FLAGS_HOST_TO_IOC |
852
                          MPI_SGE_FLAGS_64_BIT_ADDRESSING |
853
                          MPI_SGE_FLAGS_END_OF_LIST) << MPI_SGE_FLAGS_SHIFT) |
854
                        skb->len);
855
        pSimple->Address.Low = cpu_to_le32((u32) dma);
856
        if (sizeof(dma_addr_t) > sizeof(u32))
857
                pSimple->Address.High = cpu_to_le32((u32) ((u64) dma >> 32));
858
        else
859
                pSimple->Address.High = 0;
860
 
861
        mpt_put_msg_frame (LanCtx, mpt_dev->id, mf);
862
        dev->trans_start = jiffies;
863
 
864
        dioprintk((KERN_INFO MYNAM ": %s/%s: Sending packet. FlagsLength = %08x.\n",
865
                        IOC_AND_NETDEV_NAMES_s_s(dev),
866
                        le32_to_cpu(pSimple->FlagsLength)));
867
 
868
        return 0;
869
}
870
 
871
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
872
static inline void
873
mpt_lan_wake_post_buckets_task(struct net_device *dev, int priority)
874
/*
875
 * @priority: 0 = put it on the timer queue, 1 = put it on the immediate queue
876
 */
877
{
878
        struct mpt_lan_priv *priv = dev->priv;
879
 
880
        if (test_and_set_bit(0, &priv->post_buckets_active) == 0) {
881
                if (priority) {
882
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41)
883
                        schedule_work(&priv->post_buckets_task);
884
#else
885
                        queue_task(&priv->post_buckets_task, &tq_immediate);
886
                        mark_bh(IMMEDIATE_BH);
887
#endif
888
                } else {
889
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41)
890
                        schedule_delayed_work(&priv->post_buckets_task, 1);
891
#else
892
                        queue_task(&priv->post_buckets_task, &tq_timer);
893
#endif
894
                        dioprintk((KERN_INFO MYNAM ": post_buckets queued on "
895
                                   "timer.\n"));
896
                }
897
                dioprintk((KERN_INFO MYNAM ": %s/%s: Queued post_buckets task.\n",
898
                           IOC_AND_NETDEV_NAMES_s_s(dev) ));
899
        }
900
}
901
 
902
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
903
static inline int
904
mpt_lan_receive_skb(struct net_device *dev, struct sk_buff *skb)
905
{
906
        struct mpt_lan_priv *priv = dev->priv;
907
 
908
        skb->protocol = mpt_lan_type_trans(skb, dev);
909
 
910
        dioprintk((KERN_INFO MYNAM ": %s/%s: Incoming packet (%d bytes) "
911
                 "delivered to upper level.\n",
912
                        IOC_AND_NETDEV_NAMES_s_s(dev), skb->len));
913
 
914
        priv->stats.rx_bytes += skb->len;
915
        priv->stats.rx_packets++;
916
 
917
        skb->dev = dev;
918
        netif_rx(skb);
919
 
920
        dioprintk((MYNAM "/receive_skb: %d buckets remaining\n",
921
                 atomic_read(&priv->buckets_out)));
922
 
923
        if (atomic_read(&priv->buckets_out) < priv->bucketthresh)
924
                mpt_lan_wake_post_buckets_task(dev, 1);
925
 
926
        dioprintk((KERN_INFO MYNAM "/receive_post_reply: %d buckets "
927
                  "remaining, %d received back since sod\n",
928
                  atomic_read(&priv->buckets_out), priv->total_received));
929
 
930
        return 0;
931
}
932
 
933
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
934
//static inline int
935
static int
936
mpt_lan_receive_post_turbo(struct net_device *dev, u32 tmsg)
937
{
938
        struct mpt_lan_priv *priv = dev->priv;
939
        MPT_ADAPTER *mpt_dev = priv->mpt_dev;
940
        struct sk_buff *skb, *old_skb;
941
        unsigned long flags;
942
        u32 ctx, len;
943
 
944
        ctx = GET_LAN_BUCKET_CONTEXT(tmsg);
945
        skb = priv->RcvCtl[ctx].skb;
946
 
947
        len = GET_LAN_PACKET_LENGTH(tmsg);
948
 
949
        if (len < MPT_LAN_RX_COPYBREAK) {
950
                old_skb = skb;
951
 
952
                skb = (struct sk_buff *)dev_alloc_skb(len);
953
                if (!skb) {
954
                        printk (KERN_ERR MYNAM ": %s/%s: ERROR - Can't allocate skb! (%s@%d)\n",
955
                                        IOC_AND_NETDEV_NAMES_s_s(dev),
956
                                        __FILE__, __LINE__);
957
                        return -ENOMEM;
958
                }
959
 
960
                pci_dma_sync_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma,
961
                                    priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE);
962
 
963
                memcpy(skb_put(skb, len), old_skb->data, len);
964
 
965
                goto out;
966
        }
967
 
968
        skb_put(skb, len);
969
 
970
        priv->RcvCtl[ctx].skb = NULL;
971
 
972
        pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma,
973
                         priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE);
974
 
975
out:
976
        spin_lock_irqsave(&priv->rxfidx_lock, flags);
977
        priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
978
        spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
979
 
980
        atomic_dec(&priv->buckets_out);
981
        priv->total_received++;
982
 
983
        return mpt_lan_receive_skb(dev, skb);
984
}
985
 
986
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
987
static int
988
mpt_lan_receive_post_free(struct net_device *dev,
989
                          LANReceivePostReply_t *pRecvRep)
990
{
991
        struct mpt_lan_priv *priv = dev->priv;
992
        MPT_ADAPTER *mpt_dev = priv->mpt_dev;
993
        unsigned long flags;
994
        struct sk_buff *skb;
995
        u32 ctx;
996
        int count;
997
        int i;
998
 
999
        count = pRecvRep->NumberOfContexts;
1000
 
1001
/**/    dlprintk((KERN_INFO MYNAM "/receive_post_reply: "
1002
                  "IOC returned %d buckets, freeing them...\n", count));
1003
 
1004
        spin_lock_irqsave(&priv->rxfidx_lock, flags);
1005
        for (i = 0; i < count; i++) {
1006
                ctx = le32_to_cpu(pRecvRep->BucketContext[i]);
1007
 
1008
                skb = priv->RcvCtl[ctx].skb;
1009
 
1010
//              dlprintk((KERN_INFO MYNAM ": %s: dev_name = %s\n",
1011
//                              IOC_AND_NETDEV_NAMES_s_s(dev)));
1012
//              dlprintk((KERN_INFO MYNAM "@rpr[2], priv = %p, buckets_out addr = %p",
1013
//                              priv, &(priv->buckets_out)));
1014
//              dlprintk((KERN_INFO MYNAM "@rpr[2] TC + 3\n"));
1015
 
1016
                priv->RcvCtl[ctx].skb = NULL;
1017
                pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma,
1018
                                 priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE);
1019
                dev_kfree_skb_any(skb);
1020
 
1021
                priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
1022
        }
1023
        spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
1024
 
1025
        atomic_sub(count, &priv->buckets_out);
1026
 
1027
//      for (i = 0; i < priv->max_buckets_out; i++)
1028
//              if (priv->RcvCtl[i].skb != NULL)
1029
//                      dlprintk((KERN_INFO MYNAM "@rpr: bucket %03x "
1030
//                                "is still out\n", i));
1031
 
1032
/*      dlprintk((KERN_INFO MYNAM "/receive_post_reply: freed %d buckets\n",
1033
                  count));
1034
*/
1035
/**/    dlprintk((KERN_INFO MYNAM "@receive_post_reply: %d buckets "
1036
/**/              "remaining, %d received back since sod.\n",
1037
/**/              atomic_read(&priv->buckets_out), priv->total_received));
1038
        return 0;
1039
}
1040
 
1041
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1042
static int
1043
mpt_lan_receive_post_reply(struct net_device *dev,
1044
                           LANReceivePostReply_t *pRecvRep)
1045
{
1046
        struct mpt_lan_priv *priv = dev->priv;
1047
        MPT_ADAPTER *mpt_dev = priv->mpt_dev;
1048
        struct sk_buff *skb, *old_skb;
1049
        unsigned long flags;
1050
        u32 len, ctx, offset;
1051
        u32 remaining = le32_to_cpu(pRecvRep->BucketsRemaining);
1052
        int count;
1053
        int i, l;
1054
 
1055
        dioprintk((KERN_INFO MYNAM ": mpt_lan_receive_post_reply called\n"));
1056
        dioprintk((KERN_INFO MYNAM ": receive_post_reply: IOCStatus: %04x\n",
1057
                 le16_to_cpu(pRecvRep->IOCStatus)));
1058
 
1059
        if ((le16_to_cpu(pRecvRep->IOCStatus) & MPI_IOCSTATUS_MASK) ==
1060
                                                MPI_IOCSTATUS_LAN_CANCELED)
1061
                return mpt_lan_receive_post_free(dev, pRecvRep);
1062
 
1063
        len = le32_to_cpu(pRecvRep->PacketLength);
1064
        if (len == 0) {
1065
                printk (KERN_ERR MYNAM ": %s/%s: ERROR - Got a non-TURBO "
1066
                        "ReceivePostReply w/ PacketLength zero!\n",
1067
                                IOC_AND_NETDEV_NAMES_s_s(dev));
1068
                printk (KERN_ERR MYNAM ": MsgFlags = %02x, IOCStatus = %04x\n",
1069
                                pRecvRep->MsgFlags, le16_to_cpu(pRecvRep->IOCStatus));
1070
                return -1;
1071
        }
1072
 
1073
        ctx    = le32_to_cpu(pRecvRep->BucketContext[0]);
1074
        count  = pRecvRep->NumberOfContexts;
1075
        skb    = priv->RcvCtl[ctx].skb;
1076
 
1077
        offset = le32_to_cpu(pRecvRep->PacketOffset);
1078
//      if (offset != 0) {
1079
//              printk (KERN_INFO MYNAM ": %s/%s: Got a ReceivePostReply "
1080
//                      "w/ PacketOffset %u\n",
1081
//                              IOC_AND_NETDEV_NAMES_s_s(dev),
1082
//                              offset);
1083
//      }
1084
 
1085
        dioprintk((KERN_INFO MYNAM ": %s/%s: @rpr, offset = %d, len = %d\n",
1086
                        IOC_AND_NETDEV_NAMES_s_s(dev),
1087
                        offset, len));
1088
 
1089
        if (count > 1) {
1090
                int szrem = len;
1091
 
1092
//              dioprintk((KERN_INFO MYNAM ": %s/%s: Multiple buckets returned "
1093
//                      "for single packet, concatenating...\n",
1094
//                              IOC_AND_NETDEV_NAMES_s_s(dev)));
1095
 
1096
                skb = (struct sk_buff *)dev_alloc_skb(len);
1097
                if (!skb) {
1098
                        printk (KERN_ERR MYNAM ": %s/%s: ERROR - Can't allocate skb! (%s@%d)\n",
1099
                                        IOC_AND_NETDEV_NAMES_s_s(dev),
1100
                                        __FILE__, __LINE__);
1101
                        return -ENOMEM;
1102
                }
1103
 
1104
                spin_lock_irqsave(&priv->rxfidx_lock, flags);
1105
                for (i = 0; i < count; i++) {
1106
 
1107
                        ctx = le32_to_cpu(pRecvRep->BucketContext[i]);
1108
                        old_skb = priv->RcvCtl[ctx].skb;
1109
 
1110
                        l = priv->RcvCtl[ctx].len;
1111
                        if (szrem < l)
1112
                                l = szrem;
1113
 
1114
//                      dioprintk((KERN_INFO MYNAM ": %s/%s: Buckets = %d, len = %u\n",
1115
//                                      IOC_AND_NETDEV_NAMES_s_s(dev),
1116
//                                      i, l));
1117
 
1118
                        pci_dma_sync_single(mpt_dev->pcidev,
1119
                                            priv->RcvCtl[ctx].dma,
1120
                                            priv->RcvCtl[ctx].len,
1121
                                            PCI_DMA_FROMDEVICE);
1122
                        memcpy(skb_put(skb, l), old_skb->data, l);
1123
 
1124
                        priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
1125
                        szrem -= l;
1126
                }
1127
                spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
1128
 
1129
        } else if (len < MPT_LAN_RX_COPYBREAK) {
1130
 
1131
                old_skb = skb;
1132
 
1133
                skb = (struct sk_buff *)dev_alloc_skb(len);
1134
                if (!skb) {
1135
                        printk (KERN_ERR MYNAM ": %s/%s: ERROR - Can't allocate skb! (%s@%d)\n",
1136
                                        IOC_AND_NETDEV_NAMES_s_s(dev),
1137
                                        __FILE__, __LINE__);
1138
                        return -ENOMEM;
1139
                }
1140
 
1141
                pci_dma_sync_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma,
1142
                                    priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE);
1143
 
1144
                memcpy(skb_put(skb, len), old_skb->data, len);
1145
 
1146
                spin_lock_irqsave(&priv->rxfidx_lock, flags);
1147
                priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
1148
                spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
1149
 
1150
        } else {
1151
                spin_lock_irqsave(&priv->rxfidx_lock, flags);
1152
 
1153
                priv->RcvCtl[ctx].skb = NULL;
1154
 
1155
                pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma,
1156
                                 priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE);
1157
                priv->RcvCtl[ctx].dma = 0;
1158
 
1159
                priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
1160
                spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
1161
 
1162
                skb_put(skb,len);
1163
        }
1164
 
1165
        atomic_sub(count, &priv->buckets_out);
1166
        priv->total_received += count;
1167
 
1168
        if (priv->mpt_rxfidx_tail >= MPT_LAN_MAX_BUCKETS_OUT) {
1169
                printk (KERN_ERR MYNAM ": %s/%s: Yoohoo! mpt_rxfidx_tail = %d, "
1170
                        "MPT_LAN_MAX_BUCKETS_OUT = %d\n",
1171
                                IOC_AND_NETDEV_NAMES_s_s(dev),
1172
                                priv->mpt_rxfidx_tail,
1173
                                MPT_LAN_MAX_BUCKETS_OUT);
1174
 
1175
                panic("Damn it Jim! I'm a doctor, not a programmer! "
1176
                                "Oh, wait a sec, I am a programmer. "
1177
                                "And, who's Jim?!?!\n"
1178
                                "Arrgghh! We've done it again!\n");
1179
        }
1180
 
1181
        if (remaining == 0)
1182
                printk (KERN_WARNING MYNAM ": %s/%s: WARNING - IOC out of buckets! "
1183
                        "(priv->buckets_out = %d)\n",
1184
                        IOC_AND_NETDEV_NAMES_s_s(dev),
1185
                        atomic_read(&priv->buckets_out));
1186
        else if (remaining < 10)
1187
                printk (KERN_INFO MYNAM ": %s/%s: IOC says %d buckets left. "
1188
                        "(priv->buckets_out = %d)\n",
1189
                        IOC_AND_NETDEV_NAMES_s_s(dev),
1190
                        remaining, atomic_read(&priv->buckets_out));
1191
 
1192
        if ((remaining < priv->bucketthresh) &&
1193
            ((atomic_read(&priv->buckets_out) - remaining) >
1194
             MPT_LAN_BUCKETS_REMAIN_MISMATCH_THRESH)) {
1195
 
1196
                printk (KERN_WARNING MYNAM " Mismatch between driver's "
1197
                        "buckets_out count and fw's BucketsRemaining "
1198
                        "count has crossed the threshold, issuing a "
1199
                        "LanReset to clear the fw's hashtable. You may "
1200
                        "want to check your /var/log/messages for \"CRC "
1201
                        "error\" event notifications.\n");
1202
 
1203
                mpt_lan_reset(dev);
1204
                mpt_lan_wake_post_buckets_task(dev, 0);
1205
        }
1206
 
1207
        return mpt_lan_receive_skb(dev, skb);
1208
}
1209
 
1210
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1211
/* Simple SGE's only at the moment */
1212
 
1213
static void
1214
mpt_lan_post_receive_buckets(void *dev_id)
1215
{
1216
        struct net_device *dev = dev_id;
1217
        struct mpt_lan_priv *priv = dev->priv;
1218
        MPT_ADAPTER *mpt_dev = priv->mpt_dev;
1219
        MPT_FRAME_HDR *mf;
1220
        LANReceivePostRequest_t *pRecvReq;
1221
        SGETransaction32_t *pTrans;
1222
        SGESimple64_t *pSimple;
1223
        struct sk_buff *skb;
1224
        dma_addr_t dma;
1225
        u32 curr, buckets, count, max;
1226
        u32 len = (dev->mtu + dev->hard_header_len + 4);
1227
        unsigned long flags;
1228
        int i;
1229
 
1230
        curr = atomic_read(&priv->buckets_out);
1231
        buckets = (priv->max_buckets_out - curr);
1232
 
1233
        dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, Start_buckets = %u, buckets_out = %u\n",
1234
                        IOC_AND_NETDEV_NAMES_s_s(dev),
1235
                        __FUNCTION__, buckets, curr));
1236
 
1237
        max = (mpt_dev->req_sz - MPT_LAN_RECEIVE_POST_REQUEST_SIZE) /
1238
                        (MPT_LAN_TRANSACTION32_SIZE + sizeof(SGESimple64_t));
1239
 
1240
        while (buckets) {
1241
                mf = mpt_get_msg_frame(LanCtx, mpt_dev->id);
1242
                if (mf == NULL) {
1243
                        printk (KERN_ERR "%s: Unable to alloc request frame\n",
1244
                                __FUNCTION__);
1245
                        dioprintk((KERN_ERR "%s: %u buckets remaining\n",
1246
                                 __FUNCTION__, buckets));
1247
                        goto out;
1248
                }
1249
                pRecvReq = (LANReceivePostRequest_t *) mf;
1250
 
1251
                count = buckets;
1252
                if (count > max)
1253
                        count = max;
1254
 
1255
                pRecvReq->Function    = MPI_FUNCTION_LAN_RECEIVE;
1256
                pRecvReq->ChainOffset = 0;
1257
                pRecvReq->MsgFlags    = 0;
1258
                pRecvReq->PortNumber  = priv->pnum;
1259
 
1260
                pTrans = (SGETransaction32_t *) pRecvReq->SG_List;
1261
                pSimple = NULL;
1262
 
1263
                for (i = 0; i < count; i++) {
1264
                        int ctx;
1265
 
1266
                        spin_lock_irqsave(&priv->rxfidx_lock, flags);
1267
                        if (priv->mpt_rxfidx_tail < 0) {
1268
                                printk (KERN_ERR "%s: Can't alloc context\n",
1269
                                        __FUNCTION__);
1270
                                spin_unlock_irqrestore(&priv->rxfidx_lock,
1271
                                                       flags);
1272
                                break;
1273
                        }
1274
 
1275
                        ctx = priv->mpt_rxfidx[priv->mpt_rxfidx_tail--];
1276
 
1277
                        skb = priv->RcvCtl[ctx].skb;
1278
                        if (skb && (priv->RcvCtl[ctx].len != len)) {
1279
                                pci_unmap_single(mpt_dev->pcidev,
1280
                                                 priv->RcvCtl[ctx].dma,
1281
                                                 priv->RcvCtl[ctx].len,
1282
                                                 PCI_DMA_FROMDEVICE);
1283
                                dev_kfree_skb(priv->RcvCtl[ctx].skb);
1284
                                skb = priv->RcvCtl[ctx].skb = NULL;
1285
                        }
1286
 
1287
                        if (skb == NULL) {
1288
                                skb = dev_alloc_skb(len);
1289
                                if (skb == NULL) {
1290
                                        printk (KERN_WARNING
1291
                                                MYNAM "/%s: Can't alloc skb\n",
1292
                                                __FUNCTION__);
1293
                                        priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
1294
                                        spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
1295
                                        break;
1296
                                }
1297
 
1298
                                dma = pci_map_single(mpt_dev->pcidev, skb->data,
1299
                                                     len, PCI_DMA_FROMDEVICE);
1300
 
1301
                                priv->RcvCtl[ctx].skb = skb;
1302
                                priv->RcvCtl[ctx].dma = dma;
1303
                                priv->RcvCtl[ctx].len = len;
1304
                        }
1305
 
1306
                        spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
1307
 
1308
                        pTrans->ContextSize   = sizeof(u32);
1309
                        pTrans->DetailsLength = 0;
1310
                        pTrans->Flags         = 0;
1311
                        pTrans->TransactionContext[0] = cpu_to_le32(ctx);
1312
 
1313
                        pSimple = (SGESimple64_t *) pTrans->TransactionDetails;
1314
 
1315
                        pSimple->FlagsLength = cpu_to_le32(
1316
                                ((MPI_SGE_FLAGS_END_OF_BUFFER |
1317
                                  MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1318
                                  MPI_SGE_FLAGS_64_BIT_ADDRESSING) << MPI_SGE_FLAGS_SHIFT) | len);
1319
                        pSimple->Address.Low = cpu_to_le32((u32) priv->RcvCtl[ctx].dma);
1320
                        if (sizeof(dma_addr_t) > sizeof(u32))
1321
                                pSimple->Address.High = cpu_to_le32((u32) ((u64) priv->RcvCtl[ctx].dma >> 32));
1322
                        else
1323
                                pSimple->Address.High = 0;
1324
 
1325
                        pTrans = (SGETransaction32_t *) (pSimple + 1);
1326
                }
1327
 
1328
                if (pSimple == NULL) {
1329
/**/                    printk (KERN_WARNING MYNAM "/%s: No buckets posted\n",
1330
/**/                            __FUNCTION__);
1331
                        mpt_free_msg_frame(LanCtx, mpt_dev->id, mf);
1332
                        goto out;
1333
                }
1334
 
1335
                pSimple->FlagsLength |= cpu_to_le32(MPI_SGE_FLAGS_END_OF_LIST << MPI_SGE_FLAGS_SHIFT);
1336
 
1337
                pRecvReq->BucketCount = cpu_to_le32(i);
1338
 
1339
/*      printk(KERN_INFO MYNAM ": posting buckets\n   ");
1340
 *      for (i = 0; i < j + 2; i ++)
1341
 *          printk (" %08x", le32_to_cpu(msg[i]));
1342
 *      printk ("\n");
1343
 */
1344
 
1345
                mpt_put_msg_frame(LanCtx, mpt_dev->id, mf);
1346
 
1347
                priv->total_posted += i;
1348
                buckets -= i;
1349
                atomic_add(i, &priv->buckets_out);
1350
        }
1351
 
1352
out:
1353
        dioprintk((KERN_INFO MYNAM "/%s: End_buckets = %u, priv->buckets_out = %u\n",
1354
                  __FUNCTION__, buckets, atomic_read(&priv->buckets_out)));
1355
        dioprintk((KERN_INFO MYNAM "/%s: Posted %u buckets and received %u back\n",
1356
        __FUNCTION__, priv->total_posted, priv->total_received));
1357
 
1358
        clear_bit(0, &priv->post_buckets_active);
1359
}
1360
 
1361
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1362
struct net_device *
1363
mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
1364
{
1365
        struct net_device *dev = NULL;
1366
        struct mpt_lan_priv *priv = NULL;
1367
        u8 HWaddr[FC_ALEN], *a;
1368
 
1369
        dev = init_fcdev(NULL, sizeof(struct mpt_lan_priv));
1370
        if (!dev)
1371
                return (NULL);
1372
        dev->mtu = MPT_LAN_MTU;
1373
 
1374
        priv = (struct mpt_lan_priv *) dev->priv;
1375
 
1376
        priv->mpt_dev = mpt_dev;
1377
        priv->pnum = pnum;
1378
 
1379
        memset(&priv->post_buckets_task, 0, sizeof(struct mpt_work_struct));
1380
        MPT_INIT_WORK(&priv->post_buckets_task, mpt_lan_post_receive_buckets, dev);
1381
        priv->post_buckets_active = 0;
1382
 
1383
        dlprintk((KERN_INFO MYNAM "@%d: bucketlen = %d\n",
1384
                        __LINE__, dev->mtu + dev->hard_header_len + 4));
1385
 
1386
        atomic_set(&priv->buckets_out, 0);
1387
        priv->total_posted = 0;
1388
        priv->total_received = 0;
1389
        priv->max_buckets_out = max_buckets_out;
1390
        if (mpt_dev->pfacts[0].MaxLanBuckets < max_buckets_out)
1391
                priv->max_buckets_out = mpt_dev->pfacts[0].MaxLanBuckets;
1392
 
1393
        dlprintk((KERN_INFO MYNAM "@%d: MaxLanBuckets=%d, max_buckets_out/priv=%d/%d\n",
1394
                        __LINE__,
1395
                        mpt_dev->pfacts[0].MaxLanBuckets,
1396
                        max_buckets_out,
1397
                        priv->max_buckets_out));
1398
 
1399
        priv->bucketthresh = priv->max_buckets_out * 2 / 3;
1400
        priv->txfidx_lock = SPIN_LOCK_UNLOCKED;
1401
        priv->rxfidx_lock = SPIN_LOCK_UNLOCKED;
1402
 
1403
        memset(&priv->stats, 0, sizeof(priv->stats));
1404
 
1405
        /*  Grab pre-fetched LANPage1 stuff. :-) */
1406
        a = (u8 *) &mpt_dev->lan_cnfg_page1.HardwareAddressLow;
1407
 
1408
        HWaddr[0] = a[5];
1409
        HWaddr[1] = a[4];
1410
        HWaddr[2] = a[3];
1411
        HWaddr[3] = a[2];
1412
        HWaddr[4] = a[1];
1413
        HWaddr[5] = a[0];
1414
 
1415
        dev->addr_len = FC_ALEN;
1416
        memcpy(dev->dev_addr, HWaddr, FC_ALEN);
1417
        memset(dev->broadcast, 0xff, FC_ALEN);
1418
 
1419
        /* The Tx queue is 127 deep on the 909.
1420
         * Give ourselves some breathing room.
1421
         */
1422
        priv->tx_max_out = (tx_max_out_p <= MPT_TX_MAX_OUT_LIM) ?
1423
                            tx_max_out_p : MPT_TX_MAX_OUT_LIM;
1424
 
1425
        dev->open = mpt_lan_open;
1426
        dev->stop = mpt_lan_close;
1427
        dev->get_stats = mpt_lan_get_stats;
1428
        dev->set_multicast_list = NULL;
1429
        dev->change_mtu = mpt_lan_change_mtu;
1430
        dev->hard_start_xmit = mpt_lan_sdu_send;
1431
 
1432
/* Not in 2.3.42. Need 2.3.45+ */
1433
        dev->tx_timeout = mpt_lan_tx_timeout;
1434
        dev->watchdog_timeo = MPT_LAN_TX_TIMEOUT;
1435
 
1436
        dlprintk((KERN_INFO MYNAM ": Finished registering dev "
1437
                "and setting initial values\n"));
1438
 
1439
        SET_MODULE_OWNER(dev);
1440
 
1441
        return dev;
1442
}
1443
 
1444
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1445
int __init
1446
mpt_lan_init (void)
1447
{
1448
        struct net_device *dev;
1449
        MPT_ADAPTER *curadapter;
1450
        int i, j;
1451
 
1452
        show_mptmod_ver(LANAME, LANVER);
1453
 
1454
#ifdef QLOGIC_NAA_WORKAROUND
1455
        /* Init the global r/w lock for the bad_naa list. We want to do this
1456
           before any boards are initialized and may be used. */
1457
        rwlock_init(&bad_naa_lock);
1458
#endif
1459
 
1460
        if ((LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER)) <= 0) {
1461
                printk (KERN_ERR MYNAM ": Failed to register with MPT base driver\n");
1462
                return -EBUSY;
1463
        }
1464
 
1465
        /* Set the callback index to be used by driver core for turbo replies */
1466
        mpt_lan_index = LanCtx;
1467
 
1468
        dlprintk((KERN_INFO MYNAM ": assigned context of %d\n", LanCtx));
1469
 
1470
        if (mpt_reset_register(LanCtx, mpt_lan_ioc_reset) == 0) {
1471
                dlprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
1472
        } else {
1473
                printk(KERN_ERR MYNAM ": Eieee! unable to register a reset "
1474
                       "handler with mptbase! The world is at an end! "
1475
                       "Everything is fading to black! Goodbye.\n");
1476
                return -EBUSY;
1477
        }
1478
 
1479
        for (j = 0; j < MPT_MAX_ADAPTERS; j++) {
1480
                mpt_landev[j] = NULL;
1481
        }
1482
 
1483
        curadapter = mpt_adapter_find_first();
1484
        while (curadapter != NULL) {
1485
                for (i = 0; i < curadapter->facts.NumberOfPorts; i++) {
1486
                        printk (KERN_INFO MYNAM ": %s: PortNum=%x, ProtocolFlags=%02Xh (%c%c%c%c)\n",
1487
                                        curadapter->name,
1488
                                        curadapter->pfacts[i].PortNumber,
1489
                                        curadapter->pfacts[i].ProtocolFlags,
1490
                                        MPT_PROTOCOL_FLAGS_c_c_c_c(curadapter->pfacts[i].ProtocolFlags));
1491
 
1492
                        if (curadapter->pfacts[i].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
1493
                                dev = mpt_register_lan_device (curadapter, i);
1494
                                if (dev != NULL) {
1495
                                        printk (KERN_INFO MYNAM ": %s: Fusion MPT LAN device registered as '%s'\n",
1496
                                                        curadapter->name, dev->name);
1497
                                        printk (KERN_INFO MYNAM ": %s/%s: LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1498
                                                        IOC_AND_NETDEV_NAMES_s_s(dev),
1499
                                                        dev->dev_addr[0], dev->dev_addr[1],
1500
                                                        dev->dev_addr[2], dev->dev_addr[3],
1501
                                                        dev->dev_addr[4], dev->dev_addr[5]);
1502
//                                      printk (KERN_INFO MYNAM ": %s/%s: Max_TX_outstanding = %d\n",
1503
//                                                      IOC_AND_NETDEV_NAMES_s_s(dev),
1504
//                                                      NETDEV_TO_LANPRIV_PTR(dev)->tx_max_out);
1505
                                        j = curadapter->id;
1506
                                        mpt_landev[j] = dev;
1507
                                        dlprintk((KERN_INFO MYNAM "/init: dev_addr=%p, mpt_landev[%d]=%p\n",
1508
                                                        dev, j,  mpt_landev[j]));
1509
 
1510
                                } else {
1511
                                        printk (KERN_ERR MYNAM ": %s: Unable to register port%d as a LAN device\n",
1512
                                                        curadapter->name,
1513
                                                        curadapter->pfacts[i].PortNumber);
1514
                                }
1515
                        } else {
1516
                                printk (KERN_INFO MYNAM ": %s: Hmmm... LAN protocol seems to be disabled on this adapter port!\n",
1517
                                                curadapter->name);
1518
                        }
1519
                }
1520
                curadapter = mpt_adapter_find_next(curadapter);
1521
        }
1522
 
1523
        return 0;
1524
}
1525
 
1526
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1527
static void mpt_lan_exit(void)
1528
{
1529
        int i;
1530
 
1531
        mpt_reset_deregister(LanCtx);
1532
 
1533
        for (i = 0; mpt_landev[i] != NULL; i++) {
1534
                struct net_device *dev = mpt_landev[i];
1535
 
1536
                printk (KERN_INFO ": %s/%s: Fusion MPT LAN device unregistered\n",
1537
                               IOC_AND_NETDEV_NAMES_s_s(dev));
1538
                unregister_fcdev(dev);
1539
                //mpt_landev[i] = (struct net_device *) 0xdeadbeef; /* Debug */
1540
                mpt_landev[i] = NULL;
1541
        }
1542
 
1543
        if (LanCtx >= 0) {
1544
                mpt_deregister(LanCtx);
1545
                LanCtx = -1;
1546
                mpt_lan_index = 0;
1547
        }
1548
 
1549
        /* deregister any send/receive handler structs. I2Oism? */
1550
}
1551
 
1552
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1553
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,59)
1554
MODULE_PARM(tx_max_out_p, "i");
1555
MODULE_PARM(max_buckets_out, "i"); // Debug stuff. FIXME!
1556
#endif
1557
 
1558
module_init(mpt_lan_init);
1559
module_exit(mpt_lan_exit);
1560
 
1561
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1562
static unsigned short
1563
mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev)
1564
{
1565
        struct mpt_lan_ohdr *fch = (struct mpt_lan_ohdr *)skb->data;
1566
        struct fcllc *fcllc;
1567
 
1568
        skb->mac.raw = skb->data;
1569
        skb_pull(skb, sizeof(struct mpt_lan_ohdr));
1570
 
1571
        if (fch->dtype == htons(0xffff)) {
1572
                u32 *p = (u32 *) fch;
1573
 
1574
                swab32s(p + 0);
1575
                swab32s(p + 1);
1576
                swab32s(p + 2);
1577
                swab32s(p + 3);
1578
 
1579
                printk (KERN_WARNING MYNAM ": %s: WARNING - Broadcast swap F/W bug detected!\n",
1580
                                NETDEV_PTR_TO_IOC_NAME_s(dev));
1581
                printk (KERN_WARNING MYNAM ": Please update sender @ MAC_addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
1582
                                fch->saddr[0], fch->saddr[1], fch->saddr[2],
1583
                                fch->saddr[3], fch->saddr[4], fch->saddr[5]);
1584
        }
1585
 
1586
        if (*fch->daddr & 1) {
1587
                if (!memcmp(fch->daddr, dev->broadcast, FC_ALEN)) {
1588
                        skb->pkt_type = PACKET_BROADCAST;
1589
                } else {
1590
                        skb->pkt_type = PACKET_MULTICAST;
1591
                }
1592
        } else {
1593
                if (memcmp(fch->daddr, dev->dev_addr, FC_ALEN)) {
1594
                        skb->pkt_type = PACKET_OTHERHOST;
1595
                } else {
1596
                        skb->pkt_type = PACKET_HOST;
1597
                }
1598
        }
1599
 
1600
        fcllc = (struct fcllc *)skb->data;
1601
 
1602
#ifdef QLOGIC_NAA_WORKAROUND
1603
{
1604
        u16 source_naa = fch->stype, found = 0;
1605
 
1606
        /* Workaround for QLogic not following RFC 2625 in regards to the NAA
1607
           value. */
1608
 
1609
        if ((source_naa & 0xF000) == 0)
1610
                source_naa = swab16(source_naa);
1611
 
1612
        if (fcllc->ethertype == htons(ETH_P_ARP))
1613
            dlprintk ((KERN_INFO "mptlan/type_trans: got arp req/rep w/ naa of "
1614
                      "%04x.\n", source_naa));
1615
 
1616
        if ((fcllc->ethertype == htons(ETH_P_ARP)) &&
1617
           ((source_naa >> 12) !=  MPT_LAN_NAA_RFC2625)){
1618
                struct NAA_Hosed *nh, *prevnh;
1619
                int i;
1620
 
1621
                dlprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep from "
1622
                          "system with non-RFC 2625 NAA value (%04x).\n",
1623
                          source_naa));
1624
 
1625
                write_lock_irq(&bad_naa_lock);
1626
                for (prevnh = nh = mpt_bad_naa; nh != NULL;
1627
                     prevnh=nh, nh=nh->next) {
1628
                        if ((nh->ieee[0] == fch->saddr[0]) &&
1629
                            (nh->ieee[1] == fch->saddr[1]) &&
1630
                            (nh->ieee[2] == fch->saddr[2]) &&
1631
                            (nh->ieee[3] == fch->saddr[3]) &&
1632
                            (nh->ieee[4] == fch->saddr[4]) &&
1633
                            (nh->ieee[5] == fch->saddr[5])) {
1634
                                found = 1;
1635
                                dlprintk ((KERN_INFO "mptlan/type_trans: ARP Re"
1636
                                         "q/Rep w/ bad NAA from system already"
1637
                                         " in DB.\n"));
1638
                                break;
1639
                        }
1640
                }
1641
 
1642
                if ((!found) && (nh == NULL)) {
1643
 
1644
                        nh = kmalloc(sizeof(struct NAA_Hosed), GFP_KERNEL);
1645
                        dlprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep w/"
1646
                                 " bad NAA from system not yet in DB.\n"));
1647
 
1648
                        if (nh != NULL) {
1649
                                nh->next = NULL;
1650
                                if (!mpt_bad_naa)
1651
                                        mpt_bad_naa = nh;
1652
                                if (prevnh)
1653
                                        prevnh->next = nh;
1654
 
1655
                                nh->NAA = source_naa; /* Set the S_NAA value. */
1656
                                for (i = 0; i < FC_ALEN; i++)
1657
                                        nh->ieee[i] = fch->saddr[i];
1658
                                dlprintk ((KERN_INFO "Got ARP from %02x:%02x:%02x:%02x:"
1659
                                          "%02x:%02x with non-compliant S_NAA value.\n",
1660
                                          fch->saddr[0], fch->saddr[1], fch->saddr[2],
1661
                                          fch->saddr[3], fch->saddr[4],fch->saddr[5]));
1662
                        } else {
1663
                                printk (KERN_ERR "mptlan/type_trans: Unable to"
1664
                                        " kmalloc a NAA_Hosed struct.\n");
1665
                        }
1666
                } else if (!found) {
1667
                        printk (KERN_ERR "mptlan/type_trans: found not"
1668
                                " set, but nh isn't null. Evil "
1669
                                "funkiness abounds.\n");
1670
                }
1671
                write_unlock_irq(&bad_naa_lock);
1672
        }
1673
}
1674
#endif
1675
 
1676
        /* Strip the SNAP header from ARP packets since we don't
1677
         * pass them through to the 802.2/SNAP layers.
1678
         */
1679
        if (fcllc->dsap == EXTENDED_SAP &&
1680
                (fcllc->ethertype == htons(ETH_P_IP) ||
1681
                 fcllc->ethertype == htons(ETH_P_ARP))) {
1682
                skb_pull(skb, sizeof(struct fcllc));
1683
                return fcllc->ethertype;
1684
        }
1685
 
1686
        return htons(ETH_P_802_2);
1687
}
1688
 
1689
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.