bfa_port.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  1. /*
  2. * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
  3. * All rights reserved
  4. * www.brocade.com
  5. *
  6. * Linux driver for Brocade Fibre Channel Host Bus Adapter.
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License (GPL) Version 2 as
  10. * published by the Free Software Foundation
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. */
  17. #include "bfad_drv.h"
  18. #include "bfa_defs_svc.h"
  19. #include "bfa_port.h"
  20. #include "bfi.h"
  21. #include "bfa_ioc.h"
  22. BFA_TRC_FILE(CNA, PORT);
  23. static void
  24. bfa_port_stats_swap(struct bfa_port_s *port, union bfa_port_stats_u *stats)
  25. {
  26. u32 *dip = (u32 *) stats;
  27. __be32 t0, t1;
  28. int i;
  29. for (i = 0; i < sizeof(union bfa_port_stats_u)/sizeof(u32);
  30. i += 2) {
  31. t0 = dip[i];
  32. t1 = dip[i + 1];
  33. #ifdef __BIG_ENDIAN
  34. dip[i] = be32_to_cpu(t0);
  35. dip[i + 1] = be32_to_cpu(t1);
  36. #else
  37. dip[i] = be32_to_cpu(t1);
  38. dip[i + 1] = be32_to_cpu(t0);
  39. #endif
  40. }
  41. }
  42. /*
  43. * bfa_port_enable_isr()
  44. *
  45. *
  46. * @param[in] port - Pointer to the port module
  47. * status - Return status from the f/w
  48. *
  49. * @return void
  50. */
  51. static void
  52. bfa_port_enable_isr(struct bfa_port_s *port, bfa_status_t status)
  53. {
  54. bfa_trc(port, status);
  55. port->endis_pending = BFA_FALSE;
  56. port->endis_cbfn(port->endis_cbarg, status);
  57. }
  58. /*
  59. * bfa_port_disable_isr()
  60. *
  61. *
  62. * @param[in] port - Pointer to the port module
  63. * status - Return status from the f/w
  64. *
  65. * @return void
  66. */
  67. static void
  68. bfa_port_disable_isr(struct bfa_port_s *port, bfa_status_t status)
  69. {
  70. bfa_trc(port, status);
  71. port->endis_pending = BFA_FALSE;
  72. port->endis_cbfn(port->endis_cbarg, status);
  73. }
  74. /*
  75. * bfa_port_get_stats_isr()
  76. *
  77. *
  78. * @param[in] port - Pointer to the Port module
  79. * status - Return status from the f/w
  80. *
  81. * @return void
  82. */
  83. static void
  84. bfa_port_get_stats_isr(struct bfa_port_s *port, bfa_status_t status)
  85. {
  86. port->stats_status = status;
  87. port->stats_busy = BFA_FALSE;
  88. if (status == BFA_STATUS_OK) {
  89. struct timeval tv;
  90. memcpy(port->stats, port->stats_dma.kva,
  91. sizeof(union bfa_port_stats_u));
  92. bfa_port_stats_swap(port, port->stats);
  93. do_gettimeofday(&tv);
  94. port->stats->fc.secs_reset = tv.tv_sec - port->stats_reset_time;
  95. }
  96. if (port->stats_cbfn) {
  97. port->stats_cbfn(port->stats_cbarg, status);
  98. port->stats_cbfn = NULL;
  99. }
  100. }
  101. /*
  102. * bfa_port_clear_stats_isr()
  103. *
  104. *
  105. * @param[in] port - Pointer to the Port module
  106. * status - Return status from the f/w
  107. *
  108. * @return void
  109. */
  110. static void
  111. bfa_port_clear_stats_isr(struct bfa_port_s *port, bfa_status_t status)
  112. {
  113. struct timeval tv;
  114. port->stats_status = status;
  115. port->stats_busy = BFA_FALSE;
  116. /*
  117. * re-initialize time stamp for stats reset
  118. */
  119. do_gettimeofday(&tv);
  120. port->stats_reset_time = tv.tv_sec;
  121. if (port->stats_cbfn) {
  122. port->stats_cbfn(port->stats_cbarg, status);
  123. port->stats_cbfn = NULL;
  124. }
  125. }
  126. /*
  127. * bfa_port_isr()
  128. *
  129. *
  130. * @param[in] Pointer to the Port module data structure.
  131. *
  132. * @return void
  133. */
  134. static void
  135. bfa_port_isr(void *cbarg, struct bfi_mbmsg_s *m)
  136. {
  137. struct bfa_port_s *port = (struct bfa_port_s *) cbarg;
  138. union bfi_port_i2h_msg_u *i2hmsg;
  139. i2hmsg = (union bfi_port_i2h_msg_u *) m;
  140. bfa_trc(port, m->mh.msg_id);
  141. switch (m->mh.msg_id) {
  142. case BFI_PORT_I2H_ENABLE_RSP:
  143. if (port->endis_pending == BFA_FALSE)
  144. break;
  145. bfa_port_enable_isr(port, i2hmsg->enable_rsp.status);
  146. break;
  147. case BFI_PORT_I2H_DISABLE_RSP:
  148. if (port->endis_pending == BFA_FALSE)
  149. break;
  150. bfa_port_disable_isr(port, i2hmsg->disable_rsp.status);
  151. break;
  152. case BFI_PORT_I2H_GET_STATS_RSP:
  153. /* Stats busy flag is still set? (may be cmd timed out) */
  154. if (port->stats_busy == BFA_FALSE)
  155. break;
  156. bfa_port_get_stats_isr(port, i2hmsg->getstats_rsp.status);
  157. break;
  158. case BFI_PORT_I2H_CLEAR_STATS_RSP:
  159. if (port->stats_busy == BFA_FALSE)
  160. break;
  161. bfa_port_clear_stats_isr(port, i2hmsg->clearstats_rsp.status);
  162. break;
  163. default:
  164. WARN_ON(1);
  165. }
  166. }
  167. /*
  168. * bfa_port_meminfo()
  169. *
  170. *
  171. * @param[in] void
  172. *
  173. * @return Size of DMA region
  174. */
  175. u32
  176. bfa_port_meminfo(void)
  177. {
  178. return BFA_ROUNDUP(sizeof(union bfa_port_stats_u), BFA_DMA_ALIGN_SZ);
  179. }
  180. /*
  181. * bfa_port_mem_claim()
  182. *
  183. *
  184. * @param[in] port Port module pointer
  185. * dma_kva Kernel Virtual Address of Port DMA Memory
  186. * dma_pa Physical Address of Port DMA Memory
  187. *
  188. * @return void
  189. */
  190. void
  191. bfa_port_mem_claim(struct bfa_port_s *port, u8 *dma_kva, u64 dma_pa)
  192. {
  193. port->stats_dma.kva = dma_kva;
  194. port->stats_dma.pa = dma_pa;
  195. }
  196. /*
  197. * bfa_port_enable()
  198. *
  199. * Send the Port enable request to the f/w
  200. *
  201. * @param[in] Pointer to the Port module data structure.
  202. *
  203. * @return Status
  204. */
  205. bfa_status_t
  206. bfa_port_enable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn,
  207. void *cbarg)
  208. {
  209. struct bfi_port_generic_req_s *m;
  210. /* If port is PBC disabled, return error */
  211. if (port->pbc_disabled) {
  212. bfa_trc(port, BFA_STATUS_PBC);
  213. return BFA_STATUS_PBC;
  214. }
  215. if (bfa_ioc_is_disabled(port->ioc)) {
  216. bfa_trc(port, BFA_STATUS_IOC_DISABLED);
  217. return BFA_STATUS_IOC_DISABLED;
  218. }
  219. if (!bfa_ioc_is_operational(port->ioc)) {
  220. bfa_trc(port, BFA_STATUS_IOC_FAILURE);
  221. return BFA_STATUS_IOC_FAILURE;
  222. }
  223. if (port->endis_pending) {
  224. bfa_trc(port, BFA_STATUS_DEVBUSY);
  225. return BFA_STATUS_DEVBUSY;
  226. }
  227. m = (struct bfi_port_generic_req_s *) port->endis_mb.msg;
  228. port->msgtag++;
  229. port->endis_cbfn = cbfn;
  230. port->endis_cbarg = cbarg;
  231. port->endis_pending = BFA_TRUE;
  232. bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_ENABLE_REQ,
  233. bfa_ioc_portid(port->ioc));
  234. bfa_ioc_mbox_queue(port->ioc, &port->endis_mb);
  235. return BFA_STATUS_OK;
  236. }
  237. /*
  238. * bfa_port_disable()
  239. *
  240. * Send the Port disable request to the f/w
  241. *
  242. * @param[in] Pointer to the Port module data structure.
  243. *
  244. * @return Status
  245. */
  246. bfa_status_t
  247. bfa_port_disable(struct bfa_port_s *port, bfa_port_endis_cbfn_t cbfn,
  248. void *cbarg)
  249. {
  250. struct bfi_port_generic_req_s *m;
  251. /* If port is PBC disabled, return error */
  252. if (port->pbc_disabled) {
  253. bfa_trc(port, BFA_STATUS_PBC);
  254. return BFA_STATUS_PBC;
  255. }
  256. if (bfa_ioc_is_disabled(port->ioc)) {
  257. bfa_trc(port, BFA_STATUS_IOC_DISABLED);
  258. return BFA_STATUS_IOC_DISABLED;
  259. }
  260. if (!bfa_ioc_is_operational(port->ioc)) {
  261. bfa_trc(port, BFA_STATUS_IOC_FAILURE);
  262. return BFA_STATUS_IOC_FAILURE;
  263. }
  264. if (port->endis_pending) {
  265. bfa_trc(port, BFA_STATUS_DEVBUSY);
  266. return BFA_STATUS_DEVBUSY;
  267. }
  268. m = (struct bfi_port_generic_req_s *) port->endis_mb.msg;
  269. port->msgtag++;
  270. port->endis_cbfn = cbfn;
  271. port->endis_cbarg = cbarg;
  272. port->endis_pending = BFA_TRUE;
  273. bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_DISABLE_REQ,
  274. bfa_ioc_portid(port->ioc));
  275. bfa_ioc_mbox_queue(port->ioc, &port->endis_mb);
  276. return BFA_STATUS_OK;
  277. }
  278. /*
  279. * bfa_port_get_stats()
  280. *
  281. * Send the request to the f/w to fetch Port statistics.
  282. *
  283. * @param[in] Pointer to the Port module data structure.
  284. *
  285. * @return Status
  286. */
  287. bfa_status_t
  288. bfa_port_get_stats(struct bfa_port_s *port, union bfa_port_stats_u *stats,
  289. bfa_port_stats_cbfn_t cbfn, void *cbarg)
  290. {
  291. struct bfi_port_get_stats_req_s *m;
  292. if (!bfa_ioc_is_operational(port->ioc)) {
  293. bfa_trc(port, BFA_STATUS_IOC_FAILURE);
  294. return BFA_STATUS_IOC_FAILURE;
  295. }
  296. if (port->stats_busy) {
  297. bfa_trc(port, BFA_STATUS_DEVBUSY);
  298. return BFA_STATUS_DEVBUSY;
  299. }
  300. m = (struct bfi_port_get_stats_req_s *) port->stats_mb.msg;
  301. port->stats = stats;
  302. port->stats_cbfn = cbfn;
  303. port->stats_cbarg = cbarg;
  304. port->stats_busy = BFA_TRUE;
  305. bfa_dma_be_addr_set(m->dma_addr, port->stats_dma.pa);
  306. bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_GET_STATS_REQ,
  307. bfa_ioc_portid(port->ioc));
  308. bfa_ioc_mbox_queue(port->ioc, &port->stats_mb);
  309. return BFA_STATUS_OK;
  310. }
  311. /*
  312. * bfa_port_clear_stats()
  313. *
  314. *
  315. * @param[in] Pointer to the Port module data structure.
  316. *
  317. * @return Status
  318. */
  319. bfa_status_t
  320. bfa_port_clear_stats(struct bfa_port_s *port, bfa_port_stats_cbfn_t cbfn,
  321. void *cbarg)
  322. {
  323. struct bfi_port_generic_req_s *m;
  324. if (!bfa_ioc_is_operational(port->ioc)) {
  325. bfa_trc(port, BFA_STATUS_IOC_FAILURE);
  326. return BFA_STATUS_IOC_FAILURE;
  327. }
  328. if (port->stats_busy) {
  329. bfa_trc(port, BFA_STATUS_DEVBUSY);
  330. return BFA_STATUS_DEVBUSY;
  331. }
  332. m = (struct bfi_port_generic_req_s *) port->stats_mb.msg;
  333. port->stats_cbfn = cbfn;
  334. port->stats_cbarg = cbarg;
  335. port->stats_busy = BFA_TRUE;
  336. bfi_h2i_set(m->mh, BFI_MC_PORT, BFI_PORT_H2I_CLEAR_STATS_REQ,
  337. bfa_ioc_portid(port->ioc));
  338. bfa_ioc_mbox_queue(port->ioc, &port->stats_mb);
  339. return BFA_STATUS_OK;
  340. }
  341. /*
  342. * bfa_port_notify()
  343. *
  344. * Port module IOC event handler
  345. *
  346. * @param[in] Pointer to the Port module data structure.
  347. * @param[in] IOC event structure
  348. *
  349. * @return void
  350. */
  351. void
  352. bfa_port_notify(void *arg, enum bfa_ioc_event_e event)
  353. {
  354. struct bfa_port_s *port = (struct bfa_port_s *) arg;
  355. switch (event) {
  356. case BFA_IOC_E_DISABLED:
  357. case BFA_IOC_E_FAILED:
  358. /* Fail any pending get_stats/clear_stats requests */
  359. if (port->stats_busy) {
  360. if (port->stats_cbfn)
  361. port->stats_cbfn(port->stats_cbarg,
  362. BFA_STATUS_FAILED);
  363. port->stats_cbfn = NULL;
  364. port->stats_busy = BFA_FALSE;
  365. }
  366. /* Clear any enable/disable is pending */
  367. if (port->endis_pending) {
  368. if (port->endis_cbfn)
  369. port->endis_cbfn(port->endis_cbarg,
  370. BFA_STATUS_FAILED);
  371. port->endis_cbfn = NULL;
  372. port->endis_pending = BFA_FALSE;
  373. }
  374. break;
  375. default:
  376. break;
  377. }
  378. }
  379. /*
  380. * bfa_port_attach()
  381. *
  382. *
  383. * @param[in] port - Pointer to the Port module data structure
  384. * ioc - Pointer to the ioc module data structure
  385. * dev - Pointer to the device driver module data structure
  386. * The device driver specific mbox ISR functions have
  387. * this pointer as one of the parameters.
  388. * trcmod -
  389. *
  390. * @return void
  391. */
  392. void
  393. bfa_port_attach(struct bfa_port_s *port, struct bfa_ioc_s *ioc,
  394. void *dev, struct bfa_trc_mod_s *trcmod)
  395. {
  396. struct timeval tv;
  397. WARN_ON(!port);
  398. port->dev = dev;
  399. port->ioc = ioc;
  400. port->trcmod = trcmod;
  401. port->stats_busy = BFA_FALSE;
  402. port->endis_pending = BFA_FALSE;
  403. port->stats_cbfn = NULL;
  404. port->endis_cbfn = NULL;
  405. port->pbc_disabled = BFA_FALSE;
  406. bfa_ioc_mbox_regisr(port->ioc, BFI_MC_PORT, bfa_port_isr, port);
  407. bfa_q_qe_init(&port->ioc_notify);
  408. bfa_ioc_notify_init(&port->ioc_notify, bfa_port_notify, port);
  409. list_add_tail(&port->ioc_notify.qe, &port->ioc->notify_q);
  410. /*
  411. * initialize time stamp for stats reset
  412. */
  413. do_gettimeofday(&tv);
  414. port->stats_reset_time = tv.tv_sec;
  415. bfa_trc(port, 0);
  416. }
  417. /*
  418. * CEE module specific definitions
  419. */
  420. /*
  421. * bfa_cee_get_attr_isr()
  422. *
  423. * @brief CEE ISR for get-attributes responses from f/w
  424. *
  425. * @param[in] cee - Pointer to the CEE module
  426. * status - Return status from the f/w
  427. *
  428. * @return void
  429. */
  430. static void
  431. bfa_cee_get_attr_isr(struct bfa_cee_s *cee, bfa_status_t status)
  432. {
  433. struct bfa_cee_lldp_cfg_s *lldp_cfg = &cee->attr->lldp_remote;
  434. cee->get_attr_status = status;
  435. bfa_trc(cee, 0);
  436. if (status == BFA_STATUS_OK) {
  437. bfa_trc(cee, 0);
  438. memcpy(cee->attr, cee->attr_dma.kva,
  439. sizeof(struct bfa_cee_attr_s));
  440. lldp_cfg->time_to_live = be16_to_cpu(lldp_cfg->time_to_live);
  441. lldp_cfg->enabled_system_cap =
  442. be16_to_cpu(lldp_cfg->enabled_system_cap);
  443. }
  444. cee->get_attr_pending = BFA_FALSE;
  445. if (cee->cbfn.get_attr_cbfn) {
  446. bfa_trc(cee, 0);
  447. cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status);
  448. }
  449. }
  450. /*
  451. * bfa_cee_get_stats_isr()
  452. *
  453. * @brief CEE ISR for get-stats responses from f/w
  454. *
  455. * @param[in] cee - Pointer to the CEE module
  456. * status - Return status from the f/w
  457. *
  458. * @return void
  459. */
  460. static void
  461. bfa_cee_get_stats_isr(struct bfa_cee_s *cee, bfa_status_t status)
  462. {
  463. u32 *buffer;
  464. int i;
  465. cee->get_stats_status = status;
  466. bfa_trc(cee, 0);
  467. if (status == BFA_STATUS_OK) {
  468. bfa_trc(cee, 0);
  469. memcpy(cee->stats, cee->stats_dma.kva,
  470. sizeof(struct bfa_cee_stats_s));
  471. /* swap the cee stats */
  472. buffer = (u32 *)cee->stats;
  473. for (i = 0; i < (sizeof(struct bfa_cee_stats_s) /
  474. sizeof(u32)); i++)
  475. buffer[i] = cpu_to_be32(buffer[i]);
  476. }
  477. cee->get_stats_pending = BFA_FALSE;
  478. bfa_trc(cee, 0);
  479. if (cee->cbfn.get_stats_cbfn) {
  480. bfa_trc(cee, 0);
  481. cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status);
  482. }
  483. }
  484. /*
  485. * bfa_cee_reset_stats_isr()
  486. *
  487. * @brief CEE ISR for reset-stats responses from f/w
  488. *
  489. * @param[in] cee - Pointer to the CEE module
  490. * status - Return status from the f/w
  491. *
  492. * @return void
  493. */
  494. static void
  495. bfa_cee_reset_stats_isr(struct bfa_cee_s *cee, bfa_status_t status)
  496. {
  497. cee->reset_stats_status = status;
  498. cee->reset_stats_pending = BFA_FALSE;
  499. if (cee->cbfn.reset_stats_cbfn)
  500. cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status);
  501. }
  502. /*
  503. * bfa_cee_meminfo()
  504. *
  505. * @brief Returns the size of the DMA memory needed by CEE module
  506. *
  507. * @param[in] void
  508. *
  509. * @return Size of DMA region
  510. */
  511. u32
  512. bfa_cee_meminfo(void)
  513. {
  514. return BFA_ROUNDUP(sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ) +
  515. BFA_ROUNDUP(sizeof(struct bfa_cee_stats_s), BFA_DMA_ALIGN_SZ);
  516. }
  517. /*
  518. * bfa_cee_mem_claim()
  519. *
  520. * @brief Initialized CEE DMA Memory
  521. *
  522. * @param[in] cee CEE module pointer
  523. * dma_kva Kernel Virtual Address of CEE DMA Memory
  524. * dma_pa Physical Address of CEE DMA Memory
  525. *
  526. * @return void
  527. */
  528. void
  529. bfa_cee_mem_claim(struct bfa_cee_s *cee, u8 *dma_kva, u64 dma_pa)
  530. {
  531. cee->attr_dma.kva = dma_kva;
  532. cee->attr_dma.pa = dma_pa;
  533. cee->stats_dma.kva = dma_kva + BFA_ROUNDUP(
  534. sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ);
  535. cee->stats_dma.pa = dma_pa + BFA_ROUNDUP(
  536. sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ);
  537. cee->attr = (struct bfa_cee_attr_s *) dma_kva;
  538. cee->stats = (struct bfa_cee_stats_s *) (dma_kva + BFA_ROUNDUP(
  539. sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ));
  540. }
  541. /*
  542. * bfa_cee_get_attr()
  543. *
  544. * @brief
  545. * Send the request to the f/w to fetch CEE attributes.
  546. *
  547. * @param[in] Pointer to the CEE module data structure.
  548. *
  549. * @return Status
  550. */
  551. bfa_status_t
  552. bfa_cee_get_attr(struct bfa_cee_s *cee, struct bfa_cee_attr_s *attr,
  553. bfa_cee_get_attr_cbfn_t cbfn, void *cbarg)
  554. {
  555. struct bfi_cee_get_req_s *cmd;
  556. WARN_ON((cee == NULL) || (cee->ioc == NULL));
  557. bfa_trc(cee, 0);
  558. if (!bfa_ioc_is_operational(cee->ioc)) {
  559. bfa_trc(cee, 0);
  560. return BFA_STATUS_IOC_FAILURE;
  561. }
  562. if (cee->get_attr_pending == BFA_TRUE) {
  563. bfa_trc(cee, 0);
  564. return BFA_STATUS_DEVBUSY;
  565. }
  566. cee->get_attr_pending = BFA_TRUE;
  567. cmd = (struct bfi_cee_get_req_s *) cee->get_cfg_mb.msg;
  568. cee->attr = attr;
  569. cee->cbfn.get_attr_cbfn = cbfn;
  570. cee->cbfn.get_attr_cbarg = cbarg;
  571. bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_CFG_REQ,
  572. bfa_ioc_portid(cee->ioc));
  573. bfa_dma_be_addr_set(cmd->dma_addr, cee->attr_dma.pa);
  574. bfa_ioc_mbox_queue(cee->ioc, &cee->get_cfg_mb);
  575. return BFA_STATUS_OK;
  576. }
  577. /*
  578. * bfa_cee_get_stats()
  579. *
  580. * @brief
  581. * Send the request to the f/w to fetch CEE statistics.
  582. *
  583. * @param[in] Pointer to the CEE module data structure.
  584. *
  585. * @return Status
  586. */
  587. bfa_status_t
  588. bfa_cee_get_stats(struct bfa_cee_s *cee, struct bfa_cee_stats_s *stats,
  589. bfa_cee_get_stats_cbfn_t cbfn, void *cbarg)
  590. {
  591. struct bfi_cee_get_req_s *cmd;
  592. WARN_ON((cee == NULL) || (cee->ioc == NULL));
  593. if (!bfa_ioc_is_operational(cee->ioc)) {
  594. bfa_trc(cee, 0);
  595. return BFA_STATUS_IOC_FAILURE;
  596. }
  597. if (cee->get_stats_pending == BFA_TRUE) {
  598. bfa_trc(cee, 0);
  599. return BFA_STATUS_DEVBUSY;
  600. }
  601. cee->get_stats_pending = BFA_TRUE;
  602. cmd = (struct bfi_cee_get_req_s *) cee->get_stats_mb.msg;
  603. cee->stats = stats;
  604. cee->cbfn.get_stats_cbfn = cbfn;
  605. cee->cbfn.get_stats_cbarg = cbarg;
  606. bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_STATS_REQ,
  607. bfa_ioc_portid(cee->ioc));
  608. bfa_dma_be_addr_set(cmd->dma_addr, cee->stats_dma.pa);
  609. bfa_ioc_mbox_queue(cee->ioc, &cee->get_stats_mb);
  610. return BFA_STATUS_OK;
  611. }
  612. /*
  613. * bfa_cee_reset_stats()
  614. *
  615. * @brief Clears CEE Stats in the f/w.
  616. *
  617. * @param[in] Pointer to the CEE module data structure.
  618. *
  619. * @return Status
  620. */
  621. bfa_status_t
  622. bfa_cee_reset_stats(struct bfa_cee_s *cee,
  623. bfa_cee_reset_stats_cbfn_t cbfn, void *cbarg)
  624. {
  625. struct bfi_cee_reset_stats_s *cmd;
  626. WARN_ON((cee == NULL) || (cee->ioc == NULL));
  627. if (!bfa_ioc_is_operational(cee->ioc)) {
  628. bfa_trc(cee, 0);
  629. return BFA_STATUS_IOC_FAILURE;
  630. }
  631. if (cee->reset_stats_pending == BFA_TRUE) {
  632. bfa_trc(cee, 0);
  633. return BFA_STATUS_DEVBUSY;
  634. }
  635. cee->reset_stats_pending = BFA_TRUE;
  636. cmd = (struct bfi_cee_reset_stats_s *) cee->reset_stats_mb.msg;
  637. cee->cbfn.reset_stats_cbfn = cbfn;
  638. cee->cbfn.reset_stats_cbarg = cbarg;
  639. bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_RESET_STATS,
  640. bfa_ioc_portid(cee->ioc));
  641. bfa_ioc_mbox_queue(cee->ioc, &cee->reset_stats_mb);
  642. return BFA_STATUS_OK;
  643. }
  644. /*
  645. * bfa_cee_isrs()
  646. *
  647. * @brief Handles Mail-box interrupts for CEE module.
  648. *
  649. * @param[in] Pointer to the CEE module data structure.
  650. *
  651. * @return void
  652. */
  653. void
  654. bfa_cee_isr(void *cbarg, struct bfi_mbmsg_s *m)
  655. {
  656. union bfi_cee_i2h_msg_u *msg;
  657. struct bfi_cee_get_rsp_s *get_rsp;
  658. struct bfa_cee_s *cee = (struct bfa_cee_s *) cbarg;
  659. msg = (union bfi_cee_i2h_msg_u *) m;
  660. get_rsp = (struct bfi_cee_get_rsp_s *) m;
  661. bfa_trc(cee, msg->mh.msg_id);
  662. switch (msg->mh.msg_id) {
  663. case BFI_CEE_I2H_GET_CFG_RSP:
  664. bfa_trc(cee, get_rsp->cmd_status);
  665. bfa_cee_get_attr_isr(cee, get_rsp->cmd_status);
  666. break;
  667. case BFI_CEE_I2H_GET_STATS_RSP:
  668. bfa_cee_get_stats_isr(cee, get_rsp->cmd_status);
  669. break;
  670. case BFI_CEE_I2H_RESET_STATS_RSP:
  671. bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status);
  672. break;
  673. default:
  674. WARN_ON(1);
  675. }
  676. }
  677. /*
  678. * bfa_cee_notify()
  679. *
  680. * @brief CEE module IOC event handler.
  681. *
  682. * @param[in] Pointer to the CEE module data structure.
  683. * @param[in] IOC event type
  684. *
  685. * @return void
  686. */
  687. void
  688. bfa_cee_notify(void *arg, enum bfa_ioc_event_e event)
  689. {
  690. struct bfa_cee_s *cee = (struct bfa_cee_s *) arg;
  691. bfa_trc(cee, event);
  692. switch (event) {
  693. case BFA_IOC_E_DISABLED:
  694. case BFA_IOC_E_FAILED:
  695. if (cee->get_attr_pending == BFA_TRUE) {
  696. cee->get_attr_status = BFA_STATUS_FAILED;
  697. cee->get_attr_pending = BFA_FALSE;
  698. if (cee->cbfn.get_attr_cbfn) {
  699. cee->cbfn.get_attr_cbfn(
  700. cee->cbfn.get_attr_cbarg,
  701. BFA_STATUS_FAILED);
  702. }
  703. }
  704. if (cee->get_stats_pending == BFA_TRUE) {
  705. cee->get_stats_status = BFA_STATUS_FAILED;
  706. cee->get_stats_pending = BFA_FALSE;
  707. if (cee->cbfn.get_stats_cbfn) {
  708. cee->cbfn.get_stats_cbfn(
  709. cee->cbfn.get_stats_cbarg,
  710. BFA_STATUS_FAILED);
  711. }
  712. }
  713. if (cee->reset_stats_pending == BFA_TRUE) {
  714. cee->reset_stats_status = BFA_STATUS_FAILED;
  715. cee->reset_stats_pending = BFA_FALSE;
  716. if (cee->cbfn.reset_stats_cbfn) {
  717. cee->cbfn.reset_stats_cbfn(
  718. cee->cbfn.reset_stats_cbarg,
  719. BFA_STATUS_FAILED);
  720. }
  721. }
  722. break;
  723. default:
  724. break;
  725. }
  726. }
  727. /*
  728. * bfa_cee_attach()
  729. *
  730. * @brief CEE module-attach API
  731. *
  732. * @param[in] cee - Pointer to the CEE module data structure
  733. * ioc - Pointer to the ioc module data structure
  734. * dev - Pointer to the device driver module data structure
  735. * The device driver specific mbox ISR functions have
  736. * this pointer as one of the parameters.
  737. *
  738. * @return void
  739. */
  740. void
  741. bfa_cee_attach(struct bfa_cee_s *cee, struct bfa_ioc_s *ioc,
  742. void *dev)
  743. {
  744. WARN_ON(cee == NULL);
  745. cee->dev = dev;
  746. cee->ioc = ioc;
  747. bfa_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee);
  748. bfa_q_qe_init(&cee->ioc_notify);
  749. bfa_ioc_notify_init(&cee->ioc_notify, bfa_cee_notify, cee);
  750. list_add_tail(&cee->ioc_notify.qe, &cee->ioc->notify_q);
  751. }