diff options
-rw-r--r-- | drivers/net/xen-netback/common.h | 3 | ||||
-rw-r--r-- | drivers/net/xen-netback/interface.c | 84 |
2 files changed, 15 insertions, 72 deletions
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h index 5d7bbf2b2ee7..8753e6ddff8f 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h | |||
@@ -73,9 +73,6 @@ struct xenvif { | |||
73 | struct vm_struct *tx_comms_area; | 73 | struct vm_struct *tx_comms_area; |
74 | struct vm_struct *rx_comms_area; | 74 | struct vm_struct *rx_comms_area; |
75 | 75 | ||
76 | /* Flags that must not be set in dev->features */ | ||
77 | u32 features_disabled; | ||
78 | |||
79 | /* Frontend feature information. */ | 76 | /* Frontend feature information. */ |
80 | u8 can_sg:1; | 77 | u8 can_sg:1; |
81 | u8 gso:1; | 78 | u8 gso:1; |
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index de569cc19da4..0ca86f9ec4ed 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c | |||
@@ -165,69 +165,18 @@ static int xenvif_change_mtu(struct net_device *dev, int mtu) | |||
165 | return 0; | 165 | return 0; |
166 | } | 166 | } |
167 | 167 | ||
168 | static void xenvif_set_features(struct xenvif *vif) | 168 | static u32 xenvif_fix_features(struct net_device *dev, u32 features) |
169 | { | ||
170 | struct net_device *dev = vif->dev; | ||
171 | u32 features = dev->features; | ||
172 | |||
173 | if (vif->can_sg) | ||
174 | features |= NETIF_F_SG; | ||
175 | if (vif->gso || vif->gso_prefix) | ||
176 | features |= NETIF_F_TSO; | ||
177 | if (vif->csum) | ||
178 | features |= NETIF_F_IP_CSUM; | ||
179 | |||
180 | features &= ~(vif->features_disabled); | ||
181 | |||
182 | if (!(features & NETIF_F_SG) && dev->mtu > ETH_DATA_LEN) | ||
183 | dev->mtu = ETH_DATA_LEN; | ||
184 | |||
185 | dev->features = features; | ||
186 | } | ||
187 | |||
188 | static int xenvif_set_tx_csum(struct net_device *dev, u32 data) | ||
189 | { | ||
190 | struct xenvif *vif = netdev_priv(dev); | ||
191 | if (data) { | ||
192 | if (!vif->csum) | ||
193 | return -EOPNOTSUPP; | ||
194 | vif->features_disabled &= ~NETIF_F_IP_CSUM; | ||
195 | } else { | ||
196 | vif->features_disabled |= NETIF_F_IP_CSUM; | ||
197 | } | ||
198 | |||
199 | xenvif_set_features(vif); | ||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static int xenvif_set_sg(struct net_device *dev, u32 data) | ||
204 | { | 169 | { |
205 | struct xenvif *vif = netdev_priv(dev); | 170 | struct xenvif *vif = netdev_priv(dev); |
206 | if (data) { | ||
207 | if (!vif->can_sg) | ||
208 | return -EOPNOTSUPP; | ||
209 | vif->features_disabled &= ~NETIF_F_SG; | ||
210 | } else { | ||
211 | vif->features_disabled |= NETIF_F_SG; | ||
212 | } | ||
213 | 171 | ||
214 | xenvif_set_features(vif); | 172 | if (!vif->can_sg) |
215 | return 0; | 173 | features &= ~NETIF_F_SG; |
216 | } | 174 | if (!vif->gso && !vif->gso_prefix) |
175 | features &= ~NETIF_F_TSO; | ||
176 | if (!vif->csum) | ||
177 | features &= ~NETIF_F_IP_CSUM; | ||
217 | 178 | ||
218 | static int xenvif_set_tso(struct net_device *dev, u32 data) | 179 | return features; |
219 | { | ||
220 | struct xenvif *vif = netdev_priv(dev); | ||
221 | if (data) { | ||
222 | if (!vif->gso && !vif->gso_prefix) | ||
223 | return -EOPNOTSUPP; | ||
224 | vif->features_disabled &= ~NETIF_F_TSO; | ||
225 | } else { | ||
226 | vif->features_disabled |= NETIF_F_TSO; | ||
227 | } | ||
228 | |||
229 | xenvif_set_features(vif); | ||
230 | return 0; | ||
231 | } | 180 | } |
232 | 181 | ||
233 | static const struct xenvif_stat { | 182 | static const struct xenvif_stat { |
@@ -274,12 +223,6 @@ static void xenvif_get_strings(struct net_device *dev, u32 stringset, u8 * data) | |||
274 | } | 223 | } |
275 | 224 | ||
276 | static struct ethtool_ops xenvif_ethtool_ops = { | 225 | static struct ethtool_ops xenvif_ethtool_ops = { |
277 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
278 | .set_tx_csum = xenvif_set_tx_csum, | ||
279 | .get_sg = ethtool_op_get_sg, | ||
280 | .set_sg = xenvif_set_sg, | ||
281 | .get_tso = ethtool_op_get_tso, | ||
282 | .set_tso = xenvif_set_tso, | ||
283 | .get_link = ethtool_op_get_link, | 226 | .get_link = ethtool_op_get_link, |
284 | 227 | ||
285 | .get_sset_count = xenvif_get_sset_count, | 228 | .get_sset_count = xenvif_get_sset_count, |
@@ -293,6 +236,7 @@ static struct net_device_ops xenvif_netdev_ops = { | |||
293 | .ndo_open = xenvif_open, | 236 | .ndo_open = xenvif_open, |
294 | .ndo_stop = xenvif_close, | 237 | .ndo_stop = xenvif_close, |
295 | .ndo_change_mtu = xenvif_change_mtu, | 238 | .ndo_change_mtu = xenvif_change_mtu, |
239 | .ndo_fix_features = xenvif_fix_features, | ||
296 | }; | 240 | }; |
297 | 241 | ||
298 | struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, | 242 | struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, |
@@ -331,7 +275,8 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, | |||
331 | vif->credit_timeout.expires = jiffies; | 275 | vif->credit_timeout.expires = jiffies; |
332 | 276 | ||
333 | dev->netdev_ops = &xenvif_netdev_ops; | 277 | dev->netdev_ops = &xenvif_netdev_ops; |
334 | xenvif_set_features(vif); | 278 | dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO; |
279 | dev->features = dev->hw_features; | ||
335 | SET_ETHTOOL_OPS(dev, &xenvif_ethtool_ops); | 280 | SET_ETHTOOL_OPS(dev, &xenvif_ethtool_ops); |
336 | 281 | ||
337 | dev->tx_queue_len = XENVIF_QUEUE_LENGTH; | 282 | dev->tx_queue_len = XENVIF_QUEUE_LENGTH; |
@@ -367,8 +312,6 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, | |||
367 | if (vif->irq) | 312 | if (vif->irq) |
368 | return 0; | 313 | return 0; |
369 | 314 | ||
370 | xenvif_set_features(vif); | ||
371 | |||
372 | err = xen_netbk_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref); | 315 | err = xen_netbk_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref); |
373 | if (err < 0) | 316 | if (err < 0) |
374 | goto err; | 317 | goto err; |
@@ -384,9 +327,12 @@ int xenvif_connect(struct xenvif *vif, unsigned long tx_ring_ref, | |||
384 | xenvif_get(vif); | 327 | xenvif_get(vif); |
385 | 328 | ||
386 | rtnl_lock(); | 329 | rtnl_lock(); |
387 | netif_carrier_on(vif->dev); | ||
388 | if (netif_running(vif->dev)) | 330 | if (netif_running(vif->dev)) |
389 | xenvif_up(vif); | 331 | xenvif_up(vif); |
332 | if (!vif->can_sg && vif->dev->mtu > ETH_DATA_LEN) | ||
333 | dev_set_mtu(vif->dev, ETH_DATA_LEN); | ||
334 | netdev_update_features(vif->dev); | ||
335 | netif_carrier_on(vif->dev); | ||
390 | rtnl_unlock(); | 336 | rtnl_unlock(); |
391 | 337 | ||
392 | return 0; | 338 | return 0; |