|
@@ -79,6 +79,8 @@
|
|
#include <asm/iommu.h>
|
|
#include <asm/iommu.h>
|
|
#include <asm/vio.h>
|
|
#include <asm/vio.h>
|
|
|
|
|
|
|
|
+#undef DEBUG
|
|
|
|
+
|
|
#include "iseries_veth.h"
|
|
#include "iseries_veth.h"
|
|
|
|
|
|
MODULE_AUTHOR("Kyle Lucke <klucke@us.ibm.com>");
|
|
MODULE_AUTHOR("Kyle Lucke <klucke@us.ibm.com>");
|
|
@@ -176,11 +178,18 @@ static void veth_timed_ack(unsigned long connectionPtr);
|
|
* Utility functions
|
|
* Utility functions
|
|
*/
|
|
*/
|
|
|
|
|
|
-#define veth_printk(prio, fmt, args...) \
|
|
|
|
- printk(prio "%s: " fmt, __FILE__, ## args)
|
|
|
|
|
|
+#define veth_info(fmt, args...) \
|
|
|
|
+ printk(KERN_INFO "iseries_veth: " fmt, ## args)
|
|
|
|
|
|
#define veth_error(fmt, args...) \
|
|
#define veth_error(fmt, args...) \
|
|
- printk(KERN_ERR "(%s:%3.3d) ERROR: " fmt, __FILE__, __LINE__ , ## args)
|
|
|
|
|
|
+ printk(KERN_ERR "iseries_veth: Error: " fmt, ## args)
|
|
|
|
+
|
|
|
|
+#ifdef DEBUG
|
|
|
|
+#define veth_debug(fmt, args...) \
|
|
|
|
+ printk(KERN_DEBUG "iseries_veth: " fmt, ## args)
|
|
|
|
+#else
|
|
|
|
+#define veth_debug(fmt, args...) do {} while (0)
|
|
|
|
+#endif
|
|
|
|
|
|
static inline void veth_stack_push(struct veth_lpar_connection *cnx,
|
|
static inline void veth_stack_push(struct veth_lpar_connection *cnx,
|
|
struct veth_msg *msg)
|
|
struct veth_msg *msg)
|
|
@@ -278,7 +287,7 @@ static void veth_take_cap(struct veth_lpar_connection *cnx,
|
|
HvLpEvent_Type_VirtualLan);
|
|
HvLpEvent_Type_VirtualLan);
|
|
|
|
|
|
if (cnx->state & VETH_STATE_GOTCAPS) {
|
|
if (cnx->state & VETH_STATE_GOTCAPS) {
|
|
- veth_error("Received a second capabilities from lpar %d\n",
|
|
|
|
|
|
+ veth_error("Received a second capabilities from LPAR %d.\n",
|
|
cnx->remote_lp);
|
|
cnx->remote_lp);
|
|
event->base_event.xRc = HvLpEvent_Rc_BufferNotAvailable;
|
|
event->base_event.xRc = HvLpEvent_Rc_BufferNotAvailable;
|
|
HvCallEvent_ackLpEvent((struct HvLpEvent *) event);
|
|
HvCallEvent_ackLpEvent((struct HvLpEvent *) event);
|
|
@@ -297,7 +306,7 @@ static void veth_take_cap_ack(struct veth_lpar_connection *cnx,
|
|
|
|
|
|
spin_lock_irqsave(&cnx->lock, flags);
|
|
spin_lock_irqsave(&cnx->lock, flags);
|
|
if (cnx->state & VETH_STATE_GOTCAPACK) {
|
|
if (cnx->state & VETH_STATE_GOTCAPACK) {
|
|
- veth_error("Received a second capabilities ack from lpar %d\n",
|
|
|
|
|
|
+ veth_error("Received a second capabilities ack from LPAR %d.\n",
|
|
cnx->remote_lp);
|
|
cnx->remote_lp);
|
|
} else {
|
|
} else {
|
|
memcpy(&cnx->cap_ack_event, event,
|
|
memcpy(&cnx->cap_ack_event, event,
|
|
@@ -314,8 +323,7 @@ static void veth_take_monitor_ack(struct veth_lpar_connection *cnx,
|
|
unsigned long flags;
|
|
unsigned long flags;
|
|
|
|
|
|
spin_lock_irqsave(&cnx->lock, flags);
|
|
spin_lock_irqsave(&cnx->lock, flags);
|
|
- veth_printk(KERN_DEBUG, "Monitor ack returned for lpar %d\n",
|
|
|
|
- cnx->remote_lp);
|
|
|
|
|
|
+ veth_debug("cnx %d: lost connection.\n", cnx->remote_lp);
|
|
cnx->state |= VETH_STATE_RESET;
|
|
cnx->state |= VETH_STATE_RESET;
|
|
veth_kick_statemachine(cnx);
|
|
veth_kick_statemachine(cnx);
|
|
spin_unlock_irqrestore(&cnx->lock, flags);
|
|
spin_unlock_irqrestore(&cnx->lock, flags);
|
|
@@ -336,8 +344,8 @@ static void veth_handle_ack(struct VethLpEvent *event)
|
|
veth_take_monitor_ack(cnx, event);
|
|
veth_take_monitor_ack(cnx, event);
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
- veth_error("Unknown ack type %d from lpar %d\n",
|
|
|
|
- event->base_event.xSubtype, rlp);
|
|
|
|
|
|
+ veth_error("Unknown ack type %d from LPAR %d.\n",
|
|
|
|
+ event->base_event.xSubtype, rlp);
|
|
};
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
@@ -373,8 +381,8 @@ static void veth_handle_int(struct VethLpEvent *event)
|
|
veth_receive(cnx, event);
|
|
veth_receive(cnx, event);
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
- veth_error("Unknown interrupt type %d from lpar %d\n",
|
|
|
|
- event->base_event.xSubtype, rlp);
|
|
|
|
|
|
+ veth_error("Unknown interrupt type %d from LPAR %d.\n",
|
|
|
|
+ event->base_event.xSubtype, rlp);
|
|
};
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
@@ -400,8 +408,8 @@ static int veth_process_caps(struct veth_lpar_connection *cnx)
|
|
|| (remote_caps->ack_threshold > VETH_MAX_ACKS_PER_MSG)
|
|
|| (remote_caps->ack_threshold > VETH_MAX_ACKS_PER_MSG)
|
|
|| (remote_caps->ack_threshold == 0)
|
|
|| (remote_caps->ack_threshold == 0)
|
|
|| (cnx->ack_timeout == 0) ) {
|
|
|| (cnx->ack_timeout == 0) ) {
|
|
- veth_error("Received incompatible capabilities from lpar %d\n",
|
|
|
|
- cnx->remote_lp);
|
|
|
|
|
|
+ veth_error("Received incompatible capabilities from LPAR %d.\n",
|
|
|
|
+ cnx->remote_lp);
|
|
return HvLpEvent_Rc_InvalidSubtypeData;
|
|
return HvLpEvent_Rc_InvalidSubtypeData;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -418,8 +426,8 @@ static int veth_process_caps(struct veth_lpar_connection *cnx)
|
|
cnx->num_ack_events += num;
|
|
cnx->num_ack_events += num;
|
|
|
|
|
|
if (cnx->num_ack_events < num_acks_needed) {
|
|
if (cnx->num_ack_events < num_acks_needed) {
|
|
- veth_error("Couldn't allocate enough ack events for lpar %d\n",
|
|
|
|
- cnx->remote_lp);
|
|
|
|
|
|
+ veth_error("Couldn't allocate enough ack events "
|
|
|
|
+ "for LPAR %d.\n", cnx->remote_lp);
|
|
|
|
|
|
return HvLpEvent_Rc_BufferNotAvailable;
|
|
return HvLpEvent_Rc_BufferNotAvailable;
|
|
}
|
|
}
|
|
@@ -498,9 +506,8 @@ static void veth_statemachine(void *p)
|
|
} else {
|
|
} else {
|
|
if ( (rc != HvLpEvent_Rc_PartitionDead)
|
|
if ( (rc != HvLpEvent_Rc_PartitionDead)
|
|
&& (rc != HvLpEvent_Rc_PathClosed) )
|
|
&& (rc != HvLpEvent_Rc_PathClosed) )
|
|
- veth_error("Error sending monitor to "
|
|
|
|
- "lpar %d, rc=%x\n",
|
|
|
|
- rlp, (int) rc);
|
|
|
|
|
|
+ veth_error("Error sending monitor to LPAR %d, "
|
|
|
|
+ "rc = %d\n", rlp, rc);
|
|
|
|
|
|
/* Oh well, hope we get a cap from the other
|
|
/* Oh well, hope we get a cap from the other
|
|
* end and do better when that kicks us */
|
|
* end and do better when that kicks us */
|
|
@@ -523,9 +530,9 @@ static void veth_statemachine(void *p)
|
|
} else {
|
|
} else {
|
|
if ( (rc != HvLpEvent_Rc_PartitionDead)
|
|
if ( (rc != HvLpEvent_Rc_PartitionDead)
|
|
&& (rc != HvLpEvent_Rc_PathClosed) )
|
|
&& (rc != HvLpEvent_Rc_PathClosed) )
|
|
- veth_error("Error sending caps to "
|
|
|
|
- "lpar %d, rc=%x\n",
|
|
|
|
- rlp, (int) rc);
|
|
|
|
|
|
+ veth_error("Error sending caps to LPAR %d, "
|
|
|
|
+ "rc = %d\n", rlp, rc);
|
|
|
|
+
|
|
/* Oh well, hope we get a cap from the other
|
|
/* Oh well, hope we get a cap from the other
|
|
* end and do better when that kicks us */
|
|
* end and do better when that kicks us */
|
|
goto out;
|
|
goto out;
|
|
@@ -565,10 +572,8 @@ static void veth_statemachine(void *p)
|
|
add_timer(&cnx->ack_timer);
|
|
add_timer(&cnx->ack_timer);
|
|
cnx->state |= VETH_STATE_READY;
|
|
cnx->state |= VETH_STATE_READY;
|
|
} else {
|
|
} else {
|
|
- veth_printk(KERN_ERR, "Caps rejected (rc=%d) by "
|
|
|
|
- "lpar %d\n",
|
|
|
|
- cnx->cap_ack_event.base_event.xRc,
|
|
|
|
- rlp);
|
|
|
|
|
|
+ veth_error("Caps rejected by LPAR %d, rc = %d\n",
|
|
|
|
+ rlp, cnx->cap_ack_event.base_event.xRc);
|
|
goto cant_cope;
|
|
goto cant_cope;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -581,8 +586,8 @@ static void veth_statemachine(void *p)
|
|
/* FIXME: we get here if something happens we really can't
|
|
/* FIXME: we get here if something happens we really can't
|
|
* cope with. The link will never work once we get here, and
|
|
* cope with. The link will never work once we get here, and
|
|
* all we can do is not lock the rest of the system up */
|
|
* all we can do is not lock the rest of the system up */
|
|
- veth_error("Badness on connection to lpar %d (state=%04lx) "
|
|
|
|
- " - shutting down\n", rlp, cnx->state);
|
|
|
|
|
|
+ veth_error("Unrecoverable error on connection to LPAR %d, shutting down"
|
|
|
|
+ " (state = 0x%04lx)\n", rlp, cnx->state);
|
|
cnx->state |= VETH_STATE_SHUTDOWN;
|
|
cnx->state |= VETH_STATE_SHUTDOWN;
|
|
spin_unlock_irq(&cnx->lock);
|
|
spin_unlock_irq(&cnx->lock);
|
|
}
|
|
}
|
|
@@ -614,7 +619,7 @@ static int veth_init_connection(u8 rlp)
|
|
|
|
|
|
msgs = kmalloc(VETH_NUMBUFFERS * sizeof(struct veth_msg), GFP_KERNEL);
|
|
msgs = kmalloc(VETH_NUMBUFFERS * sizeof(struct veth_msg), GFP_KERNEL);
|
|
if (! msgs) {
|
|
if (! msgs) {
|
|
- veth_error("Can't allocate buffers for lpar %d\n", rlp);
|
|
|
|
|
|
+ veth_error("Can't allocate buffers for LPAR %d.\n", rlp);
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -630,8 +635,7 @@ static int veth_init_connection(u8 rlp)
|
|
cnx->num_events = veth_allocate_events(rlp, 2 + VETH_NUMBUFFERS);
|
|
cnx->num_events = veth_allocate_events(rlp, 2 + VETH_NUMBUFFERS);
|
|
|
|
|
|
if (cnx->num_events < (2 + VETH_NUMBUFFERS)) {
|
|
if (cnx->num_events < (2 + VETH_NUMBUFFERS)) {
|
|
- veth_error("Can't allocate events for lpar %d, only got %d\n",
|
|
|
|
- rlp, cnx->num_events);
|
|
|
|
|
|
+ veth_error("Can't allocate enough events for LPAR %d.\n", rlp);
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -889,15 +893,13 @@ static struct net_device * __init veth_probe_one(int vlan, struct device *vdev)
|
|
|
|
|
|
rc = register_netdev(dev);
|
|
rc = register_netdev(dev);
|
|
if (rc != 0) {
|
|
if (rc != 0) {
|
|
- veth_printk(KERN_ERR,
|
|
|
|
- "Failed to register ethernet device for vlan %d\n",
|
|
|
|
- vlan);
|
|
|
|
|
|
+ veth_error("Failed registering net device for vlan%d.\n", vlan);
|
|
free_netdev(dev);
|
|
free_netdev(dev);
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
- veth_printk(KERN_DEBUG, "%s attached to iSeries vlan %d (lpar_map=0x%04x)\n",
|
|
|
|
- dev->name, vlan, port->lpar_map);
|
|
|
|
|
|
+ veth_info("%s attached to iSeries vlan %d (LPAR map = 0x%.4X)\n",
|
|
|
|
+ dev->name, vlan, port->lpar_map);
|
|
|
|
|
|
return dev;
|
|
return dev;
|
|
}
|
|
}
|
|
@@ -1030,7 +1032,7 @@ static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|
dev_kfree_skb(skb);
|
|
dev_kfree_skb(skb);
|
|
} else {
|
|
} else {
|
|
if (port->pending_skb) {
|
|
if (port->pending_skb) {
|
|
- veth_error("%s: Tx while skb was pending!\n",
|
|
|
|
|
|
+ veth_error("%s: TX while skb was pending!\n",
|
|
dev->name);
|
|
dev->name);
|
|
dev_kfree_skb(skb);
|
|
dev_kfree_skb(skb);
|
|
spin_unlock_irqrestore(&port->pending_gate, flags);
|
|
spin_unlock_irqrestore(&port->pending_gate, flags);
|
|
@@ -1066,10 +1068,10 @@ static void veth_recycle_msg(struct veth_lpar_connection *cnx,
|
|
|
|
|
|
memset(&msg->data, 0, sizeof(msg->data));
|
|
memset(&msg->data, 0, sizeof(msg->data));
|
|
veth_stack_push(cnx, msg);
|
|
veth_stack_push(cnx, msg);
|
|
- } else
|
|
|
|
- if (cnx->state & VETH_STATE_OPEN)
|
|
|
|
- veth_error("Bogus frames ack from lpar %d (#%d)\n",
|
|
|
|
- cnx->remote_lp, msg->token);
|
|
|
|
|
|
+ } else if (cnx->state & VETH_STATE_OPEN) {
|
|
|
|
+ veth_error("Non-pending frame (# %d) acked by LPAR %d.\n",
|
|
|
|
+ cnx->remote_lp, msg->token);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
static void veth_flush_pending(struct veth_lpar_connection *cnx)
|
|
static void veth_flush_pending(struct veth_lpar_connection *cnx)
|
|
@@ -1179,8 +1181,8 @@ static void veth_flush_acks(struct veth_lpar_connection *cnx)
|
|
0, &cnx->pending_acks);
|
|
0, &cnx->pending_acks);
|
|
|
|
|
|
if (rc != HvLpEvent_Rc_Good)
|
|
if (rc != HvLpEvent_Rc_Good)
|
|
- veth_error("Error 0x%x acking frames from lpar %d!\n",
|
|
|
|
- (unsigned)rc, cnx->remote_lp);
|
|
|
|
|
|
+ veth_error("Failed acking frames from LPAR %d, rc = %d\n",
|
|
|
|
+ cnx->remote_lp, (int)rc);
|
|
|
|
|
|
cnx->num_pending_acks = 0;
|
|
cnx->num_pending_acks = 0;
|
|
memset(&cnx->pending_acks, 0xff, sizeof(cnx->pending_acks));
|
|
memset(&cnx->pending_acks, 0xff, sizeof(cnx->pending_acks));
|
|
@@ -1216,9 +1218,10 @@ static void veth_receive(struct veth_lpar_connection *cnx,
|
|
/* make sure that we have at least 1 EOF entry in the
|
|
/* make sure that we have at least 1 EOF entry in the
|
|
* remaining entries */
|
|
* remaining entries */
|
|
if (! (senddata->eofmask >> (startchunk + VETH_EOF_SHIFT))) {
|
|
if (! (senddata->eofmask >> (startchunk + VETH_EOF_SHIFT))) {
|
|
- veth_error("missing EOF frag in event "
|
|
|
|
- "eofmask=0x%x startchunk=%d\n",
|
|
|
|
- (unsigned) senddata->eofmask, startchunk);
|
|
|
|
|
|
+ veth_error("Missing EOF fragment in event "
|
|
|
|
+ "eofmask = 0x%x startchunk = %d\n",
|
|
|
|
+ (unsigned)senddata->eofmask,
|
|
|
|
+ startchunk);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1237,8 +1240,9 @@ static void veth_receive(struct veth_lpar_connection *cnx,
|
|
/* nchunks == # of chunks in this frame */
|
|
/* nchunks == # of chunks in this frame */
|
|
|
|
|
|
if ((length - ETH_HLEN) > VETH_MAX_MTU) {
|
|
if ((length - ETH_HLEN) > VETH_MAX_MTU) {
|
|
- veth_error("Received oversize frame from lpar %d "
|
|
|
|
- "(length=%d)\n", cnx->remote_lp, length);
|
|
|
|
|
|
+ veth_error("Received oversize frame from LPAR %d "
|
|
|
|
+ "(length = %d)\n",
|
|
|
|
+ cnx->remote_lp, length);
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
|