qeth_l3_sys.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027
  1. /*
  2. * drivers/s390/net/qeth_l3_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. #include "qeth_l3.h"
  11. #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
  12. struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)
  13. static const char *qeth_l3_get_checksum_str(struct qeth_card *card)
  14. {
  15. if (card->options.checksum_type == SW_CHECKSUMMING)
  16. return "sw";
  17. else if (card->options.checksum_type == HW_CHECKSUMMING)
  18. return "hw";
  19. else
  20. return "no";
  21. }
  22. static ssize_t qeth_l3_dev_route_show(struct qeth_card *card,
  23. struct qeth_routing_info *route, char *buf)
  24. {
  25. switch (route->type) {
  26. case PRIMARY_ROUTER:
  27. return sprintf(buf, "%s\n", "primary router");
  28. case SECONDARY_ROUTER:
  29. return sprintf(buf, "%s\n", "secondary router");
  30. case MULTICAST_ROUTER:
  31. if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
  32. return sprintf(buf, "%s\n", "multicast router+");
  33. else
  34. return sprintf(buf, "%s\n", "multicast router");
  35. case PRIMARY_CONNECTOR:
  36. if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
  37. return sprintf(buf, "%s\n", "primary connector+");
  38. else
  39. return sprintf(buf, "%s\n", "primary connector");
  40. case SECONDARY_CONNECTOR:
  41. if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
  42. return sprintf(buf, "%s\n", "secondary connector+");
  43. else
  44. return sprintf(buf, "%s\n", "secondary connector");
  45. default:
  46. return sprintf(buf, "%s\n", "no");
  47. }
  48. }
  49. static ssize_t qeth_l3_dev_route4_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 qeth_l3_dev_route_show(card, &card->options.route4, buf);
  56. }
  57. static ssize_t qeth_l3_dev_route_store(struct qeth_card *card,
  58. struct qeth_routing_info *route, enum qeth_prot_versions prot,
  59. const char *buf, size_t count)
  60. {
  61. enum qeth_routing_types old_route_type = route->type;
  62. char *tmp;
  63. int rc;
  64. tmp = strsep((char **) &buf, "\n");
  65. if (!strcmp(tmp, "no_router")) {
  66. route->type = NO_ROUTER;
  67. } else if (!strcmp(tmp, "primary_connector")) {
  68. route->type = PRIMARY_CONNECTOR;
  69. } else if (!strcmp(tmp, "secondary_connector")) {
  70. route->type = SECONDARY_CONNECTOR;
  71. } else if (!strcmp(tmp, "primary_router")) {
  72. route->type = PRIMARY_ROUTER;
  73. } else if (!strcmp(tmp, "secondary_router")) {
  74. route->type = SECONDARY_ROUTER;
  75. } else if (!strcmp(tmp, "multicast_router")) {
  76. route->type = MULTICAST_ROUTER;
  77. } else {
  78. return -EINVAL;
  79. }
  80. if (((card->state == CARD_STATE_SOFTSETUP) ||
  81. (card->state == CARD_STATE_UP)) &&
  82. (old_route_type != route->type)) {
  83. if (prot == QETH_PROT_IPV4)
  84. rc = qeth_l3_setrouting_v4(card);
  85. else if (prot == QETH_PROT_IPV6)
  86. rc = qeth_l3_setrouting_v6(card);
  87. }
  88. return count;
  89. }
  90. static ssize_t qeth_l3_dev_route4_store(struct device *dev,
  91. struct device_attribute *attr, const char *buf, size_t count)
  92. {
  93. struct qeth_card *card = dev_get_drvdata(dev);
  94. if (!card)
  95. return -EINVAL;
  96. return qeth_l3_dev_route_store(card, &card->options.route4,
  97. QETH_PROT_IPV4, buf, count);
  98. }
  99. static DEVICE_ATTR(route4, 0644, qeth_l3_dev_route4_show,
  100. qeth_l3_dev_route4_store);
  101. static ssize_t qeth_l3_dev_route6_show(struct device *dev,
  102. struct device_attribute *attr, char *buf)
  103. {
  104. struct qeth_card *card = dev_get_drvdata(dev);
  105. if (!card)
  106. return -EINVAL;
  107. if (!qeth_is_supported(card, IPA_IPV6))
  108. return sprintf(buf, "%s\n", "n/a");
  109. return qeth_l3_dev_route_show(card, &card->options.route6, buf);
  110. }
  111. static ssize_t qeth_l3_dev_route6_store(struct device *dev,
  112. struct device_attribute *attr, const char *buf, size_t count)
  113. {
  114. struct qeth_card *card = dev_get_drvdata(dev);
  115. if (!card)
  116. return -EINVAL;
  117. if (!qeth_is_supported(card, IPA_IPV6)) {
  118. return -EOPNOTSUPP;
  119. }
  120. return qeth_l3_dev_route_store(card, &card->options.route6,
  121. QETH_PROT_IPV6, buf, count);
  122. }
  123. static DEVICE_ATTR(route6, 0644, qeth_l3_dev_route6_show,
  124. qeth_l3_dev_route6_store);
  125. static ssize_t qeth_l3_dev_fake_broadcast_show(struct device *dev,
  126. struct device_attribute *attr, char *buf)
  127. {
  128. struct qeth_card *card = dev_get_drvdata(dev);
  129. if (!card)
  130. return -EINVAL;
  131. return sprintf(buf, "%i\n", card->options.fake_broadcast? 1:0);
  132. }
  133. static ssize_t qeth_l3_dev_fake_broadcast_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. char *tmp;
  138. int i;
  139. if (!card)
  140. return -EINVAL;
  141. if ((card->state != CARD_STATE_DOWN) &&
  142. (card->state != CARD_STATE_RECOVER))
  143. return -EPERM;
  144. i = simple_strtoul(buf, &tmp, 16);
  145. if ((i == 0) || (i == 1))
  146. card->options.fake_broadcast = i;
  147. else {
  148. return -EINVAL;
  149. }
  150. return count;
  151. }
  152. static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show,
  153. qeth_l3_dev_fake_broadcast_store);
  154. static ssize_t qeth_l3_dev_broadcast_mode_show(struct device *dev,
  155. struct device_attribute *attr, char *buf)
  156. {
  157. struct qeth_card *card = dev_get_drvdata(dev);
  158. if (!card)
  159. return -EINVAL;
  160. if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
  161. (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
  162. return sprintf(buf, "n/a\n");
  163. return sprintf(buf, "%s\n", (card->options.broadcast_mode ==
  164. QETH_TR_BROADCAST_ALLRINGS)?
  165. "all rings":"local");
  166. }
  167. static ssize_t qeth_l3_dev_broadcast_mode_store(struct device *dev,
  168. struct device_attribute *attr, const char *buf, size_t count)
  169. {
  170. struct qeth_card *card = dev_get_drvdata(dev);
  171. char *tmp;
  172. if (!card)
  173. return -EINVAL;
  174. if ((card->state != CARD_STATE_DOWN) &&
  175. (card->state != CARD_STATE_RECOVER))
  176. return -EPERM;
  177. if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
  178. (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) {
  179. return -EINVAL;
  180. }
  181. tmp = strsep((char **) &buf, "\n");
  182. if (!strcmp(tmp, "local")) {
  183. card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL;
  184. return count;
  185. } else if (!strcmp(tmp, "all_rings")) {
  186. card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
  187. return count;
  188. } else {
  189. return -EINVAL;
  190. }
  191. return count;
  192. }
  193. static DEVICE_ATTR(broadcast_mode, 0644, qeth_l3_dev_broadcast_mode_show,
  194. qeth_l3_dev_broadcast_mode_store);
  195. static ssize_t qeth_l3_dev_canonical_macaddr_show(struct device *dev,
  196. struct device_attribute *attr, char *buf)
  197. {
  198. struct qeth_card *card = dev_get_drvdata(dev);
  199. if (!card)
  200. return -EINVAL;
  201. if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
  202. (card->info.link_type == QETH_LINK_TYPE_LANE_TR)))
  203. return sprintf(buf, "n/a\n");
  204. return sprintf(buf, "%i\n", (card->options.macaddr_mode ==
  205. QETH_TR_MACADDR_CANONICAL)? 1:0);
  206. }
  207. static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev,
  208. struct device_attribute *attr, const char *buf, size_t count)
  209. {
  210. struct qeth_card *card = dev_get_drvdata(dev);
  211. char *tmp;
  212. int i;
  213. if (!card)
  214. return -EINVAL;
  215. if ((card->state != CARD_STATE_DOWN) &&
  216. (card->state != CARD_STATE_RECOVER))
  217. return -EPERM;
  218. if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) ||
  219. (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) {
  220. return -EINVAL;
  221. }
  222. i = simple_strtoul(buf, &tmp, 16);
  223. if ((i == 0) || (i == 1))
  224. card->options.macaddr_mode = i?
  225. QETH_TR_MACADDR_CANONICAL :
  226. QETH_TR_MACADDR_NONCANONICAL;
  227. else {
  228. return -EINVAL;
  229. }
  230. return count;
  231. }
  232. static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show,
  233. qeth_l3_dev_canonical_macaddr_store);
  234. static ssize_t qeth_l3_dev_checksum_show(struct device *dev,
  235. struct device_attribute *attr, char *buf)
  236. {
  237. struct qeth_card *card = dev_get_drvdata(dev);
  238. if (!card)
  239. return -EINVAL;
  240. return sprintf(buf, "%s checksumming\n",
  241. qeth_l3_get_checksum_str(card));
  242. }
  243. static ssize_t qeth_l3_dev_checksum_store(struct device *dev,
  244. struct device_attribute *attr, const char *buf, size_t count)
  245. {
  246. struct qeth_card *card = dev_get_drvdata(dev);
  247. char *tmp;
  248. if (!card)
  249. return -EINVAL;
  250. if ((card->state != CARD_STATE_DOWN) &&
  251. (card->state != CARD_STATE_RECOVER))
  252. return -EPERM;
  253. tmp = strsep((char **) &buf, "\n");
  254. if (!strcmp(tmp, "sw_checksumming"))
  255. card->options.checksum_type = SW_CHECKSUMMING;
  256. else if (!strcmp(tmp, "hw_checksumming"))
  257. card->options.checksum_type = HW_CHECKSUMMING;
  258. else if (!strcmp(tmp, "no_checksumming"))
  259. card->options.checksum_type = NO_CHECKSUMMING;
  260. else {
  261. return -EINVAL;
  262. }
  263. return count;
  264. }
  265. static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show,
  266. qeth_l3_dev_checksum_store);
  267. static struct attribute *qeth_l3_device_attrs[] = {
  268. &dev_attr_route4.attr,
  269. &dev_attr_route6.attr,
  270. &dev_attr_fake_broadcast.attr,
  271. &dev_attr_broadcast_mode.attr,
  272. &dev_attr_canonical_macaddr.attr,
  273. &dev_attr_checksumming.attr,
  274. NULL,
  275. };
  276. static struct attribute_group qeth_l3_device_attr_group = {
  277. .attrs = qeth_l3_device_attrs,
  278. };
  279. static ssize_t qeth_l3_dev_ipato_enable_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->ipato.enabled? 1:0);
  286. }
  287. static ssize_t qeth_l3_dev_ipato_enable_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. if (!card)
  293. return -EINVAL;
  294. if ((card->state != CARD_STATE_DOWN) &&
  295. (card->state != CARD_STATE_RECOVER))
  296. return -EPERM;
  297. tmp = strsep((char **) &buf, "\n");
  298. if (!strcmp(tmp, "toggle")) {
  299. card->ipato.enabled = (card->ipato.enabled)? 0 : 1;
  300. } else if (!strcmp(tmp, "1")) {
  301. card->ipato.enabled = 1;
  302. } else if (!strcmp(tmp, "0")) {
  303. card->ipato.enabled = 0;
  304. } else {
  305. return -EINVAL;
  306. }
  307. return count;
  308. }
  309. static QETH_DEVICE_ATTR(ipato_enable, enable, 0644,
  310. qeth_l3_dev_ipato_enable_show,
  311. qeth_l3_dev_ipato_enable_store);
  312. static ssize_t qeth_l3_dev_ipato_invert4_show(struct device *dev,
  313. struct device_attribute *attr, char *buf)
  314. {
  315. struct qeth_card *card = dev_get_drvdata(dev);
  316. if (!card)
  317. return -EINVAL;
  318. return sprintf(buf, "%i\n", card->ipato.invert4? 1:0);
  319. }
  320. static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev,
  321. struct device_attribute *attr,
  322. const char *buf, size_t count)
  323. {
  324. struct qeth_card *card = dev_get_drvdata(dev);
  325. char *tmp;
  326. if (!card)
  327. return -EINVAL;
  328. tmp = strsep((char **) &buf, "\n");
  329. if (!strcmp(tmp, "toggle")) {
  330. card->ipato.invert4 = (card->ipato.invert4)? 0 : 1;
  331. } else if (!strcmp(tmp, "1")) {
  332. card->ipato.invert4 = 1;
  333. } else if (!strcmp(tmp, "0")) {
  334. card->ipato.invert4 = 0;
  335. } else {
  336. return -EINVAL;
  337. }
  338. return count;
  339. }
  340. static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644,
  341. qeth_l3_dev_ipato_invert4_show,
  342. qeth_l3_dev_ipato_invert4_store);
  343. static ssize_t qeth_l3_dev_ipato_add_show(char *buf, struct qeth_card *card,
  344. enum qeth_prot_versions proto)
  345. {
  346. struct qeth_ipato_entry *ipatoe;
  347. unsigned long flags;
  348. char addr_str[40];
  349. int entry_len; /* length of 1 entry string, differs between v4 and v6 */
  350. int i = 0;
  351. entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
  352. /* add strlen for "/<mask>\n" */
  353. entry_len += (proto == QETH_PROT_IPV4)? 5 : 6;
  354. spin_lock_irqsave(&card->ip_lock, flags);
  355. list_for_each_entry(ipatoe, &card->ipato.entries, entry) {
  356. if (ipatoe->proto != proto)
  357. continue;
  358. /* String must not be longer than PAGE_SIZE. So we check if
  359. * string length gets near PAGE_SIZE. Then we can savely display
  360. * the next IPv6 address (worst case, compared to IPv4) */
  361. if ((PAGE_SIZE - i) <= entry_len)
  362. break;
  363. qeth_l3_ipaddr_to_string(proto, ipatoe->addr, addr_str);
  364. i += snprintf(buf + i, PAGE_SIZE - i,
  365. "%s/%i\n", addr_str, ipatoe->mask_bits);
  366. }
  367. spin_unlock_irqrestore(&card->ip_lock, flags);
  368. i += snprintf(buf + i, PAGE_SIZE - i, "\n");
  369. return i;
  370. }
  371. static ssize_t qeth_l3_dev_ipato_add4_show(struct device *dev,
  372. struct device_attribute *attr, char *buf)
  373. {
  374. struct qeth_card *card = dev_get_drvdata(dev);
  375. if (!card)
  376. return -EINVAL;
  377. return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV4);
  378. }
  379. static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto,
  380. u8 *addr, int *mask_bits)
  381. {
  382. const char *start, *end;
  383. char *tmp;
  384. char buffer[40] = {0, };
  385. start = buf;
  386. /* get address string */
  387. end = strchr(start, '/');
  388. if (!end || (end - start >= 40)) {
  389. return -EINVAL;
  390. }
  391. strncpy(buffer, start, end - start);
  392. if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) {
  393. return -EINVAL;
  394. }
  395. start = end + 1;
  396. *mask_bits = simple_strtoul(start, &tmp, 10);
  397. if (!strlen(start) ||
  398. (tmp == start) ||
  399. (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) {
  400. return -EINVAL;
  401. }
  402. return 0;
  403. }
  404. static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count,
  405. struct qeth_card *card, enum qeth_prot_versions proto)
  406. {
  407. struct qeth_ipato_entry *ipatoe;
  408. u8 addr[16];
  409. int mask_bits;
  410. int rc;
  411. rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
  412. if (rc)
  413. return rc;
  414. ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL);
  415. if (!ipatoe) {
  416. return -ENOMEM;
  417. }
  418. ipatoe->proto = proto;
  419. memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16);
  420. ipatoe->mask_bits = mask_bits;
  421. rc = qeth_l3_add_ipato_entry(card, ipatoe);
  422. if (rc) {
  423. kfree(ipatoe);
  424. return rc;
  425. }
  426. return count;
  427. }
  428. static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev,
  429. struct device_attribute *attr, const char *buf, size_t count)
  430. {
  431. struct qeth_card *card = dev_get_drvdata(dev);
  432. if (!card)
  433. return -EINVAL;
  434. return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV4);
  435. }
  436. static QETH_DEVICE_ATTR(ipato_add4, add4, 0644,
  437. qeth_l3_dev_ipato_add4_show,
  438. qeth_l3_dev_ipato_add4_store);
  439. static ssize_t qeth_l3_dev_ipato_del_store(const char *buf, size_t count,
  440. struct qeth_card *card, enum qeth_prot_versions proto)
  441. {
  442. u8 addr[16];
  443. int mask_bits;
  444. int rc;
  445. rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits);
  446. if (rc)
  447. return rc;
  448. qeth_l3_del_ipato_entry(card, proto, addr, mask_bits);
  449. return count;
  450. }
  451. static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev,
  452. struct device_attribute *attr, const char *buf, size_t count)
  453. {
  454. struct qeth_card *card = dev_get_drvdata(dev);
  455. if (!card)
  456. return -EINVAL;
  457. return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV4);
  458. }
  459. static QETH_DEVICE_ATTR(ipato_del4, del4, 0200, NULL,
  460. qeth_l3_dev_ipato_del4_store);
  461. static ssize_t qeth_l3_dev_ipato_invert6_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. return sprintf(buf, "%i\n", card->ipato.invert6? 1:0);
  468. }
  469. static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev,
  470. struct device_attribute *attr, const char *buf, size_t count)
  471. {
  472. struct qeth_card *card = dev_get_drvdata(dev);
  473. char *tmp;
  474. if (!card)
  475. return -EINVAL;
  476. tmp = strsep((char **) &buf, "\n");
  477. if (!strcmp(tmp, "toggle")) {
  478. card->ipato.invert6 = (card->ipato.invert6)? 0 : 1;
  479. } else if (!strcmp(tmp, "1")) {
  480. card->ipato.invert6 = 1;
  481. } else if (!strcmp(tmp, "0")) {
  482. card->ipato.invert6 = 0;
  483. } else {
  484. return -EINVAL;
  485. }
  486. return count;
  487. }
  488. static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644,
  489. qeth_l3_dev_ipato_invert6_show,
  490. qeth_l3_dev_ipato_invert6_store);
  491. static ssize_t qeth_l3_dev_ipato_add6_show(struct device *dev,
  492. struct device_attribute *attr, char *buf)
  493. {
  494. struct qeth_card *card = dev_get_drvdata(dev);
  495. if (!card)
  496. return -EINVAL;
  497. return qeth_l3_dev_ipato_add_show(buf, card, QETH_PROT_IPV6);
  498. }
  499. static ssize_t qeth_l3_dev_ipato_add6_store(struct device *dev,
  500. struct device_attribute *attr, const char *buf, size_t count)
  501. {
  502. struct qeth_card *card = dev_get_drvdata(dev);
  503. if (!card)
  504. return -EINVAL;
  505. return qeth_l3_dev_ipato_add_store(buf, count, card, QETH_PROT_IPV6);
  506. }
  507. static QETH_DEVICE_ATTR(ipato_add6, add6, 0644,
  508. qeth_l3_dev_ipato_add6_show,
  509. qeth_l3_dev_ipato_add6_store);
  510. static ssize_t qeth_l3_dev_ipato_del6_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. if (!card)
  515. return -EINVAL;
  516. return qeth_l3_dev_ipato_del_store(buf, count, card, QETH_PROT_IPV6);
  517. }
  518. static QETH_DEVICE_ATTR(ipato_del6, del6, 0200, NULL,
  519. qeth_l3_dev_ipato_del6_store);
  520. static struct attribute *qeth_ipato_device_attrs[] = {
  521. &dev_attr_ipato_enable.attr,
  522. &dev_attr_ipato_invert4.attr,
  523. &dev_attr_ipato_add4.attr,
  524. &dev_attr_ipato_del4.attr,
  525. &dev_attr_ipato_invert6.attr,
  526. &dev_attr_ipato_add6.attr,
  527. &dev_attr_ipato_del6.attr,
  528. NULL,
  529. };
  530. static struct attribute_group qeth_device_ipato_group = {
  531. .name = "ipa_takeover",
  532. .attrs = qeth_ipato_device_attrs,
  533. };
  534. static ssize_t qeth_l3_dev_vipa_add_show(char *buf, struct qeth_card *card,
  535. enum qeth_prot_versions proto)
  536. {
  537. struct qeth_ipaddr *ipaddr;
  538. char addr_str[40];
  539. int entry_len; /* length of 1 entry string, differs between v4 and v6 */
  540. unsigned long flags;
  541. int i = 0;
  542. entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
  543. entry_len += 2; /* \n + terminator */
  544. spin_lock_irqsave(&card->ip_lock, flags);
  545. list_for_each_entry(ipaddr, &card->ip_list, entry) {
  546. if (ipaddr->proto != proto)
  547. continue;
  548. if (ipaddr->type != QETH_IP_TYPE_VIPA)
  549. continue;
  550. /* String must not be longer than PAGE_SIZE. So we check if
  551. * string length gets near PAGE_SIZE. Then we can savely display
  552. * the next IPv6 address (worst case, compared to IPv4) */
  553. if ((PAGE_SIZE - i) <= entry_len)
  554. break;
  555. qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
  556. addr_str);
  557. i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
  558. }
  559. spin_unlock_irqrestore(&card->ip_lock, flags);
  560. i += snprintf(buf + i, PAGE_SIZE - i, "\n");
  561. return i;
  562. }
  563. static ssize_t qeth_l3_dev_vipa_add4_show(struct device *dev,
  564. struct device_attribute *attr, char *buf)
  565. {
  566. struct qeth_card *card = dev_get_drvdata(dev);
  567. if (!card)
  568. return -EINVAL;
  569. return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV4);
  570. }
  571. static int qeth_l3_parse_vipae(const char *buf, enum qeth_prot_versions proto,
  572. u8 *addr)
  573. {
  574. if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
  575. return -EINVAL;
  576. }
  577. return 0;
  578. }
  579. static ssize_t qeth_l3_dev_vipa_add_store(const char *buf, size_t count,
  580. struct qeth_card *card, enum qeth_prot_versions proto)
  581. {
  582. u8 addr[16] = {0, };
  583. int rc;
  584. rc = qeth_l3_parse_vipae(buf, proto, addr);
  585. if (rc)
  586. return rc;
  587. rc = qeth_l3_add_vipa(card, proto, addr);
  588. if (rc)
  589. return rc;
  590. return count;
  591. }
  592. static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev,
  593. struct device_attribute *attr, const char *buf, size_t count)
  594. {
  595. struct qeth_card *card = dev_get_drvdata(dev);
  596. if (!card)
  597. return -EINVAL;
  598. return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV4);
  599. }
  600. static QETH_DEVICE_ATTR(vipa_add4, add4, 0644,
  601. qeth_l3_dev_vipa_add4_show,
  602. qeth_l3_dev_vipa_add4_store);
  603. static ssize_t qeth_l3_dev_vipa_del_store(const char *buf, size_t count,
  604. struct qeth_card *card, enum qeth_prot_versions proto)
  605. {
  606. u8 addr[16];
  607. int rc;
  608. rc = qeth_l3_parse_vipae(buf, proto, addr);
  609. if (rc)
  610. return rc;
  611. qeth_l3_del_vipa(card, proto, addr);
  612. return count;
  613. }
  614. static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev,
  615. struct device_attribute *attr, const char *buf, size_t count)
  616. {
  617. struct qeth_card *card = dev_get_drvdata(dev);
  618. if (!card)
  619. return -EINVAL;
  620. return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV4);
  621. }
  622. static QETH_DEVICE_ATTR(vipa_del4, del4, 0200, NULL,
  623. qeth_l3_dev_vipa_del4_store);
  624. static ssize_t qeth_l3_dev_vipa_add6_show(struct device *dev,
  625. struct device_attribute *attr, char *buf)
  626. {
  627. struct qeth_card *card = dev_get_drvdata(dev);
  628. if (!card)
  629. return -EINVAL;
  630. return qeth_l3_dev_vipa_add_show(buf, card, QETH_PROT_IPV6);
  631. }
  632. static ssize_t qeth_l3_dev_vipa_add6_store(struct device *dev,
  633. struct device_attribute *attr, const char *buf, size_t count)
  634. {
  635. struct qeth_card *card = dev_get_drvdata(dev);
  636. if (!card)
  637. return -EINVAL;
  638. return qeth_l3_dev_vipa_add_store(buf, count, card, QETH_PROT_IPV6);
  639. }
  640. static QETH_DEVICE_ATTR(vipa_add6, add6, 0644,
  641. qeth_l3_dev_vipa_add6_show,
  642. qeth_l3_dev_vipa_add6_store);
  643. static ssize_t qeth_l3_dev_vipa_del6_store(struct device *dev,
  644. struct device_attribute *attr, const char *buf, size_t count)
  645. {
  646. struct qeth_card *card = dev_get_drvdata(dev);
  647. if (!card)
  648. return -EINVAL;
  649. return qeth_l3_dev_vipa_del_store(buf, count, card, QETH_PROT_IPV6);
  650. }
  651. static QETH_DEVICE_ATTR(vipa_del6, del6, 0200, NULL,
  652. qeth_l3_dev_vipa_del6_store);
  653. static struct attribute *qeth_vipa_device_attrs[] = {
  654. &dev_attr_vipa_add4.attr,
  655. &dev_attr_vipa_del4.attr,
  656. &dev_attr_vipa_add6.attr,
  657. &dev_attr_vipa_del6.attr,
  658. NULL,
  659. };
  660. static struct attribute_group qeth_device_vipa_group = {
  661. .name = "vipa",
  662. .attrs = qeth_vipa_device_attrs,
  663. };
  664. static ssize_t qeth_l3_dev_rxip_add_show(char *buf, struct qeth_card *card,
  665. enum qeth_prot_versions proto)
  666. {
  667. struct qeth_ipaddr *ipaddr;
  668. char addr_str[40];
  669. int entry_len; /* length of 1 entry string, differs between v4 and v6 */
  670. unsigned long flags;
  671. int i = 0;
  672. entry_len = (proto == QETH_PROT_IPV4)? 12 : 40;
  673. entry_len += 2; /* \n + terminator */
  674. spin_lock_irqsave(&card->ip_lock, flags);
  675. list_for_each_entry(ipaddr, &card->ip_list, entry) {
  676. if (ipaddr->proto != proto)
  677. continue;
  678. if (ipaddr->type != QETH_IP_TYPE_RXIP)
  679. continue;
  680. /* String must not be longer than PAGE_SIZE. So we check if
  681. * string length gets near PAGE_SIZE. Then we can savely display
  682. * the next IPv6 address (worst case, compared to IPv4) */
  683. if ((PAGE_SIZE - i) <= entry_len)
  684. break;
  685. qeth_l3_ipaddr_to_string(proto, (const u8 *)&ipaddr->u,
  686. addr_str);
  687. i += snprintf(buf + i, PAGE_SIZE - i, "%s\n", addr_str);
  688. }
  689. spin_unlock_irqrestore(&card->ip_lock, flags);
  690. i += snprintf(buf + i, PAGE_SIZE - i, "\n");
  691. return i;
  692. }
  693. static ssize_t qeth_l3_dev_rxip_add4_show(struct device *dev,
  694. struct device_attribute *attr, char *buf)
  695. {
  696. struct qeth_card *card = dev_get_drvdata(dev);
  697. if (!card)
  698. return -EINVAL;
  699. return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV4);
  700. }
  701. static int qeth_l3_parse_rxipe(const char *buf, enum qeth_prot_versions proto,
  702. u8 *addr)
  703. {
  704. if (qeth_l3_string_to_ipaddr(buf, proto, addr)) {
  705. return -EINVAL;
  706. }
  707. return 0;
  708. }
  709. static ssize_t qeth_l3_dev_rxip_add_store(const char *buf, size_t count,
  710. struct qeth_card *card, enum qeth_prot_versions proto)
  711. {
  712. u8 addr[16] = {0, };
  713. int rc;
  714. rc = qeth_l3_parse_rxipe(buf, proto, addr);
  715. if (rc)
  716. return rc;
  717. rc = qeth_l3_add_rxip(card, proto, addr);
  718. if (rc)
  719. return rc;
  720. return count;
  721. }
  722. static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev,
  723. struct device_attribute *attr, const char *buf, size_t count)
  724. {
  725. struct qeth_card *card = dev_get_drvdata(dev);
  726. if (!card)
  727. return -EINVAL;
  728. return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV4);
  729. }
  730. static QETH_DEVICE_ATTR(rxip_add4, add4, 0644,
  731. qeth_l3_dev_rxip_add4_show,
  732. qeth_l3_dev_rxip_add4_store);
  733. static ssize_t qeth_l3_dev_rxip_del_store(const char *buf, size_t count,
  734. struct qeth_card *card, enum qeth_prot_versions proto)
  735. {
  736. u8 addr[16];
  737. int rc;
  738. rc = qeth_l3_parse_rxipe(buf, proto, addr);
  739. if (rc)
  740. return rc;
  741. qeth_l3_del_rxip(card, proto, addr);
  742. return count;
  743. }
  744. static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev,
  745. struct device_attribute *attr, const char *buf, size_t count)
  746. {
  747. struct qeth_card *card = dev_get_drvdata(dev);
  748. if (!card)
  749. return -EINVAL;
  750. return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV4);
  751. }
  752. static QETH_DEVICE_ATTR(rxip_del4, del4, 0200, NULL,
  753. qeth_l3_dev_rxip_del4_store);
  754. static ssize_t qeth_l3_dev_rxip_add6_show(struct device *dev,
  755. struct device_attribute *attr, char *buf)
  756. {
  757. struct qeth_card *card = dev_get_drvdata(dev);
  758. if (!card)
  759. return -EINVAL;
  760. return qeth_l3_dev_rxip_add_show(buf, card, QETH_PROT_IPV6);
  761. }
  762. static ssize_t qeth_l3_dev_rxip_add6_store(struct device *dev,
  763. struct device_attribute *attr, const char *buf, size_t count)
  764. {
  765. struct qeth_card *card = dev_get_drvdata(dev);
  766. if (!card)
  767. return -EINVAL;
  768. return qeth_l3_dev_rxip_add_store(buf, count, card, QETH_PROT_IPV6);
  769. }
  770. static QETH_DEVICE_ATTR(rxip_add6, add6, 0644,
  771. qeth_l3_dev_rxip_add6_show,
  772. qeth_l3_dev_rxip_add6_store);
  773. static ssize_t qeth_l3_dev_rxip_del6_store(struct device *dev,
  774. struct device_attribute *attr, const char *buf, size_t count)
  775. {
  776. struct qeth_card *card = dev_get_drvdata(dev);
  777. if (!card)
  778. return -EINVAL;
  779. return qeth_l3_dev_rxip_del_store(buf, count, card, QETH_PROT_IPV6);
  780. }
  781. static QETH_DEVICE_ATTR(rxip_del6, del6, 0200, NULL,
  782. qeth_l3_dev_rxip_del6_store);
  783. static struct attribute *qeth_rxip_device_attrs[] = {
  784. &dev_attr_rxip_add4.attr,
  785. &dev_attr_rxip_del4.attr,
  786. &dev_attr_rxip_add6.attr,
  787. &dev_attr_rxip_del6.attr,
  788. NULL,
  789. };
  790. static struct attribute_group qeth_device_rxip_group = {
  791. .name = "rxip",
  792. .attrs = qeth_rxip_device_attrs,
  793. };
  794. int qeth_l3_create_device_attributes(struct device *dev)
  795. {
  796. int ret;
  797. ret = sysfs_create_group(&dev->kobj, &qeth_l3_device_attr_group);
  798. if (ret)
  799. return ret;
  800. ret = sysfs_create_group(&dev->kobj, &qeth_device_ipato_group);
  801. if (ret) {
  802. sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
  803. return ret;
  804. }
  805. ret = sysfs_create_group(&dev->kobj, &qeth_device_vipa_group);
  806. if (ret) {
  807. sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
  808. sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
  809. return ret;
  810. }
  811. ret = sysfs_create_group(&dev->kobj, &qeth_device_rxip_group);
  812. if (ret) {
  813. sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
  814. sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
  815. sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
  816. return ret;
  817. }
  818. return 0;
  819. }
  820. void qeth_l3_remove_device_attributes(struct device *dev)
  821. {
  822. sysfs_remove_group(&dev->kobj, &qeth_l3_device_attr_group);
  823. sysfs_remove_group(&dev->kobj, &qeth_device_ipato_group);
  824. sysfs_remove_group(&dev->kobj, &qeth_device_vipa_group);
  825. sysfs_remove_group(&dev->kobj, &qeth_device_rxip_group);
  826. }