diff options
Diffstat (limited to 'drivers/s390/net/qeth_l3_sys.c')
-rw-r--r-- | drivers/s390/net/qeth_l3_sys.c | 125 |
1 files changed, 116 insertions, 9 deletions
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index c144b9924d52..25b3e7aae44f 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c | |||
@@ -8,6 +8,8 @@ | |||
8 | * Frank Blaschka <frank.blaschka@de.ibm.com> | 8 | * Frank Blaschka <frank.blaschka@de.ibm.com> |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/slab.h> | ||
12 | |||
11 | #include "qeth_l3.h" | 13 | #include "qeth_l3.h" |
12 | 14 | ||
13 | #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \ | 15 | #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \ |
@@ -293,31 +295,134 @@ static ssize_t qeth_l3_dev_checksum_store(struct device *dev, | |||
293 | struct device_attribute *attr, const char *buf, size_t count) | 295 | struct device_attribute *attr, const char *buf, size_t count) |
294 | { | 296 | { |
295 | struct qeth_card *card = dev_get_drvdata(dev); | 297 | struct qeth_card *card = dev_get_drvdata(dev); |
298 | enum qeth_checksum_types csum_type; | ||
296 | char *tmp; | 299 | char *tmp; |
300 | int rc; | ||
297 | 301 | ||
298 | if (!card) | 302 | if (!card) |
299 | return -EINVAL; | 303 | return -EINVAL; |
300 | 304 | ||
301 | if ((card->state != CARD_STATE_DOWN) && | ||
302 | (card->state != CARD_STATE_RECOVER)) | ||
303 | return -EPERM; | ||
304 | |||
305 | tmp = strsep((char **) &buf, "\n"); | 305 | tmp = strsep((char **) &buf, "\n"); |
306 | if (!strcmp(tmp, "sw_checksumming")) | 306 | if (!strcmp(tmp, "sw_checksumming")) |
307 | card->options.checksum_type = SW_CHECKSUMMING; | 307 | csum_type = SW_CHECKSUMMING; |
308 | else if (!strcmp(tmp, "hw_checksumming")) | 308 | else if (!strcmp(tmp, "hw_checksumming")) |
309 | card->options.checksum_type = HW_CHECKSUMMING; | 309 | csum_type = HW_CHECKSUMMING; |
310 | else if (!strcmp(tmp, "no_checksumming")) | 310 | else if (!strcmp(tmp, "no_checksumming")) |
311 | card->options.checksum_type = NO_CHECKSUMMING; | 311 | csum_type = NO_CHECKSUMMING; |
312 | else { | 312 | else |
313 | return -EINVAL; | 313 | return -EINVAL; |
314 | } | 314 | |
315 | rc = qeth_l3_set_rx_csum(card, csum_type); | ||
316 | if (rc) | ||
317 | return rc; | ||
315 | return count; | 318 | return count; |
316 | } | 319 | } |
317 | 320 | ||
318 | static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show, | 321 | static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show, |
319 | qeth_l3_dev_checksum_store); | 322 | qeth_l3_dev_checksum_store); |
320 | 323 | ||
324 | static ssize_t qeth_l3_dev_sniffer_show(struct device *dev, | ||
325 | struct device_attribute *attr, char *buf) | ||
326 | { | ||
327 | struct qeth_card *card = dev_get_drvdata(dev); | ||
328 | |||
329 | if (!card) | ||
330 | return -EINVAL; | ||
331 | |||
332 | return sprintf(buf, "%i\n", card->options.sniffer ? 1 : 0); | ||
333 | } | ||
334 | |||
335 | static ssize_t qeth_l3_dev_sniffer_store(struct device *dev, | ||
336 | struct device_attribute *attr, const char *buf, size_t count) | ||
337 | { | ||
338 | struct qeth_card *card = dev_get_drvdata(dev); | ||
339 | int ret; | ||
340 | unsigned long i; | ||
341 | |||
342 | if (!card) | ||
343 | return -EINVAL; | ||
344 | |||
345 | if (card->info.type != QETH_CARD_TYPE_IQD) | ||
346 | return -EPERM; | ||
347 | |||
348 | if ((card->state != CARD_STATE_DOWN) && | ||
349 | (card->state != CARD_STATE_RECOVER)) | ||
350 | return -EPERM; | ||
351 | |||
352 | ret = strict_strtoul(buf, 16, &i); | ||
353 | if (ret) | ||
354 | return -EINVAL; | ||
355 | switch (i) { | ||
356 | case 0: | ||
357 | card->options.sniffer = i; | ||
358 | break; | ||
359 | case 1: | ||
360 | ret = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd); | ||
361 | if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) { | ||
362 | card->options.sniffer = i; | ||
363 | if (card->qdio.init_pool.buf_count != | ||
364 | QETH_IN_BUF_COUNT_MAX) | ||
365 | qeth_realloc_buffer_pool(card, | ||
366 | QETH_IN_BUF_COUNT_MAX); | ||
367 | break; | ||
368 | } else | ||
369 | return -EPERM; | ||
370 | default: /* fall through */ | ||
371 | return -EINVAL; | ||
372 | } | ||
373 | return count; | ||
374 | } | ||
375 | |||
376 | static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show, | ||
377 | qeth_l3_dev_sniffer_store); | ||
378 | |||
379 | static ssize_t qeth_l3_dev_large_send_show(struct device *dev, | ||
380 | struct device_attribute *attr, char *buf) | ||
381 | { | ||
382 | struct qeth_card *card = dev_get_drvdata(dev); | ||
383 | |||
384 | if (!card) | ||
385 | return -EINVAL; | ||
386 | |||
387 | switch (card->options.large_send) { | ||
388 | case QETH_LARGE_SEND_NO: | ||
389 | return sprintf(buf, "%s\n", "no"); | ||
390 | case QETH_LARGE_SEND_TSO: | ||
391 | return sprintf(buf, "%s\n", "TSO"); | ||
392 | default: | ||
393 | return sprintf(buf, "%s\n", "N/A"); | ||
394 | } | ||
395 | } | ||
396 | |||
397 | static ssize_t qeth_l3_dev_large_send_store(struct device *dev, | ||
398 | struct device_attribute *attr, const char *buf, size_t count) | ||
399 | { | ||
400 | struct qeth_card *card = dev_get_drvdata(dev); | ||
401 | enum qeth_large_send_types type; | ||
402 | int rc = 0; | ||
403 | char *tmp; | ||
404 | |||
405 | if (!card) | ||
406 | return -EINVAL; | ||
407 | tmp = strsep((char **) &buf, "\n"); | ||
408 | if (!strcmp(tmp, "no")) | ||
409 | type = QETH_LARGE_SEND_NO; | ||
410 | else if (!strcmp(tmp, "TSO")) | ||
411 | type = QETH_LARGE_SEND_TSO; | ||
412 | else | ||
413 | return -EINVAL; | ||
414 | |||
415 | if (card->options.large_send == type) | ||
416 | return count; | ||
417 | rc = qeth_l3_set_large_send(card, type); | ||
418 | if (rc) | ||
419 | return rc; | ||
420 | return count; | ||
421 | } | ||
422 | |||
423 | static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show, | ||
424 | qeth_l3_dev_large_send_store); | ||
425 | |||
321 | static struct attribute *qeth_l3_device_attrs[] = { | 426 | static struct attribute *qeth_l3_device_attrs[] = { |
322 | &dev_attr_route4.attr, | 427 | &dev_attr_route4.attr, |
323 | &dev_attr_route6.attr, | 428 | &dev_attr_route6.attr, |
@@ -325,6 +430,8 @@ static struct attribute *qeth_l3_device_attrs[] = { | |||
325 | &dev_attr_broadcast_mode.attr, | 430 | &dev_attr_broadcast_mode.attr, |
326 | &dev_attr_canonical_macaddr.attr, | 431 | &dev_attr_canonical_macaddr.attr, |
327 | &dev_attr_checksumming.attr, | 432 | &dev_attr_checksumming.attr, |
433 | &dev_attr_sniffer.attr, | ||
434 | &dev_attr_large_send.attr, | ||
328 | NULL, | 435 | NULL, |
329 | }; | 436 | }; |
330 | 437 | ||