aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/iseries_veth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/iseries_veth.c')
-rw-r--r--drivers/net/iseries_veth.c47
1 files changed, 19 insertions, 28 deletions
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index eaff17cc9fb8..b945bf02d257 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -938,31 +938,25 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp,
938 struct veth_port *port = (struct veth_port *) dev->priv; 938 struct veth_port *port = (struct veth_port *) dev->priv;
939 HvLpEvent_Rc rc; 939 HvLpEvent_Rc rc;
940 struct veth_msg *msg = NULL; 940 struct veth_msg *msg = NULL;
941 int err = 0;
942 unsigned long flags; 941 unsigned long flags;
943 942
944 if (! cnx) { 943 if (! cnx)
945 port->stats.tx_errors++;
946 dev_kfree_skb(skb);
947 return 0; 944 return 0;
948 }
949 945
950 spin_lock_irqsave(&cnx->lock, flags); 946 spin_lock_irqsave(&cnx->lock, flags);
951 947
952 if (! (cnx->state & VETH_STATE_READY)) 948 if (! (cnx->state & VETH_STATE_READY))
953 goto drop; 949 goto no_error;
954 950
955 if ((skb->len - 14) > VETH_MAX_MTU) 951 if ((skb->len - ETH_HLEN) > VETH_MAX_MTU)
956 goto drop; 952 goto drop;
957 953
958 msg = veth_stack_pop(cnx); 954 msg = veth_stack_pop(cnx);
959 955 if (! msg)
960 if (! msg) {
961 err = 1;
962 goto drop; 956 goto drop;
963 }
964 957
965 msg->in_use = 1; 958 msg->in_use = 1;
959 msg->skb = skb_get(skb);
966 960
967 msg->data.addr[0] = dma_map_single(port->dev, skb->data, 961 msg->data.addr[0] = dma_map_single(port->dev, skb->data,
968 skb->len, DMA_TO_DEVICE); 962 skb->len, DMA_TO_DEVICE);
@@ -970,9 +964,6 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp,
970 if (dma_mapping_error(msg->data.addr[0])) 964 if (dma_mapping_error(msg->data.addr[0]))
971 goto recycle_and_drop; 965 goto recycle_and_drop;
972 966
973 /* Is it really necessary to check the length and address
974 * fields of the first entry here? */
975 msg->skb = skb;
976 msg->dev = port->dev; 967 msg->dev = port->dev;
977 msg->data.len[0] = skb->len; 968 msg->data.len[0] = skb->len;
978 msg->data.eofmask = 1 << VETH_EOF_SHIFT; 969 msg->data.eofmask = 1 << VETH_EOF_SHIFT;
@@ -992,43 +983,43 @@ static int veth_transmit_to_one(struct sk_buff *skb, HvLpIndex rlp,
992 if (veth_stack_is_empty(cnx)) 983 if (veth_stack_is_empty(cnx))
993 veth_stop_queues(cnx); 984 veth_stop_queues(cnx);
994 985
986 no_error:
995 spin_unlock_irqrestore(&cnx->lock, flags); 987 spin_unlock_irqrestore(&cnx->lock, flags);
996 return 0; 988 return 0;
997 989
998 recycle_and_drop: 990 recycle_and_drop:
999 /* we free the skb below, so tell veth_recycle_msg() not to. */
1000 msg->skb = NULL;
1001 veth_recycle_msg(cnx, msg); 991 veth_recycle_msg(cnx, msg);
1002 drop: 992 drop:
1003 port->stats.tx_errors++;
1004 dev_kfree_skb(skb);
1005 spin_unlock_irqrestore(&cnx->lock, flags); 993 spin_unlock_irqrestore(&cnx->lock, flags);
1006 return err; 994 return 1;
1007} 995}
1008 996
1009static HvLpIndexMap veth_transmit_to_many(struct sk_buff *skb, 997static void veth_transmit_to_many(struct sk_buff *skb,
1010 HvLpIndexMap lpmask, 998 HvLpIndexMap lpmask,
1011 struct net_device *dev) 999 struct net_device *dev)
1012{ 1000{
1013 struct veth_port *port = (struct veth_port *) dev->priv; 1001 struct veth_port *port = (struct veth_port *) dev->priv;
1014 int i; 1002 int i, success, error;
1015 int rc; 1003
1004 success = error = 0;
1016 1005
1017 for (i = 0; i < HVMAXARCHITECTEDLPS; i++) { 1006 for (i = 0; i < HVMAXARCHITECTEDLPS; i++) {
1018 if ((lpmask & (1 << i)) == 0) 1007 if ((lpmask & (1 << i)) == 0)
1019 continue; 1008 continue;
1020 1009
1021 rc = veth_transmit_to_one(skb_get(skb), i, dev); 1010 if (veth_transmit_to_one(skb, i, dev))
1022 if (! rc) 1011 error = 1;
1023 lpmask &= ~(1<<i); 1012 else
1013 success = 1;
1024 } 1014 }
1025 1015
1026 if (! lpmask) { 1016 if (error)
1017 port->stats.tx_errors++;
1018
1019 if (success) {
1027 port->stats.tx_packets++; 1020 port->stats.tx_packets++;
1028 port->stats.tx_bytes += skb->len; 1021 port->stats.tx_bytes += skb->len;
1029 } 1022 }
1030
1031 return lpmask;
1032} 1023}
1033 1024
1034static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev) 1025static int veth_start_xmit(struct sk_buff *skb, struct net_device *dev)