ncsi-rsp.c 32 KB

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