1 /* 2 * drivers/s390/net/qeth_core_sys.c 3 * 4 * Copyright IBM Corp. 2007 5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>, 6 * Frank Pavlic <fpavlic@de.ibm.com>, 7 * Thomas Spatzier <tspat@de.ibm.com>, 8 * Frank Blaschka <frank.blaschka@de.ibm.com> 9 */ 10 11 #include <linux/list.h> 12 #include <linux/rwsem.h> 13 #include <asm/ebcdic.h> 14 15 #include "qeth_core.h" 16 17 static ssize_t qeth_dev_state_show(struct device *dev, 18 struct device_attribute *attr, char *buf) 19 { 20 struct qeth_card *card = dev_get_drvdata(dev); 21 if (!card) 22 return -EINVAL; 23 24 switch (card->state) { 25 case CARD_STATE_DOWN: 26 return sprintf(buf, "DOWN\n"); 27 case CARD_STATE_HARDSETUP: 28 return sprintf(buf, "HARDSETUP\n"); 29 case CARD_STATE_SOFTSETUP: 30 return sprintf(buf, "SOFTSETUP\n"); 31 case CARD_STATE_UP: 32 if (card->lan_online) 33 return sprintf(buf, "UP (LAN ONLINE)\n"); 34 else 35 return sprintf(buf, "UP (LAN OFFLINE)\n"); 36 case CARD_STATE_RECOVER: 37 return sprintf(buf, "RECOVER\n"); 38 default: 39 return sprintf(buf, "UNKNOWN\n"); 40 } 41 } 42 43 static DEVICE_ATTR(state, 0444, qeth_dev_state_show, NULL); 44 45 static ssize_t qeth_dev_chpid_show(struct device *dev, 46 struct device_attribute *attr, char *buf) 47 { 48 struct qeth_card *card = dev_get_drvdata(dev); 49 if (!card) 50 return -EINVAL; 51 52 return sprintf(buf, "%02X\n", card->info.chpid); 53 } 54 55 static DEVICE_ATTR(chpid, 0444, qeth_dev_chpid_show, NULL); 56 57 static ssize_t qeth_dev_if_name_show(struct device *dev, 58 struct device_attribute *attr, char *buf) 59 { 60 struct qeth_card *card = dev_get_drvdata(dev); 61 if (!card) 62 return -EINVAL; 63 return sprintf(buf, "%s\n", QETH_CARD_IFNAME(card)); 64 } 65 66 static DEVICE_ATTR(if_name, 0444, qeth_dev_if_name_show, NULL); 67 68 static ssize_t qeth_dev_card_type_show(struct device *dev, 69 struct device_attribute *attr, char *buf) 70 { 71 struct qeth_card *card = dev_get_drvdata(dev); 72 if (!card) 73 return -EINVAL; 74 75 return sprintf(buf, "%s\n", qeth_get_cardname_short(card)); 76 } 77 78 static DEVICE_ATTR(card_type, 0444, qeth_dev_card_type_show, NULL); 79 80 static inline const char *qeth_get_bufsize_str(struct qeth_card *card) 81 { 82 if (card->qdio.in_buf_size == 16384) 83 return "16k"; 84 else if (card->qdio.in_buf_size == 24576) 85 return "24k"; 86 else if (card->qdio.in_buf_size == 32768) 87 return "32k"; 88 else if (card->qdio.in_buf_size == 40960) 89 return "40k"; 90 else 91 return "64k"; 92 } 93 94 static ssize_t qeth_dev_inbuf_size_show(struct device *dev, 95 struct device_attribute *attr, char *buf) 96 { 97 struct qeth_card *card = dev_get_drvdata(dev); 98 if (!card) 99 return -EINVAL; 100 101 return sprintf(buf, "%s\n", qeth_get_bufsize_str(card)); 102 } 103 104 static DEVICE_ATTR(inbuf_size, 0444, qeth_dev_inbuf_size_show, NULL); 105 106 static ssize_t qeth_dev_portno_show(struct device *dev, 107 struct device_attribute *attr, char *buf) 108 { 109 struct qeth_card *card = dev_get_drvdata(dev); 110 if (!card) 111 return -EINVAL; 112 113 return sprintf(buf, "%i\n", card->info.portno); 114 } 115 116 static ssize_t qeth_dev_portno_store(struct device *dev, 117 struct device_attribute *attr, const char *buf, size_t count) 118 { 119 struct qeth_card *card = dev_get_drvdata(dev); 120 char *tmp; 121 unsigned int portno; 122 123 if (!card) 124 return -EINVAL; 125 126 if ((card->state != CARD_STATE_DOWN) && 127 (card->state != CARD_STATE_RECOVER)) 128 return -EPERM; 129 130 portno = simple_strtoul(buf, &tmp, 16); 131 if (portno > QETH_MAX_PORTNO) { 132 PRINT_WARN("portno 0x%X is out of range\n", portno); 133 return -EINVAL; 134 } 135 136 card->info.portno = portno; 137 return count; 138 } 139 140 static DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store); 141 142 static ssize_t qeth_dev_portname_show(struct device *dev, 143 struct device_attribute *attr, char *buf) 144 { 145 struct qeth_card *card = dev_get_drvdata(dev); 146 char portname[9] = {0, }; 147 148 if (!card) 149 return -EINVAL; 150 151 if (card->info.portname_required) { 152 memcpy(portname, card->info.portname + 1, 8); 153 EBCASC(portname, 8); 154 return sprintf(buf, "%s\n", portname); 155 } else 156 return sprintf(buf, "no portname required\n"); 157 } 158 159 static ssize_t qeth_dev_portname_store(struct device *dev, 160 struct device_attribute *attr, const char *buf, size_t count) 161 { 162 struct qeth_card *card = dev_get_drvdata(dev); 163 char *tmp; 164 int i; 165 166 if (!card) 167 return -EINVAL; 168 169 if ((card->state != CARD_STATE_DOWN) && 170 (card->state != CARD_STATE_RECOVER)) 171 return -EPERM; 172 173 tmp = strsep((char **) &buf, "\n"); 174 if ((strlen(tmp) > 8) || (strlen(tmp) == 0)) 175 return -EINVAL; 176 177 card->info.portname[0] = strlen(tmp); 178 /* for beauty reasons */ 179 for (i = 1; i < 9; i++) 180 card->info.portname[i] = ' '; 181 strcpy(card->info.portname + 1, tmp); 182 ASCEBC(card->info.portname + 1, 8); 183 184 return count; 185 } 186 187 static DEVICE_ATTR(portname, 0644, qeth_dev_portname_show, 188 qeth_dev_portname_store); 189 190 static ssize_t qeth_dev_prioqing_show(struct device *dev, 191 struct device_attribute *attr, char *buf) 192 { 193 struct qeth_card *card = dev_get_drvdata(dev); 194 195 if (!card) 196 return -EINVAL; 197 198 switch (card->qdio.do_prio_queueing) { 199 case QETH_PRIO_Q_ING_PREC: 200 return sprintf(buf, "%s\n", "by precedence"); 201 case QETH_PRIO_Q_ING_TOS: 202 return sprintf(buf, "%s\n", "by type of service"); 203 default: 204 return sprintf(buf, "always queue %i\n", 205 card->qdio.default_out_queue); 206 } 207 } 208 209 static ssize_t qeth_dev_prioqing_store(struct device *dev, 210 struct device_attribute *attr, const char *buf, size_t count) 211 { 212 struct qeth_card *card = dev_get_drvdata(dev); 213 char *tmp; 214 215 if (!card) 216 return -EINVAL; 217 218 if ((card->state != CARD_STATE_DOWN) && 219 (card->state != CARD_STATE_RECOVER)) 220 return -EPERM; 221 222 /* check if 1920 devices are supported , 223 * if though we have to permit priority queueing 224 */ 225 if (card->qdio.no_out_queues == 1) { 226 PRINT_WARN("Priority queueing disabled due " 227 "to hardware limitations!\n"); 228 card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT; 229 return -EPERM; 230 } 231 232 tmp = strsep((char **) &buf, "\n"); 233 if (!strcmp(tmp, "prio_queueing_prec")) 234 card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_PREC; 235 else if (!strcmp(tmp, "prio_queueing_tos")) 236 card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_TOS; 237 else if (!strcmp(tmp, "no_prio_queueing:0")) { 238 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; 239 card->qdio.default_out_queue = 0; 240 } else if (!strcmp(tmp, "no_prio_queueing:1")) { 241 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; 242 card->qdio.default_out_queue = 1; 243 } else if (!strcmp(tmp, "no_prio_queueing:2")) { 244 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; 245 card->qdio.default_out_queue = 2; 246 } else if (!strcmp(tmp, "no_prio_queueing:3")) { 247 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; 248 card->qdio.default_out_queue = 3; 249 } else if (!strcmp(tmp, "no_prio_queueing")) { 250 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; 251 card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; 252 } else { 253 PRINT_WARN("Unknown queueing type '%s'\n", tmp); 254 return -EINVAL; 255 } 256 return count; 257 } 258 259 static DEVICE_ATTR(priority_queueing, 0644, qeth_dev_prioqing_show, 260 qeth_dev_prioqing_store); 261 262 static ssize_t qeth_dev_bufcnt_show(struct device *dev, 263 struct device_attribute *attr, char *buf) 264 { 265 struct qeth_card *card = dev_get_drvdata(dev); 266 267 if (!card) 268 return -EINVAL; 269 270 return sprintf(buf, "%i\n", card->qdio.in_buf_pool.buf_count); 271 } 272 273 static ssize_t qeth_dev_bufcnt_store(struct device *dev, 274 struct device_attribute *attr, const char *buf, size_t count) 275 { 276 struct qeth_card *card = dev_get_drvdata(dev); 277 char *tmp; 278 int cnt, old_cnt; 279 int rc; 280 281 if (!card) 282 return -EINVAL; 283 284 if ((card->state != CARD_STATE_DOWN) && 285 (card->state != CARD_STATE_RECOVER)) 286 return -EPERM; 287 288 old_cnt = card->qdio.in_buf_pool.buf_count; 289 cnt = simple_strtoul(buf, &tmp, 10); 290 cnt = (cnt < QETH_IN_BUF_COUNT_MIN) ? QETH_IN_BUF_COUNT_MIN : 291 ((cnt > QETH_IN_BUF_COUNT_MAX) ? QETH_IN_BUF_COUNT_MAX : cnt); 292 if (old_cnt != cnt) { 293 rc = qeth_realloc_buffer_pool(card, cnt); 294 if (rc) 295 PRINT_WARN("Error (%d) while setting " 296 "buffer count.\n", rc); 297 } 298 return count; 299 } 300 301 static DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show, 302 qeth_dev_bufcnt_store); 303 304 static ssize_t qeth_dev_recover_store(struct device *dev, 305 struct device_attribute *attr, const char *buf, size_t count) 306 { 307 struct qeth_card *card = dev_get_drvdata(dev); 308 char *tmp; 309 int i; 310 311 if (!card) 312 return -EINVAL; 313 314 if (card->state != CARD_STATE_UP) 315 return -EPERM; 316 317 i = simple_strtoul(buf, &tmp, 16); 318 if (i == 1) 319 qeth_schedule_recovery(card); 320 321 return count; 322 } 323 324 static DEVICE_ATTR(recover, 0200, NULL, qeth_dev_recover_store); 325 326 static ssize_t qeth_dev_performance_stats_show(struct device *dev, 327 struct device_attribute *attr, char *buf) 328 { 329 struct qeth_card *card = dev_get_drvdata(dev); 330 331 if (!card) 332 return -EINVAL; 333 334 return sprintf(buf, "%i\n", card->options.performance_stats ? 1:0); 335 } 336 337 static ssize_t qeth_dev_performance_stats_store(struct device *dev, 338 struct device_attribute *attr, const char *buf, size_t count) 339 { 340 struct qeth_card *card = dev_get_drvdata(dev); 341 char *tmp; 342 int i; 343 344 if (!card) 345 return -EINVAL; 346 347 i = simple_strtoul(buf, &tmp, 16); 348 if ((i == 0) || (i == 1)) { 349 if (i == card->options.performance_stats) 350 return count; 351 card->options.performance_stats = i; 352 if (i == 0) 353 memset(&card->perf_stats, 0, 354 sizeof(struct qeth_perf_stats)); 355 card->perf_stats.initial_rx_packets = card->stats.rx_packets; 356 card->perf_stats.initial_tx_packets = card->stats.tx_packets; 357 } else { 358 PRINT_WARN("performance_stats: write 0 or 1 to this file!\n"); 359 return -EINVAL; 360 } 361 return count; 362 } 363 364 static DEVICE_ATTR(performance_stats, 0644, qeth_dev_performance_stats_show, 365 qeth_dev_performance_stats_store); 366 367 static ssize_t qeth_dev_layer2_show(struct device *dev, 368 struct device_attribute *attr, char *buf) 369 { 370 struct qeth_card *card = dev_get_drvdata(dev); 371 372 if (!card) 373 return -EINVAL; 374 375 return sprintf(buf, "%i\n", card->options.layer2 ? 1:0); 376 } 377 378 static ssize_t qeth_dev_layer2_store(struct device *dev, 379 struct device_attribute *attr, const char *buf, size_t count) 380 { 381 struct qeth_card *card = dev_get_drvdata(dev); 382 char *tmp; 383 int i, rc; 384 enum qeth_discipline_id newdis; 385 386 if (!card) 387 return -EINVAL; 388 389 if (((card->state != CARD_STATE_DOWN) && 390 (card->state != CARD_STATE_RECOVER))) 391 return -EPERM; 392 393 i = simple_strtoul(buf, &tmp, 16); 394 switch (i) { 395 case 0: 396 newdis = QETH_DISCIPLINE_LAYER3; 397 break; 398 case 1: 399 newdis = QETH_DISCIPLINE_LAYER2; 400 break; 401 default: 402 PRINT_WARN("layer2: write 0 or 1 to this file!\n"); 403 return -EINVAL; 404 } 405 406 if (card->options.layer2 == newdis) { 407 return count; 408 } else { 409 if (card->discipline.ccwgdriver) { 410 card->discipline.ccwgdriver->remove(card->gdev); 411 qeth_core_free_discipline(card); 412 } 413 } 414 415 rc = qeth_core_load_discipline(card, newdis); 416 if (rc) 417 return rc; 418 419 rc = card->discipline.ccwgdriver->probe(card->gdev); 420 if (rc) 421 return rc; 422 return count; 423 } 424 425 static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show, 426 qeth_dev_layer2_store); 427 428 static ssize_t qeth_dev_large_send_show(struct device *dev, 429 struct device_attribute *attr, char *buf) 430 { 431 struct qeth_card *card = dev_get_drvdata(dev); 432 433 if (!card) 434 return -EINVAL; 435 436 switch (card->options.large_send) { 437 case QETH_LARGE_SEND_NO: 438 return sprintf(buf, "%s\n", "no"); 439 case QETH_LARGE_SEND_EDDP: 440 return sprintf(buf, "%s\n", "EDDP"); 441 case QETH_LARGE_SEND_TSO: 442 return sprintf(buf, "%s\n", "TSO"); 443 default: 444 return sprintf(buf, "%s\n", "N/A"); 445 } 446 } 447 448 static ssize_t qeth_dev_large_send_store(struct device *dev, 449 struct device_attribute *attr, const char *buf, size_t count) 450 { 451 struct qeth_card *card = dev_get_drvdata(dev); 452 enum qeth_large_send_types type; 453 int rc = 0; 454 char *tmp; 455 456 if (!card) 457 return -EINVAL; 458 tmp = strsep((char **) &buf, "\n"); 459 if (!strcmp(tmp, "no")) { 460 type = QETH_LARGE_SEND_NO; 461 } else if (!strcmp(tmp, "EDDP")) { 462 type = QETH_LARGE_SEND_EDDP; 463 } else if (!strcmp(tmp, "TSO")) { 464 type = QETH_LARGE_SEND_TSO; 465 } else { 466 PRINT_WARN("large_send: invalid mode %s!\n", tmp); 467 return -EINVAL; 468 } 469 if (card->options.large_send == type) 470 return count; 471 rc = qeth_set_large_send(card, type); 472 if (rc) 473 return rc; 474 return count; 475 } 476 477 static DEVICE_ATTR(large_send, 0644, qeth_dev_large_send_show, 478 qeth_dev_large_send_store); 479 480 static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value) 481 { 482 483 if (!card) 484 return -EINVAL; 485 486 return sprintf(buf, "%i\n", value); 487 } 488 489 static ssize_t qeth_dev_blkt_store(struct qeth_card *card, 490 const char *buf, size_t count, int *value, int max_value) 491 { 492 char *tmp; 493 int i; 494 495 if (!card) 496 return -EINVAL; 497 498 if ((card->state != CARD_STATE_DOWN) && 499 (card->state != CARD_STATE_RECOVER)) 500 return -EPERM; 501 502 i = simple_strtoul(buf, &tmp, 10); 503 if (i <= max_value) { 504 *value = i; 505 } else { 506 PRINT_WARN("blkt total time: write values between" 507 " 0 and %d to this file!\n", max_value); 508 return -EINVAL; 509 } 510 return count; 511 } 512 513 static ssize_t qeth_dev_blkt_total_show(struct device *dev, 514 struct device_attribute *attr, char *buf) 515 { 516 struct qeth_card *card = dev_get_drvdata(dev); 517 518 return qeth_dev_blkt_show(buf, card, card->info.blkt.time_total); 519 } 520 521 static ssize_t qeth_dev_blkt_total_store(struct device *dev, 522 struct device_attribute *attr, const char *buf, size_t count) 523 { 524 struct qeth_card *card = dev_get_drvdata(dev); 525 526 return qeth_dev_blkt_store(card, buf, count, 527 &card->info.blkt.time_total, 1000); 528 } 529 530 531 532 static DEVICE_ATTR(total, 0644, qeth_dev_blkt_total_show, 533 qeth_dev_blkt_total_store); 534 535 static ssize_t qeth_dev_blkt_inter_show(struct device *dev, 536 struct device_attribute *attr, char *buf) 537 { 538 struct qeth_card *card = dev_get_drvdata(dev); 539 540 return qeth_dev_blkt_show(buf, card, card->info.blkt.inter_packet); 541 } 542 543 static ssize_t qeth_dev_blkt_inter_store(struct device *dev, 544 struct device_attribute *attr, const char *buf, size_t count) 545 { 546 struct qeth_card *card = dev_get_drvdata(dev); 547 548 return qeth_dev_blkt_store(card, buf, count, 549 &card->info.blkt.inter_packet, 100); 550 } 551 552 static DEVICE_ATTR(inter, 0644, qeth_dev_blkt_inter_show, 553 qeth_dev_blkt_inter_store); 554 555 static ssize_t qeth_dev_blkt_inter_jumbo_show(struct device *dev, 556 struct device_attribute *attr, char *buf) 557 { 558 struct qeth_card *card = dev_get_drvdata(dev); 559 560 return qeth_dev_blkt_show(buf, card, 561 card->info.blkt.inter_packet_jumbo); 562 } 563 564 static ssize_t qeth_dev_blkt_inter_jumbo_store(struct device *dev, 565 struct device_attribute *attr, const char *buf, size_t count) 566 { 567 struct qeth_card *card = dev_get_drvdata(dev); 568 569 return qeth_dev_blkt_store(card, buf, count, 570 &card->info.blkt.inter_packet_jumbo, 100); 571 } 572 573 static DEVICE_ATTR(inter_jumbo, 0644, qeth_dev_blkt_inter_jumbo_show, 574 qeth_dev_blkt_inter_jumbo_store); 575 576 static struct attribute *qeth_blkt_device_attrs[] = { 577 &dev_attr_total.attr, 578 &dev_attr_inter.attr, 579 &dev_attr_inter_jumbo.attr, 580 NULL, 581 }; 582 583 static struct attribute_group qeth_device_blkt_group = { 584 .name = "blkt", 585 .attrs = qeth_blkt_device_attrs, 586 }; 587 588 static struct attribute *qeth_device_attrs[] = { 589 &dev_attr_state.attr, 590 &dev_attr_chpid.attr, 591 &dev_attr_if_name.attr, 592 &dev_attr_card_type.attr, 593 &dev_attr_inbuf_size.attr, 594 &dev_attr_portno.attr, 595 &dev_attr_portname.attr, 596 &dev_attr_priority_queueing.attr, 597 &dev_attr_buffer_count.attr, 598 &dev_attr_recover.attr, 599 &dev_attr_performance_stats.attr, 600 &dev_attr_layer2.attr, 601 &dev_attr_large_send.attr, 602 NULL, 603 }; 604 605 static struct attribute_group qeth_device_attr_group = { 606 .attrs = qeth_device_attrs, 607 }; 608 609 static struct attribute *qeth_osn_device_attrs[] = { 610 &dev_attr_state.attr, 611 &dev_attr_chpid.attr, 612 &dev_attr_if_name.attr, 613 &dev_attr_card_type.attr, 614 &dev_attr_buffer_count.attr, 615 &dev_attr_recover.attr, 616 NULL, 617 }; 618 619 static struct attribute_group qeth_osn_device_attr_group = { 620 .attrs = qeth_osn_device_attrs, 621 }; 622 623 int qeth_core_create_device_attributes(struct device *dev) 624 { 625 int ret; 626 ret = sysfs_create_group(&dev->kobj, &qeth_device_attr_group); 627 if (ret) 628 return ret; 629 ret = sysfs_create_group(&dev->kobj, &qeth_device_blkt_group); 630 if (ret) 631 sysfs_remove_group(&dev->kobj, &qeth_device_attr_group); 632 633 return 0; 634 } 635 636 void qeth_core_remove_device_attributes(struct device *dev) 637 { 638 sysfs_remove_group(&dev->kobj, &qeth_device_attr_group); 639 sysfs_remove_group(&dev->kobj, &qeth_device_blkt_group); 640 } 641 642 int qeth_core_create_osn_attributes(struct device *dev) 643 { 644 return sysfs_create_group(&dev->kobj, &qeth_osn_device_attr_group); 645 } 646 647 void qeth_core_remove_osn_attributes(struct device *dev) 648 { 649 sysfs_remove_group(&dev->kobj, &qeth_osn_device_attr_group); 650 return; 651 } 652