ncsi-rsp.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036
  1. /*
  2. * Copyright Gavin Shan, IBM Corporation 2016.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. */
  9. #include <linux/module.h>
  10. #include <linux/kernel.h>
  11. #include <linux/init.h>
  12. #include <linux/netdevice.h>
  13. #include <linux/skbuff.h>
  14. #include <net/ncsi.h>
  15. #include <net/net_namespace.h>
  16. #include <net/sock.h>
  17. #include "internal.h"
  18. #include "ncsi-pkt.h"
  19. static int ncsi_validate_rsp_pkt(struct ncsi_request *nr,
  20. unsigned short payload)
  21. {
  22. struct ncsi_rsp_pkt_hdr *h;
  23. u32 checksum;
  24. __be32 *pchecksum;
  25. /* Check NCSI packet header. We don't need validate
  26. * the packet type, which should have been checked
  27. * before calling this function.
  28. */
  29. h = (struct ncsi_rsp_pkt_hdr *)skb_network_header(nr->rsp);
  30. if (h->common.revision != NCSI_PKT_REVISION)
  31. return -EINVAL;
  32. if (ntohs(h->common.length) != payload)
  33. return -EINVAL;
  34. /* Check on code and reason */
  35. if (ntohs(h->code) != NCSI_PKT_RSP_C_COMPLETED ||
  36. ntohs(h->reason) != NCSI_PKT_RSP_R_NO_ERROR)
  37. return -EINVAL;
  38. /* Validate checksum, which might be zeroes if the
  39. * sender doesn't support checksum according to NCSI
  40. * specification.
  41. */
  42. pchecksum = (__be32 *)((void *)(h + 1) + payload - 4);
  43. if (ntohl(*pchecksum) == 0)
  44. return 0;
  45. checksum = ncsi_calculate_checksum((unsigned char *)h,
  46. sizeof(*h) + payload - 4);
  47. if (*pchecksum != htonl(checksum))
  48. return -EINVAL;
  49. return 0;
  50. }
  51. static int ncsi_rsp_handler_cis(struct ncsi_request *nr)
  52. {
  53. struct ncsi_rsp_pkt *rsp;
  54. struct ncsi_dev_priv *ndp = nr->ndp;
  55. struct ncsi_package *np;
  56. struct ncsi_channel *nc;
  57. unsigned char id;
  58. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  59. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel, &np, &nc);
  60. if (!nc) {
  61. if (ndp->flags & NCSI_DEV_PROBED)
  62. return -ENXIO;
  63. id = NCSI_CHANNEL_INDEX(rsp->rsp.common.channel);
  64. nc = ncsi_add_channel(np, id);
  65. }
  66. return nc ? 0 : -ENODEV;
  67. }
  68. static int ncsi_rsp_handler_sp(struct ncsi_request *nr)
  69. {
  70. struct ncsi_rsp_pkt *rsp;
  71. struct ncsi_dev_priv *ndp = nr->ndp;
  72. struct ncsi_package *np;
  73. unsigned char id;
  74. /* Add the package if it's not existing. Otherwise,
  75. * to change the state of its child channels.
  76. */
  77. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  78. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  79. &np, NULL);
  80. if (!np) {
  81. if (ndp->flags & NCSI_DEV_PROBED)
  82. return -ENXIO;
  83. id = NCSI_PACKAGE_INDEX(rsp->rsp.common.channel);
  84. np = ncsi_add_package(ndp, id);
  85. if (!np)
  86. return -ENODEV;
  87. }
  88. return 0;
  89. }
  90. static int ncsi_rsp_handler_dp(struct ncsi_request *nr)
  91. {
  92. struct ncsi_rsp_pkt *rsp;
  93. struct ncsi_dev_priv *ndp = nr->ndp;
  94. struct ncsi_package *np;
  95. struct ncsi_channel *nc;
  96. unsigned long flags;
  97. /* Find the package */
  98. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  99. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  100. &np, NULL);
  101. if (!np)
  102. return -ENODEV;
  103. /* Change state of all channels attached to the package */
  104. NCSI_FOR_EACH_CHANNEL(np, nc) {
  105. spin_lock_irqsave(&nc->lock, flags);
  106. nc->state = NCSI_CHANNEL_INACTIVE;
  107. spin_unlock_irqrestore(&nc->lock, flags);
  108. }
  109. return 0;
  110. }
  111. static int ncsi_rsp_handler_ec(struct ncsi_request *nr)
  112. {
  113. struct ncsi_rsp_pkt *rsp;
  114. struct ncsi_dev_priv *ndp = nr->ndp;
  115. struct ncsi_channel *nc;
  116. struct ncsi_channel_mode *ncm;
  117. /* Find the package and channel */
  118. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  119. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  120. NULL, &nc);
  121. if (!nc)
  122. return -ENODEV;
  123. ncm = &nc->modes[NCSI_MODE_ENABLE];
  124. if (ncm->enable)
  125. return -EBUSY;
  126. ncm->enable = 1;
  127. return 0;
  128. }
  129. static int ncsi_rsp_handler_dc(struct ncsi_request *nr)
  130. {
  131. struct ncsi_rsp_pkt *rsp;
  132. struct ncsi_dev_priv *ndp = nr->ndp;
  133. struct ncsi_channel *nc;
  134. struct ncsi_channel_mode *ncm;
  135. int ret;
  136. ret = ncsi_validate_rsp_pkt(nr, 4);
  137. if (ret)
  138. return ret;
  139. /* Find the package and channel */
  140. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  141. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  142. NULL, &nc);
  143. if (!nc)
  144. return -ENODEV;
  145. ncm = &nc->modes[NCSI_MODE_ENABLE];
  146. if (!ncm->enable)
  147. return -EBUSY;
  148. ncm->enable = 0;
  149. return 0;
  150. }
  151. static int ncsi_rsp_handler_rc(struct ncsi_request *nr)
  152. {
  153. struct ncsi_rsp_pkt *rsp;
  154. struct ncsi_dev_priv *ndp = nr->ndp;
  155. struct ncsi_channel *nc;
  156. unsigned long flags;
  157. /* Find the package and channel */
  158. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  159. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  160. NULL, &nc);
  161. if (!nc)
  162. return -ENODEV;
  163. /* Update state for the specified channel */
  164. spin_lock_irqsave(&nc->lock, flags);
  165. nc->state = NCSI_CHANNEL_INACTIVE;
  166. spin_unlock_irqrestore(&nc->lock, flags);
  167. return 0;
  168. }
  169. static int ncsi_rsp_handler_ecnt(struct ncsi_request *nr)
  170. {
  171. struct ncsi_rsp_pkt *rsp;
  172. struct ncsi_dev_priv *ndp = nr->ndp;
  173. struct ncsi_channel *nc;
  174. struct ncsi_channel_mode *ncm;
  175. /* Find the package and channel */
  176. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  177. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  178. NULL, &nc);
  179. if (!nc)
  180. return -ENODEV;
  181. ncm = &nc->modes[NCSI_MODE_TX_ENABLE];
  182. if (ncm->enable)
  183. return -EBUSY;
  184. ncm->enable = 1;
  185. return 0;
  186. }
  187. static int ncsi_rsp_handler_dcnt(struct ncsi_request *nr)
  188. {
  189. struct ncsi_rsp_pkt *rsp;
  190. struct ncsi_dev_priv *ndp = nr->ndp;
  191. struct ncsi_channel *nc;
  192. struct ncsi_channel_mode *ncm;
  193. /* Find the package and channel */
  194. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  195. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  196. NULL, &nc);
  197. if (!nc)
  198. return -ENODEV;
  199. ncm = &nc->modes[NCSI_MODE_TX_ENABLE];
  200. if (!ncm->enable)
  201. return -EBUSY;
  202. ncm->enable = 1;
  203. return 0;
  204. }
  205. static int ncsi_rsp_handler_ae(struct ncsi_request *nr)
  206. {
  207. struct ncsi_cmd_ae_pkt *cmd;
  208. struct ncsi_rsp_pkt *rsp;
  209. struct ncsi_dev_priv *ndp = nr->ndp;
  210. struct ncsi_channel *nc;
  211. struct ncsi_channel_mode *ncm;
  212. /* Find the package and channel */
  213. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  214. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  215. NULL, &nc);
  216. if (!nc)
  217. return -ENODEV;
  218. /* Check if the AEN has been enabled */
  219. ncm = &nc->modes[NCSI_MODE_AEN];
  220. if (ncm->enable)
  221. return -EBUSY;
  222. /* Update to AEN configuration */
  223. cmd = (struct ncsi_cmd_ae_pkt *)skb_network_header(nr->cmd);
  224. ncm->enable = 1;
  225. ncm->data[0] = cmd->mc_id;
  226. ncm->data[1] = ntohl(cmd->mode);
  227. return 0;
  228. }
  229. static int ncsi_rsp_handler_sl(struct ncsi_request *nr)
  230. {
  231. struct ncsi_cmd_sl_pkt *cmd;
  232. struct ncsi_rsp_pkt *rsp;
  233. struct ncsi_dev_priv *ndp = nr->ndp;
  234. struct ncsi_channel *nc;
  235. struct ncsi_channel_mode *ncm;
  236. /* Find the package and channel */
  237. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  238. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  239. NULL, &nc);
  240. if (!nc)
  241. return -ENODEV;
  242. cmd = (struct ncsi_cmd_sl_pkt *)skb_network_header(nr->cmd);
  243. ncm = &nc->modes[NCSI_MODE_LINK];
  244. ncm->data[0] = ntohl(cmd->mode);
  245. ncm->data[1] = ntohl(cmd->oem_mode);
  246. return 0;
  247. }
  248. static int ncsi_rsp_handler_gls(struct ncsi_request *nr)
  249. {
  250. struct ncsi_rsp_gls_pkt *rsp;
  251. struct ncsi_dev_priv *ndp = nr->ndp;
  252. struct ncsi_channel *nc;
  253. struct ncsi_channel_mode *ncm;
  254. unsigned long flags;
  255. /* Find the package and channel */
  256. rsp = (struct ncsi_rsp_gls_pkt *)skb_network_header(nr->rsp);
  257. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  258. NULL, &nc);
  259. if (!nc)
  260. return -ENODEV;
  261. ncm = &nc->modes[NCSI_MODE_LINK];
  262. ncm->data[2] = ntohl(rsp->status);
  263. ncm->data[3] = ntohl(rsp->other);
  264. ncm->data[4] = ntohl(rsp->oem_status);
  265. if (nr->flags & NCSI_REQ_FLAG_EVENT_DRIVEN)
  266. return 0;
  267. /* Reset the channel monitor if it has been enabled */
  268. spin_lock_irqsave(&nc->lock, flags);
  269. nc->monitor.state = NCSI_CHANNEL_MONITOR_START;
  270. spin_unlock_irqrestore(&nc->lock, flags);
  271. return 0;
  272. }
  273. static int ncsi_rsp_handler_svf(struct ncsi_request *nr)
  274. {
  275. struct ncsi_cmd_svf_pkt *cmd;
  276. struct ncsi_rsp_pkt *rsp;
  277. struct ncsi_dev_priv *ndp = nr->ndp;
  278. struct ncsi_channel *nc;
  279. struct ncsi_channel_filter *ncf;
  280. unsigned short vlan;
  281. int ret;
  282. /* Find the package and channel */
  283. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  284. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  285. NULL, &nc);
  286. if (!nc)
  287. return -ENODEV;
  288. cmd = (struct ncsi_cmd_svf_pkt *)skb_network_header(nr->cmd);
  289. ncf = nc->filters[NCSI_FILTER_VLAN];
  290. if (!ncf)
  291. return -ENOENT;
  292. if (cmd->index >= ncf->total)
  293. return -ERANGE;
  294. /* Add or remove the VLAN filter */
  295. if (!(cmd->enable & 0x1)) {
  296. ret = ncsi_remove_filter(nc, NCSI_FILTER_VLAN, cmd->index);
  297. } else {
  298. vlan = ntohs(cmd->vlan);
  299. ret = ncsi_add_filter(nc, NCSI_FILTER_VLAN, &vlan);
  300. }
  301. return ret;
  302. }
  303. static int ncsi_rsp_handler_ev(struct ncsi_request *nr)
  304. {
  305. struct ncsi_cmd_ev_pkt *cmd;
  306. struct ncsi_rsp_pkt *rsp;
  307. struct ncsi_dev_priv *ndp = nr->ndp;
  308. struct ncsi_channel *nc;
  309. struct ncsi_channel_mode *ncm;
  310. /* Find the package and channel */
  311. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  312. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  313. NULL, &nc);
  314. if (!nc)
  315. return -ENODEV;
  316. /* Check if VLAN mode has been enabled */
  317. ncm = &nc->modes[NCSI_MODE_VLAN];
  318. if (ncm->enable)
  319. return -EBUSY;
  320. /* Update to VLAN mode */
  321. cmd = (struct ncsi_cmd_ev_pkt *)skb_network_header(nr->cmd);
  322. ncm->enable = 1;
  323. ncm->data[0] = ntohl(cmd->mode);
  324. return 0;
  325. }
  326. static int ncsi_rsp_handler_dv(struct ncsi_request *nr)
  327. {
  328. struct ncsi_rsp_pkt *rsp;
  329. struct ncsi_dev_priv *ndp = nr->ndp;
  330. struct ncsi_channel *nc;
  331. struct ncsi_channel_mode *ncm;
  332. /* Find the package and channel */
  333. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  334. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  335. NULL, &nc);
  336. if (!nc)
  337. return -ENODEV;
  338. /* Check if VLAN mode has been enabled */
  339. ncm = &nc->modes[NCSI_MODE_VLAN];
  340. if (!ncm->enable)
  341. return -EBUSY;
  342. /* Update to VLAN mode */
  343. ncm->enable = 0;
  344. return 0;
  345. }
  346. static int ncsi_rsp_handler_sma(struct ncsi_request *nr)
  347. {
  348. struct ncsi_cmd_sma_pkt *cmd;
  349. struct ncsi_rsp_pkt *rsp;
  350. struct ncsi_dev_priv *ndp = nr->ndp;
  351. struct ncsi_channel *nc;
  352. struct ncsi_channel_filter *ncf;
  353. void *bitmap;
  354. /* Find the package and channel */
  355. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  356. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  357. NULL, &nc);
  358. if (!nc)
  359. return -ENODEV;
  360. /* According to NCSI spec 1.01, the mixed filter table
  361. * isn't supported yet.
  362. */
  363. cmd = (struct ncsi_cmd_sma_pkt *)skb_network_header(nr->cmd);
  364. switch (cmd->at_e >> 5) {
  365. case 0x0: /* UC address */
  366. ncf = nc->filters[NCSI_FILTER_UC];
  367. break;
  368. case 0x1: /* MC address */
  369. ncf = nc->filters[NCSI_FILTER_MC];
  370. break;
  371. default:
  372. return -EINVAL;
  373. }
  374. /* Sanity check on the filter */
  375. if (!ncf)
  376. return -ENOENT;
  377. else if (cmd->index >= ncf->total)
  378. return -ERANGE;
  379. bitmap = &ncf->bitmap;
  380. if (cmd->at_e & 0x1) {
  381. if (test_and_set_bit(cmd->index, bitmap))
  382. return -EBUSY;
  383. memcpy(ncf->data + 6 * cmd->index, cmd->mac, 6);
  384. } else {
  385. if (!test_and_clear_bit(cmd->index, bitmap))
  386. return -EBUSY;
  387. memset(ncf->data + 6 * cmd->index, 0, 6);
  388. }
  389. return 0;
  390. }
  391. static int ncsi_rsp_handler_ebf(struct ncsi_request *nr)
  392. {
  393. struct ncsi_cmd_ebf_pkt *cmd;
  394. struct ncsi_rsp_pkt *rsp;
  395. struct ncsi_dev_priv *ndp = nr->ndp;
  396. struct ncsi_channel *nc;
  397. struct ncsi_channel_mode *ncm;
  398. /* Find the package and channel */
  399. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  400. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel, NULL, &nc);
  401. if (!nc)
  402. return -ENODEV;
  403. /* Check if broadcast filter has been enabled */
  404. ncm = &nc->modes[NCSI_MODE_BC];
  405. if (ncm->enable)
  406. return -EBUSY;
  407. /* Update to broadcast filter mode */
  408. cmd = (struct ncsi_cmd_ebf_pkt *)skb_network_header(nr->cmd);
  409. ncm->enable = 1;
  410. ncm->data[0] = ntohl(cmd->mode);
  411. return 0;
  412. }
  413. static int ncsi_rsp_handler_dbf(struct ncsi_request *nr)
  414. {
  415. struct ncsi_rsp_pkt *rsp;
  416. struct ncsi_dev_priv *ndp = nr->ndp;
  417. struct ncsi_channel *nc;
  418. struct ncsi_channel_mode *ncm;
  419. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  420. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  421. NULL, &nc);
  422. if (!nc)
  423. return -ENODEV;
  424. /* Check if broadcast filter isn't enabled */
  425. ncm = &nc->modes[NCSI_MODE_BC];
  426. if (!ncm->enable)
  427. return -EBUSY;
  428. /* Update to broadcast filter mode */
  429. ncm->enable = 0;
  430. ncm->data[0] = 0;
  431. return 0;
  432. }
  433. static int ncsi_rsp_handler_egmf(struct ncsi_request *nr)
  434. {
  435. struct ncsi_cmd_egmf_pkt *cmd;
  436. struct ncsi_rsp_pkt *rsp;
  437. struct ncsi_dev_priv *ndp = nr->ndp;
  438. struct ncsi_channel *nc;
  439. struct ncsi_channel_mode *ncm;
  440. /* Find the channel */
  441. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  442. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  443. NULL, &nc);
  444. if (!nc)
  445. return -ENODEV;
  446. /* Check if multicast filter has been enabled */
  447. ncm = &nc->modes[NCSI_MODE_MC];
  448. if (ncm->enable)
  449. return -EBUSY;
  450. /* Update to multicast filter mode */
  451. cmd = (struct ncsi_cmd_egmf_pkt *)skb_network_header(nr->cmd);
  452. ncm->enable = 1;
  453. ncm->data[0] = ntohl(cmd->mode);
  454. return 0;
  455. }
  456. static int ncsi_rsp_handler_dgmf(struct ncsi_request *nr)
  457. {
  458. struct ncsi_rsp_pkt *rsp;
  459. struct ncsi_dev_priv *ndp = nr->ndp;
  460. struct ncsi_channel *nc;
  461. struct ncsi_channel_mode *ncm;
  462. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  463. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  464. NULL, &nc);
  465. if (!nc)
  466. return -ENODEV;
  467. /* Check if multicast filter has been enabled */
  468. ncm = &nc->modes[NCSI_MODE_MC];
  469. if (!ncm->enable)
  470. return -EBUSY;
  471. /* Update to multicast filter mode */
  472. ncm->enable = 0;
  473. ncm->data[0] = 0;
  474. return 0;
  475. }
  476. static int ncsi_rsp_handler_snfc(struct ncsi_request *nr)
  477. {
  478. struct ncsi_cmd_snfc_pkt *cmd;
  479. struct ncsi_rsp_pkt *rsp;
  480. struct ncsi_dev_priv *ndp = nr->ndp;
  481. struct ncsi_channel *nc;
  482. struct ncsi_channel_mode *ncm;
  483. /* Find the channel */
  484. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  485. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  486. NULL, &nc);
  487. if (!nc)
  488. return -ENODEV;
  489. /* Check if flow control has been enabled */
  490. ncm = &nc->modes[NCSI_MODE_FC];
  491. if (ncm->enable)
  492. return -EBUSY;
  493. /* Update to flow control mode */
  494. cmd = (struct ncsi_cmd_snfc_pkt *)skb_network_header(nr->cmd);
  495. ncm->enable = 1;
  496. ncm->data[0] = cmd->mode;
  497. return 0;
  498. }
  499. static int ncsi_rsp_handler_gvi(struct ncsi_request *nr)
  500. {
  501. struct ncsi_rsp_gvi_pkt *rsp;
  502. struct ncsi_dev_priv *ndp = nr->ndp;
  503. struct ncsi_channel *nc;
  504. struct ncsi_channel_version *ncv;
  505. int i;
  506. /* Find the channel */
  507. rsp = (struct ncsi_rsp_gvi_pkt *)skb_network_header(nr->rsp);
  508. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  509. NULL, &nc);
  510. if (!nc)
  511. return -ENODEV;
  512. /* Update to channel's version info */
  513. ncv = &nc->version;
  514. ncv->version = ntohl(rsp->ncsi_version);
  515. ncv->alpha2 = rsp->alpha2;
  516. memcpy(ncv->fw_name, rsp->fw_name, 12);
  517. ncv->fw_version = ntohl(rsp->fw_version);
  518. for (i = 0; i < ARRAY_SIZE(ncv->pci_ids); i++)
  519. ncv->pci_ids[i] = ntohs(rsp->pci_ids[i]);
  520. ncv->mf_id = ntohl(rsp->mf_id);
  521. return 0;
  522. }
  523. static int ncsi_rsp_handler_gc(struct ncsi_request *nr)
  524. {
  525. struct ncsi_rsp_gc_pkt *rsp;
  526. struct ncsi_dev_priv *ndp = nr->ndp;
  527. struct ncsi_channel *nc;
  528. struct ncsi_channel_filter *ncf;
  529. size_t size, entry_size;
  530. int cnt, i;
  531. /* Find the channel */
  532. rsp = (struct ncsi_rsp_gc_pkt *)skb_network_header(nr->rsp);
  533. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  534. NULL, &nc);
  535. if (!nc)
  536. return -ENODEV;
  537. /* Update channel's capabilities */
  538. nc->caps[NCSI_CAP_GENERIC].cap = ntohl(rsp->cap) &
  539. NCSI_CAP_GENERIC_MASK;
  540. nc->caps[NCSI_CAP_BC].cap = ntohl(rsp->bc_cap) &
  541. NCSI_CAP_BC_MASK;
  542. nc->caps[NCSI_CAP_MC].cap = ntohl(rsp->mc_cap) &
  543. NCSI_CAP_MC_MASK;
  544. nc->caps[NCSI_CAP_BUFFER].cap = ntohl(rsp->buf_cap);
  545. nc->caps[NCSI_CAP_AEN].cap = ntohl(rsp->aen_cap) &
  546. NCSI_CAP_AEN_MASK;
  547. nc->caps[NCSI_CAP_VLAN].cap = rsp->vlan_mode &
  548. NCSI_CAP_VLAN_MASK;
  549. /* Build filters */
  550. for (i = 0; i < NCSI_FILTER_MAX; i++) {
  551. switch (i) {
  552. case NCSI_FILTER_VLAN:
  553. cnt = rsp->vlan_cnt;
  554. entry_size = 2;
  555. break;
  556. case NCSI_FILTER_MIXED:
  557. cnt = rsp->mixed_cnt;
  558. entry_size = 6;
  559. break;
  560. case NCSI_FILTER_MC:
  561. cnt = rsp->mc_cnt;
  562. entry_size = 6;
  563. break;
  564. case NCSI_FILTER_UC:
  565. cnt = rsp->uc_cnt;
  566. entry_size = 6;
  567. break;
  568. default:
  569. continue;
  570. }
  571. if (!cnt || nc->filters[i])
  572. continue;
  573. size = sizeof(*ncf) + cnt * entry_size;
  574. ncf = kzalloc(size, GFP_ATOMIC);
  575. if (!ncf) {
  576. pr_warn("%s: Cannot alloc filter table (%d)\n",
  577. __func__, i);
  578. return -ENOMEM;
  579. }
  580. ncf->index = i;
  581. ncf->total = cnt;
  582. ncf->bitmap = 0x0ul;
  583. nc->filters[i] = ncf;
  584. }
  585. return 0;
  586. }
  587. static int ncsi_rsp_handler_gp(struct ncsi_request *nr)
  588. {
  589. struct ncsi_rsp_gp_pkt *rsp;
  590. struct ncsi_dev_priv *ndp = nr->ndp;
  591. struct ncsi_channel *nc;
  592. unsigned short enable, vlan;
  593. unsigned char *pdata;
  594. int table, i;
  595. /* Find the channel */
  596. rsp = (struct ncsi_rsp_gp_pkt *)skb_network_header(nr->rsp);
  597. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  598. NULL, &nc);
  599. if (!nc)
  600. return -ENODEV;
  601. /* Modes with explicit enabled indications */
  602. if (ntohl(rsp->valid_modes) & 0x1) { /* BC filter mode */
  603. nc->modes[NCSI_MODE_BC].enable = 1;
  604. nc->modes[NCSI_MODE_BC].data[0] = ntohl(rsp->bc_mode);
  605. }
  606. if (ntohl(rsp->valid_modes) & 0x2) /* Channel enabled */
  607. nc->modes[NCSI_MODE_ENABLE].enable = 1;
  608. if (ntohl(rsp->valid_modes) & 0x4) /* Channel Tx enabled */
  609. nc->modes[NCSI_MODE_TX_ENABLE].enable = 1;
  610. if (ntohl(rsp->valid_modes) & 0x8) /* MC filter mode */
  611. nc->modes[NCSI_MODE_MC].enable = 1;
  612. /* Modes without explicit enabled indications */
  613. nc->modes[NCSI_MODE_LINK].enable = 1;
  614. nc->modes[NCSI_MODE_LINK].data[0] = ntohl(rsp->link_mode);
  615. nc->modes[NCSI_MODE_VLAN].enable = 1;
  616. nc->modes[NCSI_MODE_VLAN].data[0] = rsp->vlan_mode;
  617. nc->modes[NCSI_MODE_FC].enable = 1;
  618. nc->modes[NCSI_MODE_FC].data[0] = rsp->fc_mode;
  619. nc->modes[NCSI_MODE_AEN].enable = 1;
  620. nc->modes[NCSI_MODE_AEN].data[0] = ntohl(rsp->aen_mode);
  621. /* MAC addresses filter table */
  622. pdata = (unsigned char *)rsp + 48;
  623. enable = rsp->mac_enable;
  624. for (i = 0; i < rsp->mac_cnt; i++, pdata += 6) {
  625. if (i >= (nc->filters[NCSI_FILTER_UC]->total +
  626. nc->filters[NCSI_FILTER_MC]->total))
  627. table = NCSI_FILTER_MIXED;
  628. else if (i >= nc->filters[NCSI_FILTER_UC]->total)
  629. table = NCSI_FILTER_MC;
  630. else
  631. table = NCSI_FILTER_UC;
  632. if (!(enable & (0x1 << i)))
  633. continue;
  634. if (ncsi_find_filter(nc, table, pdata) >= 0)
  635. continue;
  636. ncsi_add_filter(nc, table, pdata);
  637. }
  638. /* VLAN filter table */
  639. enable = ntohs(rsp->vlan_enable);
  640. for (i = 0; i < rsp->vlan_cnt; i++, pdata += 2) {
  641. if (!(enable & (0x1 << i)))
  642. continue;
  643. vlan = ntohs(*(__be16 *)pdata);
  644. if (ncsi_find_filter(nc, NCSI_FILTER_VLAN, &vlan) >= 0)
  645. continue;
  646. ncsi_add_filter(nc, NCSI_FILTER_VLAN, &vlan);
  647. }
  648. return 0;
  649. }
  650. static int ncsi_rsp_handler_gcps(struct ncsi_request *nr)
  651. {
  652. struct ncsi_rsp_gcps_pkt *rsp;
  653. struct ncsi_dev_priv *ndp = nr->ndp;
  654. struct ncsi_channel *nc;
  655. struct ncsi_channel_stats *ncs;
  656. /* Find the channel */
  657. rsp = (struct ncsi_rsp_gcps_pkt *)skb_network_header(nr->rsp);
  658. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  659. NULL, &nc);
  660. if (!nc)
  661. return -ENODEV;
  662. /* Update HNC's statistics */
  663. ncs = &nc->stats;
  664. ncs->hnc_cnt_hi = ntohl(rsp->cnt_hi);
  665. ncs->hnc_cnt_lo = ntohl(rsp->cnt_lo);
  666. ncs->hnc_rx_bytes = ntohl(rsp->rx_bytes);
  667. ncs->hnc_tx_bytes = ntohl(rsp->tx_bytes);
  668. ncs->hnc_rx_uc_pkts = ntohl(rsp->rx_uc_pkts);
  669. ncs->hnc_rx_mc_pkts = ntohl(rsp->rx_mc_pkts);
  670. ncs->hnc_rx_bc_pkts = ntohl(rsp->rx_bc_pkts);
  671. ncs->hnc_tx_uc_pkts = ntohl(rsp->tx_uc_pkts);
  672. ncs->hnc_tx_mc_pkts = ntohl(rsp->tx_mc_pkts);
  673. ncs->hnc_tx_bc_pkts = ntohl(rsp->tx_bc_pkts);
  674. ncs->hnc_fcs_err = ntohl(rsp->fcs_err);
  675. ncs->hnc_align_err = ntohl(rsp->align_err);
  676. ncs->hnc_false_carrier = ntohl(rsp->false_carrier);
  677. ncs->hnc_runt_pkts = ntohl(rsp->runt_pkts);
  678. ncs->hnc_jabber_pkts = ntohl(rsp->jabber_pkts);
  679. ncs->hnc_rx_pause_xon = ntohl(rsp->rx_pause_xon);
  680. ncs->hnc_rx_pause_xoff = ntohl(rsp->rx_pause_xoff);
  681. ncs->hnc_tx_pause_xon = ntohl(rsp->tx_pause_xon);
  682. ncs->hnc_tx_pause_xoff = ntohl(rsp->tx_pause_xoff);
  683. ncs->hnc_tx_s_collision = ntohl(rsp->tx_s_collision);
  684. ncs->hnc_tx_m_collision = ntohl(rsp->tx_m_collision);
  685. ncs->hnc_l_collision = ntohl(rsp->l_collision);
  686. ncs->hnc_e_collision = ntohl(rsp->e_collision);
  687. ncs->hnc_rx_ctl_frames = ntohl(rsp->rx_ctl_frames);
  688. ncs->hnc_rx_64_frames = ntohl(rsp->rx_64_frames);
  689. ncs->hnc_rx_127_frames = ntohl(rsp->rx_127_frames);
  690. ncs->hnc_rx_255_frames = ntohl(rsp->rx_255_frames);
  691. ncs->hnc_rx_511_frames = ntohl(rsp->rx_511_frames);
  692. ncs->hnc_rx_1023_frames = ntohl(rsp->rx_1023_frames);
  693. ncs->hnc_rx_1522_frames = ntohl(rsp->rx_1522_frames);
  694. ncs->hnc_rx_9022_frames = ntohl(rsp->rx_9022_frames);
  695. ncs->hnc_tx_64_frames = ntohl(rsp->tx_64_frames);
  696. ncs->hnc_tx_127_frames = ntohl(rsp->tx_127_frames);
  697. ncs->hnc_tx_255_frames = ntohl(rsp->tx_255_frames);
  698. ncs->hnc_tx_511_frames = ntohl(rsp->tx_511_frames);
  699. ncs->hnc_tx_1023_frames = ntohl(rsp->tx_1023_frames);
  700. ncs->hnc_tx_1522_frames = ntohl(rsp->tx_1522_frames);
  701. ncs->hnc_tx_9022_frames = ntohl(rsp->tx_9022_frames);
  702. ncs->hnc_rx_valid_bytes = ntohl(rsp->rx_valid_bytes);
  703. ncs->hnc_rx_runt_pkts = ntohl(rsp->rx_runt_pkts);
  704. ncs->hnc_rx_jabber_pkts = ntohl(rsp->rx_jabber_pkts);
  705. return 0;
  706. }
  707. static int ncsi_rsp_handler_gns(struct ncsi_request *nr)
  708. {
  709. struct ncsi_rsp_gns_pkt *rsp;
  710. struct ncsi_dev_priv *ndp = nr->ndp;
  711. struct ncsi_channel *nc;
  712. struct ncsi_channel_stats *ncs;
  713. /* Find the channel */
  714. rsp = (struct ncsi_rsp_gns_pkt *)skb_network_header(nr->rsp);
  715. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  716. NULL, &nc);
  717. if (!nc)
  718. return -ENODEV;
  719. /* Update HNC's statistics */
  720. ncs = &nc->stats;
  721. ncs->ncsi_rx_cmds = ntohl(rsp->rx_cmds);
  722. ncs->ncsi_dropped_cmds = ntohl(rsp->dropped_cmds);
  723. ncs->ncsi_cmd_type_errs = ntohl(rsp->cmd_type_errs);
  724. ncs->ncsi_cmd_csum_errs = ntohl(rsp->cmd_csum_errs);
  725. ncs->ncsi_rx_pkts = ntohl(rsp->rx_pkts);
  726. ncs->ncsi_tx_pkts = ntohl(rsp->tx_pkts);
  727. ncs->ncsi_tx_aen_pkts = ntohl(rsp->tx_aen_pkts);
  728. return 0;
  729. }
  730. static int ncsi_rsp_handler_gnpts(struct ncsi_request *nr)
  731. {
  732. struct ncsi_rsp_gnpts_pkt *rsp;
  733. struct ncsi_dev_priv *ndp = nr->ndp;
  734. struct ncsi_channel *nc;
  735. struct ncsi_channel_stats *ncs;
  736. /* Find the channel */
  737. rsp = (struct ncsi_rsp_gnpts_pkt *)skb_network_header(nr->rsp);
  738. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  739. NULL, &nc);
  740. if (!nc)
  741. return -ENODEV;
  742. /* Update HNC's statistics */
  743. ncs = &nc->stats;
  744. ncs->pt_tx_pkts = ntohl(rsp->tx_pkts);
  745. ncs->pt_tx_dropped = ntohl(rsp->tx_dropped);
  746. ncs->pt_tx_channel_err = ntohl(rsp->tx_channel_err);
  747. ncs->pt_tx_us_err = ntohl(rsp->tx_us_err);
  748. ncs->pt_rx_pkts = ntohl(rsp->rx_pkts);
  749. ncs->pt_rx_dropped = ntohl(rsp->rx_dropped);
  750. ncs->pt_rx_channel_err = ntohl(rsp->rx_channel_err);
  751. ncs->pt_rx_us_err = ntohl(rsp->rx_us_err);
  752. ncs->pt_rx_os_err = ntohl(rsp->rx_os_err);
  753. return 0;
  754. }
  755. static int ncsi_rsp_handler_gps(struct ncsi_request *nr)
  756. {
  757. struct ncsi_rsp_gps_pkt *rsp;
  758. struct ncsi_dev_priv *ndp = nr->ndp;
  759. struct ncsi_package *np;
  760. /* Find the package */
  761. rsp = (struct ncsi_rsp_gps_pkt *)skb_network_header(nr->rsp);
  762. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  763. &np, NULL);
  764. if (!np)
  765. return -ENODEV;
  766. return 0;
  767. }
  768. static int ncsi_rsp_handler_gpuuid(struct ncsi_request *nr)
  769. {
  770. struct ncsi_rsp_gpuuid_pkt *rsp;
  771. struct ncsi_dev_priv *ndp = nr->ndp;
  772. struct ncsi_package *np;
  773. /* Find the package */
  774. rsp = (struct ncsi_rsp_gpuuid_pkt *)skb_network_header(nr->rsp);
  775. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  776. &np, NULL);
  777. if (!np)
  778. return -ENODEV;
  779. memcpy(np->uuid, rsp->uuid, sizeof(rsp->uuid));
  780. return 0;
  781. }
  782. static struct ncsi_rsp_handler {
  783. unsigned char type;
  784. int payload;
  785. int (*handler)(struct ncsi_request *nr);
  786. } ncsi_rsp_handlers[] = {
  787. { NCSI_PKT_RSP_CIS, 4, ncsi_rsp_handler_cis },
  788. { NCSI_PKT_RSP_SP, 4, ncsi_rsp_handler_sp },
  789. { NCSI_PKT_RSP_DP, 4, ncsi_rsp_handler_dp },
  790. { NCSI_PKT_RSP_EC, 4, ncsi_rsp_handler_ec },
  791. { NCSI_PKT_RSP_DC, 4, ncsi_rsp_handler_dc },
  792. { NCSI_PKT_RSP_RC, 4, ncsi_rsp_handler_rc },
  793. { NCSI_PKT_RSP_ECNT, 4, ncsi_rsp_handler_ecnt },
  794. { NCSI_PKT_RSP_DCNT, 4, ncsi_rsp_handler_dcnt },
  795. { NCSI_PKT_RSP_AE, 4, ncsi_rsp_handler_ae },
  796. { NCSI_PKT_RSP_SL, 4, ncsi_rsp_handler_sl },
  797. { NCSI_PKT_RSP_GLS, 16, ncsi_rsp_handler_gls },
  798. { NCSI_PKT_RSP_SVF, 4, ncsi_rsp_handler_svf },
  799. { NCSI_PKT_RSP_EV, 4, ncsi_rsp_handler_ev },
  800. { NCSI_PKT_RSP_DV, 4, ncsi_rsp_handler_dv },
  801. { NCSI_PKT_RSP_SMA, 4, ncsi_rsp_handler_sma },
  802. { NCSI_PKT_RSP_EBF, 4, ncsi_rsp_handler_ebf },
  803. { NCSI_PKT_RSP_DBF, 4, ncsi_rsp_handler_dbf },
  804. { NCSI_PKT_RSP_EGMF, 4, ncsi_rsp_handler_egmf },
  805. { NCSI_PKT_RSP_DGMF, 4, ncsi_rsp_handler_dgmf },
  806. { NCSI_PKT_RSP_SNFC, 4, ncsi_rsp_handler_snfc },
  807. { NCSI_PKT_RSP_GVI, 36, ncsi_rsp_handler_gvi },
  808. { NCSI_PKT_RSP_GC, 32, ncsi_rsp_handler_gc },
  809. { NCSI_PKT_RSP_GP, -1, ncsi_rsp_handler_gp },
  810. { NCSI_PKT_RSP_GCPS, 172, ncsi_rsp_handler_gcps },
  811. { NCSI_PKT_RSP_GNS, 172, ncsi_rsp_handler_gns },
  812. { NCSI_PKT_RSP_GNPTS, 172, ncsi_rsp_handler_gnpts },
  813. { NCSI_PKT_RSP_GPS, 8, ncsi_rsp_handler_gps },
  814. { NCSI_PKT_RSP_OEM, 0, NULL },
  815. { NCSI_PKT_RSP_PLDM, 0, NULL },
  816. { NCSI_PKT_RSP_GPUUID, 20, ncsi_rsp_handler_gpuuid }
  817. };
  818. int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
  819. struct packet_type *pt, struct net_device *orig_dev)
  820. {
  821. struct ncsi_rsp_handler *nrh = NULL;
  822. struct ncsi_dev *nd;
  823. struct ncsi_dev_priv *ndp;
  824. struct ncsi_request *nr;
  825. struct ncsi_pkt_hdr *hdr;
  826. unsigned long flags;
  827. int payload, i, ret;
  828. /* Find the NCSI device */
  829. nd = ncsi_find_dev(dev);
  830. ndp = nd ? TO_NCSI_DEV_PRIV(nd) : NULL;
  831. if (!ndp)
  832. return -ENODEV;
  833. /* Check if it is AEN packet */
  834. hdr = (struct ncsi_pkt_hdr *)skb_network_header(skb);
  835. if (hdr->type == NCSI_PKT_AEN)
  836. return ncsi_aen_handler(ndp, skb);
  837. /* Find the handler */
  838. for (i = 0; i < ARRAY_SIZE(ncsi_rsp_handlers); i++) {
  839. if (ncsi_rsp_handlers[i].type == hdr->type) {
  840. if (ncsi_rsp_handlers[i].handler)
  841. nrh = &ncsi_rsp_handlers[i];
  842. else
  843. nrh = NULL;
  844. break;
  845. }
  846. }
  847. if (!nrh) {
  848. netdev_err(nd->dev, "Received unrecognized packet (0x%x)\n",
  849. hdr->type);
  850. return -ENOENT;
  851. }
  852. /* Associate with the request */
  853. spin_lock_irqsave(&ndp->lock, flags);
  854. nr = &ndp->requests[hdr->id];
  855. if (!nr->used) {
  856. spin_unlock_irqrestore(&ndp->lock, flags);
  857. return -ENODEV;
  858. }
  859. nr->rsp = skb;
  860. if (!nr->enabled) {
  861. spin_unlock_irqrestore(&ndp->lock, flags);
  862. ret = -ENOENT;
  863. goto out;
  864. }
  865. /* Validate the packet */
  866. spin_unlock_irqrestore(&ndp->lock, flags);
  867. payload = nrh->payload;
  868. if (payload < 0)
  869. payload = ntohs(hdr->length);
  870. ret = ncsi_validate_rsp_pkt(nr, payload);
  871. if (ret)
  872. goto out;
  873. /* Process the packet */
  874. ret = nrh->handler(nr);
  875. out:
  876. ncsi_free_request(nr);
  877. return ret;
  878. }