682 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Copyright IBM Corp. 20074 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>,5 * Frank Pavlic <fpavlic@de.ibm.com>,6 * Thomas Spatzier <tspat@de.ibm.com>,7 * Frank Blaschka <frank.blaschka@de.ibm.com>8 */9 10#define KMSG_COMPONENT "qeth"11#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt12 13#include <linux/list.h>14#include <linux/rwsem.h>15#include <asm/ebcdic.h>16 17#include "qeth_core.h"18 19static ssize_t qeth_dev_state_show(struct device *dev,20 struct device_attribute *attr, char *buf)21{22 struct qeth_card *card = dev_get_drvdata(dev);23 24 switch (card->state) {25 case CARD_STATE_DOWN:26 return sysfs_emit(buf, "DOWN\n");27 case CARD_STATE_SOFTSETUP:28 if (card->dev->flags & IFF_UP)29 return sysfs_emit(buf, "UP (LAN %s)\n",30 netif_carrier_ok(card->dev) ?31 "ONLINE" : "OFFLINE");32 return sysfs_emit(buf, "SOFTSETUP\n");33 default:34 return sysfs_emit(buf, "UNKNOWN\n");35 }36}37 38static DEVICE_ATTR(state, 0444, qeth_dev_state_show, NULL);39 40static ssize_t qeth_dev_chpid_show(struct device *dev,41 struct device_attribute *attr, char *buf)42{43 struct qeth_card *card = dev_get_drvdata(dev);44 45 return sysfs_emit(buf, "%02X\n", card->info.chpid);46}47 48static DEVICE_ATTR(chpid, 0444, qeth_dev_chpid_show, NULL);49 50static ssize_t qeth_dev_if_name_show(struct device *dev,51 struct device_attribute *attr, char *buf)52{53 struct qeth_card *card = dev_get_drvdata(dev);54 55 return sysfs_emit(buf, "%s\n", netdev_name(card->dev));56}57 58static DEVICE_ATTR(if_name, 0444, qeth_dev_if_name_show, NULL);59 60static ssize_t qeth_dev_card_type_show(struct device *dev,61 struct device_attribute *attr, char *buf)62{63 struct qeth_card *card = dev_get_drvdata(dev);64 65 return sysfs_emit(buf, "%s\n", qeth_get_cardname_short(card));66}67 68static DEVICE_ATTR(card_type, 0444, qeth_dev_card_type_show, NULL);69 70static const char *qeth_get_bufsize_str(struct qeth_card *card)71{72 if (card->qdio.in_buf_size == 16384)73 return "16k";74 else if (card->qdio.in_buf_size == 24576)75 return "24k";76 else if (card->qdio.in_buf_size == 32768)77 return "32k";78 else if (card->qdio.in_buf_size == 40960)79 return "40k";80 else81 return "64k";82}83 84static ssize_t qeth_dev_inbuf_size_show(struct device *dev,85 struct device_attribute *attr, char *buf)86{87 struct qeth_card *card = dev_get_drvdata(dev);88 89 return sysfs_emit(buf, "%s\n", qeth_get_bufsize_str(card));90}91 92static DEVICE_ATTR(inbuf_size, 0444, qeth_dev_inbuf_size_show, NULL);93 94static ssize_t qeth_dev_portno_show(struct device *dev,95 struct device_attribute *attr, char *buf)96{97 struct qeth_card *card = dev_get_drvdata(dev);98 99 return sysfs_emit(buf, "%i\n", card->dev->dev_port);100}101 102static ssize_t qeth_dev_portno_store(struct device *dev,103 struct device_attribute *attr, const char *buf, size_t count)104{105 struct qeth_card *card = dev_get_drvdata(dev);106 unsigned int portno, limit;107 int rc = 0;108 109 rc = kstrtouint(buf, 16, &portno);110 if (rc)111 return rc;112 if (portno > QETH_MAX_PORTNO)113 return -EINVAL;114 115 mutex_lock(&card->conf_mutex);116 if (card->state != CARD_STATE_DOWN) {117 rc = -EPERM;118 goto out;119 }120 121 limit = (card->ssqd.pcnt ? card->ssqd.pcnt - 1 : card->ssqd.pcnt);122 if (portno > limit) {123 rc = -EINVAL;124 goto out;125 }126 card->dev->dev_port = portno;127out:128 mutex_unlock(&card->conf_mutex);129 return rc ? rc : count;130}131 132static DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store);133 134static ssize_t qeth_dev_portname_show(struct device *dev,135 struct device_attribute *attr, char *buf)136{137 return sysfs_emit(buf, "no portname required\n");138}139 140static ssize_t qeth_dev_portname_store(struct device *dev,141 struct device_attribute *attr, const char *buf, size_t count)142{143 struct qeth_card *card = dev_get_drvdata(dev);144 145 dev_warn_once(&card->gdev->dev,146 "portname is deprecated and is ignored\n");147 return count;148}149 150static DEVICE_ATTR(portname, 0644, qeth_dev_portname_show,151 qeth_dev_portname_store);152 153static ssize_t qeth_dev_prioqing_show(struct device *dev,154 struct device_attribute *attr, char *buf)155{156 struct qeth_card *card = dev_get_drvdata(dev);157 158 switch (card->qdio.do_prio_queueing) {159 case QETH_PRIO_Q_ING_PREC:160 return sysfs_emit(buf, "%s\n", "by precedence");161 case QETH_PRIO_Q_ING_TOS:162 return sysfs_emit(buf, "%s\n", "by type of service");163 case QETH_PRIO_Q_ING_SKB:164 return sysfs_emit(buf, "%s\n", "by skb-priority");165 case QETH_PRIO_Q_ING_VLAN:166 return sysfs_emit(buf, "%s\n", "by VLAN headers");167 case QETH_PRIO_Q_ING_FIXED:168 return sysfs_emit(buf, "always queue %i\n",169 card->qdio.default_out_queue);170 default:171 return sysfs_emit(buf, "disabled\n");172 }173}174 175static ssize_t qeth_dev_prioqing_store(struct device *dev,176 struct device_attribute *attr, const char *buf, size_t count)177{178 struct qeth_card *card = dev_get_drvdata(dev);179 int rc = 0;180 181 if (IS_IQD(card) || IS_VM_NIC(card))182 return -EOPNOTSUPP;183 184 mutex_lock(&card->conf_mutex);185 if (card->state != CARD_STATE_DOWN) {186 rc = -EPERM;187 goto out;188 }189 190 /* check if 1920 devices are supported ,191 * if though we have to permit priority queueing192 */193 if (card->qdio.no_out_queues == 1) {194 card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT;195 rc = -EPERM;196 goto out;197 }198 199 if (sysfs_streq(buf, "prio_queueing_prec")) {200 card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_PREC;201 card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;202 } else if (sysfs_streq(buf, "prio_queueing_skb")) {203 card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_SKB;204 card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;205 } else if (sysfs_streq(buf, "prio_queueing_tos")) {206 card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_TOS;207 card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;208 } else if (sysfs_streq(buf, "prio_queueing_vlan")) {209 if (IS_LAYER3(card)) {210 rc = -EOPNOTSUPP;211 goto out;212 }213 card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_VLAN;214 card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;215 } else if (sysfs_streq(buf, "no_prio_queueing:0")) {216 card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_FIXED;217 card->qdio.default_out_queue = 0;218 } else if (sysfs_streq(buf, "no_prio_queueing:1")) {219 card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_FIXED;220 card->qdio.default_out_queue = 1;221 } else if (sysfs_streq(buf, "no_prio_queueing:2")) {222 card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_FIXED;223 card->qdio.default_out_queue = 2;224 } else if (sysfs_streq(buf, "no_prio_queueing:3")) {225 card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_FIXED;226 card->qdio.default_out_queue = 3;227 } else if (sysfs_streq(buf, "no_prio_queueing")) {228 card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;229 card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;230 } else231 rc = -EINVAL;232out:233 mutex_unlock(&card->conf_mutex);234 return rc ? rc : count;235}236 237static DEVICE_ATTR(priority_queueing, 0644, qeth_dev_prioqing_show,238 qeth_dev_prioqing_store);239 240static ssize_t qeth_dev_bufcnt_show(struct device *dev,241 struct device_attribute *attr, char *buf)242{243 struct qeth_card *card = dev_get_drvdata(dev);244 245 return sysfs_emit(buf, "%i\n", card->qdio.in_buf_pool.buf_count);246}247 248static ssize_t qeth_dev_bufcnt_store(struct device *dev,249 struct device_attribute *attr, const char *buf, size_t count)250{251 struct qeth_card *card = dev_get_drvdata(dev);252 unsigned int cnt;253 int rc = 0;254 255 rc = kstrtouint(buf, 10, &cnt);256 if (rc)257 return rc;258 259 mutex_lock(&card->conf_mutex);260 if (card->state != CARD_STATE_DOWN) {261 rc = -EPERM;262 goto out;263 }264 265 cnt = clamp(cnt, QETH_IN_BUF_COUNT_MIN, QETH_IN_BUF_COUNT_MAX);266 rc = qeth_resize_buffer_pool(card, cnt);267 268out:269 mutex_unlock(&card->conf_mutex);270 return rc ? rc : count;271}272 273static DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show,274 qeth_dev_bufcnt_store);275 276static ssize_t qeth_dev_recover_store(struct device *dev,277 struct device_attribute *attr, const char *buf, size_t count)278{279 struct qeth_card *card = dev_get_drvdata(dev);280 bool reset;281 int rc;282 283 rc = kstrtobool(buf, &reset);284 if (rc)285 return rc;286 287 if (!qeth_card_hw_is_reachable(card))288 return -EPERM;289 290 if (reset)291 rc = qeth_schedule_recovery(card);292 293 return rc ? rc : count;294}295 296static DEVICE_ATTR(recover, 0200, NULL, qeth_dev_recover_store);297 298static ssize_t qeth_dev_performance_stats_show(struct device *dev,299 struct device_attribute *attr, char *buf)300{301 return sysfs_emit(buf, "1\n");302}303 304static ssize_t qeth_dev_performance_stats_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 struct qeth_qdio_out_q *queue;309 unsigned int i;310 bool reset;311 int rc;312 313 rc = kstrtobool(buf, &reset);314 if (rc)315 return rc;316 317 if (reset) {318 memset(&card->stats, 0, sizeof(card->stats));319 for (i = 0; i < card->qdio.no_out_queues; i++) {320 queue = card->qdio.out_qs[i];321 if (!queue)322 break;323 memset(&queue->stats, 0, sizeof(queue->stats));324 }325 }326 327 return count;328}329 330static DEVICE_ATTR(performance_stats, 0644, qeth_dev_performance_stats_show,331 qeth_dev_performance_stats_store);332 333static ssize_t qeth_dev_layer2_show(struct device *dev,334 struct device_attribute *attr, char *buf)335{336 struct qeth_card *card = dev_get_drvdata(dev);337 338 return sysfs_emit(buf, "%i\n", card->options.layer);339}340 341static ssize_t qeth_dev_layer2_store(struct device *dev,342 struct device_attribute *attr, const char *buf, size_t count)343{344 struct qeth_card *card = dev_get_drvdata(dev);345 struct net_device *ndev;346 enum qeth_discipline_id newdis;347 unsigned int input;348 int rc;349 350 rc = kstrtouint(buf, 16, &input);351 if (rc)352 return rc;353 354 switch (input) {355 case 0:356 newdis = QETH_DISCIPLINE_LAYER3;357 break;358 case 1:359 newdis = QETH_DISCIPLINE_LAYER2;360 break;361 default:362 return -EINVAL;363 }364 365 mutex_lock(&card->discipline_mutex);366 if (card->state != CARD_STATE_DOWN) {367 rc = -EPERM;368 goto out;369 }370 371 if (card->options.layer == newdis)372 goto out;373 if (card->info.layer_enforced) {374 /* fixed layer, can't switch */375 rc = -EOPNOTSUPP;376 goto out;377 }378 379 if (card->discipline) {380 /* start with a new, pristine netdevice: */381 ndev = qeth_clone_netdev(card->dev);382 if (!ndev) {383 rc = -ENOMEM;384 goto out;385 }386 387 qeth_remove_discipline(card);388 free_netdev(card->dev);389 card->dev = ndev;390 }391 392 rc = qeth_setup_discipline(card, newdis);393 394out:395 mutex_unlock(&card->discipline_mutex);396 return rc ? rc : count;397}398 399static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show,400 qeth_dev_layer2_store);401 402#define ATTR_QETH_ISOLATION_NONE ("none")403#define ATTR_QETH_ISOLATION_FWD ("forward")404#define ATTR_QETH_ISOLATION_DROP ("drop")405 406static ssize_t qeth_dev_isolation_show(struct device *dev,407 struct device_attribute *attr, char *buf)408{409 struct qeth_card *card = dev_get_drvdata(dev);410 411 switch (card->options.isolation) {412 case ISOLATION_MODE_NONE:413 return sysfs_emit(buf, "%s\n", ATTR_QETH_ISOLATION_NONE);414 case ISOLATION_MODE_FWD:415 return sysfs_emit(buf, "%s\n", ATTR_QETH_ISOLATION_FWD);416 case ISOLATION_MODE_DROP:417 return sysfs_emit(buf, "%s\n", ATTR_QETH_ISOLATION_DROP);418 default:419 return sysfs_emit(buf, "%s\n", "N/A");420 }421}422 423static ssize_t qeth_dev_isolation_store(struct device *dev,424 struct device_attribute *attr, const char *buf, size_t count)425{426 struct qeth_card *card = dev_get_drvdata(dev);427 enum qeth_ipa_isolation_modes isolation;428 int rc = 0;429 430 mutex_lock(&card->conf_mutex);431 if (!IS_OSD(card) && !IS_OSX(card)) {432 rc = -EOPNOTSUPP;433 dev_err(&card->gdev->dev, "Adapter does not "434 "support QDIO data connection isolation\n");435 goto out;436 }437 438 /* parse input into isolation mode */439 if (sysfs_streq(buf, ATTR_QETH_ISOLATION_NONE)) {440 isolation = ISOLATION_MODE_NONE;441 } else if (sysfs_streq(buf, ATTR_QETH_ISOLATION_FWD)) {442 isolation = ISOLATION_MODE_FWD;443 } else if (sysfs_streq(buf, ATTR_QETH_ISOLATION_DROP)) {444 isolation = ISOLATION_MODE_DROP;445 } else {446 rc = -EINVAL;447 goto out;448 }449 450 if (qeth_card_hw_is_reachable(card))451 rc = qeth_setadpparms_set_access_ctrl(card, isolation);452 453 if (!rc)454 WRITE_ONCE(card->options.isolation, isolation);455 456out:457 mutex_unlock(&card->conf_mutex);458 459 return rc ? rc : count;460}461 462static DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show,463 qeth_dev_isolation_store);464 465static ssize_t qeth_dev_switch_attrs_show(struct device *dev,466 struct device_attribute *attr, char *buf)467{468 struct qeth_card *card = dev_get_drvdata(dev);469 struct qeth_switch_info sw_info;470 int rc = 0;471 472 if (!qeth_card_hw_is_reachable(card))473 return sysfs_emit(buf, "n/a\n");474 475 rc = qeth_query_switch_attributes(card, &sw_info);476 if (rc)477 return rc;478 479 if (!sw_info.capabilities)480 rc = sysfs_emit(buf, "unknown");481 482 if (sw_info.capabilities & QETH_SWITCH_FORW_802_1)483 rc = sysfs_emit(buf,484 (sw_info.settings & QETH_SWITCH_FORW_802_1 ?485 "[802.1]" : "802.1"));486 if (sw_info.capabilities & QETH_SWITCH_FORW_REFL_RELAY)487 rc += sysfs_emit_at(buf, rc,488 (sw_info.settings &489 QETH_SWITCH_FORW_REFL_RELAY ?490 " [rr]" : " rr"));491 rc += sysfs_emit_at(buf, rc, "\n");492 493 return rc;494}495 496static DEVICE_ATTR(switch_attrs, 0444,497 qeth_dev_switch_attrs_show, NULL);498 499static ssize_t qeth_hw_trap_show(struct device *dev,500 struct device_attribute *attr, char *buf)501{502 struct qeth_card *card = dev_get_drvdata(dev);503 504 if (card->info.hwtrap)505 return sysfs_emit(buf, "arm\n");506 else507 return sysfs_emit(buf, "disarm\n");508}509 510static ssize_t qeth_hw_trap_store(struct device *dev,511 struct device_attribute *attr, const char *buf, size_t count)512{513 struct qeth_card *card = dev_get_drvdata(dev);514 int rc = 0;515 int state = 0;516 517 mutex_lock(&card->conf_mutex);518 if (qeth_card_hw_is_reachable(card))519 state = 1;520 521 if (sysfs_streq(buf, "arm") && !card->info.hwtrap) {522 if (state) {523 if (qeth_is_diagass_supported(card,524 QETH_DIAGS_CMD_TRAP)) {525 rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_ARM);526 if (!rc)527 card->info.hwtrap = 1;528 } else529 rc = -EINVAL;530 } else531 card->info.hwtrap = 1;532 } else if (sysfs_streq(buf, "disarm") && card->info.hwtrap) {533 if (state) {534 rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);535 if (!rc)536 card->info.hwtrap = 0;537 } else538 card->info.hwtrap = 0;539 } else if (sysfs_streq(buf, "trap") && state && card->info.hwtrap)540 rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_CAPTURE);541 else542 rc = -EINVAL;543 544 mutex_unlock(&card->conf_mutex);545 return rc ? rc : count;546}547 548static DEVICE_ATTR(hw_trap, 0644, qeth_hw_trap_show,549 qeth_hw_trap_store);550 551static ssize_t qeth_dev_blkt_store(struct qeth_card *card,552 const char *buf, size_t count, int *value, int max_value)553{554 unsigned int input;555 int rc;556 557 rc = kstrtouint(buf, 10, &input);558 if (rc)559 return rc;560 561 if (input > max_value)562 return -EINVAL;563 564 mutex_lock(&card->conf_mutex);565 if (card->state != CARD_STATE_DOWN)566 rc = -EPERM;567 else568 *value = input;569 mutex_unlock(&card->conf_mutex);570 return rc ? rc : count;571}572 573static ssize_t qeth_dev_blkt_total_show(struct device *dev,574 struct device_attribute *attr, char *buf)575{576 struct qeth_card *card = dev_get_drvdata(dev);577 578 return sysfs_emit(buf, "%i\n", card->info.blkt.time_total);579}580 581static ssize_t qeth_dev_blkt_total_store(struct device *dev,582 struct device_attribute *attr, const char *buf, size_t count)583{584 struct qeth_card *card = dev_get_drvdata(dev);585 586 return qeth_dev_blkt_store(card, buf, count,587 &card->info.blkt.time_total, 5000);588}589 590static DEVICE_ATTR(total, 0644, qeth_dev_blkt_total_show,591 qeth_dev_blkt_total_store);592 593static ssize_t qeth_dev_blkt_inter_show(struct device *dev,594 struct device_attribute *attr, char *buf)595{596 struct qeth_card *card = dev_get_drvdata(dev);597 598 return sysfs_emit(buf, "%i\n", card->info.blkt.inter_packet);599}600 601static ssize_t qeth_dev_blkt_inter_store(struct device *dev,602 struct device_attribute *attr, const char *buf, size_t count)603{604 struct qeth_card *card = dev_get_drvdata(dev);605 606 return qeth_dev_blkt_store(card, buf, count,607 &card->info.blkt.inter_packet, 1000);608}609 610static DEVICE_ATTR(inter, 0644, qeth_dev_blkt_inter_show,611 qeth_dev_blkt_inter_store);612 613static ssize_t qeth_dev_blkt_inter_jumbo_show(struct device *dev,614 struct device_attribute *attr, char *buf)615{616 struct qeth_card *card = dev_get_drvdata(dev);617 618 return sysfs_emit(buf, "%i\n", card->info.blkt.inter_packet_jumbo);619}620 621static ssize_t qeth_dev_blkt_inter_jumbo_store(struct device *dev,622 struct device_attribute *attr, const char *buf, size_t count)623{624 struct qeth_card *card = dev_get_drvdata(dev);625 626 return qeth_dev_blkt_store(card, buf, count,627 &card->info.blkt.inter_packet_jumbo, 1000);628}629 630static DEVICE_ATTR(inter_jumbo, 0644, qeth_dev_blkt_inter_jumbo_show,631 qeth_dev_blkt_inter_jumbo_store);632 633static struct attribute *qeth_blkt_device_attrs[] = {634 &dev_attr_total.attr,635 &dev_attr_inter.attr,636 &dev_attr_inter_jumbo.attr,637 NULL,638};639 640static const struct attribute_group qeth_dev_blkt_group = {641 .name = "blkt",642 .attrs = qeth_blkt_device_attrs,643};644 645static struct attribute *qeth_dev_extended_attrs[] = {646 &dev_attr_inbuf_size.attr,647 &dev_attr_portno.attr,648 &dev_attr_portname.attr,649 &dev_attr_priority_queueing.attr,650 &dev_attr_performance_stats.attr,651 &dev_attr_layer2.attr,652 &dev_attr_isolation.attr,653 &dev_attr_hw_trap.attr,654 &dev_attr_switch_attrs.attr,655 NULL,656};657 658static const struct attribute_group qeth_dev_extended_group = {659 .attrs = qeth_dev_extended_attrs,660};661 662static struct attribute *qeth_dev_attrs[] = {663 &dev_attr_state.attr,664 &dev_attr_chpid.attr,665 &dev_attr_if_name.attr,666 &dev_attr_card_type.attr,667 &dev_attr_buffer_count.attr,668 &dev_attr_recover.attr,669 NULL,670};671 672static const struct attribute_group qeth_dev_group = {673 .attrs = qeth_dev_attrs,674};675 676const struct attribute_group *qeth_dev_groups[] = {677 &qeth_dev_group,678 &qeth_dev_extended_group,679 &qeth_dev_blkt_group,680 NULL,681};682