qeth_core_sys.c 19 KB

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