aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/xen-netfront.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/xen-netfront.c')
-rw-r--r--drivers/net/xen-netfront.c106
1 files changed, 51 insertions, 55 deletions
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 5c8d9c385be0..db9a763aaa7f 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1140,6 +1140,42 @@ static void xennet_uninit(struct net_device *dev)
1140 gnttab_free_grant_references(np->gref_rx_head); 1140 gnttab_free_grant_references(np->gref_rx_head);
1141} 1141}
1142 1142
1143static u32 xennet_fix_features(struct net_device *dev, u32 features)
1144{
1145 struct netfront_info *np = netdev_priv(dev);
1146 int val;
1147
1148 if (features & NETIF_F_SG) {
1149 if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg",
1150 "%d", &val) < 0)
1151 val = 0;
1152
1153 if (!val)
1154 features &= ~NETIF_F_SG;
1155 }
1156
1157 if (features & NETIF_F_TSO) {
1158 if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
1159 "feature-gso-tcpv4", "%d", &val) < 0)
1160 val = 0;
1161
1162 if (!val)
1163 features &= ~NETIF_F_TSO;
1164 }
1165
1166 return features;
1167}
1168
1169static int xennet_set_features(struct net_device *dev, u32 features)
1170{
1171 if (!(features & NETIF_F_SG) && dev->mtu > ETH_DATA_LEN) {
1172 netdev_info(dev, "Reducing MTU because no SG offload");
1173 dev->mtu = ETH_DATA_LEN;
1174 }
1175
1176 return 0;
1177}
1178
1143static const struct net_device_ops xennet_netdev_ops = { 1179static const struct net_device_ops xennet_netdev_ops = {
1144 .ndo_open = xennet_open, 1180 .ndo_open = xennet_open,
1145 .ndo_uninit = xennet_uninit, 1181 .ndo_uninit = xennet_uninit,
@@ -1148,6 +1184,8 @@ static const struct net_device_ops xennet_netdev_ops = {
1148 .ndo_change_mtu = xennet_change_mtu, 1184 .ndo_change_mtu = xennet_change_mtu,
1149 .ndo_set_mac_address = eth_mac_addr, 1185 .ndo_set_mac_address = eth_mac_addr,
1150 .ndo_validate_addr = eth_validate_addr, 1186 .ndo_validate_addr = eth_validate_addr,
1187 .ndo_fix_features = xennet_fix_features,
1188 .ndo_set_features = xennet_set_features,
1151}; 1189};
1152 1190
1153static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev) 1191static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev)
@@ -1209,7 +1247,17 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev
1209 netdev->netdev_ops = &xennet_netdev_ops; 1247 netdev->netdev_ops = &xennet_netdev_ops;
1210 1248
1211 netif_napi_add(netdev, &np->napi, xennet_poll, 64); 1249 netif_napi_add(netdev, &np->napi, xennet_poll, 64);
1212 netdev->features = NETIF_F_IP_CSUM; 1250 netdev->features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
1251 NETIF_F_GSO_ROBUST;
1252 netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO;
1253
1254 /*
1255 * Assume that all hw features are available for now. This set
1256 * will be adjusted by the call to netdev_update_features() in
1257 * xennet_connect() which is the earliest point where we can
1258 * negotiate with the backend regarding supported features.
1259 */
1260 netdev->features |= netdev->hw_features;
1213 1261
1214 SET_ETHTOOL_OPS(netdev, &xennet_ethtool_ops); 1262 SET_ETHTOOL_OPS(netdev, &xennet_ethtool_ops);
1215 SET_NETDEV_DEV(netdev, &dev->dev); 1263 SET_NETDEV_DEV(netdev, &dev->dev);
@@ -1416,8 +1464,7 @@ static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info)
1416 goto fail; 1464 goto fail;
1417 1465
1418 err = bind_evtchn_to_irqhandler(info->evtchn, xennet_interrupt, 1466 err = bind_evtchn_to_irqhandler(info->evtchn, xennet_interrupt,
1419 IRQF_SAMPLE_RANDOM, netdev->name, 1467 0, netdev->name, netdev);
1420 netdev);
1421 if (err < 0) 1468 if (err < 0)
1422 goto fail; 1469 goto fail;
1423 netdev->irq = err; 1470 netdev->irq = err;
@@ -1510,54 +1557,6 @@ again:
1510 return err; 1557 return err;
1511} 1558}
1512 1559
1513static int xennet_set_sg(struct net_device *dev, u32 data)
1514{
1515 if (data) {
1516 struct netfront_info *np = netdev_priv(dev);
1517 int val;
1518
1519 if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg",
1520 "%d", &val) < 0)
1521 val = 0;
1522 if (!val)
1523 return -ENOSYS;
1524 } else if (dev->mtu > ETH_DATA_LEN)
1525 dev->mtu = ETH_DATA_LEN;
1526
1527 return ethtool_op_set_sg(dev, data);
1528}
1529
1530static int xennet_set_tso(struct net_device *dev, u32 data)
1531{
1532 if (data) {
1533 struct netfront_info *np = netdev_priv(dev);
1534 int val;
1535
1536 if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
1537 "feature-gso-tcpv4", "%d", &val) < 0)
1538 val = 0;
1539 if (!val)
1540 return -ENOSYS;
1541 }
1542
1543 return ethtool_op_set_tso(dev, data);
1544}
1545
1546static void xennet_set_features(struct net_device *dev)
1547{
1548 /* Turn off all GSO bits except ROBUST. */
1549 dev->features &= ~NETIF_F_GSO_MASK;
1550 dev->features |= NETIF_F_GSO_ROBUST;
1551 xennet_set_sg(dev, 0);
1552
1553 /* We need checksum offload to enable scatter/gather and TSO. */
1554 if (!(dev->features & NETIF_F_IP_CSUM))
1555 return;
1556
1557 if (!xennet_set_sg(dev, 1))
1558 xennet_set_tso(dev, 1);
1559}
1560
1561static int xennet_connect(struct net_device *dev) 1560static int xennet_connect(struct net_device *dev)
1562{ 1561{
1563 struct netfront_info *np = netdev_priv(dev); 1562 struct netfront_info *np = netdev_priv(dev);
@@ -1582,7 +1581,7 @@ static int xennet_connect(struct net_device *dev)
1582 if (err) 1581 if (err)
1583 return err; 1582 return err;
1584 1583
1585 xennet_set_features(dev); 1584 netdev_update_features(dev);
1586 1585
1587 spin_lock_bh(&np->rx_lock); 1586 spin_lock_bh(&np->rx_lock);
1588 spin_lock_irq(&np->tx_lock); 1587 spin_lock_irq(&np->tx_lock);
@@ -1710,9 +1709,6 @@ static void xennet_get_strings(struct net_device *dev, u32 stringset, u8 * data)
1710 1709
1711static const struct ethtool_ops xennet_ethtool_ops = 1710static const struct ethtool_ops xennet_ethtool_ops =
1712{ 1711{
1713 .set_tx_csum = ethtool_op_set_tx_csum,
1714 .set_sg = xennet_set_sg,
1715 .set_tso = xennet_set_tso,
1716 .get_link = ethtool_op_get_link, 1712 .get_link = ethtool_op_get_link,
1717 1713
1718 .get_sset_count = xennet_get_sset_count, 1714 .get_sset_count = xennet_get_sset_count,