diff options
Diffstat (limited to 'drivers/infiniband/ulp/ipoib/ipoib_main.c')
| -rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 54 |
1 files changed, 33 insertions, 21 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 5636fc3da6b8..b58d9dca5c93 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
| @@ -925,9 +925,12 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr, | |||
| 925 | ipoib_neigh_free(neigh); | 925 | ipoib_neigh_free(neigh); |
| 926 | goto err_drop; | 926 | goto err_drop; |
| 927 | } | 927 | } |
| 928 | if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) | 928 | if (skb_queue_len(&neigh->queue) < |
| 929 | IPOIB_MAX_PATH_REC_QUEUE) { | ||
| 930 | /* put pseudoheader back on for next time */ | ||
| 931 | skb_push(skb, IPOIB_PSEUDO_LEN); | ||
| 929 | __skb_queue_tail(&neigh->queue, skb); | 932 | __skb_queue_tail(&neigh->queue, skb); |
| 930 | else { | 933 | } else { |
| 931 | ipoib_warn(priv, "queue length limit %d. Packet drop.\n", | 934 | ipoib_warn(priv, "queue length limit %d. Packet drop.\n", |
| 932 | skb_queue_len(&neigh->queue)); | 935 | skb_queue_len(&neigh->queue)); |
| 933 | goto err_drop; | 936 | goto err_drop; |
| @@ -964,7 +967,7 @@ err_drop: | |||
| 964 | } | 967 | } |
| 965 | 968 | ||
| 966 | static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, | 969 | static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, |
| 967 | struct ipoib_cb *cb) | 970 | struct ipoib_pseudo_header *phdr) |
| 968 | { | 971 | { |
| 969 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 972 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 970 | struct ipoib_path *path; | 973 | struct ipoib_path *path; |
| @@ -972,16 +975,18 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, | |||
| 972 | 975 | ||
| 973 | spin_lock_irqsave(&priv->lock, flags); | 976 | spin_lock_irqsave(&priv->lock, flags); |
| 974 | 977 | ||
| 975 | path = __path_find(dev, cb->hwaddr + 4); | 978 | path = __path_find(dev, phdr->hwaddr + 4); |
| 976 | if (!path || !path->valid) { | 979 | if (!path || !path->valid) { |
| 977 | int new_path = 0; | 980 | int new_path = 0; |
| 978 | 981 | ||
| 979 | if (!path) { | 982 | if (!path) { |
| 980 | path = path_rec_create(dev, cb->hwaddr + 4); | 983 | path = path_rec_create(dev, phdr->hwaddr + 4); |
| 981 | new_path = 1; | 984 | new_path = 1; |
| 982 | } | 985 | } |
| 983 | if (path) { | 986 | if (path) { |
| 984 | if (skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) { | 987 | if (skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) { |
| 988 | /* put pseudoheader back on for next time */ | ||
| 989 | skb_push(skb, IPOIB_PSEUDO_LEN); | ||
| 985 | __skb_queue_tail(&path->queue, skb); | 990 | __skb_queue_tail(&path->queue, skb); |
| 986 | } else { | 991 | } else { |
| 987 | ++dev->stats.tx_dropped; | 992 | ++dev->stats.tx_dropped; |
| @@ -1009,10 +1014,12 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev, | |||
| 1009 | be16_to_cpu(path->pathrec.dlid)); | 1014 | be16_to_cpu(path->pathrec.dlid)); |
| 1010 | 1015 | ||
| 1011 | spin_unlock_irqrestore(&priv->lock, flags); | 1016 | spin_unlock_irqrestore(&priv->lock, flags); |
| 1012 | ipoib_send(dev, skb, path->ah, IPOIB_QPN(cb->hwaddr)); | 1017 | ipoib_send(dev, skb, path->ah, IPOIB_QPN(phdr->hwaddr)); |
| 1013 | return; | 1018 | return; |
| 1014 | } else if ((path->query || !path_rec_start(dev, path)) && | 1019 | } else if ((path->query || !path_rec_start(dev, path)) && |
| 1015 | skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) { | 1020 | skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) { |
| 1021 | /* put pseudoheader back on for next time */ | ||
| 1022 | skb_push(skb, IPOIB_PSEUDO_LEN); | ||
| 1016 | __skb_queue_tail(&path->queue, skb); | 1023 | __skb_queue_tail(&path->queue, skb); |
| 1017 | } else { | 1024 | } else { |
| 1018 | ++dev->stats.tx_dropped; | 1025 | ++dev->stats.tx_dropped; |
| @@ -1026,13 +1033,15 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1026 | { | 1033 | { |
| 1027 | struct ipoib_dev_priv *priv = netdev_priv(dev); | 1034 | struct ipoib_dev_priv *priv = netdev_priv(dev); |
| 1028 | struct ipoib_neigh *neigh; | 1035 | struct ipoib_neigh *neigh; |
| 1029 | struct ipoib_cb *cb = ipoib_skb_cb(skb); | 1036 | struct ipoib_pseudo_header *phdr; |
| 1030 | struct ipoib_header *header; | 1037 | struct ipoib_header *header; |
| 1031 | unsigned long flags; | 1038 | unsigned long flags; |
| 1032 | 1039 | ||
| 1040 | phdr = (struct ipoib_pseudo_header *) skb->data; | ||
| 1041 | skb_pull(skb, sizeof(*phdr)); | ||
| 1033 | header = (struct ipoib_header *) skb->data; | 1042 | header = (struct ipoib_header *) skb->data; |
| 1034 | 1043 | ||
| 1035 | if (unlikely(cb->hwaddr[4] == 0xff)) { | 1044 | if (unlikely(phdr->hwaddr[4] == 0xff)) { |
| 1036 | /* multicast, arrange "if" according to probability */ | 1045 | /* multicast, arrange "if" according to probability */ |
| 1037 | if ((header->proto != htons(ETH_P_IP)) && | 1046 | if ((header->proto != htons(ETH_P_IP)) && |
| 1038 | (header->proto != htons(ETH_P_IPV6)) && | 1047 | (header->proto != htons(ETH_P_IPV6)) && |
| @@ -1045,13 +1054,13 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1045 | return NETDEV_TX_OK; | 1054 | return NETDEV_TX_OK; |
| 1046 | } | 1055 | } |
| 1047 | /* Add in the P_Key for multicast*/ | 1056 | /* Add in the P_Key for multicast*/ |
| 1048 | cb->hwaddr[8] = (priv->pkey >> 8) & 0xff; | 1057 | phdr->hwaddr[8] = (priv->pkey >> 8) & 0xff; |
| 1049 | cb->hwaddr[9] = priv->pkey & 0xff; | 1058 | phdr->hwaddr[9] = priv->pkey & 0xff; |
| 1050 | 1059 | ||
| 1051 | neigh = ipoib_neigh_get(dev, cb->hwaddr); | 1060 | neigh = ipoib_neigh_get(dev, phdr->hwaddr); |
| 1052 | if (likely(neigh)) | 1061 | if (likely(neigh)) |
| 1053 | goto send_using_neigh; | 1062 | goto send_using_neigh; |
| 1054 | ipoib_mcast_send(dev, cb->hwaddr, skb); | 1063 | ipoib_mcast_send(dev, phdr->hwaddr, skb); |
| 1055 | return NETDEV_TX_OK; | 1064 | return NETDEV_TX_OK; |
| 1056 | } | 1065 | } |
| 1057 | 1066 | ||
| @@ -1060,16 +1069,16 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 1060 | case htons(ETH_P_IP): | 1069 | case htons(ETH_P_IP): |
| 1061 | case htons(ETH_P_IPV6): | 1070 | case htons(ETH_P_IPV6): |
| 1062 | case htons(ETH_P_TIPC): | 1071 | case htons(ETH_P_TIPC): |
| 1063 | neigh = ipoib_neigh_get(dev, cb->hwaddr); | 1072 | neigh = ipoib_neigh_get(dev, phdr->hwaddr); |
| 1064 | if (unlikely(!neigh)) { | 1073 | if (unlikely(!neigh)) { |
| 1065 | neigh_add_path(skb, cb->hwaddr, dev); | 1074 | neigh_add_path(skb, phdr->hwaddr, dev); |
| 1066 | return NETDEV_TX_OK; | 1075 | return NETDEV_TX_OK; |
| 1067 | } | 1076 | } |
| 1068 | break; | 1077 | break; |
| 1069 | case htons(ETH_P_ARP): | 1078 | case htons(ETH_P_ARP): |
| 1070 | case htons(ETH_P_RARP): | 1079 | case htons(ETH_P_RARP): |
| 1071 | /* for unicast ARP and RARP should always perform path find */ | 1080 | /* for unicast ARP and RARP should always perform path find */ |
| 1072 | unicast_arp_send(skb, dev, cb); | 1081 | unicast_arp_send(skb, dev, phdr); |
| 1073 | return NETDEV_TX_OK; | 1082 | return NETDEV_TX_OK; |
| 1074 | default: | 1083 | default: |
| 1075 | /* ethertype not supported by IPoIB */ | 1084 | /* ethertype not supported by IPoIB */ |
| @@ -1086,11 +1095,13 @@ send_using_neigh: | |||
| 1086 | goto unref; | 1095 | goto unref; |
| 1087 | } | 1096 | } |
| 1088 | } else if (neigh->ah) { | 1097 | } else if (neigh->ah) { |
| 1089 | ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(cb->hwaddr)); | 1098 | ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(phdr->hwaddr)); |
| 1090 | goto unref; | 1099 | goto unref; |
| 1091 | } | 1100 | } |
| 1092 | 1101 | ||
| 1093 | if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) { | 1102 | if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) { |
| 1103 | /* put pseudoheader back on for next time */ | ||
| 1104 | skb_push(skb, sizeof(*phdr)); | ||
| 1094 | spin_lock_irqsave(&priv->lock, flags); | 1105 | spin_lock_irqsave(&priv->lock, flags); |
| 1095 | __skb_queue_tail(&neigh->queue, skb); | 1106 | __skb_queue_tail(&neigh->queue, skb); |
| 1096 | spin_unlock_irqrestore(&priv->lock, flags); | 1107 | spin_unlock_irqrestore(&priv->lock, flags); |
| @@ -1122,8 +1133,8 @@ static int ipoib_hard_header(struct sk_buff *skb, | |||
| 1122 | unsigned short type, | 1133 | unsigned short type, |
| 1123 | const void *daddr, const void *saddr, unsigned len) | 1134 | const void *daddr, const void *saddr, unsigned len) |
| 1124 | { | 1135 | { |
| 1136 | struct ipoib_pseudo_header *phdr; | ||
| 1125 | struct ipoib_header *header; | 1137 | struct ipoib_header *header; |
| 1126 | struct ipoib_cb *cb = ipoib_skb_cb(skb); | ||
| 1127 | 1138 | ||
| 1128 | header = (struct ipoib_header *) skb_push(skb, sizeof *header); | 1139 | header = (struct ipoib_header *) skb_push(skb, sizeof *header); |
| 1129 | 1140 | ||
| @@ -1132,12 +1143,13 @@ static int ipoib_hard_header(struct sk_buff *skb, | |||
| 1132 | 1143 | ||
| 1133 | /* | 1144 | /* |
| 1134 | * we don't rely on dst_entry structure, always stuff the | 1145 | * we don't rely on dst_entry structure, always stuff the |
| 1135 | * destination address into skb->cb so we can figure out where | 1146 | * destination address into skb hard header so we can figure out where |
| 1136 | * to send the packet later. | 1147 | * to send the packet later. |
| 1137 | */ | 1148 | */ |
| 1138 | memcpy(cb->hwaddr, daddr, INFINIBAND_ALEN); | 1149 | phdr = (struct ipoib_pseudo_header *) skb_push(skb, sizeof(*phdr)); |
| 1150 | memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN); | ||
| 1139 | 1151 | ||
| 1140 | return sizeof *header; | 1152 | return IPOIB_HARD_LEN; |
| 1141 | } | 1153 | } |
| 1142 | 1154 | ||
| 1143 | static void ipoib_set_mcast_list(struct net_device *dev) | 1155 | static void ipoib_set_mcast_list(struct net_device *dev) |
| @@ -1759,7 +1771,7 @@ void ipoib_setup(struct net_device *dev) | |||
| 1759 | 1771 | ||
| 1760 | dev->flags |= IFF_BROADCAST | IFF_MULTICAST; | 1772 | dev->flags |= IFF_BROADCAST | IFF_MULTICAST; |
| 1761 | 1773 | ||
| 1762 | dev->hard_header_len = IPOIB_ENCAP_LEN; | 1774 | dev->hard_header_len = IPOIB_HARD_LEN; |
| 1763 | dev->addr_len = INFINIBAND_ALEN; | 1775 | dev->addr_len = INFINIBAND_ALEN; |
| 1764 | dev->type = ARPHRD_INFINIBAND; | 1776 | dev->type = ARPHRD_INFINIBAND; |
| 1765 | dev->tx_queue_len = ipoib_sendq_size * 2; | 1777 | dev->tx_queue_len = ipoib_sendq_size * 2; |
