qeth_l3_sys.c 26 KB

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