diff options
author | Michał Mirosław <mirq-linux@rere.qmqm.pl> | 2011-04-18 20:43:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-04-20 04:30:42 -0400 |
commit | 6204b47ec4394f7e472885c8d05d9cda96d97a25 (patch) | |
tree | 887f57b02c53cc2cf0f7c6365978747474133bbe /drivers/s390/net | |
parent | dd6f6d024906b8f05a0832c78c16a1e818958321 (diff) |
net: s390: convert to hw_features
options.large_send was easy to get rid of. options.checksum_type has deeper
roots so is left for later cleanup.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/s390/net')
-rw-r--r-- | drivers/s390/net/qeth_core.h | 7 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_main.c | 117 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_sys.c | 35 |
3 files changed, 52 insertions, 107 deletions
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index af3f7b095647..8d6146a107d9 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h | |||
@@ -407,12 +407,6 @@ struct qeth_qdio_q { | |||
407 | int next_buf_to_init; | 407 | int next_buf_to_init; |
408 | } __attribute__ ((aligned(256))); | 408 | } __attribute__ ((aligned(256))); |
409 | 409 | ||
410 | /* possible types of qeth large_send support */ | ||
411 | enum qeth_large_send_types { | ||
412 | QETH_LARGE_SEND_NO, | ||
413 | QETH_LARGE_SEND_TSO, | ||
414 | }; | ||
415 | |||
416 | struct qeth_qdio_out_buffer { | 410 | struct qeth_qdio_out_buffer { |
417 | struct qdio_buffer *buffer; | 411 | struct qdio_buffer *buffer; |
418 | atomic_t state; | 412 | atomic_t state; |
@@ -651,7 +645,6 @@ struct qeth_card_options { | |||
651 | int fake_broadcast; | 645 | int fake_broadcast; |
652 | int add_hhlen; | 646 | int add_hhlen; |
653 | int layer2; | 647 | int layer2; |
654 | enum qeth_large_send_types large_send; | ||
655 | int performance_stats; | 648 | int performance_stats; |
656 | int rx_sg_cb; | 649 | int rx_sg_cb; |
657 | enum qeth_ipa_isolation_modes isolation; | 650 | enum qeth_ipa_isolation_modes isolation; |
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 142e5f6ef4f3..1496661507ea 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
@@ -43,33 +43,6 @@ static int qeth_l3_deregister_addr_entry(struct qeth_card *, | |||
43 | static int __qeth_l3_set_online(struct ccwgroup_device *, int); | 43 | static int __qeth_l3_set_online(struct ccwgroup_device *, int); |
44 | static int __qeth_l3_set_offline(struct ccwgroup_device *, int); | 44 | static int __qeth_l3_set_offline(struct ccwgroup_device *, int); |
45 | 45 | ||
46 | int qeth_l3_set_large_send(struct qeth_card *card, | ||
47 | enum qeth_large_send_types type) | ||
48 | { | ||
49 | int rc = 0; | ||
50 | |||
51 | card->options.large_send = type; | ||
52 | if (card->dev == NULL) | ||
53 | return 0; | ||
54 | |||
55 | if (card->options.large_send == QETH_LARGE_SEND_TSO) { | ||
56 | if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) { | ||
57 | card->dev->features |= NETIF_F_TSO | NETIF_F_SG | | ||
58 | NETIF_F_IP_CSUM; | ||
59 | } else { | ||
60 | card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | | ||
61 | NETIF_F_IP_CSUM); | ||
62 | card->options.large_send = QETH_LARGE_SEND_NO; | ||
63 | rc = -EOPNOTSUPP; | ||
64 | } | ||
65 | } else { | ||
66 | card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | | ||
67 | NETIF_F_IP_CSUM); | ||
68 | card->options.large_send = QETH_LARGE_SEND_NO; | ||
69 | } | ||
70 | return rc; | ||
71 | } | ||
72 | |||
73 | static int qeth_l3_isxdigit(char *buf) | 46 | static int qeth_l3_isxdigit(char *buf) |
74 | { | 47 | { |
75 | while (*buf) { | 48 | while (*buf) { |
@@ -1485,6 +1458,7 @@ int qeth_l3_set_rx_csum(struct qeth_card *card, | |||
1485 | if (rc) | 1458 | if (rc) |
1486 | return -EIO; | 1459 | return -EIO; |
1487 | } | 1460 | } |
1461 | card->dev->features |= NETIF_F_RXCSUM; | ||
1488 | } else { | 1462 | } else { |
1489 | if (csum_type == HW_CHECKSUMMING) { | 1463 | if (csum_type == HW_CHECKSUMMING) { |
1490 | if (card->state != CARD_STATE_DOWN) { | 1464 | if (card->state != CARD_STATE_DOWN) { |
@@ -1496,6 +1470,7 @@ int qeth_l3_set_rx_csum(struct qeth_card *card, | |||
1496 | return -EIO; | 1470 | return -EIO; |
1497 | } | 1471 | } |
1498 | } | 1472 | } |
1473 | card->dev->features &= ~NETIF_F_RXCSUM; | ||
1499 | } | 1474 | } |
1500 | card->options.checksum_type = csum_type; | 1475 | card->options.checksum_type = csum_type; |
1501 | return rc; | 1476 | return rc; |
@@ -1580,10 +1555,8 @@ static int qeth_l3_start_ipa_tso(struct qeth_card *card) | |||
1580 | dev_info(&card->gdev->dev, | 1555 | dev_info(&card->gdev->dev, |
1581 | "Outbound TSO enabled\n"); | 1556 | "Outbound TSO enabled\n"); |
1582 | } | 1557 | } |
1583 | if (rc && (card->options.large_send == QETH_LARGE_SEND_TSO)) { | 1558 | if (rc) |
1584 | card->options.large_send = QETH_LARGE_SEND_NO; | 1559 | card->dev->features &= ~NETIF_F_TSO; |
1585 | card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG); | ||
1586 | } | ||
1587 | return rc; | 1560 | return rc; |
1588 | } | 1561 | } |
1589 | 1562 | ||
@@ -3024,7 +2997,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3024 | struct qeth_qdio_out_q *queue = card->qdio.out_qs | 2997 | struct qeth_qdio_out_q *queue = card->qdio.out_qs |
3025 | [qeth_get_priority_queue(card, skb, ipv, cast_type)]; | 2998 | [qeth_get_priority_queue(card, skb, ipv, cast_type)]; |
3026 | int tx_bytes = skb->len; | 2999 | int tx_bytes = skb->len; |
3027 | enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO; | 3000 | bool large_send; |
3028 | int data_offset = -1; | 3001 | int data_offset = -1; |
3029 | int nr_frags; | 3002 | int nr_frags; |
3030 | 3003 | ||
@@ -3046,8 +3019,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3046 | card->perf_stats.outbound_start_time = qeth_get_micros(); | 3019 | card->perf_stats.outbound_start_time = qeth_get_micros(); |
3047 | } | 3020 | } |
3048 | 3021 | ||
3049 | if (skb_is_gso(skb)) | 3022 | large_send = skb_is_gso(skb); |
3050 | large_send = card->options.large_send; | ||
3051 | 3023 | ||
3052 | if ((card->info.type == QETH_CARD_TYPE_IQD) && (!large_send) && | 3024 | if ((card->info.type == QETH_CARD_TYPE_IQD) && (!large_send) && |
3053 | (skb_shinfo(skb)->nr_frags == 0)) { | 3025 | (skb_shinfo(skb)->nr_frags == 0)) { |
@@ -3096,7 +3068,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3096 | /* fix hardware limitation: as long as we do not have sbal | 3068 | /* fix hardware limitation: as long as we do not have sbal |
3097 | * chaining we can not send long frag lists | 3069 | * chaining we can not send long frag lists |
3098 | */ | 3070 | */ |
3099 | if (large_send == QETH_LARGE_SEND_TSO) { | 3071 | if (large_send) { |
3100 | if (qeth_l3_tso_elements(new_skb) + 1 > 16) { | 3072 | if (qeth_l3_tso_elements(new_skb) + 1 > 16) { |
3101 | if (skb_linearize(new_skb)) | 3073 | if (skb_linearize(new_skb)) |
3102 | goto tx_drop; | 3074 | goto tx_drop; |
@@ -3105,8 +3077,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3105 | } | 3077 | } |
3106 | } | 3078 | } |
3107 | 3079 | ||
3108 | if ((large_send == QETH_LARGE_SEND_TSO) && | 3080 | if (large_send && (cast_type == RTN_UNSPEC)) { |
3109 | (cast_type == RTN_UNSPEC)) { | ||
3110 | hdr = (struct qeth_hdr *)skb_push(new_skb, | 3081 | hdr = (struct qeth_hdr *)skb_push(new_skb, |
3111 | sizeof(struct qeth_hdr_tso)); | 3082 | sizeof(struct qeth_hdr_tso)); |
3112 | memset(hdr, 0, sizeof(struct qeth_hdr_tso)); | 3083 | memset(hdr, 0, sizeof(struct qeth_hdr_tso)); |
@@ -3141,7 +3112,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3141 | 3112 | ||
3142 | if (card->info.type != QETH_CARD_TYPE_IQD) { | 3113 | if (card->info.type != QETH_CARD_TYPE_IQD) { |
3143 | int len; | 3114 | int len; |
3144 | if (large_send == QETH_LARGE_SEND_TSO) | 3115 | if (large_send) |
3145 | len = ((unsigned long)tcp_hdr(new_skb) + | 3116 | len = ((unsigned long)tcp_hdr(new_skb) + |
3146 | tcp_hdr(new_skb)->doff * 4) - | 3117 | tcp_hdr(new_skb)->doff * 4) - |
3147 | (unsigned long)new_skb->data; | 3118 | (unsigned long)new_skb->data; |
@@ -3162,7 +3133,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3162 | if (new_skb != skb) | 3133 | if (new_skb != skb) |
3163 | dev_kfree_skb_any(skb); | 3134 | dev_kfree_skb_any(skb); |
3164 | if (card->options.performance_stats) { | 3135 | if (card->options.performance_stats) { |
3165 | if (large_send != QETH_LARGE_SEND_NO) { | 3136 | if (large_send) { |
3166 | card->perf_stats.large_send_bytes += tx_bytes; | 3137 | card->perf_stats.large_send_bytes += tx_bytes; |
3167 | card->perf_stats.large_send_cnt++; | 3138 | card->perf_stats.large_send_cnt++; |
3168 | } | 3139 | } |
@@ -3248,65 +3219,40 @@ static int qeth_l3_stop(struct net_device *dev) | |||
3248 | return 0; | 3219 | return 0; |
3249 | } | 3220 | } |
3250 | 3221 | ||
3251 | static u32 qeth_l3_ethtool_get_rx_csum(struct net_device *dev) | 3222 | static u32 qeth_l3_fix_features(struct net_device *dev, u32 features) |
3252 | { | 3223 | { |
3253 | struct qeth_card *card = dev->ml_priv; | 3224 | struct qeth_card *card = dev->ml_priv; |
3254 | 3225 | ||
3255 | return (card->options.checksum_type == HW_CHECKSUMMING); | 3226 | if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM)) |
3227 | features &= ~NETIF_F_IP_CSUM; | ||
3228 | if (!qeth_is_supported(card, IPA_OUTBOUND_TSO)) | ||
3229 | features &= ~NETIF_F_TSO; | ||
3230 | if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM)) | ||
3231 | features &= ~NETIF_F_RXCSUM; | ||
3232 | |||
3233 | return features; | ||
3256 | } | 3234 | } |
3257 | 3235 | ||
3258 | static int qeth_l3_ethtool_set_rx_csum(struct net_device *dev, u32 data) | 3236 | static int qeth_l3_set_features(struct net_device *dev, u32 features) |
3259 | { | 3237 | { |
3260 | struct qeth_card *card = dev->ml_priv; | ||
3261 | enum qeth_checksum_types csum_type; | 3238 | enum qeth_checksum_types csum_type; |
3239 | struct qeth_card *card = dev->ml_priv; | ||
3240 | u32 changed = dev->features ^ features; | ||
3262 | 3241 | ||
3263 | if (data) | 3242 | if (!(changed & NETIF_F_RXCSUM)) |
3243 | return 0; | ||
3244 | |||
3245 | if (features & NETIF_F_RXCSUM) | ||
3264 | csum_type = HW_CHECKSUMMING; | 3246 | csum_type = HW_CHECKSUMMING; |
3265 | else | 3247 | else |
3266 | csum_type = SW_CHECKSUMMING; | 3248 | csum_type = SW_CHECKSUMMING; |
3267 | 3249 | ||
3250 | dev->features = features ^ NETIF_F_RXCSUM; | ||
3268 | return qeth_l3_set_rx_csum(card, csum_type); | 3251 | return qeth_l3_set_rx_csum(card, csum_type); |
3269 | } | 3252 | } |
3270 | 3253 | ||
3271 | static int qeth_l3_ethtool_set_tso(struct net_device *dev, u32 data) | ||
3272 | { | ||
3273 | struct qeth_card *card = dev->ml_priv; | ||
3274 | int rc = 0; | ||
3275 | |||
3276 | if (data) { | ||
3277 | rc = qeth_l3_set_large_send(card, QETH_LARGE_SEND_TSO); | ||
3278 | } else { | ||
3279 | dev->features &= ~NETIF_F_TSO; | ||
3280 | card->options.large_send = QETH_LARGE_SEND_NO; | ||
3281 | } | ||
3282 | return rc; | ||
3283 | } | ||
3284 | |||
3285 | static int qeth_l3_ethtool_set_tx_csum(struct net_device *dev, u32 data) | ||
3286 | { | ||
3287 | struct qeth_card *card = dev->ml_priv; | ||
3288 | |||
3289 | if (data) { | ||
3290 | if (qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM)) | ||
3291 | dev->features |= NETIF_F_IP_CSUM; | ||
3292 | else | ||
3293 | return -EPERM; | ||
3294 | } else | ||
3295 | dev->features &= ~NETIF_F_IP_CSUM; | ||
3296 | |||
3297 | return 0; | ||
3298 | } | ||
3299 | |||
3300 | static const struct ethtool_ops qeth_l3_ethtool_ops = { | 3254 | static const struct ethtool_ops qeth_l3_ethtool_ops = { |
3301 | .get_link = ethtool_op_get_link, | 3255 | .get_link = ethtool_op_get_link, |
3302 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
3303 | .set_tx_csum = qeth_l3_ethtool_set_tx_csum, | ||
3304 | .get_rx_csum = qeth_l3_ethtool_get_rx_csum, | ||
3305 | .set_rx_csum = qeth_l3_ethtool_set_rx_csum, | ||
3306 | .get_sg = ethtool_op_get_sg, | ||
3307 | .set_sg = ethtool_op_set_sg, | ||
3308 | .get_tso = ethtool_op_get_tso, | ||
3309 | .set_tso = qeth_l3_ethtool_set_tso, | ||
3310 | .get_strings = qeth_core_get_strings, | 3256 | .get_strings = qeth_core_get_strings, |
3311 | .get_ethtool_stats = qeth_core_get_ethtool_stats, | 3257 | .get_ethtool_stats = qeth_core_get_ethtool_stats, |
3312 | .get_sset_count = qeth_core_get_sset_count, | 3258 | .get_sset_count = qeth_core_get_sset_count, |
@@ -3347,6 +3293,8 @@ static const struct net_device_ops qeth_l3_netdev_ops = { | |||
3347 | .ndo_set_multicast_list = qeth_l3_set_multicast_list, | 3293 | .ndo_set_multicast_list = qeth_l3_set_multicast_list, |
3348 | .ndo_do_ioctl = qeth_l3_do_ioctl, | 3294 | .ndo_do_ioctl = qeth_l3_do_ioctl, |
3349 | .ndo_change_mtu = qeth_change_mtu, | 3295 | .ndo_change_mtu = qeth_change_mtu, |
3296 | .ndo_fix_features = qeth_l3_fix_features, | ||
3297 | .ndo_set_features = qeth_l3_set_features, | ||
3350 | .ndo_vlan_rx_register = qeth_l3_vlan_rx_register, | 3298 | .ndo_vlan_rx_register = qeth_l3_vlan_rx_register, |
3351 | .ndo_vlan_rx_add_vid = qeth_l3_vlan_rx_add_vid, | 3299 | .ndo_vlan_rx_add_vid = qeth_l3_vlan_rx_add_vid, |
3352 | .ndo_vlan_rx_kill_vid = qeth_l3_vlan_rx_kill_vid, | 3300 | .ndo_vlan_rx_kill_vid = qeth_l3_vlan_rx_kill_vid, |
@@ -3362,6 +3310,8 @@ static const struct net_device_ops qeth_l3_osa_netdev_ops = { | |||
3362 | .ndo_set_multicast_list = qeth_l3_set_multicast_list, | 3310 | .ndo_set_multicast_list = qeth_l3_set_multicast_list, |
3363 | .ndo_do_ioctl = qeth_l3_do_ioctl, | 3311 | .ndo_do_ioctl = qeth_l3_do_ioctl, |
3364 | .ndo_change_mtu = qeth_change_mtu, | 3312 | .ndo_change_mtu = qeth_change_mtu, |
3313 | .ndo_fix_features = qeth_l3_fix_features, | ||
3314 | .ndo_set_features = qeth_l3_set_features, | ||
3365 | .ndo_vlan_rx_register = qeth_l3_vlan_rx_register, | 3315 | .ndo_vlan_rx_register = qeth_l3_vlan_rx_register, |
3366 | .ndo_vlan_rx_add_vid = qeth_l3_vlan_rx_add_vid, | 3316 | .ndo_vlan_rx_add_vid = qeth_l3_vlan_rx_add_vid, |
3367 | .ndo_vlan_rx_kill_vid = qeth_l3_vlan_rx_kill_vid, | 3317 | .ndo_vlan_rx_kill_vid = qeth_l3_vlan_rx_kill_vid, |
@@ -3392,8 +3342,6 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) | |||
3392 | if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD)) | 3342 | if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD)) |
3393 | card->dev->dev_id = card->info.unique_id & | 3343 | card->dev->dev_id = card->info.unique_id & |
3394 | 0xffff; | 3344 | 0xffff; |
3395 | if (!card->info.guestlan) | ||
3396 | card->dev->features |= NETIF_F_GRO; | ||
3397 | } | 3345 | } |
3398 | } else if (card->info.type == QETH_CARD_TYPE_IQD) { | 3346 | } else if (card->info.type == QETH_CARD_TYPE_IQD) { |
3399 | card->dev = alloc_netdev(0, "hsi%d", ether_setup); | 3347 | card->dev = alloc_netdev(0, "hsi%d", ether_setup); |
@@ -3409,6 +3357,8 @@ static int qeth_l3_setup_netdev(struct qeth_card *card) | |||
3409 | card->dev->watchdog_timeo = QETH_TX_TIMEOUT; | 3357 | card->dev->watchdog_timeo = QETH_TX_TIMEOUT; |
3410 | card->dev->mtu = card->info.initial_mtu; | 3358 | card->dev->mtu = card->info.initial_mtu; |
3411 | SET_ETHTOOL_OPS(card->dev, &qeth_l3_ethtool_ops); | 3359 | SET_ETHTOOL_OPS(card->dev, &qeth_l3_ethtool_ops); |
3360 | card->dev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | | ||
3361 | NETIF_F_IP_CSUM | NETIF_F_TSO; | ||
3412 | card->dev->features |= NETIF_F_HW_VLAN_TX | | 3362 | card->dev->features |= NETIF_F_HW_VLAN_TX | |
3413 | NETIF_F_HW_VLAN_RX | | 3363 | NETIF_F_HW_VLAN_RX | |
3414 | NETIF_F_HW_VLAN_FILTER; | 3364 | NETIF_F_HW_VLAN_FILTER; |
@@ -3516,7 +3466,6 @@ contin: | |||
3516 | rc = qeth_l3_start_ipassists(card); | 3466 | rc = qeth_l3_start_ipassists(card); |
3517 | if (rc) | 3467 | if (rc) |
3518 | QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); | 3468 | QETH_DBF_TEXT_(SETUP, 2, "3err%d", rc); |
3519 | qeth_l3_set_large_send(card, card->options.large_send); | ||
3520 | rc = qeth_l3_setrouting_v4(card); | 3469 | rc = qeth_l3_setrouting_v4(card); |
3521 | if (rc) | 3470 | if (rc) |
3522 | QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc); | 3471 | QETH_DBF_TEXT_(SETUP, 2, "4err%d", rc); |
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index 67cfa68dcf1b..bf9f003e3a97 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c | |||
@@ -410,39 +410,42 @@ static ssize_t qeth_l3_dev_large_send_show(struct device *dev, | |||
410 | if (!card) | 410 | if (!card) |
411 | return -EINVAL; | 411 | return -EINVAL; |
412 | 412 | ||
413 | switch (card->options.large_send) { | 413 | if (!(card->dev->features & NETIF_F_TSO)) |
414 | case QETH_LARGE_SEND_NO: | ||
415 | return sprintf(buf, "%s\n", "no"); | 414 | return sprintf(buf, "%s\n", "no"); |
416 | case QETH_LARGE_SEND_TSO: | 415 | else |
417 | return sprintf(buf, "%s\n", "TSO"); | 416 | return sprintf(buf, "%s\n", "TSO"); |
418 | default: | ||
419 | return sprintf(buf, "%s\n", "N/A"); | ||
420 | } | ||
421 | } | 417 | } |
422 | 418 | ||
423 | static ssize_t qeth_l3_dev_large_send_store(struct device *dev, | 419 | static ssize_t qeth_l3_dev_large_send_store(struct device *dev, |
424 | struct device_attribute *attr, const char *buf, size_t count) | 420 | struct device_attribute *attr, const char *buf, size_t count) |
425 | { | 421 | { |
426 | struct qeth_card *card = dev_get_drvdata(dev); | 422 | struct qeth_card *card; |
427 | enum qeth_large_send_types type; | ||
428 | int rc = 0; | ||
429 | char *tmp; | 423 | char *tmp; |
424 | int enable; | ||
430 | 425 | ||
431 | if (!card) | 426 | if (!card) |
432 | return -EINVAL; | 427 | return -EINVAL; |
433 | tmp = strsep((char **) &buf, "\n"); | 428 | tmp = strsep((char **) &buf, "\n"); |
434 | if (!strcmp(tmp, "no")) | 429 | if (!strcmp(tmp, "no")) |
435 | type = QETH_LARGE_SEND_NO; | 430 | enable = 0; |
436 | else if (!strcmp(tmp, "TSO")) | 431 | else if (!strcmp(tmp, "TSO")) |
437 | type = QETH_LARGE_SEND_TSO; | 432 | enable = 1; |
438 | else | 433 | else |
439 | return -EINVAL; | 434 | return -EINVAL; |
440 | 435 | ||
441 | mutex_lock(&card->conf_mutex); | 436 | rtnl_lock(); |
442 | if (card->options.large_send != type) | 437 | |
443 | rc = qeth_l3_set_large_send(card, type); | 438 | card = dev_get_drvdata(dev); |
444 | mutex_unlock(&card->conf_mutex); | 439 | |
445 | return rc ? rc : count; | 440 | if (enable) |
441 | card->dev->wanted_features |= NETIF_F_TSO; | ||
442 | else | ||
443 | card->dev->wanted_features &= ~NETIF_F_TSO; | ||
444 | netdev_update_features(card->dev); | ||
445 | |||
446 | rtnl_unlock(); | ||
447 | |||
448 | return count; | ||
446 | } | 449 | } |
447 | 450 | ||
448 | static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show, | 451 | static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show, |