diff options
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib.h | 1 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_main.c | 67 | ||||
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_vlan.c | 4 |
3 files changed, 44 insertions, 28 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index 68ba5c3482e4..e0c7dfabf2b4 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h | |||
@@ -507,6 +507,7 @@ int ipoib_pkey_dev_delay_open(struct net_device *dev); | |||
507 | void ipoib_drain_cq(struct net_device *dev); | 507 | void ipoib_drain_cq(struct net_device *dev); |
508 | 508 | ||
509 | void ipoib_set_ethtool_ops(struct net_device *dev); | 509 | void ipoib_set_ethtool_ops(struct net_device *dev); |
510 | int ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca); | ||
510 | 511 | ||
511 | #ifdef CONFIG_INFINIBAND_IPOIB_CM | 512 | #ifdef CONFIG_INFINIBAND_IPOIB_CM |
512 | 513 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index c0ee514396df..fddded7900d1 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -1173,11 +1173,48 @@ int ipoib_add_pkey_attr(struct net_device *dev) | |||
1173 | return device_create_file(&dev->dev, &dev_attr_pkey); | 1173 | return device_create_file(&dev->dev, &dev_attr_pkey); |
1174 | } | 1174 | } |
1175 | 1175 | ||
1176 | int ipoib_set_dev_features(struct ipoib_dev_priv *priv, struct ib_device *hca) | ||
1177 | { | ||
1178 | struct ib_device_attr *device_attr; | ||
1179 | int result = -ENOMEM; | ||
1180 | |||
1181 | device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL); | ||
1182 | if (!device_attr) { | ||
1183 | printk(KERN_WARNING "%s: allocation of %zu bytes failed\n", | ||
1184 | hca->name, sizeof *device_attr); | ||
1185 | return result; | ||
1186 | } | ||
1187 | |||
1188 | result = ib_query_device(hca, device_attr); | ||
1189 | if (result) { | ||
1190 | printk(KERN_WARNING "%s: ib_query_device failed (ret = %d)\n", | ||
1191 | hca->name, result); | ||
1192 | kfree(device_attr); | ||
1193 | return result; | ||
1194 | } | ||
1195 | priv->hca_caps = device_attr->device_cap_flags; | ||
1196 | |||
1197 | kfree(device_attr); | ||
1198 | |||
1199 | if (priv->hca_caps & IB_DEVICE_UD_IP_CSUM) { | ||
1200 | set_bit(IPOIB_FLAG_CSUM, &priv->flags); | ||
1201 | priv->dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; | ||
1202 | } | ||
1203 | |||
1204 | if (lro) | ||
1205 | priv->dev->features |= NETIF_F_LRO; | ||
1206 | |||
1207 | if (priv->dev->features & NETIF_F_SG && priv->hca_caps & IB_DEVICE_UD_TSO) | ||
1208 | priv->dev->features |= NETIF_F_TSO; | ||
1209 | |||
1210 | return 0; | ||
1211 | } | ||
1212 | |||
1213 | |||
1176 | static struct net_device *ipoib_add_port(const char *format, | 1214 | static struct net_device *ipoib_add_port(const char *format, |
1177 | struct ib_device *hca, u8 port) | 1215 | struct ib_device *hca, u8 port) |
1178 | { | 1216 | { |
1179 | struct ipoib_dev_priv *priv; | 1217 | struct ipoib_dev_priv *priv; |
1180 | struct ib_device_attr *device_attr; | ||
1181 | struct ib_port_attr attr; | 1218 | struct ib_port_attr attr; |
1182 | int result = -ENOMEM; | 1219 | int result = -ENOMEM; |
1183 | 1220 | ||
@@ -1206,31 +1243,8 @@ static struct net_device *ipoib_add_port(const char *format, | |||
1206 | goto device_init_failed; | 1243 | goto device_init_failed; |
1207 | } | 1244 | } |
1208 | 1245 | ||
1209 | device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL); | 1246 | if (ipoib_set_dev_features(priv, hca)) |
1210 | if (!device_attr) { | ||
1211 | printk(KERN_WARNING "%s: allocation of %zu bytes failed\n", | ||
1212 | hca->name, sizeof *device_attr); | ||
1213 | goto device_init_failed; | 1247 | goto device_init_failed; |
1214 | } | ||
1215 | |||
1216 | result = ib_query_device(hca, device_attr); | ||
1217 | if (result) { | ||
1218 | printk(KERN_WARNING "%s: ib_query_device failed (ret = %d)\n", | ||
1219 | hca->name, result); | ||
1220 | kfree(device_attr); | ||
1221 | goto device_init_failed; | ||
1222 | } | ||
1223 | priv->hca_caps = device_attr->device_cap_flags; | ||
1224 | |||
1225 | kfree(device_attr); | ||
1226 | |||
1227 | if (priv->hca_caps & IB_DEVICE_UD_IP_CSUM) { | ||
1228 | set_bit(IPOIB_FLAG_CSUM, &priv->flags); | ||
1229 | priv->dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; | ||
1230 | } | ||
1231 | |||
1232 | if (lro) | ||
1233 | priv->dev->features |= NETIF_F_LRO; | ||
1234 | 1248 | ||
1235 | /* | 1249 | /* |
1236 | * Set the full membership bit, so that we join the right | 1250 | * Set the full membership bit, so that we join the right |
@@ -1266,9 +1280,6 @@ static struct net_device *ipoib_add_port(const char *format, | |||
1266 | goto event_failed; | 1280 | goto event_failed; |
1267 | } | 1281 | } |
1268 | 1282 | ||
1269 | if (priv->dev->features & NETIF_F_SG && priv->hca_caps & IB_DEVICE_UD_TSO) | ||
1270 | priv->dev->features |= NETIF_F_TSO; | ||
1271 | |||
1272 | result = register_netdev(priv->dev); | 1283 | result = register_netdev(priv->dev); |
1273 | if (result) { | 1284 | if (result) { |
1274 | printk(KERN_WARNING "%s: couldn't register ipoib port %d; error %d\n", | 1285 | printk(KERN_WARNING "%s: couldn't register ipoib port %d; error %d\n", |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c index b08eb56196d3..2cf1a4088718 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c | |||
@@ -93,6 +93,10 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey) | |||
93 | priv->mcast_mtu = priv->admin_mtu = priv->dev->mtu; | 93 | priv->mcast_mtu = priv->admin_mtu = priv->dev->mtu; |
94 | set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags); | 94 | set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags); |
95 | 95 | ||
96 | result = ipoib_set_dev_features(priv, ppriv->ca); | ||
97 | if (result) | ||
98 | goto device_init_failed; | ||
99 | |||
96 | priv->pkey = pkey; | 100 | priv->pkey = pkey; |
97 | 101 | ||
98 | memcpy(priv->dev->dev_addr, ppriv->dev->dev_addr, INFINIBAND_ALEN); | 102 | memcpy(priv->dev->dev_addr, ppriv->dev->dev_addr, INFINIBAND_ALEN); |