import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.git] / drivers / message / fusion / mptlan.c
1 /*
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 2005/04/11 02:50:25 jack 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 it's 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_PRE_RESET ? "pre" : "post"));
343
344         if (priv->mpt_rxfidx == NULL)
345                 return (1);
346
347         if (reset_phase == MPT_IOC_PRE_RESET) {
348                 int i;
349                 unsigned long flags;
350
351                 netif_stop_queue(dev);
352
353                 dlprintk ((KERN_INFO "mptlan/ioc_reset: called netif_stop_queue for %s.\n", dev->name));
354
355                 atomic_set(&priv->buckets_out, 0);
356
357                 /* Reset Rx Free Tail index and re-populate the queue. */
358                 spin_lock_irqsave(&priv->rxfidx_lock, flags);
359                 priv->mpt_rxfidx_tail = -1;
360                 for (i = 0; i < priv->max_buckets_out; i++)
361                         priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i;
362                 spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
363         } else {
364                 mpt_lan_post_receive_buckets(dev);
365                 netif_wake_queue(dev);
366         }
367
368         return 1;
369 }
370
371 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
372 static int
373 mpt_lan_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
374 {
375         dlprintk((KERN_INFO MYNAM ": MPT event routed to LAN driver!\n"));
376
377         switch (le32_to_cpu(pEvReply->Event)) {
378         case MPI_EVENT_NONE:                            /* 00 */
379         case MPI_EVENT_LOG_DATA:                        /* 01 */
380         case MPI_EVENT_STATE_CHANGE:                    /* 02 */
381         case MPI_EVENT_UNIT_ATTENTION:                  /* 03 */
382         case MPI_EVENT_IOC_BUS_RESET:                   /* 04 */
383         case MPI_EVENT_EXT_BUS_RESET:                   /* 05 */
384         case MPI_EVENT_RESCAN:                          /* 06 */
385                 /* Ok, do we need to do anything here? As far as
386                    I can tell, this is when a new device gets added
387                    to the loop. */
388         case MPI_EVENT_LINK_STATUS_CHANGE:              /* 07 */
389         case MPI_EVENT_LOOP_STATE_CHANGE:               /* 08 */
390         case MPI_EVENT_LOGOUT:                          /* 09 */
391         case MPI_EVENT_EVENT_CHANGE:                    /* 0A */
392         default:
393                 break;
394         }
395
396         /*
397          *  NOTE: pEvent->AckRequired handling now done in mptbase.c;
398          *  Do NOT do it here now!
399          */
400
401         return 1;
402 }
403
404 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
405 static int
406 mpt_lan_open(struct net_device *dev)
407 {
408         struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
409         int i;
410
411         if (mpt_lan_reset(dev) != 0) {
412                 MPT_ADAPTER *mpt_dev = priv->mpt_dev;
413
414                 printk (KERN_WARNING MYNAM "/lan_open: lan_reset failed.");
415
416                 if (mpt_dev->active)
417                         printk ("The ioc is active. Perhaps it needs to be"
418                                 " reset?\n");
419                 else
420                         printk ("The ioc in inactive, most likely in the "
421                                 "process of being reset. Please try again in "
422                                 "a moment.\n");
423         }
424
425         priv->mpt_txfidx = kmalloc(priv->tx_max_out * sizeof(int), GFP_KERNEL);
426         if (priv->mpt_txfidx == NULL)
427                 goto out;
428         priv->mpt_txfidx_tail = -1;
429
430         priv->SendCtl = kmalloc(priv->tx_max_out * sizeof(struct BufferControl),
431                                 GFP_KERNEL);
432         if (priv->SendCtl == NULL)
433                 goto out_mpt_txfidx;
434         for (i = 0; i < priv->tx_max_out; i++) {
435                 memset(&priv->SendCtl[i], 0, sizeof(struct BufferControl));
436                 priv->mpt_txfidx[++priv->mpt_txfidx_tail] = i;
437         }
438
439         dlprintk((KERN_INFO MYNAM "@lo: Finished initializing SendCtl\n"));
440
441         priv->mpt_rxfidx = kmalloc(priv->max_buckets_out * sizeof(int),
442                                    GFP_KERNEL);
443         if (priv->mpt_rxfidx == NULL)
444                 goto out_SendCtl;
445         priv->mpt_rxfidx_tail = -1;
446
447         priv->RcvCtl = kmalloc(priv->max_buckets_out *
448                                                 sizeof(struct BufferControl),
449                                GFP_KERNEL);
450         if (priv->RcvCtl == NULL)
451                 goto out_mpt_rxfidx;
452         for (i = 0; i < priv->max_buckets_out; i++) {
453                 memset(&priv->RcvCtl[i], 0, sizeof(struct BufferControl));
454                 priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = i;
455         }
456
457 /**/    dlprintk((KERN_INFO MYNAM "/lo: txfidx contains - "));
458 /**/    for (i = 0; i < priv->tx_max_out; i++)
459 /**/            dlprintk((" %xh", priv->mpt_txfidx[i]));
460 /**/    dlprintk(("\n"));
461
462         dlprintk((KERN_INFO MYNAM "/lo: Finished initializing RcvCtl\n"));
463
464         mpt_lan_post_receive_buckets(dev);
465         printk(KERN_INFO MYNAM ": %s/%s: interface up & active\n",
466                         IOC_AND_NETDEV_NAMES_s_s(dev));
467
468         if (mpt_event_register(LanCtx, mpt_lan_event_process) != 0) {
469                 printk (KERN_WARNING MYNAM "/lo: Unable to register for Event"
470                         " Notifications. This is a bad thing! We're not going "
471                         "to go ahead, but I'd be leery of system stability at "
472                         "this point.\n");
473         }
474
475         netif_start_queue(dev);
476         dlprintk((KERN_INFO MYNAM "/lo: Done.\n"));
477
478         return 0;
479 out_mpt_rxfidx:
480         kfree(priv->mpt_rxfidx);
481         priv->mpt_rxfidx = NULL;
482 out_SendCtl:
483         kfree(priv->SendCtl);
484         priv->SendCtl = NULL;
485 out_mpt_txfidx:
486         kfree(priv->mpt_txfidx);
487         priv->mpt_txfidx = NULL;
488 out:    return -ENOMEM;
489 }
490
491 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
492 /* Send a LanReset message to the FW. This should result in the FW returning
493    any buckets it still has. */
494 static int
495 mpt_lan_reset(struct net_device *dev)
496 {
497         MPT_FRAME_HDR *mf;
498         LANResetRequest_t *pResetReq;
499         struct mpt_lan_priv *priv = (struct mpt_lan_priv *)dev->priv;
500
501         mf = mpt_get_msg_frame(LanCtx, priv->mpt_dev->id);
502
503         if (mf == NULL) {
504 /*              dlprintk((KERN_ERR MYNAM "/reset: Evil funkiness abounds! "
505                 "Unable to allocate a request frame.\n"));
506 */
507                 return -1;
508         }
509
510         pResetReq = (LANResetRequest_t *) mf;
511
512         pResetReq->Function     = MPI_FUNCTION_LAN_RESET;
513         pResetReq->ChainOffset  = 0;
514         pResetReq->Reserved     = 0;
515         pResetReq->PortNumber   = priv->pnum;
516         pResetReq->MsgFlags     = 0;
517         pResetReq->Reserved2    = 0;
518
519         mpt_put_msg_frame(LanCtx, priv->mpt_dev->id, mf);
520
521         return 0;
522 }
523
524 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
525 static int
526 mpt_lan_close(struct net_device *dev)
527 {
528         struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
529         MPT_ADAPTER *mpt_dev = priv->mpt_dev;
530         unsigned int timeout;
531         int i;
532
533         dlprintk((KERN_INFO MYNAM ": mpt_lan_close called\n"));
534
535         mpt_event_deregister(LanCtx);
536
537         dlprintk((KERN_INFO MYNAM ":lan_close: Posted %d buckets "
538                   "since driver was loaded, %d still out\n",
539                   priv->total_posted,atomic_read(&priv->buckets_out)));
540
541         netif_stop_queue(dev);
542
543         mpt_lan_reset(dev);
544
545         timeout = 2 * HZ;
546         while (atomic_read(&priv->buckets_out) && --timeout) {
547                 set_current_state(TASK_INTERRUPTIBLE);
548                 schedule_timeout(1);
549         }
550
551         for (i = 0; i < priv->max_buckets_out; i++) {
552                 if (priv->RcvCtl[i].skb != NULL) {
553 /**/                    dlprintk((KERN_INFO MYNAM "/lan_close: bucket %05x "
554 /**/                              "is still out\n", i));
555                         pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[i].dma,
556                                          priv->RcvCtl[i].len,
557                                          PCI_DMA_FROMDEVICE);
558                         dev_kfree_skb(priv->RcvCtl[i].skb);
559                 }
560         }
561
562         kfree (priv->RcvCtl);
563         kfree (priv->mpt_rxfidx);
564
565         for (i = 0; i < priv->tx_max_out; i++) {
566                 if (priv->SendCtl[i].skb != NULL) {
567                         pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[i].dma,
568                                          priv->SendCtl[i].len,
569                                          PCI_DMA_TODEVICE);
570                         dev_kfree_skb(priv->SendCtl[i].skb);
571                 }
572         }
573
574         kfree(priv->SendCtl);
575         kfree(priv->mpt_txfidx);
576
577         atomic_set(&priv->buckets_out, 0);
578
579         printk(KERN_INFO MYNAM ": %s/%s: interface down & inactive\n",
580                         IOC_AND_NETDEV_NAMES_s_s(dev));
581
582         return 0;
583 }
584
585 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
586 static struct net_device_stats *
587 mpt_lan_get_stats(struct net_device *dev)
588 {
589         struct mpt_lan_priv *priv = (struct mpt_lan_priv *)dev->priv;
590
591         return (struct net_device_stats *) &priv->stats;
592 }
593
594 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
595 static int
596 mpt_lan_change_mtu(struct net_device *dev, int new_mtu)
597 {
598         if ((new_mtu < MPT_LAN_MIN_MTU) || (new_mtu > MPT_LAN_MAX_MTU))
599                 return -EINVAL;
600         dev->mtu = new_mtu;
601         return 0;
602 }
603
604 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
605 /* Tx timeout handler. */
606 static void
607 mpt_lan_tx_timeout(struct net_device *dev)
608 {
609         struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
610         MPT_ADAPTER *mpt_dev = priv->mpt_dev;
611
612         if (mpt_dev->active) {
613                 dlprintk (("mptlan/tx_timeout: calling netif_wake_queue for %s.\n", dev->name));
614                 netif_wake_queue(dev);
615         }
616 }
617
618 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
619 //static inline int
620 static int
621 mpt_lan_send_turbo(struct net_device *dev, u32 tmsg)
622 {
623         struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
624         MPT_ADAPTER *mpt_dev = priv->mpt_dev;
625         struct sk_buff *sent;
626         unsigned long flags;
627         u32 ctx;
628
629         ctx = GET_LAN_BUFFER_CONTEXT(tmsg);
630         sent = priv->SendCtl[ctx].skb;
631
632         priv->stats.tx_packets++;
633         priv->stats.tx_bytes += sent->len;
634
635         dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, skb %p sent.\n",
636                         IOC_AND_NETDEV_NAMES_s_s(dev),
637                         __FUNCTION__, sent));
638
639         priv->SendCtl[ctx].skb = NULL;
640         pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[ctx].dma,
641                          priv->SendCtl[ctx].len, PCI_DMA_TODEVICE);
642         dev_kfree_skb_irq(sent);
643
644         spin_lock_irqsave(&priv->txfidx_lock, flags);
645         priv->mpt_txfidx[++priv->mpt_txfidx_tail] = ctx;
646         spin_unlock_irqrestore(&priv->txfidx_lock, flags);
647
648         netif_wake_queue(dev);
649         return 0;
650 }
651
652 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
653 static int
654 mpt_lan_send_reply(struct net_device *dev, LANSendReply_t *pSendRep)
655 {
656         struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
657         MPT_ADAPTER *mpt_dev = priv->mpt_dev;
658         struct sk_buff *sent;
659         unsigned long flags;
660         int FreeReqFrame = 0;
661         u32 *pContext;
662         u32 ctx;
663         u8 count;
664
665         count = pSendRep->NumberOfContexts;
666
667         dioprintk((KERN_INFO MYNAM ": send_reply: IOCStatus: %04x\n",
668                  le16_to_cpu(pSendRep->IOCStatus)));
669
670         /* Add check for Loginfo Flag in IOCStatus */
671
672         switch (le16_to_cpu(pSendRep->IOCStatus) & MPI_IOCSTATUS_MASK) {
673         case MPI_IOCSTATUS_SUCCESS:
674                 priv->stats.tx_packets += count;
675                 break;
676
677         case MPI_IOCSTATUS_LAN_CANCELED:
678         case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED:
679                 break;
680
681         case MPI_IOCSTATUS_INVALID_SGL:
682                 priv->stats.tx_errors += count;
683                 printk (KERN_ERR MYNAM ": %s/%s: ERROR - Invalid SGL sent to IOC!\n",
684                                 IOC_AND_NETDEV_NAMES_s_s(dev));
685                 goto out;
686
687         default:
688                 priv->stats.tx_errors += count;
689                 break;
690         }
691
692         pContext = &pSendRep->BufferContext;
693
694         spin_lock_irqsave(&priv->txfidx_lock, flags);
695         while (count > 0) {
696                 ctx = GET_LAN_BUFFER_CONTEXT(le32_to_cpu(*pContext));
697
698                 sent = priv->SendCtl[ctx].skb;
699                 priv->stats.tx_bytes += sent->len;
700
701                 dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, skb %p sent.\n",
702                                 IOC_AND_NETDEV_NAMES_s_s(dev),
703                                 __FUNCTION__, sent));
704
705                 priv->SendCtl[ctx].skb = NULL;
706                 pci_unmap_single(mpt_dev->pcidev, priv->SendCtl[ctx].dma,
707                                  priv->SendCtl[ctx].len, PCI_DMA_TODEVICE);
708                 dev_kfree_skb_irq(sent);
709
710                 priv->mpt_txfidx[++priv->mpt_txfidx_tail] = ctx;
711
712                 pContext++;
713                 count--;
714         }
715         spin_unlock_irqrestore(&priv->txfidx_lock, flags);
716
717 out:
718         if (!(pSendRep->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY))
719                 FreeReqFrame = 1;
720
721         netif_wake_queue(dev);
722         return FreeReqFrame;
723 }
724
725 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
726 static int
727 mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
728 {
729         struct mpt_lan_priv *priv = (struct mpt_lan_priv *) dev->priv;
730         MPT_ADAPTER *mpt_dev = priv->mpt_dev;
731         MPT_FRAME_HDR *mf;
732         LANSendRequest_t *pSendReq;
733         SGETransaction32_t *pTrans;
734         SGESimple64_t *pSimple;
735         dma_addr_t dma;
736         unsigned long flags;
737         int ctx;
738         u16 cur_naa = 0x1000;
739
740         dioprintk((KERN_INFO MYNAM ": %s called, skb_addr = %p\n",
741                         __FUNCTION__, skb));
742
743         spin_lock_irqsave(&priv->txfidx_lock, flags);
744         if (priv->mpt_txfidx_tail < 0) {
745                 netif_stop_queue(dev);
746                 spin_unlock_irqrestore(&priv->txfidx_lock, flags);
747
748                 printk (KERN_ERR "%s: no tx context available: %u\n",
749                         __FUNCTION__, priv->mpt_txfidx_tail);
750                 return 1;
751         }
752
753         mf = mpt_get_msg_frame(LanCtx, mpt_dev->id);
754         if (mf == NULL) {
755                 netif_stop_queue(dev);
756                 spin_unlock_irqrestore(&priv->txfidx_lock, flags);
757
758                 printk (KERN_ERR "%s: Unable to alloc request frame\n",
759                         __FUNCTION__);
760                 return 1;
761         }
762
763         ctx = priv->mpt_txfidx[priv->mpt_txfidx_tail--];
764         spin_unlock_irqrestore(&priv->txfidx_lock, flags);
765
766 //      dioprintk((KERN_INFO MYNAM ": %s/%s: Creating new msg frame (send).\n",
767 //                      IOC_AND_NETDEV_NAMES_s_s(dev)));
768
769         pSendReq = (LANSendRequest_t *) mf;
770
771         /* Set the mac.raw pointer, since this apparently isn't getting
772          * done before we get the skb. Pull the data pointer past the mac data.
773          */
774         skb->mac.raw = skb->data;
775         skb_pull(skb, 12);
776
777         dma = pci_map_single(mpt_dev->pcidev, skb->data, skb->len,
778                              PCI_DMA_TODEVICE);
779
780         priv->SendCtl[ctx].skb = skb;
781         priv->SendCtl[ctx].dma = dma;
782         priv->SendCtl[ctx].len = skb->len;
783
784         /* Message Header */
785         pSendReq->Reserved    = 0;
786         pSendReq->Function    = MPI_FUNCTION_LAN_SEND;
787         pSendReq->ChainOffset = 0;
788         pSendReq->Reserved2   = 0;
789         pSendReq->MsgFlags    = 0;
790         pSendReq->PortNumber  = priv->pnum;
791
792         /* Transaction Context Element */
793         pTrans = (SGETransaction32_t *) pSendReq->SG_List;
794
795         /* No Flags, 8 bytes of Details, 32bit Context (bloody turbo replies) */
796         pTrans->ContextSize   = sizeof(u32);
797         pTrans->DetailsLength = 2 * sizeof(u32);
798         pTrans->Flags         = 0;
799         pTrans->TransactionContext[0] = cpu_to_le32(ctx);
800
801 //      dioprintk((KERN_INFO MYNAM ": %s/%s: BC = %08x, skb = %p, buff = %p\n",
802 //                      IOC_AND_NETDEV_NAMES_s_s(dev),
803 //                      ctx, skb, skb->data));
804
805 #ifdef QLOGIC_NAA_WORKAROUND
806 {
807         struct NAA_Hosed *nh;
808
809         /* Munge the NAA for Tx packets to QLogic boards, which don't follow
810            RFC 2625. The longer I look at this, the more my opinion of Qlogic
811            drops. */
812         read_lock_irq(&bad_naa_lock);
813         for (nh = mpt_bad_naa; nh != NULL; nh=nh->next) {
814                 if ((nh->ieee[0] == skb->mac.raw[0]) &&
815                     (nh->ieee[1] == skb->mac.raw[1]) &&
816                     (nh->ieee[2] == skb->mac.raw[2]) &&
817                     (nh->ieee[3] == skb->mac.raw[3]) &&
818                     (nh->ieee[4] == skb->mac.raw[4]) &&
819                     (nh->ieee[5] == skb->mac.raw[5])) {
820                         cur_naa = nh->NAA;
821                         dlprintk ((KERN_INFO "mptlan/sdu_send: using NAA value "
822                                   "= %04x.\n", cur_naa));
823                         break;
824                 }
825         }
826         read_unlock_irq(&bad_naa_lock);
827 }
828 #endif
829
830         pTrans->TransactionDetails[0] = cpu_to_le32((cur_naa         << 16) |
831                                                     (skb->mac.raw[0] <<  8) |
832                                                     (skb->mac.raw[1] <<  0));
833         pTrans->TransactionDetails[1] = cpu_to_le32((skb->mac.raw[2] << 24) |
834                                                     (skb->mac.raw[3] << 16) |
835                                                     (skb->mac.raw[4] <<  8) |
836                                                     (skb->mac.raw[5] <<  0));
837
838         pSimple = (SGESimple64_t *) &pTrans->TransactionDetails[2];
839
840         /* If we ever decide to send more than one Simple SGE per LANSend, then
841            we will need to make sure that LAST_ELEMENT only gets set on the
842            last one. Otherwise, bad voodoo and evil funkiness will commence. */
843         pSimple->FlagsLength = cpu_to_le32(
844                         ((MPI_SGE_FLAGS_LAST_ELEMENT |
845                           MPI_SGE_FLAGS_END_OF_BUFFER |
846                           MPI_SGE_FLAGS_SIMPLE_ELEMENT |
847                           MPI_SGE_FLAGS_SYSTEM_ADDRESS |
848                           MPI_SGE_FLAGS_HOST_TO_IOC |
849                           MPI_SGE_FLAGS_64_BIT_ADDRESSING |
850                           MPI_SGE_FLAGS_END_OF_LIST) << MPI_SGE_FLAGS_SHIFT) |
851                         skb->len);
852         pSimple->Address.Low = cpu_to_le32((u32) dma);
853         if (sizeof(dma_addr_t) > sizeof(u32))
854                 pSimple->Address.High = cpu_to_le32((u32) ((u64) dma >> 32));
855         else
856                 pSimple->Address.High = 0;
857
858         mpt_put_msg_frame (LanCtx, mpt_dev->id, mf);
859         dev->trans_start = jiffies;
860
861         dioprintk((KERN_INFO MYNAM ": %s/%s: Sending packet. FlagsLength = %08x.\n",
862                         IOC_AND_NETDEV_NAMES_s_s(dev),
863                         le32_to_cpu(pSimple->FlagsLength)));
864
865         return 0;
866 }
867
868 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
869 static inline void
870 mpt_lan_wake_post_buckets_task(struct net_device *dev, int priority)
871 /* 
872  * @priority: 0 = put it on the timer queue, 1 = put it on the immediate queue
873  */
874 {
875         struct mpt_lan_priv *priv = dev->priv;
876         
877         if (test_and_set_bit(0, &priv->post_buckets_active) == 0) {
878                 if (priority) {
879 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41)
880                         schedule_work(&priv->post_buckets_task);
881 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,40)
882                         schedule_task(&priv->post_buckets_task);
883 #else
884                         queue_task(&priv->post_buckets_task, &tq_immediate);
885                         mark_bh(IMMEDIATE_BH);
886 #endif
887                 } else {
888 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,41)
889                         schedule_delayed_work(&priv->post_buckets_task, 1);
890 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,40)
891                         schedule_task(&priv->post_buckets_task);
892 #else
893                         queue_task(&priv->post_buckets_task, &tq_timer);
894 #endif
895                         dioprintk((KERN_INFO MYNAM ": post_buckets queued on "
896                                    "timer.\n"));
897                 }
898                 dioprintk((KERN_INFO MYNAM ": %s/%s: Queued post_buckets task.\n",
899                            IOC_AND_NETDEV_NAMES_s_s(dev) ));
900         }
901 }
902
903 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
904 static inline int
905 mpt_lan_receive_skb(struct net_device *dev, struct sk_buff *skb)
906 {
907         struct mpt_lan_priv *priv = dev->priv;
908
909         skb->protocol = mpt_lan_type_trans(skb, dev);
910
911         dioprintk((KERN_INFO MYNAM ": %s/%s: Incoming packet (%d bytes) "
912                  "delivered to upper level.\n",
913                         IOC_AND_NETDEV_NAMES_s_s(dev), skb->len));
914
915         priv->stats.rx_bytes += skb->len;
916         priv->stats.rx_packets++;
917
918         skb->dev = dev;
919         netif_rx(skb);
920
921         dioprintk((MYNAM "/receive_skb: %d buckets remaining\n",
922                  atomic_read(&priv->buckets_out)));
923
924         if (atomic_read(&priv->buckets_out) < priv->bucketthresh)
925                 mpt_lan_wake_post_buckets_task(dev, 1);
926
927         dioprintk((KERN_INFO MYNAM "/receive_post_reply: %d buckets "
928                   "remaining, %d received back since sod\n",
929                   atomic_read(&priv->buckets_out), priv->total_received));
930
931         return 0;
932 }
933
934 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
935 //static inline int
936 static int
937 mpt_lan_receive_post_turbo(struct net_device *dev, u32 tmsg)
938 {
939         struct mpt_lan_priv *priv = dev->priv;
940         MPT_ADAPTER *mpt_dev = priv->mpt_dev;
941         struct sk_buff *skb, *old_skb;
942         unsigned long flags;
943         u32 ctx, len;
944
945         ctx = GET_LAN_BUCKET_CONTEXT(tmsg);
946         skb = priv->RcvCtl[ctx].skb;
947
948         len = GET_LAN_PACKET_LENGTH(tmsg);
949
950         if (len < MPT_LAN_RX_COPYBREAK) {
951                 old_skb = skb;
952
953                 skb = (struct sk_buff *)dev_alloc_skb(len);
954                 if (!skb) {
955                         printk (KERN_ERR MYNAM ": %s/%s: ERROR - Can't allocate skb! (%s@%d)\n",
956                                         IOC_AND_NETDEV_NAMES_s_s(dev),
957                                         __FILE__, __LINE__);
958                         return -ENOMEM;
959                 }
960
961                 pci_dma_sync_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma,
962                                     priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE);
963
964                 memcpy(skb_put(skb, len), old_skb->data, len);
965
966                 goto out;
967         }
968
969         skb_put(skb, len);
970
971         priv->RcvCtl[ctx].skb = NULL;
972
973         pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma,
974                          priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE);
975
976 out:
977         spin_lock_irqsave(&priv->rxfidx_lock, flags);
978         priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
979         spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
980
981         atomic_dec(&priv->buckets_out);
982         priv->total_received++;
983
984         return mpt_lan_receive_skb(dev, skb);
985 }
986
987 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
988 static int
989 mpt_lan_receive_post_free(struct net_device *dev,
990                           LANReceivePostReply_t *pRecvRep)
991 {
992         struct mpt_lan_priv *priv = dev->priv;
993         MPT_ADAPTER *mpt_dev = priv->mpt_dev;
994         unsigned long flags;
995         struct sk_buff *skb;
996         u32 ctx;
997         int count;
998         int i;
999
1000         count = pRecvRep->NumberOfContexts;
1001
1002 /**/    dlprintk((KERN_INFO MYNAM "/receive_post_reply: "
1003                   "IOC returned %d buckets, freeing them...\n", count));
1004
1005         spin_lock_irqsave(&priv->rxfidx_lock, flags);
1006         for (i = 0; i < count; i++) {
1007                 ctx = le32_to_cpu(pRecvRep->BucketContext[i]);
1008
1009                 skb = priv->RcvCtl[ctx].skb;
1010
1011 //              dlprintk((KERN_INFO MYNAM ": %s: dev_name = %s\n",
1012 //                              IOC_AND_NETDEV_NAMES_s_s(dev)));
1013 //              dlprintk((KERN_INFO MYNAM "@rpr[2], priv = %p, buckets_out addr = %p",
1014 //                              priv, &(priv->buckets_out)));
1015 //              dlprintk((KERN_INFO MYNAM "@rpr[2] TC + 3\n"));
1016
1017                 priv->RcvCtl[ctx].skb = NULL;
1018                 pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma,
1019                                  priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE);
1020                 dev_kfree_skb_any(skb);
1021
1022                 priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
1023         }
1024         spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
1025
1026         atomic_sub(count, &priv->buckets_out);
1027
1028 //      for (i = 0; i < priv->max_buckets_out; i++)
1029 //              if (priv->RcvCtl[i].skb != NULL)
1030 //                      dlprintk((KERN_INFO MYNAM "@rpr: bucket %03x "
1031 //                                "is still out\n", i));
1032
1033 /*      dlprintk((KERN_INFO MYNAM "/receive_post_reply: freed %d buckets\n",
1034                   count));
1035 */
1036 /**/    dlprintk((KERN_INFO MYNAM "@receive_post_reply: %d buckets "
1037 /**/              "remaining, %d received back since sod.\n",
1038 /**/              atomic_read(&priv->buckets_out), priv->total_received));
1039         return 0;
1040 }
1041
1042 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1043 static int
1044 mpt_lan_receive_post_reply(struct net_device *dev,
1045                            LANReceivePostReply_t *pRecvRep)
1046 {
1047         struct mpt_lan_priv *priv = dev->priv;
1048         MPT_ADAPTER *mpt_dev = priv->mpt_dev;
1049         struct sk_buff *skb, *old_skb;
1050         unsigned long flags;
1051         u32 len, ctx, offset;
1052         u32 remaining = le32_to_cpu(pRecvRep->BucketsRemaining);
1053         int count;
1054         int i, l;
1055
1056         dioprintk((KERN_INFO MYNAM ": mpt_lan_receive_post_reply called\n"));
1057         dioprintk((KERN_INFO MYNAM ": receive_post_reply: IOCStatus: %04x\n",
1058                  le16_to_cpu(pRecvRep->IOCStatus)));
1059
1060         if ((le16_to_cpu(pRecvRep->IOCStatus) & MPI_IOCSTATUS_MASK) ==
1061                                                 MPI_IOCSTATUS_LAN_CANCELED)
1062                 return mpt_lan_receive_post_free(dev, pRecvRep);
1063
1064         len = le32_to_cpu(pRecvRep->PacketLength);
1065         if (len == 0) {
1066                 printk (KERN_ERR MYNAM ": %s/%s: ERROR - Got a non-TURBO "
1067                         "ReceivePostReply w/ PacketLength zero!\n",
1068                                 IOC_AND_NETDEV_NAMES_s_s(dev));
1069                 printk (KERN_ERR MYNAM ": MsgFlags = %02x, IOCStatus = %04x\n",
1070                                 pRecvRep->MsgFlags, le16_to_cpu(pRecvRep->IOCStatus));
1071                 return -1;
1072         }
1073
1074         ctx    = le32_to_cpu(pRecvRep->BucketContext[0]);
1075         count  = pRecvRep->NumberOfContexts;
1076         skb    = priv->RcvCtl[ctx].skb;
1077
1078         offset = le32_to_cpu(pRecvRep->PacketOffset);
1079 //      if (offset != 0) {
1080 //              printk (KERN_INFO MYNAM ": %s/%s: Got a ReceivePostReply "
1081 //                      "w/ PacketOffset %u\n",
1082 //                              IOC_AND_NETDEV_NAMES_s_s(dev),
1083 //                              offset);
1084 //      }
1085
1086         dioprintk((KERN_INFO MYNAM ": %s/%s: @rpr, offset = %d, len = %d\n",
1087                         IOC_AND_NETDEV_NAMES_s_s(dev),
1088                         offset, len));
1089
1090         if (count > 1) {
1091                 int szrem = len;
1092
1093 //              dioprintk((KERN_INFO MYNAM ": %s/%s: Multiple buckets returned "
1094 //                      "for single packet, concatenating...\n",
1095 //                              IOC_AND_NETDEV_NAMES_s_s(dev)));
1096
1097                 skb = (struct sk_buff *)dev_alloc_skb(len);
1098                 if (!skb) {
1099                         printk (KERN_ERR MYNAM ": %s/%s: ERROR - Can't allocate skb! (%s@%d)\n",
1100                                         IOC_AND_NETDEV_NAMES_s_s(dev),
1101                                         __FILE__, __LINE__);
1102                         return -ENOMEM;
1103                 }
1104
1105                 spin_lock_irqsave(&priv->rxfidx_lock, flags);
1106                 for (i = 0; i < count; i++) {
1107
1108                         ctx = le32_to_cpu(pRecvRep->BucketContext[i]);
1109                         old_skb = priv->RcvCtl[ctx].skb;
1110
1111                         l = priv->RcvCtl[ctx].len;
1112                         if (szrem < l)
1113                                 l = szrem;
1114
1115 //                      dioprintk((KERN_INFO MYNAM ": %s/%s: Buckets = %d, len = %u\n",
1116 //                                      IOC_AND_NETDEV_NAMES_s_s(dev),
1117 //                                      i, l));
1118
1119                         pci_dma_sync_single(mpt_dev->pcidev,
1120                                             priv->RcvCtl[ctx].dma,
1121                                             priv->RcvCtl[ctx].len,
1122                                             PCI_DMA_FROMDEVICE);
1123                         memcpy(skb_put(skb, l), old_skb->data, l);
1124
1125                         priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
1126                         szrem -= l;
1127                 }
1128                 spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
1129
1130         } else if (len < MPT_LAN_RX_COPYBREAK) {
1131
1132                 old_skb = skb;
1133
1134                 skb = (struct sk_buff *)dev_alloc_skb(len);
1135                 if (!skb) {
1136                         printk (KERN_ERR MYNAM ": %s/%s: ERROR - Can't allocate skb! (%s@%d)\n",
1137                                         IOC_AND_NETDEV_NAMES_s_s(dev),
1138                                         __FILE__, __LINE__);
1139                         return -ENOMEM;
1140                 }
1141
1142                 pci_dma_sync_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma,
1143                                     priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE);
1144
1145                 memcpy(skb_put(skb, len), old_skb->data, len);
1146
1147                 spin_lock_irqsave(&priv->rxfidx_lock, flags);
1148                 priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
1149                 spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
1150
1151         } else {
1152                 spin_lock_irqsave(&priv->rxfidx_lock, flags);
1153
1154                 priv->RcvCtl[ctx].skb = NULL;
1155
1156                 pci_unmap_single(mpt_dev->pcidev, priv->RcvCtl[ctx].dma,
1157                                  priv->RcvCtl[ctx].len, PCI_DMA_FROMDEVICE);
1158                 priv->RcvCtl[ctx].dma = 0;
1159
1160                 priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
1161                 spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
1162
1163                 skb_put(skb,len);
1164         }
1165
1166         atomic_sub(count, &priv->buckets_out);
1167         priv->total_received += count;
1168
1169         if (priv->mpt_rxfidx_tail >= MPT_LAN_MAX_BUCKETS_OUT) {
1170                 printk (KERN_ERR MYNAM ": %s/%s: Yoohoo! mpt_rxfidx_tail = %d, "
1171                         "MPT_LAN_MAX_BUCKETS_OUT = %d\n",
1172                                 IOC_AND_NETDEV_NAMES_s_s(dev),
1173                                 priv->mpt_rxfidx_tail,
1174                                 MPT_LAN_MAX_BUCKETS_OUT);
1175
1176                 panic("Damn it Jim! I'm a doctor, not a programmer! "
1177                                 "Oh, wait a sec, I am a programmer. "
1178                                 "And, who's Jim?!?!\n"
1179                                 "Arrgghh! We've done it again!\n");
1180         }
1181
1182         if (remaining == 0)
1183                 printk (KERN_WARNING MYNAM ": %s/%s: WARNING - IOC out of buckets! "
1184                         "(priv->buckets_out = %d)\n",
1185                         IOC_AND_NETDEV_NAMES_s_s(dev),
1186                         atomic_read(&priv->buckets_out));
1187         else if (remaining < 10)
1188                 printk (KERN_INFO MYNAM ": %s/%s: IOC says %d buckets left. "
1189                         "(priv->buckets_out = %d)\n",
1190                         IOC_AND_NETDEV_NAMES_s_s(dev),
1191                         remaining, atomic_read(&priv->buckets_out));
1192         
1193         if ((remaining < priv->bucketthresh) &&
1194             ((atomic_read(&priv->buckets_out) - remaining) > 
1195              MPT_LAN_BUCKETS_REMAIN_MISMATCH_THRESH)) {
1196                 
1197                 printk (KERN_WARNING MYNAM " Mismatch between driver's "
1198                         "buckets_out count and fw's BucketsRemaining "
1199                         "count has crossed the threshold, issuing a "
1200                         "LanReset to clear the fw's hashtable. You may "
1201                         "want to check your /var/log/messages for \"CRC "
1202                         "error\" event notifications.\n");
1203                 
1204                 mpt_lan_reset(dev);
1205                 mpt_lan_wake_post_buckets_task(dev, 0);
1206         }
1207         
1208         return mpt_lan_receive_skb(dev, skb);
1209 }
1210
1211 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1212 /* Simple SGE's only at the moment */
1213
1214 static void
1215 mpt_lan_post_receive_buckets(void *dev_id)
1216 {
1217         struct net_device *dev = dev_id;
1218         struct mpt_lan_priv *priv = dev->priv;
1219         MPT_ADAPTER *mpt_dev = priv->mpt_dev;
1220         MPT_FRAME_HDR *mf;
1221         LANReceivePostRequest_t *pRecvReq;
1222         SGETransaction32_t *pTrans;
1223         SGESimple64_t *pSimple;
1224         struct sk_buff *skb;
1225         dma_addr_t dma;
1226         u32 curr, buckets, count, max;
1227         u32 len = (dev->mtu + dev->hard_header_len + 4);
1228         unsigned long flags;
1229         int i;
1230
1231         curr = atomic_read(&priv->buckets_out);
1232         buckets = (priv->max_buckets_out - curr);
1233
1234         dioprintk((KERN_INFO MYNAM ": %s/%s: @%s, Start_buckets = %u, buckets_out = %u\n",
1235                         IOC_AND_NETDEV_NAMES_s_s(dev),
1236                         __FUNCTION__, buckets, curr));
1237
1238         max = (mpt_dev->req_sz - MPT_LAN_RECEIVE_POST_REQUEST_SIZE) /
1239                         (MPT_LAN_TRANSACTION32_SIZE + sizeof(SGESimple64_t));
1240
1241         while (buckets) {
1242                 mf = mpt_get_msg_frame(LanCtx, mpt_dev->id);
1243                 if (mf == NULL) {
1244                         printk (KERN_ERR "%s: Unable to alloc request frame\n",
1245                                 __FUNCTION__);
1246                         dioprintk((KERN_ERR "%s: %u buckets remaining\n",
1247                                  __FUNCTION__, buckets));
1248                         goto out;
1249                 }
1250                 pRecvReq = (LANReceivePostRequest_t *) mf;
1251
1252                 count = buckets;
1253                 if (count > max)
1254                         count = max;
1255
1256                 pRecvReq->Function    = MPI_FUNCTION_LAN_RECEIVE;
1257                 pRecvReq->ChainOffset = 0;
1258                 pRecvReq->MsgFlags    = 0;
1259                 pRecvReq->PortNumber  = priv->pnum;
1260
1261                 pTrans = (SGETransaction32_t *) pRecvReq->SG_List;
1262                 pSimple = NULL;
1263
1264                 for (i = 0; i < count; i++) {
1265                         int ctx;
1266
1267                         spin_lock_irqsave(&priv->rxfidx_lock, flags);
1268                         if (priv->mpt_rxfidx_tail < 0) {
1269                                 printk (KERN_ERR "%s: Can't alloc context\n",
1270                                         __FUNCTION__);
1271                                 spin_unlock_irqrestore(&priv->rxfidx_lock,
1272                                                        flags);
1273                                 break;
1274                         }
1275
1276                         ctx = priv->mpt_rxfidx[priv->mpt_rxfidx_tail--];
1277
1278                         skb = priv->RcvCtl[ctx].skb;
1279                         if (skb && (priv->RcvCtl[ctx].len != len)) {
1280                                 pci_unmap_single(mpt_dev->pcidev,
1281                                                  priv->RcvCtl[ctx].dma,
1282                                                  priv->RcvCtl[ctx].len,
1283                                                  PCI_DMA_FROMDEVICE);
1284                                 dev_kfree_skb(priv->RcvCtl[ctx].skb);
1285                                 skb = priv->RcvCtl[ctx].skb = NULL;
1286                         }
1287
1288                         if (skb == NULL) {
1289                                 skb = dev_alloc_skb(len);
1290                                 if (skb == NULL) {
1291                                         printk (KERN_WARNING
1292                                                 MYNAM "/%s: Can't alloc skb\n",
1293                                                 __FUNCTION__);
1294                                         priv->mpt_rxfidx[++priv->mpt_rxfidx_tail] = ctx;
1295                                         spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
1296                                         break;
1297                                 }
1298
1299                                 dma = pci_map_single(mpt_dev->pcidev, skb->data,
1300                                                      len, PCI_DMA_FROMDEVICE);
1301
1302                                 priv->RcvCtl[ctx].skb = skb;
1303                                 priv->RcvCtl[ctx].dma = dma;
1304                                 priv->RcvCtl[ctx].len = len;
1305                         }
1306
1307                         spin_unlock_irqrestore(&priv->rxfidx_lock, flags);
1308
1309                         pTrans->ContextSize   = sizeof(u32);
1310                         pTrans->DetailsLength = 0;
1311                         pTrans->Flags         = 0;
1312                         pTrans->TransactionContext[0] = cpu_to_le32(ctx);
1313
1314                         pSimple = (SGESimple64_t *) pTrans->TransactionDetails;
1315
1316                         pSimple->FlagsLength = cpu_to_le32(
1317                                 ((MPI_SGE_FLAGS_END_OF_BUFFER |
1318                                   MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1319                                   MPI_SGE_FLAGS_64_BIT_ADDRESSING) << MPI_SGE_FLAGS_SHIFT) | len);
1320                         pSimple->Address.Low = cpu_to_le32((u32) priv->RcvCtl[ctx].dma);
1321                         if (sizeof(dma_addr_t) > sizeof(u32))
1322                                 pSimple->Address.High = cpu_to_le32((u32) ((u64) priv->RcvCtl[ctx].dma >> 32));
1323                         else
1324                                 pSimple->Address.High = 0;
1325
1326                         pTrans = (SGETransaction32_t *) (pSimple + 1);
1327                 }
1328
1329                 if (pSimple == NULL) {
1330 /**/                    printk (KERN_WARNING MYNAM "/%s: No buckets posted\n",
1331 /**/                            __FUNCTION__);
1332                         mpt_free_msg_frame(LanCtx, mpt_dev->id, mf);
1333                         goto out;
1334                 }
1335
1336                 pSimple->FlagsLength |= cpu_to_le32(MPI_SGE_FLAGS_END_OF_LIST << MPI_SGE_FLAGS_SHIFT);
1337
1338                 pRecvReq->BucketCount = cpu_to_le32(i);
1339
1340 /*      printk(KERN_INFO MYNAM ": posting buckets\n   ");
1341  *      for (i = 0; i < j + 2; i ++)
1342  *          printk (" %08x", le32_to_cpu(msg[i]));
1343  *      printk ("\n");
1344  */
1345
1346                 mpt_put_msg_frame(LanCtx, mpt_dev->id, mf);
1347
1348                 priv->total_posted += i;
1349                 buckets -= i;
1350                 atomic_add(i, &priv->buckets_out);
1351         }
1352
1353 out:
1354         dioprintk((KERN_INFO MYNAM "/%s: End_buckets = %u, priv->buckets_out = %u\n",
1355                   __FUNCTION__, buckets, atomic_read(&priv->buckets_out)));
1356         dioprintk((KERN_INFO MYNAM "/%s: Posted %u buckets and received %u back\n",
1357         __FUNCTION__, priv->total_posted, priv->total_received));
1358
1359         clear_bit(0, &priv->post_buckets_active);
1360 }
1361
1362 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1363 struct net_device *
1364 mpt_register_lan_device (MPT_ADAPTER *mpt_dev, int pnum)
1365 {
1366         struct net_device *dev = NULL;
1367         struct mpt_lan_priv *priv = NULL;
1368         u8 HWaddr[FC_ALEN], *a;
1369
1370         dev = init_fcdev(NULL, sizeof(struct mpt_lan_priv));
1371         if (!dev)
1372                 return (NULL);
1373         dev->mtu = MPT_LAN_MTU;
1374
1375         priv = (struct mpt_lan_priv *) dev->priv;
1376
1377         priv->mpt_dev = mpt_dev;
1378         priv->pnum = pnum;
1379
1380         memset(&priv->post_buckets_task, 0, sizeof(struct mpt_work_struct));
1381         MPT_INIT_WORK(&priv->post_buckets_task, mpt_lan_post_receive_buckets, dev);
1382         priv->post_buckets_active = 0;
1383
1384         dlprintk((KERN_INFO MYNAM "@%d: bucketlen = %d\n",
1385                         __LINE__, dev->mtu + dev->hard_header_len + 4));
1386
1387         atomic_set(&priv->buckets_out, 0);
1388         priv->total_posted = 0;
1389         priv->total_received = 0;
1390         priv->max_buckets_out = max_buckets_out;
1391         if (mpt_dev->pfacts[0].MaxLanBuckets < max_buckets_out)
1392                 priv->max_buckets_out = mpt_dev->pfacts[0].MaxLanBuckets;
1393
1394         dlprintk((KERN_INFO MYNAM "@%d: MaxLanBuckets=%d, max_buckets_out/priv=%d/%d\n",
1395                         __LINE__,
1396                         mpt_dev->pfacts[0].MaxLanBuckets,
1397                         max_buckets_out,
1398                         priv->max_buckets_out));
1399
1400         priv->bucketthresh = priv->max_buckets_out * 2 / 3;
1401         priv->txfidx_lock = SPIN_LOCK_UNLOCKED;
1402         priv->rxfidx_lock = SPIN_LOCK_UNLOCKED;
1403
1404         memset(&priv->stats, 0, sizeof(priv->stats));
1405
1406         /*  Grab pre-fetched LANPage1 stuff. :-) */
1407         a = (u8 *) &mpt_dev->lan_cnfg_page1.HardwareAddressLow;
1408
1409         HWaddr[0] = a[5];
1410         HWaddr[1] = a[4];
1411         HWaddr[2] = a[3];
1412         HWaddr[3] = a[2];
1413         HWaddr[4] = a[1];
1414         HWaddr[5] = a[0];
1415
1416         dev->addr_len = FC_ALEN;
1417         memcpy(dev->dev_addr, HWaddr, FC_ALEN);
1418         memset(dev->broadcast, 0xff, FC_ALEN);
1419
1420         /* The Tx queue is 127 deep on the 909.
1421          * Give ourselves some breathing room.
1422          */
1423         priv->tx_max_out = (tx_max_out_p <= MPT_TX_MAX_OUT_LIM) ?
1424                             tx_max_out_p : MPT_TX_MAX_OUT_LIM;
1425
1426         dev->open = mpt_lan_open;
1427         dev->stop = mpt_lan_close;
1428         dev->get_stats = mpt_lan_get_stats;
1429         dev->set_multicast_list = NULL;
1430         dev->change_mtu = mpt_lan_change_mtu;
1431         dev->hard_start_xmit = mpt_lan_sdu_send;
1432
1433 /* Not in 2.3.42. Need 2.3.45+ */
1434         dev->tx_timeout = mpt_lan_tx_timeout;
1435         dev->watchdog_timeo = MPT_LAN_TX_TIMEOUT;
1436
1437         dlprintk((KERN_INFO MYNAM ": Finished registering dev "
1438                 "and setting initial values\n"));
1439
1440         SET_MODULE_OWNER(dev);
1441
1442         return dev;
1443 }
1444
1445 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1446 int __init
1447 mpt_lan_init (void)
1448 {
1449         struct net_device *dev;
1450         MPT_ADAPTER *curadapter;
1451         int i, j;
1452
1453         show_mptmod_ver(LANAME, LANVER);
1454
1455 #ifdef QLOGIC_NAA_WORKAROUND
1456         /* Init the global r/w lock for the bad_naa list. We want to do this
1457            before any boards are initialized and may be used. */
1458         rwlock_init(&bad_naa_lock);
1459 #endif
1460
1461         if ((LanCtx = mpt_register(lan_reply, MPTLAN_DRIVER)) <= 0) {
1462                 printk (KERN_ERR MYNAM ": Failed to register with MPT base driver\n");
1463                 return -EBUSY;
1464         }
1465
1466         /* Set the callback index to be used by driver core for turbo replies */
1467         mpt_lan_index = LanCtx;
1468
1469         dlprintk((KERN_INFO MYNAM ": assigned context of %d\n", LanCtx));
1470
1471         if (mpt_reset_register(LanCtx, mpt_lan_ioc_reset) == 0) {
1472                 dlprintk((KERN_INFO MYNAM ": Registered for IOC reset notifications\n"));
1473         } else {
1474                 printk(KERN_ERR MYNAM ": Eieee! unable to register a reset "
1475                        "handler with mptbase! The world is at an end! "
1476                        "Everything is fading to black! Goodbye.\n");
1477                 return -EBUSY;
1478         }
1479
1480         for (j = 0; j < MPT_MAX_ADAPTERS; j++) {
1481                 mpt_landev[j] = NULL;
1482         }
1483
1484         curadapter = mpt_adapter_find_first();
1485         while (curadapter != NULL) {
1486                 for (i = 0; i < curadapter->facts.NumberOfPorts; i++) {
1487                         printk (KERN_INFO MYNAM ": %s: PortNum=%x, ProtocolFlags=%02Xh (%c%c%c%c)\n",
1488                                         curadapter->name,
1489                                         curadapter->pfacts[i].PortNumber,
1490                                         curadapter->pfacts[i].ProtocolFlags,
1491                                         MPT_PROTOCOL_FLAGS_c_c_c_c(curadapter->pfacts[i].ProtocolFlags));
1492
1493                         if (curadapter->pfacts[i].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
1494                                 dev = mpt_register_lan_device (curadapter, i);
1495                                 if (dev != NULL) {
1496                                         printk (KERN_INFO MYNAM ": %s: Fusion MPT LAN device registered as '%s'\n",
1497                                                         curadapter->name, dev->name);
1498                                         printk (KERN_INFO MYNAM ": %s/%s: LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1499                                                         IOC_AND_NETDEV_NAMES_s_s(dev),
1500                                                         dev->dev_addr[0], dev->dev_addr[1],
1501                                                         dev->dev_addr[2], dev->dev_addr[3],
1502                                                         dev->dev_addr[4], dev->dev_addr[5]);
1503 //                                      printk (KERN_INFO MYNAM ": %s/%s: Max_TX_outstanding = %d\n",
1504 //                                                      IOC_AND_NETDEV_NAMES_s_s(dev),
1505 //                                                      NETDEV_TO_LANPRIV_PTR(dev)->tx_max_out);
1506                                         j = curadapter->id;
1507                                         mpt_landev[j] = dev;
1508                                         dlprintk((KERN_INFO MYNAM "/init: dev_addr=%p, mpt_landev[%d]=%p\n",
1509                                                         dev, j,  mpt_landev[j]));
1510
1511                                 } else {
1512                                         printk (KERN_ERR MYNAM ": %s: Unable to register port%d as a LAN device\n",
1513                                                         curadapter->name,
1514                                                         curadapter->pfacts[i].PortNumber);
1515                                 }
1516                         } else {
1517                                 printk (KERN_INFO MYNAM ": %s: Hmmm... LAN protocol seems to be disabled on this adapter port!\n",
1518                                                 curadapter->name);
1519                         }
1520                 }
1521                 curadapter = mpt_adapter_find_next(curadapter);
1522         }
1523
1524         return 0;
1525 }
1526
1527 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1528 void __init mpt_lan_exit(void)
1529 {
1530         int i;
1531
1532         mpt_reset_deregister(LanCtx);
1533
1534         for (i = 0; mpt_landev[i] != NULL; i++) {
1535                 struct net_device *dev = mpt_landev[i];
1536
1537                 printk (KERN_INFO MYNAM ": %s/%s: Fusion MPT LAN device unregistered\n",
1538                                IOC_AND_NETDEV_NAMES_s_s(dev));
1539                 unregister_fcdev(dev);
1540                 mpt_landev[i] = (struct net_device *) 0xdeadbeef; /* Debug */
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
1554 MODULE_PARM(tx_max_out_p, "i");
1555 MODULE_PARM(max_buckets_out, "i"); // Debug stuff. FIXME!
1556
1557 module_init(mpt_lan_init);
1558 module_exit(mpt_lan_exit);
1559
1560 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1561 static unsigned short
1562 mpt_lan_type_trans(struct sk_buff *skb, struct net_device *dev)
1563 {
1564         struct mpt_lan_ohdr *fch = (struct mpt_lan_ohdr *)skb->data;
1565         struct fcllc *fcllc;
1566
1567         skb->mac.raw = skb->data;
1568         skb_pull(skb, sizeof(struct mpt_lan_ohdr));
1569
1570         if (fch->dtype == htons(0xffff)) {
1571                 u32 *p = (u32 *) fch;
1572
1573                 swab32s(p + 0);
1574                 swab32s(p + 1);
1575                 swab32s(p + 2);
1576                 swab32s(p + 3);
1577
1578                 printk (KERN_WARNING MYNAM ": %s: WARNING - Broadcast swap F/W bug detected!\n",
1579                                 NETDEV_PTR_TO_IOC_NAME_s(dev));
1580                 printk (KERN_WARNING MYNAM ": Please update sender @ MAC_addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
1581                                 fch->saddr[0], fch->saddr[1], fch->saddr[2],
1582                                 fch->saddr[3], fch->saddr[4], fch->saddr[5]);
1583         }
1584
1585         if (*fch->daddr & 1) {
1586                 if (!memcmp(fch->daddr, dev->broadcast, FC_ALEN)) {
1587                         skb->pkt_type = PACKET_BROADCAST;
1588                 } else {
1589                         skb->pkt_type = PACKET_MULTICAST;
1590                 }
1591         } else {
1592                 if (memcmp(fch->daddr, dev->dev_addr, FC_ALEN)) {
1593                         skb->pkt_type = PACKET_OTHERHOST;
1594                 } else {
1595                         skb->pkt_type = PACKET_HOST;
1596                 }
1597         }
1598
1599         fcllc = (struct fcllc *)skb->data;
1600
1601 #ifdef QLOGIC_NAA_WORKAROUND
1602 {
1603         u16 source_naa = fch->stype, found = 0;
1604
1605         /* Workaround for QLogic not following RFC 2625 in regards to the NAA
1606            value. */
1607
1608         if ((source_naa & 0xF000) == 0)
1609                 source_naa = swab16(source_naa);
1610
1611         if (fcllc->ethertype == htons(ETH_P_ARP))
1612             dlprintk ((KERN_INFO "mptlan/type_trans: got arp req/rep w/ naa of "
1613                       "%04x.\n", source_naa));
1614
1615         if ((fcllc->ethertype == htons(ETH_P_ARP)) &&
1616            ((source_naa >> 12) !=  MPT_LAN_NAA_RFC2625)){
1617                 struct NAA_Hosed *nh, *prevnh;
1618                 int i;
1619
1620                 dlprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep from "
1621                           "system with non-RFC 2625 NAA value (%04x).\n",
1622                           source_naa));
1623
1624                 write_lock_irq(&bad_naa_lock);
1625                 for (prevnh = nh = mpt_bad_naa; nh != NULL;
1626                      prevnh=nh, nh=nh->next) {
1627                         if ((nh->ieee[0] == fch->saddr[0]) &&
1628                             (nh->ieee[1] == fch->saddr[1]) &&
1629                             (nh->ieee[2] == fch->saddr[2]) &&
1630                             (nh->ieee[3] == fch->saddr[3]) &&
1631                             (nh->ieee[4] == fch->saddr[4]) &&
1632                             (nh->ieee[5] == fch->saddr[5])) {
1633                                 found = 1;
1634                                 dlprintk ((KERN_INFO "mptlan/type_trans: ARP Re"
1635                                          "q/Rep w/ bad NAA from system already"
1636                                          " in DB.\n"));
1637                                 break;
1638                         }
1639                 }
1640
1641                 if ((!found) && (nh == NULL)) {
1642
1643                         nh = kmalloc(sizeof(struct NAA_Hosed), GFP_KERNEL);
1644                         dlprintk ((KERN_INFO "mptlan/type_trans: ARP Req/Rep w/"
1645                                  " bad NAA from system not yet in DB.\n"));
1646
1647                         if (nh != NULL) {
1648                                 nh->next = NULL;
1649                                 if (!mpt_bad_naa)
1650                                         mpt_bad_naa = nh;
1651                                 if (prevnh)
1652                                         prevnh->next = nh;
1653
1654                                 nh->NAA = source_naa; /* Set the S_NAA value. */
1655                                 for (i = 0; i < FC_ALEN; i++)
1656                                         nh->ieee[i] = fch->saddr[i];
1657                                 dlprintk ((KERN_INFO "Got ARP from %02x:%02x:%02x:%02x:"
1658                                           "%02x:%02x with non-compliant S_NAA value.\n",
1659                                           fch->saddr[0], fch->saddr[1], fch->saddr[2],
1660                                           fch->saddr[3], fch->saddr[4],fch->saddr[5]));
1661                         } else {
1662                                 printk (KERN_ERR "mptlan/type_trans: Unable to"
1663                                         " kmalloc a NAA_Hosed struct.\n");
1664                         }
1665                 } else if (!found) {
1666                         printk (KERN_ERR "mptlan/type_trans: found not"
1667                                 " set, but nh isn't null. Evil "
1668                                 "funkiness abounds.\n");
1669                 }
1670                 write_unlock_irq(&bad_naa_lock);
1671         }
1672 }
1673 #endif
1674
1675         /* Strip the SNAP header from ARP packets since we don't
1676          * pass them through to the 802.2/SNAP layers.
1677          */
1678         if (fcllc->dsap == EXTENDED_SAP &&
1679                 (fcllc->ethertype == htons(ETH_P_IP) ||
1680                  fcllc->ethertype == htons(ETH_P_ARP))) {
1681                 skb_pull(skb, sizeof(struct fcllc));
1682                 return fcllc->ethertype;
1683         }
1684
1685         return htons(ETH_P_802_2);
1686 }
1687
1688 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/