aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib.h1
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c67
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_vlan.c4
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);
507void ipoib_drain_cq(struct net_device *dev); 507void ipoib_drain_cq(struct net_device *dev);
508 508
509void ipoib_set_ethtool_ops(struct net_device *dev); 509void ipoib_set_ethtool_ops(struct net_device *dev);
510int 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
1176int 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
1176static struct net_device *ipoib_add_port(const char *format, 1214static 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);