ncsi-rsp.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155
  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 <net/genetlink.h>
  18. #include "internal.h"
  19. #include "ncsi-pkt.h"
  20. #include "ncsi-netlink.h"
  21. static int ncsi_validate_rsp_pkt(struct ncsi_request *nr,
  22. unsigned short payload)
  23. {
  24. struct ncsi_rsp_pkt_hdr *h;
  25. u32 checksum;
  26. __be32 *pchecksum;
  27. /* Check NCSI packet header. We don't need validate
  28. * the packet type, which should have been checked
  29. * before calling this function.
  30. */
  31. h = (struct ncsi_rsp_pkt_hdr *)skb_network_header(nr->rsp);
  32. if (h->common.revision != NCSI_PKT_REVISION) {
  33. netdev_dbg(nr->ndp->ndev.dev,
  34. "NCSI: unsupported header revision\n");
  35. return -EINVAL;
  36. }
  37. if (ntohs(h->common.length) != payload) {
  38. netdev_dbg(nr->ndp->ndev.dev,
  39. "NCSI: payload length mismatched\n");
  40. return -EINVAL;
  41. }
  42. /* Check on code and reason */
  43. if (ntohs(h->code) != NCSI_PKT_RSP_C_COMPLETED ||
  44. ntohs(h->reason) != NCSI_PKT_RSP_R_NO_ERROR) {
  45. netdev_dbg(nr->ndp->ndev.dev,
  46. "NCSI: non zero response/reason code\n");
  47. return -EPERM;
  48. }
  49. /* Validate checksum, which might be zeroes if the
  50. * sender doesn't support checksum according to NCSI
  51. * specification.
  52. */
  53. pchecksum = (__be32 *)((void *)(h + 1) + payload - 4);
  54. if (ntohl(*pchecksum) == 0)
  55. return 0;
  56. checksum = ncsi_calculate_checksum((unsigned char *)h,
  57. sizeof(*h) + payload - 4);
  58. if (*pchecksum != htonl(checksum)) {
  59. netdev_dbg(nr->ndp->ndev.dev, "NCSI: checksum mismatched\n");
  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 = 1;
  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. memset(&ncf->addrs[index], 0, ETH_ALEN);
  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 Broadcom command Get Mac Address */
  509. static int ncsi_rsp_handler_oem_bcm_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[BCM_MAC_ADDR_OFFSET], ETH_ALEN);
  522. /* Increase mac address by 1 for BMC's address */
  523. saddr.sa_data[ETH_ALEN - 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 Broadcom card */
  530. static int ncsi_rsp_handler_oem_bcm(struct ncsi_request *nr)
  531. {
  532. struct ncsi_rsp_oem_bcm_pkt *bcm;
  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. bcm = (struct ncsi_rsp_oem_bcm_pkt *)(rsp->data);
  537. if (bcm->type == NCSI_OEM_BCM_CMD_GMA)
  538. return ncsi_rsp_handler_oem_bcm_gma(nr);
  539. return 0;
  540. }
  541. static struct ncsi_rsp_oem_handler {
  542. unsigned int mfr_id;
  543. int (*handler)(struct ncsi_request *nr);
  544. } ncsi_rsp_oem_handlers[] = {
  545. { NCSI_OEM_MFR_MLX_ID, NULL },
  546. { NCSI_OEM_MFR_BCM_ID, ncsi_rsp_handler_oem_bcm }
  547. };
  548. /* Response handler for OEM command */
  549. static int ncsi_rsp_handler_oem(struct ncsi_request *nr)
  550. {
  551. struct ncsi_rsp_oem_handler *nrh = NULL;
  552. struct ncsi_rsp_oem_pkt *rsp;
  553. unsigned int mfr_id, i;
  554. /* Get the response header */
  555. rsp = (struct ncsi_rsp_oem_pkt *)skb_network_header(nr->rsp);
  556. mfr_id = ntohl(rsp->mfr_id);
  557. /* Check for manufacturer id and Find the handler */
  558. for (i = 0; i < ARRAY_SIZE(ncsi_rsp_oem_handlers); i++) {
  559. if (ncsi_rsp_oem_handlers[i].mfr_id == mfr_id) {
  560. if (ncsi_rsp_oem_handlers[i].handler)
  561. nrh = &ncsi_rsp_oem_handlers[i];
  562. else
  563. nrh = NULL;
  564. break;
  565. }
  566. }
  567. if (!nrh) {
  568. netdev_err(nr->ndp->ndev.dev, "Received unrecognized OEM packet with MFR-ID (0x%x)\n",
  569. mfr_id);
  570. return -ENOENT;
  571. }
  572. /* Process the packet */
  573. return nrh->handler(nr);
  574. }
  575. static int ncsi_rsp_handler_gvi(struct ncsi_request *nr)
  576. {
  577. struct ncsi_rsp_gvi_pkt *rsp;
  578. struct ncsi_dev_priv *ndp = nr->ndp;
  579. struct ncsi_channel *nc;
  580. struct ncsi_channel_version *ncv;
  581. int i;
  582. /* Find the channel */
  583. rsp = (struct ncsi_rsp_gvi_pkt *)skb_network_header(nr->rsp);
  584. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  585. NULL, &nc);
  586. if (!nc)
  587. return -ENODEV;
  588. /* Update to channel's version info */
  589. ncv = &nc->version;
  590. ncv->version = ntohl(rsp->ncsi_version);
  591. ncv->alpha2 = rsp->alpha2;
  592. memcpy(ncv->fw_name, rsp->fw_name, 12);
  593. ncv->fw_version = ntohl(rsp->fw_version);
  594. for (i = 0; i < ARRAY_SIZE(ncv->pci_ids); i++)
  595. ncv->pci_ids[i] = ntohs(rsp->pci_ids[i]);
  596. ncv->mf_id = ntohl(rsp->mf_id);
  597. return 0;
  598. }
  599. static int ncsi_rsp_handler_gc(struct ncsi_request *nr)
  600. {
  601. struct ncsi_rsp_gc_pkt *rsp;
  602. struct ncsi_dev_priv *ndp = nr->ndp;
  603. struct ncsi_channel *nc;
  604. size_t size;
  605. /* Find the channel */
  606. rsp = (struct ncsi_rsp_gc_pkt *)skb_network_header(nr->rsp);
  607. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  608. NULL, &nc);
  609. if (!nc)
  610. return -ENODEV;
  611. /* Update channel's capabilities */
  612. nc->caps[NCSI_CAP_GENERIC].cap = ntohl(rsp->cap) &
  613. NCSI_CAP_GENERIC_MASK;
  614. nc->caps[NCSI_CAP_BC].cap = ntohl(rsp->bc_cap) &
  615. NCSI_CAP_BC_MASK;
  616. nc->caps[NCSI_CAP_MC].cap = ntohl(rsp->mc_cap) &
  617. NCSI_CAP_MC_MASK;
  618. nc->caps[NCSI_CAP_BUFFER].cap = ntohl(rsp->buf_cap);
  619. nc->caps[NCSI_CAP_AEN].cap = ntohl(rsp->aen_cap) &
  620. NCSI_CAP_AEN_MASK;
  621. nc->caps[NCSI_CAP_VLAN].cap = rsp->vlan_mode &
  622. NCSI_CAP_VLAN_MASK;
  623. size = (rsp->uc_cnt + rsp->mc_cnt + rsp->mixed_cnt) * ETH_ALEN;
  624. nc->mac_filter.addrs = kzalloc(size, GFP_ATOMIC);
  625. if (!nc->mac_filter.addrs)
  626. return -ENOMEM;
  627. nc->mac_filter.n_uc = rsp->uc_cnt;
  628. nc->mac_filter.n_mc = rsp->mc_cnt;
  629. nc->mac_filter.n_mixed = rsp->mixed_cnt;
  630. nc->vlan_filter.vids = kcalloc(rsp->vlan_cnt,
  631. sizeof(*nc->vlan_filter.vids),
  632. GFP_ATOMIC);
  633. if (!nc->vlan_filter.vids)
  634. return -ENOMEM;
  635. /* Set VLAN filters active so they are cleared in the first
  636. * configuration state
  637. */
  638. nc->vlan_filter.bitmap = U64_MAX;
  639. nc->vlan_filter.n_vids = rsp->vlan_cnt;
  640. return 0;
  641. }
  642. static int ncsi_rsp_handler_gp(struct ncsi_request *nr)
  643. {
  644. struct ncsi_channel_vlan_filter *ncvf;
  645. struct ncsi_channel_mac_filter *ncmf;
  646. struct ncsi_dev_priv *ndp = nr->ndp;
  647. struct ncsi_rsp_gp_pkt *rsp;
  648. struct ncsi_channel *nc;
  649. unsigned short enable;
  650. unsigned char *pdata;
  651. unsigned long flags;
  652. void *bitmap;
  653. int i;
  654. /* Find the channel */
  655. rsp = (struct ncsi_rsp_gp_pkt *)skb_network_header(nr->rsp);
  656. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  657. NULL, &nc);
  658. if (!nc)
  659. return -ENODEV;
  660. /* Modes with explicit enabled indications */
  661. if (ntohl(rsp->valid_modes) & 0x1) { /* BC filter mode */
  662. nc->modes[NCSI_MODE_BC].enable = 1;
  663. nc->modes[NCSI_MODE_BC].data[0] = ntohl(rsp->bc_mode);
  664. }
  665. if (ntohl(rsp->valid_modes) & 0x2) /* Channel enabled */
  666. nc->modes[NCSI_MODE_ENABLE].enable = 1;
  667. if (ntohl(rsp->valid_modes) & 0x4) /* Channel Tx enabled */
  668. nc->modes[NCSI_MODE_TX_ENABLE].enable = 1;
  669. if (ntohl(rsp->valid_modes) & 0x8) /* MC filter mode */
  670. nc->modes[NCSI_MODE_MC].enable = 1;
  671. /* Modes without explicit enabled indications */
  672. nc->modes[NCSI_MODE_LINK].enable = 1;
  673. nc->modes[NCSI_MODE_LINK].data[0] = ntohl(rsp->link_mode);
  674. nc->modes[NCSI_MODE_VLAN].enable = 1;
  675. nc->modes[NCSI_MODE_VLAN].data[0] = rsp->vlan_mode;
  676. nc->modes[NCSI_MODE_FC].enable = 1;
  677. nc->modes[NCSI_MODE_FC].data[0] = rsp->fc_mode;
  678. nc->modes[NCSI_MODE_AEN].enable = 1;
  679. nc->modes[NCSI_MODE_AEN].data[0] = ntohl(rsp->aen_mode);
  680. /* MAC addresses filter table */
  681. pdata = (unsigned char *)rsp + 48;
  682. enable = rsp->mac_enable;
  683. ncmf = &nc->mac_filter;
  684. spin_lock_irqsave(&nc->lock, flags);
  685. bitmap = &ncmf->bitmap;
  686. for (i = 0; i < rsp->mac_cnt; i++, pdata += 6) {
  687. if (!(enable & (0x1 << i)))
  688. clear_bit(i, bitmap);
  689. else
  690. set_bit(i, bitmap);
  691. memcpy(&ncmf->addrs[i * ETH_ALEN], pdata, ETH_ALEN);
  692. }
  693. spin_unlock_irqrestore(&nc->lock, flags);
  694. /* VLAN filter table */
  695. enable = ntohs(rsp->vlan_enable);
  696. ncvf = &nc->vlan_filter;
  697. bitmap = &ncvf->bitmap;
  698. spin_lock_irqsave(&nc->lock, flags);
  699. for (i = 0; i < rsp->vlan_cnt; i++, pdata += 2) {
  700. if (!(enable & (0x1 << i)))
  701. clear_bit(i, bitmap);
  702. else
  703. set_bit(i, bitmap);
  704. ncvf->vids[i] = ntohs(*(__be16 *)pdata);
  705. }
  706. spin_unlock_irqrestore(&nc->lock, flags);
  707. return 0;
  708. }
  709. static int ncsi_rsp_handler_gcps(struct ncsi_request *nr)
  710. {
  711. struct ncsi_rsp_gcps_pkt *rsp;
  712. struct ncsi_dev_priv *ndp = nr->ndp;
  713. struct ncsi_channel *nc;
  714. struct ncsi_channel_stats *ncs;
  715. /* Find the channel */
  716. rsp = (struct ncsi_rsp_gcps_pkt *)skb_network_header(nr->rsp);
  717. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  718. NULL, &nc);
  719. if (!nc)
  720. return -ENODEV;
  721. /* Update HNC's statistics */
  722. ncs = &nc->stats;
  723. ncs->hnc_cnt_hi = ntohl(rsp->cnt_hi);
  724. ncs->hnc_cnt_lo = ntohl(rsp->cnt_lo);
  725. ncs->hnc_rx_bytes = ntohl(rsp->rx_bytes);
  726. ncs->hnc_tx_bytes = ntohl(rsp->tx_bytes);
  727. ncs->hnc_rx_uc_pkts = ntohl(rsp->rx_uc_pkts);
  728. ncs->hnc_rx_mc_pkts = ntohl(rsp->rx_mc_pkts);
  729. ncs->hnc_rx_bc_pkts = ntohl(rsp->rx_bc_pkts);
  730. ncs->hnc_tx_uc_pkts = ntohl(rsp->tx_uc_pkts);
  731. ncs->hnc_tx_mc_pkts = ntohl(rsp->tx_mc_pkts);
  732. ncs->hnc_tx_bc_pkts = ntohl(rsp->tx_bc_pkts);
  733. ncs->hnc_fcs_err = ntohl(rsp->fcs_err);
  734. ncs->hnc_align_err = ntohl(rsp->align_err);
  735. ncs->hnc_false_carrier = ntohl(rsp->false_carrier);
  736. ncs->hnc_runt_pkts = ntohl(rsp->runt_pkts);
  737. ncs->hnc_jabber_pkts = ntohl(rsp->jabber_pkts);
  738. ncs->hnc_rx_pause_xon = ntohl(rsp->rx_pause_xon);
  739. ncs->hnc_rx_pause_xoff = ntohl(rsp->rx_pause_xoff);
  740. ncs->hnc_tx_pause_xon = ntohl(rsp->tx_pause_xon);
  741. ncs->hnc_tx_pause_xoff = ntohl(rsp->tx_pause_xoff);
  742. ncs->hnc_tx_s_collision = ntohl(rsp->tx_s_collision);
  743. ncs->hnc_tx_m_collision = ntohl(rsp->tx_m_collision);
  744. ncs->hnc_l_collision = ntohl(rsp->l_collision);
  745. ncs->hnc_e_collision = ntohl(rsp->e_collision);
  746. ncs->hnc_rx_ctl_frames = ntohl(rsp->rx_ctl_frames);
  747. ncs->hnc_rx_64_frames = ntohl(rsp->rx_64_frames);
  748. ncs->hnc_rx_127_frames = ntohl(rsp->rx_127_frames);
  749. ncs->hnc_rx_255_frames = ntohl(rsp->rx_255_frames);
  750. ncs->hnc_rx_511_frames = ntohl(rsp->rx_511_frames);
  751. ncs->hnc_rx_1023_frames = ntohl(rsp->rx_1023_frames);
  752. ncs->hnc_rx_1522_frames = ntohl(rsp->rx_1522_frames);
  753. ncs->hnc_rx_9022_frames = ntohl(rsp->rx_9022_frames);
  754. ncs->hnc_tx_64_frames = ntohl(rsp->tx_64_frames);
  755. ncs->hnc_tx_127_frames = ntohl(rsp->tx_127_frames);
  756. ncs->hnc_tx_255_frames = ntohl(rsp->tx_255_frames);
  757. ncs->hnc_tx_511_frames = ntohl(rsp->tx_511_frames);
  758. ncs->hnc_tx_1023_frames = ntohl(rsp->tx_1023_frames);
  759. ncs->hnc_tx_1522_frames = ntohl(rsp->tx_1522_frames);
  760. ncs->hnc_tx_9022_frames = ntohl(rsp->tx_9022_frames);
  761. ncs->hnc_rx_valid_bytes = ntohl(rsp->rx_valid_bytes);
  762. ncs->hnc_rx_runt_pkts = ntohl(rsp->rx_runt_pkts);
  763. ncs->hnc_rx_jabber_pkts = ntohl(rsp->rx_jabber_pkts);
  764. return 0;
  765. }
  766. static int ncsi_rsp_handler_gns(struct ncsi_request *nr)
  767. {
  768. struct ncsi_rsp_gns_pkt *rsp;
  769. struct ncsi_dev_priv *ndp = nr->ndp;
  770. struct ncsi_channel *nc;
  771. struct ncsi_channel_stats *ncs;
  772. /* Find the channel */
  773. rsp = (struct ncsi_rsp_gns_pkt *)skb_network_header(nr->rsp);
  774. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  775. NULL, &nc);
  776. if (!nc)
  777. return -ENODEV;
  778. /* Update HNC's statistics */
  779. ncs = &nc->stats;
  780. ncs->ncsi_rx_cmds = ntohl(rsp->rx_cmds);
  781. ncs->ncsi_dropped_cmds = ntohl(rsp->dropped_cmds);
  782. ncs->ncsi_cmd_type_errs = ntohl(rsp->cmd_type_errs);
  783. ncs->ncsi_cmd_csum_errs = ntohl(rsp->cmd_csum_errs);
  784. ncs->ncsi_rx_pkts = ntohl(rsp->rx_pkts);
  785. ncs->ncsi_tx_pkts = ntohl(rsp->tx_pkts);
  786. ncs->ncsi_tx_aen_pkts = ntohl(rsp->tx_aen_pkts);
  787. return 0;
  788. }
  789. static int ncsi_rsp_handler_gnpts(struct ncsi_request *nr)
  790. {
  791. struct ncsi_rsp_gnpts_pkt *rsp;
  792. struct ncsi_dev_priv *ndp = nr->ndp;
  793. struct ncsi_channel *nc;
  794. struct ncsi_channel_stats *ncs;
  795. /* Find the channel */
  796. rsp = (struct ncsi_rsp_gnpts_pkt *)skb_network_header(nr->rsp);
  797. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  798. NULL, &nc);
  799. if (!nc)
  800. return -ENODEV;
  801. /* Update HNC's statistics */
  802. ncs = &nc->stats;
  803. ncs->pt_tx_pkts = ntohl(rsp->tx_pkts);
  804. ncs->pt_tx_dropped = ntohl(rsp->tx_dropped);
  805. ncs->pt_tx_channel_err = ntohl(rsp->tx_channel_err);
  806. ncs->pt_tx_us_err = ntohl(rsp->tx_us_err);
  807. ncs->pt_rx_pkts = ntohl(rsp->rx_pkts);
  808. ncs->pt_rx_dropped = ntohl(rsp->rx_dropped);
  809. ncs->pt_rx_channel_err = ntohl(rsp->rx_channel_err);
  810. ncs->pt_rx_us_err = ntohl(rsp->rx_us_err);
  811. ncs->pt_rx_os_err = ntohl(rsp->rx_os_err);
  812. return 0;
  813. }
  814. static int ncsi_rsp_handler_gps(struct ncsi_request *nr)
  815. {
  816. struct ncsi_rsp_gps_pkt *rsp;
  817. struct ncsi_dev_priv *ndp = nr->ndp;
  818. struct ncsi_package *np;
  819. /* Find the package */
  820. rsp = (struct ncsi_rsp_gps_pkt *)skb_network_header(nr->rsp);
  821. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  822. &np, NULL);
  823. if (!np)
  824. return -ENODEV;
  825. return 0;
  826. }
  827. static int ncsi_rsp_handler_gpuuid(struct ncsi_request *nr)
  828. {
  829. struct ncsi_rsp_gpuuid_pkt *rsp;
  830. struct ncsi_dev_priv *ndp = nr->ndp;
  831. struct ncsi_package *np;
  832. /* Find the package */
  833. rsp = (struct ncsi_rsp_gpuuid_pkt *)skb_network_header(nr->rsp);
  834. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  835. &np, NULL);
  836. if (!np)
  837. return -ENODEV;
  838. memcpy(np->uuid, rsp->uuid, sizeof(rsp->uuid));
  839. return 0;
  840. }
  841. static int ncsi_rsp_handler_netlink(struct ncsi_request *nr)
  842. {
  843. struct ncsi_dev_priv *ndp = nr->ndp;
  844. struct ncsi_rsp_pkt *rsp;
  845. struct ncsi_package *np;
  846. struct ncsi_channel *nc;
  847. int ret;
  848. /* Find the package */
  849. rsp = (struct ncsi_rsp_pkt *)skb_network_header(nr->rsp);
  850. ncsi_find_package_and_channel(ndp, rsp->rsp.common.channel,
  851. &np, &nc);
  852. if (!np)
  853. return -ENODEV;
  854. ret = ncsi_send_netlink_rsp(nr, np, nc);
  855. return ret;
  856. }
  857. static struct ncsi_rsp_handler {
  858. unsigned char type;
  859. int payload;
  860. int (*handler)(struct ncsi_request *nr);
  861. } ncsi_rsp_handlers[] = {
  862. { NCSI_PKT_RSP_CIS, 4, ncsi_rsp_handler_cis },
  863. { NCSI_PKT_RSP_SP, 4, ncsi_rsp_handler_sp },
  864. { NCSI_PKT_RSP_DP, 4, ncsi_rsp_handler_dp },
  865. { NCSI_PKT_RSP_EC, 4, ncsi_rsp_handler_ec },
  866. { NCSI_PKT_RSP_DC, 4, ncsi_rsp_handler_dc },
  867. { NCSI_PKT_RSP_RC, 4, ncsi_rsp_handler_rc },
  868. { NCSI_PKT_RSP_ECNT, 4, ncsi_rsp_handler_ecnt },
  869. { NCSI_PKT_RSP_DCNT, 4, ncsi_rsp_handler_dcnt },
  870. { NCSI_PKT_RSP_AE, 4, ncsi_rsp_handler_ae },
  871. { NCSI_PKT_RSP_SL, 4, ncsi_rsp_handler_sl },
  872. { NCSI_PKT_RSP_GLS, 16, ncsi_rsp_handler_gls },
  873. { NCSI_PKT_RSP_SVF, 4, ncsi_rsp_handler_svf },
  874. { NCSI_PKT_RSP_EV, 4, ncsi_rsp_handler_ev },
  875. { NCSI_PKT_RSP_DV, 4, ncsi_rsp_handler_dv },
  876. { NCSI_PKT_RSP_SMA, 4, ncsi_rsp_handler_sma },
  877. { NCSI_PKT_RSP_EBF, 4, ncsi_rsp_handler_ebf },
  878. { NCSI_PKT_RSP_DBF, 4, ncsi_rsp_handler_dbf },
  879. { NCSI_PKT_RSP_EGMF, 4, ncsi_rsp_handler_egmf },
  880. { NCSI_PKT_RSP_DGMF, 4, ncsi_rsp_handler_dgmf },
  881. { NCSI_PKT_RSP_SNFC, 4, ncsi_rsp_handler_snfc },
  882. { NCSI_PKT_RSP_GVI, 40, ncsi_rsp_handler_gvi },
  883. { NCSI_PKT_RSP_GC, 32, ncsi_rsp_handler_gc },
  884. { NCSI_PKT_RSP_GP, -1, ncsi_rsp_handler_gp },
  885. { NCSI_PKT_RSP_GCPS, 172, ncsi_rsp_handler_gcps },
  886. { NCSI_PKT_RSP_GNS, 172, ncsi_rsp_handler_gns },
  887. { NCSI_PKT_RSP_GNPTS, 172, ncsi_rsp_handler_gnpts },
  888. { NCSI_PKT_RSP_GPS, 8, ncsi_rsp_handler_gps },
  889. { NCSI_PKT_RSP_OEM, -1, ncsi_rsp_handler_oem },
  890. { NCSI_PKT_RSP_PLDM, 0, NULL },
  891. { NCSI_PKT_RSP_GPUUID, 20, ncsi_rsp_handler_gpuuid }
  892. };
  893. int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev,
  894. struct packet_type *pt, struct net_device *orig_dev)
  895. {
  896. struct ncsi_rsp_handler *nrh = NULL;
  897. struct ncsi_dev *nd;
  898. struct ncsi_dev_priv *ndp;
  899. struct ncsi_request *nr;
  900. struct ncsi_pkt_hdr *hdr;
  901. unsigned long flags;
  902. int payload, i, ret;
  903. /* Find the NCSI device */
  904. nd = ncsi_find_dev(dev);
  905. ndp = nd ? TO_NCSI_DEV_PRIV(nd) : NULL;
  906. if (!ndp)
  907. return -ENODEV;
  908. /* Check if it is AEN packet */
  909. hdr = (struct ncsi_pkt_hdr *)skb_network_header(skb);
  910. if (hdr->type == NCSI_PKT_AEN)
  911. return ncsi_aen_handler(ndp, skb);
  912. /* Find the handler */
  913. for (i = 0; i < ARRAY_SIZE(ncsi_rsp_handlers); i++) {
  914. if (ncsi_rsp_handlers[i].type == hdr->type) {
  915. if (ncsi_rsp_handlers[i].handler)
  916. nrh = &ncsi_rsp_handlers[i];
  917. else
  918. nrh = NULL;
  919. break;
  920. }
  921. }
  922. if (!nrh) {
  923. netdev_err(nd->dev, "Received unrecognized packet (0x%x)\n",
  924. hdr->type);
  925. return -ENOENT;
  926. }
  927. /* Associate with the request */
  928. spin_lock_irqsave(&ndp->lock, flags);
  929. nr = &ndp->requests[hdr->id];
  930. if (!nr->used) {
  931. spin_unlock_irqrestore(&ndp->lock, flags);
  932. return -ENODEV;
  933. }
  934. nr->rsp = skb;
  935. if (!nr->enabled) {
  936. spin_unlock_irqrestore(&ndp->lock, flags);
  937. ret = -ENOENT;
  938. goto out;
  939. }
  940. /* Validate the packet */
  941. spin_unlock_irqrestore(&ndp->lock, flags);
  942. payload = nrh->payload;
  943. if (payload < 0)
  944. payload = ntohs(hdr->length);
  945. ret = ncsi_validate_rsp_pkt(nr, payload);
  946. if (ret) {
  947. netdev_warn(ndp->ndev.dev,
  948. "NCSI: 'bad' packet ignored for type 0x%x\n",
  949. hdr->type);
  950. if (nr->flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) {
  951. if (ret == -EPERM)
  952. goto out_netlink;
  953. else
  954. ncsi_send_netlink_err(ndp->ndev.dev,
  955. nr->snd_seq,
  956. nr->snd_portid,
  957. &nr->nlhdr,
  958. ret);
  959. }
  960. goto out;
  961. }
  962. /* Process the packet */
  963. ret = nrh->handler(nr);
  964. if (ret)
  965. netdev_err(ndp->ndev.dev,
  966. "NCSI: Handler for packet type 0x%x returned %d\n",
  967. hdr->type, ret);
  968. out_netlink:
  969. if (nr->flags == NCSI_REQ_FLAG_NETLINK_DRIVEN) {
  970. ret = ncsi_rsp_handler_netlink(nr);
  971. if (ret) {
  972. netdev_err(ndp->ndev.dev,
  973. "NCSI: Netlink handler for packet type 0x%x returned %d\n",
  974. hdr->type, ret);
  975. }
  976. }
  977. out:
  978. ncsi_free_request(nr);
  979. return ret;
  980. }