added a lot of printk output to ease writing of emulator
[linux-2.4.21-pre4.git] / drivers / iseries / veth.c
1 /* File veth.c created by Kyle A. Lucke on Mon Aug  7 2000. */
2
3 /**************************************************************************/
4 /*                                                                        */
5 /* IBM eServer iSeries Virtual Ethernet Device Driver                     */
6 /* Copyright (C) 2001 Kyle A. Lucke (klucke@us.ibm.com), IBM Corp.        */
7 /*                                                                        */
8 /*  This program is free software; you can redistribute it and/or modify  */
9 /*  it under the terms of the GNU General Public License as published by  */
10 /*  the Free Software Foundation; either version 2 of the License, or     */
11 /*  (at your option) any later version.                                   */
12 /*                                                                        */
13 /*  This program is distributed in the hope that it will be useful,       */
14 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */
15 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         */
16 /*  GNU General Public License for more details.                          */
17 /*                                                                        */
18 /*  You should have received a copy of the GNU General Public License     */
19 /*  along with this program; if not, write to the Free Software           */
20 /*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  */
21 /*                                                                   USA  */
22 /*                                                                        */
23 /* This module contains the implementation of a virtual ethernet device   */
24 /* for use with iSeries LPAR Linux.  It utilizes low-level message passing*/
25 /* provided by the hypervisor to enable an ethernet-like network device   */
26 /* that can be used to enable inter-partition communications on the same  */
27 /* physical iSeries.                                                      */
28 /*                                                                        */
29 /* The iSeries LPAR hypervisor has currently defined the ability for a    */
30 /* partition to communicate on up to 16 different virtual ethernets, all  */
31 /* dynamically configurable, at least for an OS/400 partition.  The       */
32 /* dynamic nature is not supported for Linux yet.                         */
33 /*                                                                        */
34 /* Each virtual ethernet a given Linux partition participates in will     */
35 /* cause a network device with the form ethXX to be created,              */
36 /*                                                                        */
37 /* The virtual ethernet a given ethXX virtual ethernet device talks on    */
38 /* can be determined either by dumping /proc/iSeries/veth/vethX, where    */
39 /* X is the virtual ethernet number, and the netdevice name will be       */
40 /* printed out.  The virtual ethernet a given ethX device communicates on */
41 /* is also printed to the printk() buffer at module load time.            */
42 /*                                                                        */
43 /* This driver (and others like it on other partitions) is responsible for*/
44 /* routing packets to and from other partitions.  The MAC addresses used  */
45 /* by the virtual ethernets contain meaning, and should not be modified.  */
46 /* Doing so could disable the ability of your Linux partition to          */
47 /* communicate with the other OS/400 partitions on your physical iSeries. */
48 /* Similarly, setting the MAC address to something other than the         */
49 /* "virtual burned-in" address is not allowed, for the same reason.       */
50 /*                                                                        */
51 /* Notes:                                                                 */
52 /*                                                                        */
53 /* 1. Although there is the capability to talk on multiple shared         */
54 /*    ethernets to communicate to the same partition, each shared         */
55 /*    ethernet to a given partition X will use a finite, shared amount    */
56 /*    of hypervisor messages to do the communication.  So having 2 shared */
57 /*    ethernets to the same remote partition DOES NOT double the          */
58 /*    available bandwidth.  Each of the 2 shared ethernets will share the */
59 /*    same bandwidth available to another.                                */
60 /*                                                                        */
61 /* 2. It is allowed to have a virtual ethernet that does not communicate  */
62 /*    with any other partition.  It won't do anything, but it's allowed.  */
63 /*                                                                        */
64 /* 3. There is no "loopback" mode for a virtual ethernet device.  If you  */
65 /*    send a packet to your own mac address, it will just be dropped, you */
66 /*    won't get it on the receive side.  Such a thing could be done,      */
67 /*    but my default driver DOES NOT do so.                               */
68 /*                                                                        */
69 /* 4. Multicast addressing is implemented via broadcasting the multicast  */
70 /*    frames to other partitions.  It is the responsibility of the        */
71 /*    receiving partition to filter the addresses desired.                */
72 /*                                                                        */
73 /* 5. This module utilizes several different bottom half handlers for     */
74 /*    non-high-use path function (setup, error handling, etc.).  Multiple */
75 /*    bottom halves were used because only one would not keep up to the   */
76 /*    much faster iSeries device drivers this Linux driver is talking to. */
77 /*    All hi-priority work (receiving frames, handling frame acks) is done*/
78 /*    in the interrupt handler for maximum performance.                   */
79 /*                                                                        */
80 /* Tunable parameters:                                                    */
81 /*                                                                        */
82 /* VethBuffersToAllocate: This compile time option defaults to 120. It can*/
83 /* be safely changed to something greater or less than the default.  It   */
84 /* controls how much memory Linux will allocate per remote partition it is*/
85 /* communicating with.  The user can play with this to see how it affects */
86 /* performance, packets dropped, etc.  Without trying to understand the   */
87 /* complete driver, it can be thought of as the maximum number of packets */
88 /* outstanding to a remote partition at a time.                           */
89 /*                                                                        */
90 /**************************************************************************/
91
92 #include <linux/config.h>
93 #include <linux/module.h>
94 #include <linux/version.h>
95 #include <linux/types.h>
96 #include <linux/errno.h>
97 #include <linux/ioport.h>
98 #include <linux/pci.h>
99 #include <linux/kernel.h>
100 #include <linux/netdevice.h>
101 #include <linux/etherdevice.h>
102 #include <linux/skbuff.h>
103 #include <linux/init.h>
104 #include <linux/delay.h>
105 #include <linux/mm.h>
106 #include <asm/iSeries/mf.h>
107
108 #ifndef _VETH_H
109 #include "veth.h"
110 #endif
111 #ifndef _HVLPCONFIG_H
112 #include <asm/iSeries/HvLpConfig.h>
113 #endif
114 #ifndef _VETH_PROC_H
115 #include <asm/iSeries/veth-proc.h>
116 #endif
117 #ifndef _HVTYPES_H
118 #include <asm/iSeries/HvTypes.h>
119 #endif
120 #ifndef _ISERIES_PROC_H
121 #include <asm/iSeries/iSeries_proc.h>
122 #endif
123 #include <asm/semaphore.h>
124 #include <linux/proc_fs.h>
125
126
127 #define veth_printk(fmt, args...) \
128 printk(KERN_INFO "%s: " fmt, __FILE__, ## args)
129
130 #define veth_error_printk(fmt, args...) \
131 printk(KERN_ERR "(%s:%3.3d) ERROR: " fmt, __FILE__, __LINE__ , ## args)
132
133 #ifdef MODULE
134     #define VIRT_TO_ABSOLUTE(a) virt_to_absolute_outline(a)
135 #else
136     #define VIRT_TO_ABSOLUTE(a) virt_to_absolute(a)
137 #endif
138
139 static const char __initdata *version = 
140 "v0.9 02/15/2001  Kyle Lucke, klucke@us.ibm.com\n";
141
142 static int probed __initdata = 0;
143 #define VethBuffersToAllocate 120
144
145 static struct VethFabricMgr *mFabricMgr = NULL;
146 static struct proc_dir_entry * veth_proc_root = NULL;
147
148 DECLARE_MUTEX_LOCKED(VethProcSemaphore);
149
150 static int veth_open(struct net_device *dev);
151 static int veth_close(struct net_device *dev);
152 static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev);
153 static int veth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
154 static void veth_handleEvent(struct HvLpEvent *, struct pt_regs *);
155 static void veth_handleAck(struct HvLpEvent *);
156 static void veth_handleInt(struct HvLpEvent *);
157 static void veth_openConnections(void);
158 static void veth_openConnection(u8, int lockMe);
159 static void veth_closeConnection(u8, int lockMe);
160 static void veth_intFinishOpeningConnections(void *, int number);
161 static void veth_finishOpeningConnections(void *);
162 static void veth_finishOpeningConnectionsLocked(struct VethLpConnection *);
163 static int veth_multicast_wanted(struct VethPort *port, u64 dest);
164 static void veth_set_multicast_list(struct net_device *dev);
165
166 static void veth_sendCap(struct VethLpConnection *);
167 static void veth_sendMonitor(struct VethLpConnection *);
168 static void veth_takeCap(struct VethLpConnection *, struct VethLpEvent *);
169 static void veth_takeCapAck(struct VethLpConnection *, struct VethLpEvent *);
170 static void veth_takeMonitorAck(struct VethLpConnection *, struct VethLpEvent *);
171 static void veth_msgsInit(struct VethLpConnection *connection);
172 static void veth_recycleMsg(struct VethLpConnection *, u16);
173 static void veth_capBh(struct VethLpConnection *);
174 static void veth_capAckBh(struct VethLpConnection *);
175 static void veth_monitorAckBh(struct VethLpConnection *);
176 static void veth_takeFrames(struct VethLpConnection *, struct VethLpEvent *);
177 static void veth_pTransmit(struct sk_buff *skb, HvLpIndex remoteLp, struct net_device *dev);
178 static struct net_device_stats *veth_get_stats(struct net_device *dev);
179 static void veth_intFinishMsgsInit(void *, int);
180 static void veth_finishMsgsInit(struct VethLpConnection *connection);
181 static void veth_intFinishCapBh(void *, int);
182 static void veth_finishCapBh(struct VethLpConnection *connection);
183 static void veth_finishCapBhLocked(struct VethLpConnection *connection);
184 static void veth_finishSendCap(struct VethLpConnection *connection);
185 static void veth_timedAck(unsigned long connectionPtr);
186 #ifdef MODULE
187 static void veth_waitForEnd(void);
188 #endif
189 static void veth_failMe(struct VethLpConnection *connection);
190
191 extern struct pci_dev * iSeries_veth_dev;
192
193 int __init veth_probe(void)
194 {
195     struct net_device *dev= NULL;
196     struct VethPort *port = NULL;
197     int vlansFound = 0;
198     int displayVersion = 0;
199
200     u16 vlanMap = HvLpConfig_getVirtualLanIndexMap(); 
201     int vlanIndex = 0;
202
203     if (probed)
204         return -ENODEV;
205     probed = 1;
206
207     while (vlanMap != 0)
208     {
209         int bitOn = vlanMap & 0x8000;
210
211         if (bitOn)
212         {
213             vlansFound++;
214
215             dev = init_etherdev(NULL, sizeof(struct VethPort));
216
217             if (dev == NULL) {
218                 veth_error_printk("Unable to allocate net_device structure!\n");
219                 break;
220             }
221
222             if (!dev->priv)
223                 dev->priv = kmalloc(sizeof(struct VethPort), GFP_KERNEL);
224             if (!dev->priv) {
225                 veth_error_printk("Unable to allocate memory\n");
226                 return -ENOMEM;
227             }
228
229             veth_printk("Found an ethernet device %s (veth=%d) (addr=%p)\n", dev->name, vlanIndex, dev);
230             port = mFabricMgr->mPorts[vlanIndex] = (struct VethPort *)dev->priv;
231             memset(port, 0, sizeof(struct VethPort));
232             rwlock_init(&(port->mMcastGate));
233             mFabricMgr->mPorts[vlanIndex]->mDev = dev;
234
235             dev->dev_addr[0] = 0x02;
236             dev->dev_addr[1] = 0x01;
237             dev->dev_addr[2] = 0xFF;
238             dev->dev_addr[3] = vlanIndex; 
239             dev->dev_addr[4] = 0xFF;
240             dev->dev_addr[5] = HvLpConfig_getLpIndex_outline();
241             dev->mtu = 9000;
242
243             memcpy(&(port->mMyAddress), dev->dev_addr, 6);
244
245             dev->open = &veth_open;
246             dev->hard_start_xmit = &veth_start_xmit;
247             dev->stop = &veth_close;
248             dev->get_stats = veth_get_stats;
249             dev->set_multicast_list = &veth_set_multicast_list;
250             dev->do_ioctl = &veth_ioctl;
251
252             /* display version info if adapter is found */
253             if (!displayVersion)
254             {
255                 /* set display flag to TRUE so that */
256                 /* we only display this string ONCE */
257                 displayVersion = 1;
258                 veth_printk("%s", version);
259             }
260
261         }
262
263         ++vlanIndex;
264         vlanMap = vlanMap << 1;
265     }
266
267     if (vlansFound > 0)
268         return 0;
269     else
270         return -ENODEV;
271 }
272
273 #ifdef MODULE
274 MODULE_AUTHOR("Kyle Lucke <klucke@us.ibm.com>");
275 MODULE_DESCRIPTION("iSeries Virtual ethernet driver");
276
277 DECLARE_MUTEX_LOCKED(VethModuleBhDone);
278 int VethModuleReopen = 1;
279
280 void veth_proc_delete(struct proc_dir_entry *iSeries_proc)
281 {
282     int i=0;
283     HvLpIndex thisLp = HvLpConfig_getLpIndex_outline();
284     u16 vlanMap = HvLpConfig_getVirtualLanIndexMap(); 
285     int vlanIndex = 0;
286
287     for (i=0; i < HvMaxArchitectedLps; ++i)
288     {
289         if (i != thisLp)
290         {
291             if (HvLpConfig_doLpsCommunicateOnVirtualLan(thisLp, i))
292             {
293                 char name[10] = "";
294                 sprintf(name, "lpar%d", i);
295                 remove_proc_entry(name, veth_proc_root);
296             }
297         }
298     }
299
300     while (vlanMap != 0)
301     {
302         int bitOn = vlanMap & 0x8000;
303
304         if (bitOn)
305         {
306             char name[10] = "";
307             sprintf(name, "veth%d", vlanIndex);
308             remove_proc_entry(name, veth_proc_root);
309         }
310
311         ++vlanIndex;
312         vlanMap = vlanMap << 1;
313     }
314
315     remove_proc_entry("veth", iSeries_proc);
316
317     up(&VethProcSemaphore);
318 }
319
320 void veth_waitForEnd(void)
321 {
322     up(&VethModuleBhDone);
323 }
324
325 void __exit veth_module_cleanup(void)
326 {
327     int i;
328     struct VethFabricMgr *myFm = mFabricMgr;
329     struct tq_struct myBottomHalf;
330     struct net_device *thisOne = NULL;
331
332     VethModuleReopen = 0;
333
334     for (i = 0; i < HvMaxArchitectedLps; ++i)
335     {
336         veth_closeConnection(i, 1);
337     }
338
339     myBottomHalf.routine = (void *)(void *)veth_waitForEnd;
340
341     queue_task(&myBottomHalf, &tq_immediate);
342     mark_bh(IMMEDIATE_BH);
343
344     down(&VethModuleBhDone);
345
346     HvLpEvent_unregisterHandler(HvLpEvent_Type_VirtualLan);
347
348     mb();
349     mFabricMgr = NULL;
350     mb();
351
352     down(&VethProcSemaphore);
353
354     iSeries_proc_callback(&veth_proc_delete);
355
356     down(&VethProcSemaphore);
357
358     for (i = 0; i < HvMaxArchitectedLps; ++i)
359     {
360         if (myFm->mConnection[i].mNumberAllocated + myFm->mConnection[i].mNumberRcvMsgs > 0)
361         {
362             mf_deallocateLpEvents(myFm->mConnection[i].mRemoteLp,
363                                   HvLpEvent_Type_VirtualLan,
364                                   myFm->mConnection[i].mNumberAllocated + myFm->mConnection[i].mNumberRcvMsgs,
365                                   NULL,
366                                   NULL);
367         }
368
369         if (myFm->mConnection[i].mMsgs != NULL)
370         {
371             kfree(myFm->mConnection[i].mMsgs);
372         }
373     }
374
375     for (i = 0; i < HvMaxArchitectedVirtualLans; ++i)
376     {
377         if (myFm->mPorts[i] != NULL)
378         {
379             thisOne = myFm->mPorts[i]->mDev;
380             myFm->mPorts[i] = NULL;
381
382             mb();
383
384             if (thisOne != NULL)
385             {
386                 veth_printk("Unregistering %s (veth=%d)\n", thisOne->name, i);
387                 unregister_netdev(thisOne);
388             }
389         }
390     }
391
392     kfree(myFm);
393 }
394
395 module_exit(veth_module_cleanup);
396 #endif
397
398
399 void veth_proc_init(struct proc_dir_entry *iSeries_proc)
400 {
401     long i=0;
402     HvLpIndex thisLp = HvLpConfig_getLpIndex_outline();
403     u16 vlanMap = HvLpConfig_getVirtualLanIndexMap(); 
404     long vlanIndex = 0;
405
406
407     veth_proc_root = proc_mkdir("veth", iSeries_proc);
408     if (!veth_proc_root) return;
409
410     for (i=0; i < HvMaxArchitectedLps; ++i)
411     {
412         if (i != thisLp)
413         {
414             if (HvLpConfig_doLpsCommunicateOnVirtualLan(thisLp, i))
415             {
416                 struct proc_dir_entry *ent;
417                 char name[10] = "";
418                 sprintf(name, "lpar%d", (int)i);
419                 ent = create_proc_entry(name, S_IFREG|S_IRUSR, veth_proc_root);
420                 if (!ent) return;
421                 ent->nlink = 1;
422                 ent->data = (void *)i;
423                 ent->read_proc = proc_veth_dump_connection;
424                 ent->write_proc = NULL;
425             }
426         }
427     }
428
429     while (vlanMap != 0)
430     {
431         int bitOn = vlanMap & 0x8000;
432
433         if (bitOn)
434         {
435             struct proc_dir_entry *ent;
436             char name[10] = "";
437             sprintf(name, "veth%d", (int)vlanIndex);
438             ent = create_proc_entry(name, S_IFREG|S_IRUSR, veth_proc_root);
439             if (!ent) return;
440             ent->nlink = 1;
441             ent->data = (void *)vlanIndex;
442             ent->read_proc = proc_veth_dump_port;
443             ent->write_proc = NULL;
444         }
445
446         ++vlanIndex;
447         vlanMap = vlanMap << 1;
448     }
449
450     up(&VethProcSemaphore);
451 }
452
453 int __init veth_module_init(void)
454 {
455     int status;
456     int i;
457
458     mFabricMgr = kmalloc(sizeof(struct VethFabricMgr), GFP_KERNEL);
459     memset(mFabricMgr, 0, sizeof(struct VethFabricMgr));
460     veth_printk("Initializing veth module, fabric mgr (address=%p)\n", mFabricMgr);
461
462     mFabricMgr->mEyecatcher = 0x56455448464D4752ULL;
463     mFabricMgr->mThisLp = HvLpConfig_getLpIndex_outline();
464
465     for (i=0; i < HvMaxArchitectedLps; ++i)
466     {
467         mFabricMgr->mConnection[i].mEyecatcher = 0x564554484C50434EULL;
468         veth_failMe(mFabricMgr->mConnection+i);
469         spin_lock_init(&mFabricMgr->mConnection[i].mAckGate);
470         spin_lock_init(&mFabricMgr->mConnection[i].mStatusGate);
471     }
472
473     status = veth_probe();
474
475     if (status == 0)
476     {
477         veth_openConnections();
478     }
479
480     iSeries_proc_callback(&veth_proc_init);
481
482     return status;
483 }
484
485 module_init(veth_module_init);
486
487 static void veth_failMe(struct VethLpConnection *connection)
488 {
489     connection->mConnectionStatus.mSentCap = 0;
490     connection->mConnectionStatus.mCapAcked = 0;
491     connection->mConnectionStatus.mGotCap = 0;
492     connection->mConnectionStatus.mGotCapAcked = 0;
493     connection->mConnectionStatus.mSentMonitor = 0;
494     connection->mConnectionStatus.mFailed = 1;
495 }
496
497 static int veth_open(struct net_device *dev)
498 {
499     struct VethPort *port = (struct VethPort *)dev->priv;
500
501     memset(&port->mStats, 0, sizeof(port->mStats));
502     MOD_INC_USE_COUNT;
503
504     netif_start_queue(dev);
505
506     return 0;
507 }
508
509 static int veth_close(struct net_device *dev)
510 {
511     netif_stop_queue(dev);
512
513     MOD_DEC_USE_COUNT;
514
515     return 0;
516 }
517
518 static struct net_device_stats *veth_get_stats(struct net_device *dev)
519 {
520     struct VethPort *port = (struct VethPort *)dev->priv;
521
522     return(&port->mStats);
523 }
524
525
526 static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev)
527 {
528     unsigned char *frame = skb->data;
529     HvLpIndex remoteLp = frame[5];
530     int i = 0;
531     int clone = 0;
532
533     if (mFabricMgr == NULL)
534     {
535         veth_error_printk("NULL fabric manager with active ports!\n");
536         netif_stop_queue(dev);
537         return 1;
538     }
539
540     mb();
541
542     if ((*frame & 0x01) != 0x01) /* broadcast or multicast */
543     {
544         if ((remoteLp != mFabricMgr->mThisLp) &&
545             (HvLpConfig_doLpsCommunicateOnVirtualLan(mFabricMgr->mThisLp, remoteLp)))
546             veth_pTransmit(skb, remoteLp, dev);
547     }
548     else
549     {
550         for (i=0; i < HvMaxArchitectedLps; ++i)
551         {
552             if (i != mFabricMgr->mThisLp)
553             {
554                 if (clone)
555                     skb = skb_clone(skb, GFP_ATOMIC);
556                 else
557                     clone = 1;
558
559                 if (HvLpConfig_doLpsCommunicateOnVirtualLan(mFabricMgr->mThisLp, i))
560                 {
561                     /* the ack handles deleting the skb */
562                     veth_pTransmit(skb, i, dev);
563                 }
564             }
565         }
566     }
567
568     return 0;
569 }
570
571 static void veth_pTransmit(struct sk_buff *skb, HvLpIndex remoteLp, struct net_device *dev)
572 {
573     struct VethLpConnection *connection = mFabricMgr->mConnection + remoteLp;
574     HvLpEvent_Rc returnCode;
575
576     if (connection->mConnectionStatus.mFailed != 1)
577     {
578         struct VethMsg *msg = NULL;
579         VETHSTACKPOP(&(connection->mMsgStack), msg);
580
581         if (msg != NULL)
582         {
583             if ((skb->len > 14) &&
584                 (skb->len <= 9018))
585             {
586                 dma_addr_t dma_addr = pci_map_single(iSeries_veth_dev,
587                                                      skb->data,
588                                                      skb->len,
589                                                      PCI_DMA_TODEVICE);
590
591                 
592
593                 if (dma_addr != -1)
594                 {
595                     msg->mSkb = skb;
596                     msg->mEvent.mSendData.mAddress[0] = dma_addr;
597                     msg->mEvent.mSendData.mLength[0] = skb->len;
598                     msg->mEvent.mSendData.mEofMask = 0xFFFFFFFFUL;
599
600                     test_and_set_bit(0, &(msg->mInUse));
601
602                     returnCode = HvCallEvent_signalLpEventFast(remoteLp,
603                                                                HvLpEvent_Type_VirtualLan,
604                                                                VethEventTypeFrames,
605                                                                HvLpEvent_AckInd_NoAck,
606                                                                HvLpEvent_AckType_ImmediateAck,
607                                                                connection->mSourceInst,
608                                                                connection->mTargetInst,
609                                                                msg->mIndex,
610                                                                msg->mEvent.mFpData.mData1,
611                                                                msg->mEvent.mFpData.mData2,
612                                                                msg->mEvent.mFpData.mData3,
613                                                                msg->mEvent.mFpData.mData4,
614                                                                msg->mEvent.mFpData.mData5);
615                 } 
616                 else
617                 {
618                     returnCode = -1; /* Bad return code */
619                 }
620
621                 if (returnCode != HvLpEvent_Rc_Good)
622                 {
623                     struct VethPort *port = (struct VethPort *)dev->priv;
624
625                     if (msg->mEvent.mSendData.mAddress[0])
626                     {
627                         pci_unmap_single(iSeries_veth_dev, dma_addr, skb->len, PCI_DMA_TODEVICE);
628                     }
629
630                     dev_kfree_skb_irq(skb);
631
632                     msg->mSkb = NULL;
633                     memset(&(msg->mEvent.mSendData), 0, sizeof(struct VethFramesData));
634                     VETHSTACKPUSH(&(connection->mMsgStack), msg);
635                     port->mStats.tx_dropped++;
636                 }
637                 else
638                 {
639                     struct VethPort *port = (struct VethPort *)dev->priv;
640                     port->mStats.tx_packets++;
641                     port->mStats.tx_bytes += skb->len;
642                 }
643             }
644         }
645         else
646         {
647             struct VethPort *port = (struct VethPort *)dev->priv;
648             port->mStats.tx_dropped++;
649         }
650     }
651     else
652     {
653         struct VethPort *port = (struct VethPort *)dev->priv;
654         port->mStats.tx_dropped++;
655     }
656 }
657
658 static int veth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
659 {
660
661     return -EOPNOTSUPP;
662 }
663
664 static void veth_set_multicast_list(struct net_device *dev)
665 {
666     char *addrs;
667     struct VethPort *port = (struct VethPort *)dev->priv;
668     u64 newAddress = 0;
669     unsigned long flags;
670
671     write_lock_irqsave(&port->mMcastGate, flags);
672
673     if (dev->flags & IFF_PROMISC) {             /* set promiscuous mode */
674         port->mPromiscuous = 1;
675     } else {
676         struct dev_mc_list *dmi = dev->mc_list;
677
678         if (dev->flags & IFF_ALLMULTI) {
679             port->mAllMcast = 1;
680         } else {
681             int i;
682             /* Update table */
683             port->mNumAddrs = 0;
684
685             for (i = 0; ((i < dev->mc_count) && (i < 12)); i++) {       /* for each address in the list */
686                 addrs = dmi->dmi_addr;
687                 dmi = dmi->next;
688                 if ((*addrs & 0x01) == 1) {     /* multicast address? */
689                     memcpy(&newAddress, addrs, 6);
690                     newAddress &= 0xFFFFFFFFFFFF0000;
691
692                     port->mMcasts[port->mNumAddrs] = newAddress;
693                     mb();
694                     port->mNumAddrs = port->mNumAddrs + 1;
695                 }
696             }
697         }
698     }
699
700     write_unlock_irqrestore(&port->mMcastGate, flags);
701 }
702
703
704 static void veth_handleEvent(struct HvLpEvent *event, struct pt_regs *regs)
705 {
706     if (event->xFlags.xFunction == HvLpEvent_Function_Ack)
707     {
708         veth_handleAck(event);
709     }
710     else if (event->xFlags.xFunction == HvLpEvent_Function_Int)
711     {
712         veth_handleInt(event);
713     }
714 }
715
716 static void veth_handleAck(struct HvLpEvent *event)
717 {
718     struct VethLpConnection *connection = &(mFabricMgr->mConnection[event->xTargetLp]);
719     struct VethLpEvent *vethEvent = (struct VethLpEvent *)event;
720
721     switch(event->xSubtype)
722     {
723         case VethEventTypeCap:
724             {
725                 veth_takeCapAck(connection, vethEvent);
726                 break;
727             }
728         case VethEventTypeMonitor:
729             {
730                 veth_takeMonitorAck(connection, vethEvent);
731                 break;
732             }
733         default:
734             {
735                 veth_error_printk("Unknown ack type %d from lpar %d\n", event->xSubtype, connection->mRemoteLp);
736             }
737     };
738 }
739
740 static void veth_handleInt(struct HvLpEvent *event)
741 {
742     int i=0;
743     struct VethLpConnection *connection = &(mFabricMgr->mConnection[event->xSourceLp]);
744     struct VethLpEvent *vethEvent = (struct VethLpEvent *)event;
745
746     switch(event->xSubtype)
747     {
748         case VethEventTypeCap:
749             {
750                 veth_takeCap(connection, vethEvent);
751                 break;
752             }
753         case VethEventTypeMonitor:
754             {
755                 /* do nothing... this'll hang out here til we're dead, and the hypervisor will return it for us. */
756                 break;
757             }
758         case VethEventTypeFramesAck:
759             {
760                 for (i=0; i < VethMaxFramesMsgsAcked; ++i)
761                 {
762                     u16 msg = vethEvent->mDerivedData.mFramesAckData.mToken[i];
763                     veth_recycleMsg(connection, msg);
764                 }
765                 break;
766             }
767         case VethEventTypeFrames:
768             {
769                 veth_takeFrames(connection, vethEvent);
770                 break;
771             }
772         default:
773             {
774                 veth_error_printk("Unknown interrupt type %d from lpar %d\n", event->xSubtype, connection->mRemoteLp);
775             }
776     };
777 }
778
779 static void veth_openConnections()
780 {
781     int i=0;
782
783     HvLpEvent_registerHandler(HvLpEvent_Type_VirtualLan, &veth_handleEvent);
784
785     /* Now I need to run through the active lps and open connections to the ones I'm supposed to
786      open to. */
787
788     for (i=HvMaxArchitectedLps-1; i >=0; --i)
789     {
790         if (i != mFabricMgr->mThisLp)
791         {
792             if (HvLpConfig_doLpsCommunicateOnVirtualLan(mFabricMgr->mThisLp, i))
793             {
794                 veth_openConnection(i, 1);
795             }
796             else
797             {
798                 veth_closeConnection(i, 1);
799             }
800         }       
801     }
802 }
803
804 static void veth_intFinishOpeningConnections(void *parm, int number)
805 {
806     struct VethLpConnection *connection = (struct VethLpConnection *)parm;
807     connection->mAllocBhTq.data = parm;
808     connection->mNumberAllocated = number;
809     queue_task(&connection->mAllocBhTq, &tq_immediate);
810     mark_bh(IMMEDIATE_BH);
811 }
812
813 static void veth_finishOpeningConnections(void *parm)
814 {
815     unsigned long flags;
816     struct VethLpConnection *connection = (struct VethLpConnection *)parm;
817     spin_lock_irqsave(&connection->mStatusGate, flags);
818     veth_finishOpeningConnectionsLocked(connection);
819     spin_unlock_irqrestore(&connection->mStatusGate, flags);
820 }
821
822 static void veth_finishOpeningConnectionsLocked(struct VethLpConnection *connection)
823 {
824     if (connection->mNumberAllocated >= 2)
825     {
826         connection->mConnectionStatus.mCapMonAlloced = 1;
827         veth_sendCap(connection);
828     }
829     else
830     {
831         veth_error_printk("Couldn't allocate base msgs for lpar %d, only got %d\n", connection->mRemoteLp, connection->mNumberAllocated);
832         veth_failMe(connection);
833     }
834 }
835
836 static void veth_openConnection(u8 remoteLp, int lockMe)
837 {
838     unsigned long flags;
839     unsigned long flags2;
840     HvLpInstanceId source;
841     HvLpInstanceId target;
842     u64 i = 0;
843     struct VethLpConnection *connection = &(mFabricMgr->mConnection[remoteLp]);
844
845     memset(&connection->mCapBhTq, 0, sizeof(connection->mCapBhTq));
846     connection->mCapBhTq.routine = (void *)(void *)veth_capBh;
847
848     memset(&connection->mCapAckBhTq, 0, sizeof(connection->mCapAckBhTq));
849     connection->mCapAckBhTq.routine = (void *)(void *)veth_capAckBh;
850
851     memset(&connection->mMonitorAckBhTq, 0, sizeof(connection->mMonitorAckBhTq));
852     connection->mMonitorAckBhTq.routine = (void *)(void *)veth_monitorAckBh;
853
854     memset(&connection->mAllocBhTq, 0, sizeof(connection->mAllocBhTq));
855     connection->mAllocBhTq.routine = (void *)(void *)veth_finishOpeningConnections;
856
857     if (lockMe)
858         spin_lock_irqsave(&connection->mStatusGate, flags);
859
860     connection->mRemoteLp = remoteLp;
861
862     spin_lock_irqsave(&connection->mAckGate, flags2);
863
864     memset(&connection->mEventData, 0xFF, sizeof(connection->mEventData));
865     connection->mNumAcks = 0;
866
867     HvCallEvent_openLpEventPath(remoteLp, HvLpEvent_Type_VirtualLan);
868
869     /* clean up non-acked msgs */
870     for (i=0; i < connection->mNumMsgs; ++i)
871     {
872         veth_recycleMsg(connection, i);
873     }
874
875     connection->mConnectionStatus.mOpen = 1;
876
877     source = connection->mSourceInst = HvCallEvent_getSourceLpInstanceId(remoteLp, HvLpEvent_Type_VirtualLan);
878     target = connection->mTargetInst = HvCallEvent_getTargetLpInstanceId(remoteLp, HvLpEvent_Type_VirtualLan);
879
880     if (connection->mConnectionStatus.mCapMonAlloced != 1)
881     {
882         connection->mAllocBhTq.routine = (void *)(void *)veth_finishOpeningConnections;
883         mf_allocateLpEvents(remoteLp,
884                             HvLpEvent_Type_VirtualLan,
885                             sizeof(struct VethLpEvent),
886                             2,
887                             &veth_intFinishOpeningConnections,
888                             connection);
889     }
890     else
891     {
892         veth_finishOpeningConnectionsLocked(connection);
893     }
894
895     spin_unlock_irqrestore(&connection->mAckGate, flags2);
896
897     if (lockMe)
898         spin_unlock_irqrestore(&connection->mStatusGate, flags);
899 }
900
901 static void veth_closeConnection(u8 remoteLp, int lockMe)
902 {
903     struct VethLpConnection *connection = &(mFabricMgr->mConnection[remoteLp]);
904     unsigned long flags;
905     unsigned long flags2;
906     if (lockMe)
907         spin_lock_irqsave(&connection->mStatusGate, flags);
908
909     del_timer(&connection->mAckTimer);
910
911     if (connection->mConnectionStatus.mOpen == 1)
912     {
913         HvCallEvent_closeLpEventPath(remoteLp, HvLpEvent_Type_VirtualLan);
914         connection->mConnectionStatus.mOpen = 0;
915         veth_failMe(connection);
916
917         /* reset ack data */
918         spin_lock_irqsave(&connection->mAckGate, flags2);
919
920         memset(&connection->mEventData, 0xFF, sizeof(connection->mEventData));
921         connection->mNumAcks = 0;
922
923         spin_unlock_irqrestore(&connection->mAckGate, flags2);
924     }
925
926     if (lockMe)
927         spin_unlock_irqrestore(&connection->mStatusGate, flags);
928 }
929
930 static void veth_msgsInit(struct VethLpConnection *connection)
931 {
932     connection->mAllocBhTq.routine = (void *)(void *)veth_finishMsgsInit;
933     mf_allocateLpEvents(connection->mRemoteLp,
934                         HvLpEvent_Type_VirtualLan,
935                         sizeof(struct VethLpEvent),
936                         connection->mMyCap.mUnionData.mFields.mNumberBuffers,
937                         &veth_intFinishMsgsInit,
938                         connection);
939 }
940
941 static void veth_intFinishMsgsInit(void *parm, int number)
942 {
943     struct VethLpConnection *connection = (struct VethLpConnection *)parm;
944     connection->mAllocBhTq.data = parm;
945     connection->mNumberRcvMsgs = number;
946     queue_task(&connection->mAllocBhTq, &tq_immediate);
947     mark_bh(IMMEDIATE_BH);
948 }
949
950 static void veth_intFinishCapBh(void *parm, int number)
951 {
952     struct VethLpConnection *connection = (struct VethLpConnection *)parm;
953     connection->mAllocBhTq.data = parm;
954     if (number > 0)
955         connection->mNumberLpAcksAlloced += number;
956
957     queue_task(&connection->mAllocBhTq, &tq_immediate);
958     mark_bh(IMMEDIATE_BH);
959 }
960
961 static void veth_finishMsgsInit(struct VethLpConnection *connection)
962 {
963     int i=0;
964     unsigned int numberGotten = 0;
965     u64 amountOfHeapToGet = connection->mMyCap.mUnionData.mFields.mNumberBuffers * sizeof(struct VethMsg);
966     char *msgs = NULL;
967     unsigned long flags;
968     spin_lock_irqsave(&connection->mStatusGate, flags);
969
970     if (connection->mNumberRcvMsgs >= connection->mMyCap.mUnionData.mFields.mNumberBuffers)
971     {
972         msgs = kmalloc(amountOfHeapToGet, GFP_ATOMIC);
973
974         connection->mMsgs = (struct VethMsg *)msgs;
975
976         if (msgs != NULL)
977         {
978             memset(msgs, 0, amountOfHeapToGet);
979
980             for (i=0; i < connection->mMyCap.mUnionData.mFields.mNumberBuffers; ++i)
981             {
982                 connection->mMsgs[i].mIndex = i;
983                 ++numberGotten;
984                 VETHSTACKPUSH(&(connection->mMsgStack), (connection->mMsgs+i));
985             }
986             if (numberGotten > 0)
987             {
988                 connection->mNumMsgs = numberGotten;
989             }
990         }
991         else
992         {
993             kfree(msgs);
994             connection->mMsgs = NULL;
995         }
996     }
997
998     connection->mMyCap.mUnionData.mFields.mNumberBuffers = connection->mNumMsgs;
999
1000     if (connection->mNumMsgs < 10)
1001         connection->mMyCap.mUnionData.mFields.mThreshold = 1;
1002     else if (connection->mNumMsgs < 20)
1003         connection->mMyCap.mUnionData.mFields.mThreshold = 4;
1004     else if (connection->mNumMsgs < 40)
1005         connection->mMyCap.mUnionData.mFields.mThreshold = 10;
1006     else
1007         connection->mMyCap.mUnionData.mFields.mThreshold = 20;
1008
1009     connection->mMyCap.mUnionData.mFields.mTimer = VethAckTimeoutUsec;
1010
1011     veth_finishSendCap(connection);
1012
1013     spin_unlock_irqrestore(&connection->mStatusGate, flags);
1014 }
1015
1016 static void veth_sendCap(struct VethLpConnection *connection)
1017 {
1018     if (connection->mMsgs == NULL)
1019     {
1020         connection->mMyCap.mUnionData.mFields.mNumberBuffers = VethBuffersToAllocate;
1021         veth_msgsInit(connection);
1022     }
1023     else
1024     {
1025         veth_finishSendCap(connection);
1026     }
1027 }
1028
1029 static void veth_finishSendCap(struct VethLpConnection *connection)
1030 {
1031     HvLpEvent_Rc returnCode = HvCallEvent_signalLpEventFast(connection->mRemoteLp,
1032                                                             HvLpEvent_Type_VirtualLan,
1033                                                             VethEventTypeCap,
1034                                                             HvLpEvent_AckInd_DoAck,
1035                                                             HvLpEvent_AckType_ImmediateAck,
1036                                                             connection->mSourceInst,
1037                                                             connection->mTargetInst,
1038                                                             0,
1039                                                             connection->mMyCap.mUnionData.mNoFields.mReserved1,
1040                                                             connection->mMyCap.mUnionData.mNoFields.mReserved2,
1041                                                             connection->mMyCap.mUnionData.mNoFields.mReserved3,
1042                                                             connection->mMyCap.mUnionData.mNoFields.mReserved4,
1043                                                             connection->mMyCap.mUnionData.mNoFields.mReserved5);
1044
1045     if ((returnCode == HvLpEvent_Rc_PartitionDead) ||
1046         (returnCode == HvLpEvent_Rc_PathClosed))
1047     {
1048         connection->mConnectionStatus.mSentCap = 0;
1049     }
1050     else if (returnCode != HvLpEvent_Rc_Good)
1051     {
1052         veth_error_printk("Couldn't send cap to lpar %d, rc %x\n", connection->mRemoteLp, (int)returnCode);
1053         veth_failMe(connection);
1054     }
1055     else
1056     {
1057         connection->mConnectionStatus.mSentCap = 1;
1058     }
1059 }
1060
1061 static void veth_takeCap(struct VethLpConnection *connection, struct VethLpEvent *event)
1062 {
1063     if (!test_and_set_bit(0,&(connection->mCapBhPending)))
1064     {
1065         connection->mCapBhTq.data = connection;
1066         memcpy(&connection->mCapEvent, event, sizeof(connection->mCapEvent));
1067         queue_task(&connection->mCapBhTq, &tq_immediate);
1068         mark_bh(IMMEDIATE_BH);
1069     }
1070     else
1071     {
1072         veth_error_printk("Received a capabilities from lpar %d while already processing one\n", connection->mRemoteLp);
1073         event->mBaseEvent.xRc = HvLpEvent_Rc_BufferNotAvailable;
1074         HvCallEvent_ackLpEvent((struct HvLpEvent *)event);
1075     }
1076 }
1077
1078 static void veth_takeCapAck(struct VethLpConnection *connection, struct VethLpEvent *event)
1079 {
1080     if (!test_and_set_bit(0,&(connection->mCapAckBhPending)))
1081     {
1082         connection->mCapAckBhTq.data = connection;
1083         memcpy(&connection->mCapAckEvent, event, sizeof(connection->mCapAckEvent));
1084         queue_task(&connection->mCapAckBhTq, &tq_immediate);
1085         mark_bh(IMMEDIATE_BH);
1086     }
1087     else
1088     {
1089         veth_error_printk("Received a capabilities ack from lpar %d while already processing one\n", connection->mRemoteLp);
1090     }
1091 }
1092
1093 static void veth_takeMonitorAck(struct VethLpConnection *connection, struct VethLpEvent *event)
1094 {
1095     if (!test_and_set_bit(0,&(connection->mMonitorAckBhPending)))
1096     {
1097         connection->mMonitorAckBhTq.data = connection;
1098         memcpy(&connection->mMonitorAckEvent, event, sizeof(connection->mMonitorAckEvent));
1099         queue_task(&connection->mMonitorAckBhTq, &tq_immediate);
1100         mark_bh(IMMEDIATE_BH);
1101     }
1102     else
1103     {
1104         veth_error_printk("Received a monitor ack from lpar %d while already processing one\n", connection->mRemoteLp);
1105     }
1106 }
1107
1108 static void veth_recycleMsg(struct VethLpConnection *connection, u16 msg)
1109 {
1110     if (msg < connection->mNumMsgs)
1111     {
1112         struct VethMsg *myMsg = connection->mMsgs + msg;
1113         if (test_and_clear_bit(0, &(myMsg->mInUse)))
1114         {
1115             pci_unmap_single(iSeries_veth_dev, 
1116                              myMsg->mEvent.mSendData.mAddress[0],
1117                              myMsg->mEvent.mSendData.mLength[0],
1118                              PCI_DMA_TODEVICE);
1119             dev_kfree_skb_irq(myMsg->mSkb);
1120
1121             myMsg->mSkb = NULL;
1122             memset(&(myMsg->mEvent.mSendData), 0, sizeof(struct VethFramesData));
1123             VETHSTACKPUSH(&connection->mMsgStack, myMsg);
1124         }
1125         else
1126         {
1127             if (connection->mConnectionStatus.mOpen)
1128             {
1129                 veth_error_printk("Received a frames ack for msg %d from lpar %d while not outstanding\n", msg, connection->mRemoteLp);
1130             }
1131         }
1132     }
1133 }
1134
1135 static void veth_capBh(struct VethLpConnection *connection)
1136 {
1137     struct VethLpEvent *event = &connection->mCapEvent;
1138     unsigned long flags;
1139     struct VethCapData *remoteCap = &(connection->mRemoteCap);
1140     u64 numAcks = 0;
1141     spin_lock_irqsave(&connection->mStatusGate, flags);
1142     connection->mConnectionStatus.mGotCap = 1;
1143
1144     memcpy(remoteCap, &(event->mDerivedData.mCapabilitiesData), sizeof(connection->mRemoteCap));
1145
1146     if ((remoteCap->mUnionData.mFields.mNumberBuffers <= VethMaxFramesMsgs) &&
1147         (remoteCap->mUnionData.mFields.mNumberBuffers != 0) &&
1148         (remoteCap->mUnionData.mFields.mThreshold <= VethMaxFramesMsgsAcked) &&
1149         (remoteCap->mUnionData.mFields.mThreshold != 0))
1150     {
1151         numAcks = (remoteCap->mUnionData.mFields.mNumberBuffers / remoteCap->mUnionData.mFields.mThreshold) + 1;
1152
1153         if (connection->mNumberLpAcksAlloced < numAcks)
1154         {
1155             numAcks = numAcks - connection->mNumberLpAcksAlloced;
1156             connection->mAllocBhTq.routine = (void *)(void *)veth_finishCapBh;
1157             mf_allocateLpEvents(connection->mRemoteLp,
1158                                 HvLpEvent_Type_VirtualLan,
1159                                 sizeof(struct VethLpEvent),
1160                                 numAcks,
1161                                 &veth_intFinishCapBh,
1162                                 connection);
1163         }
1164         else
1165             veth_finishCapBhLocked(connection);
1166     }
1167     else
1168     {
1169         veth_error_printk("Received incompatible capabilities from lpar %d\n", connection->mRemoteLp);
1170         event->mBaseEvent.xRc = HvLpEvent_Rc_InvalidSubtypeData;
1171         HvCallEvent_ackLpEvent((struct HvLpEvent *)event);
1172     }
1173
1174     clear_bit(0,&(connection->mCapBhPending));
1175     spin_unlock_irqrestore(&connection->mStatusGate, flags);
1176 }
1177
1178 static void veth_capAckBh(struct VethLpConnection *connection)
1179 {
1180     struct VethLpEvent *event = &connection->mCapAckEvent;
1181     unsigned long flags;
1182
1183     spin_lock_irqsave(&connection->mStatusGate, flags);
1184
1185     if (event->mBaseEvent.xRc == HvLpEvent_Rc_Good)
1186     {
1187         connection->mConnectionStatus.mCapAcked = 1;
1188
1189         if ((connection->mConnectionStatus.mGotCap == 1) && 
1190             (connection->mConnectionStatus.mGotCapAcked == 1))
1191         {
1192             if (connection->mConnectionStatus.mSentMonitor != 1)
1193                 veth_sendMonitor(connection);
1194         }
1195     }
1196     else
1197     {
1198         veth_error_printk("Bad rc(%d) from lpar %d on capabilities\n", event->mBaseEvent.xRc, connection->mRemoteLp);
1199         veth_failMe(connection);
1200     }
1201
1202     clear_bit(0,&(connection->mCapAckBhPending));
1203     spin_unlock_irqrestore(&connection->mStatusGate, flags);
1204 }
1205
1206 static void veth_monitorAckBh(struct VethLpConnection *connection)
1207 {
1208     unsigned long flags;
1209
1210     spin_lock_irqsave(&connection->mStatusGate, flags);
1211
1212     veth_failMe(connection);
1213
1214     veth_printk("Monitor ack returned for lpar %d\n", connection->mRemoteLp);
1215
1216     if (connection->mConnectionStatus.mOpen)
1217     {
1218         veth_closeConnection(connection->mRemoteLp, 0);
1219
1220         udelay(100);
1221
1222         queue_task(&connection->mMonitorAckBhTq, &tq_immediate);
1223         mark_bh(IMMEDIATE_BH);
1224     }
1225     else
1226     {
1227 #ifdef MODULE
1228         if (VethModuleReopen)
1229 #endif
1230             veth_openConnection(connection->mRemoteLp, 0);
1231 #ifdef MODULE
1232         else
1233         {
1234             int i=0;
1235
1236             for (i=0; i < connection->mNumMsgs; ++i)
1237             {
1238                 veth_recycleMsg(connection, i);
1239             }
1240         }
1241 #endif
1242         clear_bit(0,&(connection->mMonitorAckBhPending));
1243     }
1244
1245     spin_unlock_irqrestore(&connection->mStatusGate, flags);
1246 }
1247
1248 #define number_of_pages(v, l) ((((unsigned long)(v) & ((1 << 12) - 1)) + (l) + 4096 - 1) / 4096)
1249 #define page_offset(v) ((unsigned long)(v) & ((1 << 12) - 1))
1250
1251 static void veth_takeFrames(struct VethLpConnection *connection, struct VethLpEvent *event)
1252 {
1253     int i;
1254     struct VethPort *port = NULL;
1255     struct BufList
1256     {
1257         union
1258         {
1259             struct
1260             {
1261                 u32 token2;
1262                 u32 garbage;
1263             } token1;
1264             u64 address;
1265         } addr;
1266         u64 size;
1267     };
1268
1269     struct BufList myBufList[4];
1270     struct BufList remoteList;
1271
1272     for (i=0; i < VethMaxFramesPerMsg; ++i)
1273     {
1274         u16 length = event->mDerivedData.mSendData.mLength[i];
1275         u32 address = event->mDerivedData.mSendData.mAddress[i];
1276         if ((address != 0) &&
1277             (length <= 9018) &&
1278             (length > 14))
1279         {
1280             struct sk_buff *skb = alloc_skb(event->mDerivedData.mSendData.mLength[i], GFP_ATOMIC);
1281             remoteList.addr.token1.token2 = address;
1282             remoteList.size = length;
1283             if (skb != NULL)
1284             {
1285                 HvLpDma_Rc returnCode = HvLpDma_Rc_Good;
1286                 int numPages = number_of_pages((skb->data), length);
1287
1288
1289                 myBufList[0].addr.address = (0x8000000000000000LL | (VIRT_TO_ABSOLUTE((unsigned long)skb->data)));
1290                 myBufList[0].size = (numPages > 1) ? (4096 - page_offset(skb->data)) : length;
1291
1292                 if (numPages > 1)
1293                 {
1294                     myBufList[1].addr.address = (0x8000000000000000LL | (VIRT_TO_ABSOLUTE((unsigned long) skb->data + myBufList[0].size)));
1295                     myBufList[1].size = (numPages > 2) ? (4096 - page_offset(skb->data)) : length - myBufList[0].size;
1296
1297                     if (numPages > 2)
1298                     {
1299                         myBufList[2].addr.address = (0x8000000000000000LL | (VIRT_TO_ABSOLUTE((unsigned long) skb->data + myBufList[0].size + myBufList[1].size)));
1300                         myBufList[2].size = (numPages > 3) ? (4096 - page_offset(skb->data)) : length - myBufList[1].size - myBufList[0].size;
1301
1302                         if (numPages > 3)
1303                         {
1304                             myBufList[3].addr.address = 0x8000000000000000LL | (VIRT_TO_ABSOLUTE((unsigned long) skb->data + myBufList[0].size + myBufList[1].size + myBufList[2].size));
1305                             myBufList[3].size = (numPages > 4) ? (4096 - page_offset(skb->data)) : length - myBufList[2].size - myBufList[1].size - myBufList[0].size;
1306                         }
1307                     }
1308                 }
1309
1310                 returnCode = HvCallEvent_dmaBufList(HvLpEvent_Type_VirtualLan,
1311                                                    event->mBaseEvent.xSourceLp,
1312                                                    HvLpDma_Direction_RemoteToLocal,
1313                                                    connection->mSourceInst,
1314                                                    connection->mTargetInst,
1315                                                    HvLpDma_AddressType_RealAddress,
1316                                                    HvLpDma_AddressType_TceIndex,
1317                                                    0x8000000000000000LL | (VIRT_TO_ABSOLUTE((unsigned long)&myBufList)),
1318                                                    0x8000000000000000LL | (VIRT_TO_ABSOLUTE((unsigned long)&remoteList)),
1319                                                    length);
1320
1321                 if (returnCode == HvLpDma_Rc_Good) 
1322                 {
1323                     HvLpVirtualLanIndex vlan = skb->data[9];
1324                     u64 dest = *((u64 *)skb->data) & 0xFFFFFFFFFFFF0000;
1325
1326                     if (((vlan < HvMaxArchitectedVirtualLans) &&
1327                          ((port = mFabricMgr->mPorts[vlan]) != NULL)) &&
1328                         ((dest == port->mMyAddress) || /* it's for me */
1329                          (dest == 0xFFFFFFFFFFFF0000) || /* it's a broadcast */
1330                          (veth_multicast_wanted(port, dest)) ||   /* it's one of my multicasts */
1331                          (port->mPromiscuous == 1))) /* I'm promiscuous */
1332                     {
1333                         skb_put(skb, length);
1334                         skb->dev = port->mDev;
1335                         skb->protocol = eth_type_trans(skb, port->mDev);
1336                         skb->ip_summed = CHECKSUM_NONE;
1337                         netif_rx(skb);          /* send it up */
1338                         port->mStats.rx_packets++;
1339                         port->mStats.rx_bytes += length;
1340
1341                     }
1342                     else
1343                     {
1344                         dev_kfree_skb_irq(skb);
1345                     }
1346                 }
1347                 else
1348                 {
1349                     printk("bad lp event rc %x length %d remote address %x raw address %x\n", (int)returnCode, length, remoteList.addr.token1.token2, address);
1350                     dev_kfree_skb_irq(skb);
1351                 }
1352             }
1353         }
1354         else
1355             break;
1356     }
1357     /* Ack it */
1358
1359     {
1360         unsigned long flags;
1361         spin_lock_irqsave(&connection->mAckGate, flags);
1362
1363         if (connection->mNumAcks < VethMaxFramesMsgsAcked)
1364         {
1365             connection->mEventData.mAckData.mToken[connection->mNumAcks] = event->mBaseEvent.xCorrelationToken;
1366             ++connection->mNumAcks;
1367
1368             if (connection->mNumAcks == connection->mRemoteCap.mUnionData.mFields.mThreshold)
1369             {
1370                 HvLpEvent_Rc rc = HvCallEvent_signalLpEventFast(connection->mRemoteLp,
1371                                                                 HvLpEvent_Type_VirtualLan,
1372                                                                 VethEventTypeFramesAck,
1373                                                                 HvLpEvent_AckInd_NoAck,
1374                                                                 HvLpEvent_AckType_ImmediateAck,
1375                                                                 connection->mSourceInst,
1376                                                                 connection->mTargetInst,
1377                                                                 0,
1378                                                                 connection->mEventData.mFpData.mData1,
1379                                                                 connection->mEventData.mFpData.mData2,
1380                                                                 connection->mEventData.mFpData.mData3,
1381                                                                 connection->mEventData.mFpData.mData4,
1382                                                                 connection->mEventData.mFpData.mData5);
1383
1384                 if (rc != HvLpEvent_Rc_Good)
1385                 {
1386                     veth_error_printk("Bad lp event return code(%x) acking frames from lpar %d\n", (int)rc, connection->mRemoteLp);
1387                 }
1388
1389                 connection->mNumAcks = 0;
1390
1391                 memset(&connection->mEventData, 0xFF, sizeof(connection->mEventData));
1392             }
1393
1394         }
1395
1396         spin_unlock_irqrestore(&connection->mAckGate, flags);
1397     }
1398 }
1399 #undef number_of_pages
1400 #undef page_offset
1401
1402 static void veth_timedAck(unsigned long connectionPtr)
1403 {
1404     unsigned long flags;
1405     HvLpEvent_Rc rc;
1406     struct VethLpConnection *connection = (struct VethLpConnection *) connectionPtr;
1407     /* Ack all the events */
1408     spin_lock_irqsave(&connection->mAckGate, flags);
1409
1410     if (connection->mNumAcks > 0)
1411     {
1412         rc = HvCallEvent_signalLpEventFast(connection->mRemoteLp,
1413                                            HvLpEvent_Type_VirtualLan,
1414                                            VethEventTypeFramesAck,
1415                                            HvLpEvent_AckInd_NoAck,
1416                                            HvLpEvent_AckType_ImmediateAck,
1417                                            connection->mSourceInst,
1418                                            connection->mTargetInst,
1419                                            0,
1420                                            connection->mEventData.mFpData.mData1,
1421                                            connection->mEventData.mFpData.mData2,
1422                                            connection->mEventData.mFpData.mData3,
1423                                            connection->mEventData.mFpData.mData4,
1424                                            connection->mEventData.mFpData.mData5);
1425
1426         if (rc != HvLpEvent_Rc_Good)
1427         {
1428             veth_error_printk("Bad lp event return code(%x) acking frames from lpar %d!\n", (int)rc, connection->mRemoteLp);
1429         }
1430
1431         connection->mNumAcks = 0;
1432
1433         memset(&connection->mEventData, 0xFF, sizeof(connection->mEventData));
1434     }
1435
1436     spin_unlock_irqrestore(&connection->mAckGate, flags);
1437
1438     /* Reschedule the timer */
1439     connection->mAckTimer.expires = jiffies + connection->mTimeout;
1440     add_timer(&connection->mAckTimer);
1441 }
1442
1443 static int veth_multicast_wanted(struct VethPort *port, u64 thatAddr)
1444 {
1445     int returnParm = 0;
1446     int i;
1447     unsigned long flags;
1448
1449     if ((*((char *)&thatAddr) & 0x01) != 1)
1450         return 0;
1451
1452     read_lock_irqsave(&port->mMcastGate, flags);
1453     if (port->mAllMcast)
1454         return 1;
1455
1456     for (i=0; i < port->mNumAddrs; ++i)
1457     {
1458         u64 thisAddr = port->mMcasts[i];
1459
1460         if (thisAddr == thatAddr)
1461         {
1462             returnParm = 1;
1463             break;
1464         } 
1465     }
1466     read_unlock_irqrestore(&port->mMcastGate, flags);
1467
1468     return returnParm;
1469 }
1470
1471 static void veth_sendMonitor(struct VethLpConnection *connection)
1472 {
1473     HvLpEvent_Rc returnCode = HvCallEvent_signalLpEventFast(connection->mRemoteLp,
1474                                                             HvLpEvent_Type_VirtualLan,
1475                                                             VethEventTypeMonitor,
1476                                                             HvLpEvent_AckInd_DoAck,
1477                                                             HvLpEvent_AckType_DeferredAck,
1478                                                             connection->mSourceInst,
1479                                                             connection->mTargetInst,
1480                                                             0, 0, 0, 0, 0, 0);
1481
1482     if (returnCode == HvLpEvent_Rc_Good)
1483     {
1484         connection->mConnectionStatus.mSentMonitor = 1;
1485         connection->mConnectionStatus.mFailed = 0;
1486
1487         /* Start the ACK timer */
1488         init_timer(&connection->mAckTimer);
1489         connection->mAckTimer.function = veth_timedAck;
1490         connection->mAckTimer.data = (unsigned long) connection;
1491         connection->mAckTimer.expires = jiffies + connection->mTimeout;
1492         add_timer(&connection->mAckTimer);
1493
1494     }
1495     else
1496     {
1497         veth_error_printk("Monitor send to lpar %d failed with rc %x\n", connection->mRemoteLp, (int)returnCode);
1498         veth_failMe(connection);
1499     }
1500 }
1501
1502 static void veth_finishCapBh(struct VethLpConnection *connection)
1503 {
1504     unsigned long flags;
1505     spin_lock_irqsave(&connection->mStatusGate, flags);
1506     veth_finishCapBhLocked(connection);
1507     spin_unlock_irqrestore(&connection->mStatusGate, flags);
1508 }
1509
1510 static void veth_finishCapBhLocked(struct VethLpConnection *connection)
1511 {
1512     struct VethLpEvent *event = &connection->mCapEvent;
1513     struct VethCapData *remoteCap = &(connection->mRemoteCap);
1514     int numAcks = (remoteCap->mUnionData.mFields.mNumberBuffers / remoteCap->mUnionData.mFields.mThreshold) + 1;
1515
1516     /* Convert timer to jiffies */
1517     if (connection->mMyCap.mUnionData.mFields.mTimer)
1518         connection->mTimeout = remoteCap->mUnionData.mFields.mTimer * HZ / 1000000;
1519     else
1520         connection->mTimeout = VethAckTimeoutUsec * HZ / 1000000;
1521
1522     if (connection->mNumberLpAcksAlloced >= numAcks)
1523     {
1524         HvLpEvent_Rc returnCode = HvCallEvent_ackLpEvent((struct HvLpEvent *)event);
1525
1526         if (returnCode == HvLpEvent_Rc_Good)
1527         {
1528             connection->mConnectionStatus.mGotCapAcked = 1;
1529
1530             if (connection->mConnectionStatus.mSentCap != 1)
1531             {
1532                 connection->mTargetInst = HvCallEvent_getTargetLpInstanceId(connection->mRemoteLp, HvLpEvent_Type_VirtualLan);
1533
1534                 veth_sendCap(connection);
1535             }
1536             else if (connection->mConnectionStatus.mCapAcked == 1)
1537             {
1538                 if (connection->mConnectionStatus.mSentMonitor != 1)
1539                     veth_sendMonitor(connection);
1540             }
1541         }
1542         else
1543         {
1544             veth_error_printk("Failed to ack remote cap for lpar %d with rc %x\n", connection->mRemoteLp, (int)returnCode);
1545             veth_failMe(connection);
1546         }
1547     }
1548     else
1549     {
1550         veth_error_printk("Couldn't allocate all the frames ack events for lpar %d\n", connection->mRemoteLp);
1551         event->mBaseEvent.xRc = HvLpEvent_Rc_BufferNotAvailable;
1552         HvCallEvent_ackLpEvent((struct HvLpEvent *)event);
1553     }
1554 }
1555
1556 int proc_veth_dump_connection
1557 (char *page, char **start, off_t off, int count, int *eof, void *data)
1558 {
1559     char *out = page;
1560     long whichConnection = (long) data;
1561     int         len = 0;
1562     struct VethLpConnection *connection = NULL;
1563
1564     if ((whichConnection < 0) || (whichConnection > HvMaxArchitectedLps) || (mFabricMgr == NULL))
1565     {
1566         veth_error_printk("Got bad data from /proc file system\n");
1567         len = sprintf(page, "ERROR\n");
1568     }
1569     else
1570     {
1571         int thereWasStuffBefore = 0;
1572         connection = &(mFabricMgr->mConnection[whichConnection]);
1573
1574         out += sprintf(out, "Remote Lp:\t%d\n", connection->mRemoteLp);
1575         out += sprintf(out, "Source Inst:\t%04X\n", connection->mSourceInst);
1576         out += sprintf(out, "Target Inst:\t%04X\n", connection->mTargetInst);
1577         out += sprintf(out, "Num Msgs:\t%d\n", connection->mNumMsgs);
1578         out += sprintf(out, "Num Lp Acks:\t%d\n", connection->mNumberLpAcksAlloced);
1579         out += sprintf(out, "Num Acks:\t%d\n", connection->mNumAcks);
1580
1581         if (connection->mConnectionStatus.mOpen)
1582         {
1583             out += sprintf(out, "<Open");
1584             thereWasStuffBefore = 1;
1585         }
1586
1587         if (connection->mConnectionStatus.mCapMonAlloced)
1588         {
1589             if (thereWasStuffBefore)
1590                 out += sprintf(out,"/");
1591             else
1592                 out += sprintf(out,"<");
1593             out += sprintf(out, "CapMonAlloced");
1594             thereWasStuffBefore = 1;
1595         }
1596
1597         if (connection->mConnectionStatus.mBaseMsgsAlloced)
1598         {
1599             if (thereWasStuffBefore)
1600                 out += sprintf(out,"/");
1601             else
1602                 out += sprintf(out,"<");
1603             out += sprintf(out, "BaseMsgsAlloced");
1604             thereWasStuffBefore = 1;
1605         }
1606
1607         if (connection->mConnectionStatus.mSentCap)
1608         {
1609             if (thereWasStuffBefore)
1610                 out += sprintf(out,"/");
1611             else
1612                 out += sprintf(out,"<");
1613             out += sprintf(out, "SentCap");
1614             thereWasStuffBefore = 1;
1615         }
1616
1617         if (connection->mConnectionStatus.mCapAcked)
1618         {
1619             if (thereWasStuffBefore)
1620                 out += sprintf(out,"/");
1621             else
1622                 out += sprintf(out,"<");
1623             out += sprintf(out, "CapAcked");
1624             thereWasStuffBefore = 1;
1625         }
1626
1627         if (connection->mConnectionStatus.mGotCap)
1628         {
1629             if (thereWasStuffBefore)
1630                 out += sprintf(out,"/");
1631             else
1632                 out += sprintf(out,"<");
1633             out += sprintf(out, "GotCap");
1634             thereWasStuffBefore = 1;
1635         }
1636
1637         if (connection->mConnectionStatus.mGotCapAcked)
1638         {
1639             if (thereWasStuffBefore)
1640                 out += sprintf(out,"/");
1641             else
1642                 out += sprintf(out,"<");
1643             out += sprintf(out, "GotCapAcked");
1644             thereWasStuffBefore = 1;
1645         }
1646
1647         if (connection->mConnectionStatus.mSentMonitor)
1648         {
1649             if (thereWasStuffBefore)
1650                 out += sprintf(out,"/");
1651             else
1652                 out += sprintf(out,"<");
1653             out += sprintf(out, "SentMonitor");
1654             thereWasStuffBefore = 1;
1655         }
1656
1657         if (connection->mConnectionStatus.mPopulatedRings)
1658         {
1659             if (thereWasStuffBefore)
1660                 out += sprintf(out,"/");
1661             else
1662                 out += sprintf(out,"<");
1663             out += sprintf(out, "PopulatedRings");
1664             thereWasStuffBefore = 1;
1665         }
1666
1667         if (connection->mConnectionStatus.mFailed)
1668         {
1669             if (thereWasStuffBefore)
1670                 out += sprintf(out,"/");
1671             else
1672                 out += sprintf(out,"<");
1673             out += sprintf(out, "Failed");
1674             thereWasStuffBefore = 1;
1675         }
1676
1677         if (thereWasStuffBefore)
1678             out += sprintf(out, ">");
1679
1680         out += sprintf(out, "\n");
1681
1682         out += sprintf(out, "Capabilities (System:<Version/Buffers/Threshold/Timeout>):\n");
1683         out += sprintf(out, "\tLocal:<");
1684         out += sprintf(out, "%d/%d/%d/%d>\n", 
1685                        connection->mMyCap.mUnionData.mFields.mVersion,
1686                        connection->mMyCap.mUnionData.mFields.mNumberBuffers,
1687                        connection->mMyCap.mUnionData.mFields.mThreshold,
1688                        connection->mMyCap.mUnionData.mFields.mTimer);
1689         out += sprintf(out, "\tRemote:<");
1690         out += sprintf(out, "%d/%d/%d/%d>\n", 
1691                        connection->mRemoteCap.mUnionData.mFields.mVersion,
1692                        connection->mRemoteCap.mUnionData.mFields.mNumberBuffers,
1693                        connection->mRemoteCap.mUnionData.mFields.mThreshold,
1694                        connection->mRemoteCap.mUnionData.mFields.mTimer);
1695         len = out - page;
1696     }
1697     len -= off;                 
1698     if (len < count) {          
1699         *eof = 1;               
1700         if (len <= 0)           
1701             return 0;   
1702     } else                              
1703         len = count;            
1704     *start = page + off;                
1705     return len;                 
1706 }
1707
1708 int proc_veth_dump_port
1709 (char *page, char **start, off_t off, int count, int *eof, void *data)
1710 {
1711     char *out = page;
1712     long whichPort = (long) data;
1713     int         len = 0;
1714     struct VethPort *port = NULL;
1715
1716     if ((whichPort < 0) || (whichPort > HvMaxArchitectedVirtualLans) || (mFabricMgr == NULL))
1717         len = sprintf(page, "Virtual ethernet is not configured.\n");
1718     else
1719     {
1720         int i=0;
1721         u32 *myAddr;
1722         u16 *myEndAddr;
1723         port = mFabricMgr->mPorts[whichPort];
1724
1725         if (port != NULL)
1726         {
1727             myAddr = (u32 *)&(port->mMyAddress);
1728             myEndAddr = (u16 *)(myAddr + 1);
1729             out += sprintf(out, "Net device:\t%p\n", port->mDev);
1730             out += sprintf(out, "Net device name:\t%s\n", port->mDev->name);
1731             out += sprintf(out, "Address:\t%08X%04X\n", myAddr[0], myEndAddr[0]);
1732             out += sprintf(out, "Promiscuous:\t%d\n", port->mPromiscuous);
1733             out += sprintf(out, "All multicast:\t%d\n", port->mAllMcast);
1734             out += sprintf(out, "Number multicast:\t%d\n", port->mNumAddrs);
1735
1736             for (i=0; i < port->mNumAddrs; ++i)
1737             {
1738                 u32 *multi = (u32 *)&(port->mMcasts[i]);
1739                 u16 *multiEnd = (u16 *)(multi + 1);
1740                 out += sprintf(out, "   %08X%04X\n", multi[0], multiEnd[0]);
1741             }
1742         }
1743         else
1744         {
1745             out += sprintf(page, "veth%d is not configured.\n", (int)whichPort);
1746         }
1747
1748         len = out - page;
1749     }
1750     len -= off;                 
1751     if (len < count) {          
1752         *eof = 1;               
1753         if (len <= 0)           
1754             return 0;   
1755     } else                              
1756         len = count;            
1757     *start = page + off;                
1758     return len;                 
1759 }
1760
1761