bfa_cee.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. /*
  2. * Copyright (c) 2005-2009 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 <defs/bfa_defs_cee.h>
  18. #include <cs/bfa_trc.h>
  19. #include <cs/bfa_log.h>
  20. #include <cs/bfa_debug.h>
  21. #include <cee/bfa_cee.h>
  22. #include <bfi/bfi_cee.h>
  23. #include <bfi/bfi.h>
  24. #include <bfa_ioc.h>
  25. #include <cna/bfa_cna_trcmod.h>
  26. BFA_TRC_FILE(CNA, CEE);
  27. #define bfa_ioc_portid(__ioc) ((__ioc)->port_id)
  28. #define bfa_lpuid(__arg) bfa_ioc_portid(&(__arg)->ioc)
  29. static void bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg_s *lldp_cfg);
  30. static void bfa_cee_format_dcbcx_stats(struct bfa_cee_dcbx_stats_s
  31. *dcbcx_stats);
  32. static void bfa_cee_format_lldp_stats(struct bfa_cee_lldp_stats_s
  33. *lldp_stats);
  34. static void bfa_cee_format_cfg_stats(struct bfa_cee_cfg_stats_s *cfg_stats);
  35. static void bfa_cee_format_cee_cfg(void *buffer);
  36. static void bfa_cee_format_cee_stats(void *buffer);
  37. static void
  38. bfa_cee_format_cee_stats(void *buffer)
  39. {
  40. struct bfa_cee_stats_s *cee_stats = buffer;
  41. bfa_cee_format_dcbcx_stats(&cee_stats->dcbx_stats);
  42. bfa_cee_format_lldp_stats(&cee_stats->lldp_stats);
  43. bfa_cee_format_cfg_stats(&cee_stats->cfg_stats);
  44. }
  45. static void
  46. bfa_cee_format_cee_cfg(void *buffer)
  47. {
  48. struct bfa_cee_attr_s *cee_cfg = buffer;
  49. bfa_cee_format_lldp_cfg(&cee_cfg->lldp_remote);
  50. }
  51. static void
  52. bfa_cee_format_dcbcx_stats(struct bfa_cee_dcbx_stats_s *dcbcx_stats)
  53. {
  54. dcbcx_stats->subtlvs_unrecognized =
  55. bfa_os_ntohl(dcbcx_stats->subtlvs_unrecognized);
  56. dcbcx_stats->negotiation_failed =
  57. bfa_os_ntohl(dcbcx_stats->negotiation_failed);
  58. dcbcx_stats->remote_cfg_changed =
  59. bfa_os_ntohl(dcbcx_stats->remote_cfg_changed);
  60. dcbcx_stats->tlvs_received = bfa_os_ntohl(dcbcx_stats->tlvs_received);
  61. dcbcx_stats->tlvs_invalid = bfa_os_ntohl(dcbcx_stats->tlvs_invalid);
  62. dcbcx_stats->seqno = bfa_os_ntohl(dcbcx_stats->seqno);
  63. dcbcx_stats->ackno = bfa_os_ntohl(dcbcx_stats->ackno);
  64. dcbcx_stats->recvd_seqno = bfa_os_ntohl(dcbcx_stats->recvd_seqno);
  65. dcbcx_stats->recvd_ackno = bfa_os_ntohl(dcbcx_stats->recvd_ackno);
  66. }
  67. static void
  68. bfa_cee_format_lldp_stats(struct bfa_cee_lldp_stats_s *lldp_stats)
  69. {
  70. lldp_stats->frames_transmitted =
  71. bfa_os_ntohl(lldp_stats->frames_transmitted);
  72. lldp_stats->frames_aged_out = bfa_os_ntohl(lldp_stats->frames_aged_out);
  73. lldp_stats->frames_discarded =
  74. bfa_os_ntohl(lldp_stats->frames_discarded);
  75. lldp_stats->frames_in_error = bfa_os_ntohl(lldp_stats->frames_in_error);
  76. lldp_stats->frames_rcvd = bfa_os_ntohl(lldp_stats->frames_rcvd);
  77. lldp_stats->tlvs_discarded = bfa_os_ntohl(lldp_stats->tlvs_discarded);
  78. lldp_stats->tlvs_unrecognized =
  79. bfa_os_ntohl(lldp_stats->tlvs_unrecognized);
  80. }
  81. static void
  82. bfa_cee_format_cfg_stats(struct bfa_cee_cfg_stats_s *cfg_stats)
  83. {
  84. cfg_stats->cee_status_down = bfa_os_ntohl(cfg_stats->cee_status_down);
  85. cfg_stats->cee_status_up = bfa_os_ntohl(cfg_stats->cee_status_up);
  86. cfg_stats->cee_hw_cfg_changed =
  87. bfa_os_ntohl(cfg_stats->cee_hw_cfg_changed);
  88. cfg_stats->recvd_invalid_cfg =
  89. bfa_os_ntohl(cfg_stats->recvd_invalid_cfg);
  90. }
  91. static void
  92. bfa_cee_format_lldp_cfg(struct bfa_cee_lldp_cfg_s *lldp_cfg)
  93. {
  94. lldp_cfg->time_to_interval = bfa_os_ntohs(lldp_cfg->time_to_interval);
  95. lldp_cfg->enabled_system_cap =
  96. bfa_os_ntohs(lldp_cfg->enabled_system_cap);
  97. }
  98. /**
  99. * bfa_cee_attr_meminfo()
  100. *
  101. *
  102. * @param[in] void
  103. *
  104. * @return Size of DMA region
  105. */
  106. static u32
  107. bfa_cee_attr_meminfo(void)
  108. {
  109. return BFA_ROUNDUP(sizeof(struct bfa_cee_attr_s), BFA_DMA_ALIGN_SZ);
  110. }
  111. /**
  112. * bfa_cee_stats_meminfo()
  113. *
  114. *
  115. * @param[in] void
  116. *
  117. * @return Size of DMA region
  118. */
  119. static u32
  120. bfa_cee_stats_meminfo(void)
  121. {
  122. return BFA_ROUNDUP(sizeof(struct bfa_cee_stats_s), BFA_DMA_ALIGN_SZ);
  123. }
  124. /**
  125. * bfa_cee_get_attr_isr()
  126. *
  127. *
  128. * @param[in] cee - Pointer to the CEE module
  129. * status - Return status from the f/w
  130. *
  131. * @return void
  132. */
  133. static void
  134. bfa_cee_get_attr_isr(struct bfa_cee_s *cee, bfa_status_t status)
  135. {
  136. cee->get_attr_status = status;
  137. bfa_trc(cee, 0);
  138. if (status == BFA_STATUS_OK) {
  139. bfa_trc(cee, 0);
  140. /*
  141. * The requested data has been copied to the DMA area, *process
  142. * it.
  143. */
  144. memcpy(cee->attr, cee->attr_dma.kva,
  145. sizeof(struct bfa_cee_attr_s));
  146. bfa_cee_format_cee_cfg(cee->attr);
  147. }
  148. cee->get_attr_pending = BFA_FALSE;
  149. if (cee->cbfn.get_attr_cbfn) {
  150. bfa_trc(cee, 0);
  151. cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg, status);
  152. }
  153. bfa_trc(cee, 0);
  154. }
  155. /**
  156. * bfa_cee_get_attr_isr()
  157. *
  158. *
  159. * @param[in] cee - Pointer to the CEE module
  160. * status - Return status from the f/w
  161. *
  162. * @return void
  163. */
  164. static void
  165. bfa_cee_get_stats_isr(struct bfa_cee_s *cee, bfa_status_t status)
  166. {
  167. cee->get_stats_status = status;
  168. bfa_trc(cee, 0);
  169. if (status == BFA_STATUS_OK) {
  170. bfa_trc(cee, 0);
  171. /*
  172. * The requested data has been copied to the DMA area, process
  173. * it.
  174. */
  175. memcpy(cee->stats, cee->stats_dma.kva,
  176. sizeof(struct bfa_cee_stats_s));
  177. bfa_cee_format_cee_stats(cee->stats);
  178. }
  179. cee->get_stats_pending = BFA_FALSE;
  180. bfa_trc(cee, 0);
  181. if (cee->cbfn.get_stats_cbfn) {
  182. bfa_trc(cee, 0);
  183. cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg, status);
  184. }
  185. bfa_trc(cee, 0);
  186. }
  187. /**
  188. * bfa_cee_get_attr_isr()
  189. *
  190. *
  191. * @param[in] cee - Pointer to the CEE module
  192. * status - Return status from the f/w
  193. *
  194. * @return void
  195. */
  196. static void
  197. bfa_cee_reset_stats_isr(struct bfa_cee_s *cee, bfa_status_t status)
  198. {
  199. cee->reset_stats_status = status;
  200. cee->reset_stats_pending = BFA_FALSE;
  201. if (cee->cbfn.reset_stats_cbfn)
  202. cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg, status);
  203. }
  204. /**
  205. * bfa_cee_meminfo()
  206. *
  207. *
  208. * @param[in] void
  209. *
  210. * @return Size of DMA region
  211. */
  212. u32
  213. bfa_cee_meminfo(void)
  214. {
  215. return bfa_cee_attr_meminfo() + bfa_cee_stats_meminfo();
  216. }
  217. /**
  218. * bfa_cee_mem_claim()
  219. *
  220. *
  221. * @param[in] cee CEE module pointer
  222. * dma_kva Kernel Virtual Address of CEE DMA Memory
  223. * dma_pa Physical Address of CEE DMA Memory
  224. *
  225. * @return void
  226. */
  227. void
  228. bfa_cee_mem_claim(struct bfa_cee_s *cee, u8 *dma_kva, u64 dma_pa)
  229. {
  230. cee->attr_dma.kva = dma_kva;
  231. cee->attr_dma.pa = dma_pa;
  232. cee->stats_dma.kva = dma_kva + bfa_cee_attr_meminfo();
  233. cee->stats_dma.pa = dma_pa + bfa_cee_attr_meminfo();
  234. cee->attr = (struct bfa_cee_attr_s *)dma_kva;
  235. cee->stats =
  236. (struct bfa_cee_stats_s *)(dma_kva + bfa_cee_attr_meminfo());
  237. }
  238. /**
  239. * bfa_cee_get_attr()
  240. *
  241. * Send the request to the f/w to fetch CEE attributes.
  242. *
  243. * @param[in] Pointer to the CEE module data structure.
  244. *
  245. * @return Status
  246. */
  247. bfa_status_t
  248. bfa_cee_get_attr(struct bfa_cee_s *cee, struct bfa_cee_attr_s *attr,
  249. bfa_cee_get_attr_cbfn_t cbfn, void *cbarg)
  250. {
  251. struct bfi_cee_get_req_s *cmd;
  252. bfa_assert((cee != NULL) && (cee->ioc != NULL));
  253. bfa_trc(cee, 0);
  254. if (!bfa_ioc_is_operational(cee->ioc)) {
  255. bfa_trc(cee, 0);
  256. return BFA_STATUS_IOC_FAILURE;
  257. }
  258. if (cee->get_attr_pending == BFA_TRUE) {
  259. bfa_trc(cee, 0);
  260. return BFA_STATUS_DEVBUSY;
  261. }
  262. cee->get_attr_pending = BFA_TRUE;
  263. cmd = (struct bfi_cee_get_req_s *)cee->get_cfg_mb.msg;
  264. cee->attr = attr;
  265. cee->cbfn.get_attr_cbfn = cbfn;
  266. cee->cbfn.get_attr_cbarg = cbarg;
  267. bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_CFG_REQ,
  268. bfa_ioc_portid(cee->ioc));
  269. bfa_dma_be_addr_set(cmd->dma_addr, cee->attr_dma.pa);
  270. bfa_ioc_mbox_queue(cee->ioc, &cee->get_cfg_mb);
  271. bfa_trc(cee, 0);
  272. return BFA_STATUS_OK;
  273. }
  274. /**
  275. * bfa_cee_get_stats()
  276. *
  277. * Send the request to the f/w to fetch CEE statistics.
  278. *
  279. * @param[in] Pointer to the CEE module data structure.
  280. *
  281. * @return Status
  282. */
  283. bfa_status_t
  284. bfa_cee_get_stats(struct bfa_cee_s *cee, struct bfa_cee_stats_s *stats,
  285. bfa_cee_get_stats_cbfn_t cbfn, void *cbarg)
  286. {
  287. struct bfi_cee_get_req_s *cmd;
  288. bfa_assert((cee != NULL) && (cee->ioc != NULL));
  289. if (!bfa_ioc_is_operational(cee->ioc)) {
  290. bfa_trc(cee, 0);
  291. return BFA_STATUS_IOC_FAILURE;
  292. }
  293. if (cee->get_stats_pending == BFA_TRUE) {
  294. bfa_trc(cee, 0);
  295. return BFA_STATUS_DEVBUSY;
  296. }
  297. cee->get_stats_pending = BFA_TRUE;
  298. cmd = (struct bfi_cee_get_req_s *)cee->get_stats_mb.msg;
  299. cee->stats = stats;
  300. cee->cbfn.get_stats_cbfn = cbfn;
  301. cee->cbfn.get_stats_cbarg = cbarg;
  302. bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_GET_STATS_REQ,
  303. bfa_ioc_portid(cee->ioc));
  304. bfa_dma_be_addr_set(cmd->dma_addr, cee->stats_dma.pa);
  305. bfa_ioc_mbox_queue(cee->ioc, &cee->get_stats_mb);
  306. bfa_trc(cee, 0);
  307. return BFA_STATUS_OK;
  308. }
  309. /**
  310. * bfa_cee_reset_stats()
  311. *
  312. *
  313. * @param[in] Pointer to the CEE module data structure.
  314. *
  315. * @return Status
  316. */
  317. bfa_status_t
  318. bfa_cee_reset_stats(struct bfa_cee_s *cee, bfa_cee_reset_stats_cbfn_t cbfn,
  319. void *cbarg)
  320. {
  321. struct bfi_cee_reset_stats_s *cmd;
  322. bfa_assert((cee != NULL) && (cee->ioc != NULL));
  323. if (!bfa_ioc_is_operational(cee->ioc)) {
  324. bfa_trc(cee, 0);
  325. return BFA_STATUS_IOC_FAILURE;
  326. }
  327. if (cee->reset_stats_pending == BFA_TRUE) {
  328. bfa_trc(cee, 0);
  329. return BFA_STATUS_DEVBUSY;
  330. }
  331. cee->reset_stats_pending = BFA_TRUE;
  332. cmd = (struct bfi_cee_reset_stats_s *)cee->reset_stats_mb.msg;
  333. cee->cbfn.reset_stats_cbfn = cbfn;
  334. cee->cbfn.reset_stats_cbarg = cbarg;
  335. bfi_h2i_set(cmd->mh, BFI_MC_CEE, BFI_CEE_H2I_RESET_STATS,
  336. bfa_ioc_portid(cee->ioc));
  337. bfa_ioc_mbox_queue(cee->ioc, &cee->reset_stats_mb);
  338. bfa_trc(cee, 0);
  339. return BFA_STATUS_OK;
  340. }
  341. /**
  342. * bfa_cee_isrs()
  343. *
  344. *
  345. * @param[in] Pointer to the CEE module data structure.
  346. *
  347. * @return void
  348. */
  349. void
  350. bfa_cee_isr(void *cbarg, struct bfi_mbmsg_s *m)
  351. {
  352. union bfi_cee_i2h_msg_u *msg;
  353. struct bfi_cee_get_rsp_s *get_rsp;
  354. struct bfa_cee_s *cee = (struct bfa_cee_s *)cbarg;
  355. msg = (union bfi_cee_i2h_msg_u *)m;
  356. get_rsp = (struct bfi_cee_get_rsp_s *)m;
  357. bfa_trc(cee, msg->mh.msg_id);
  358. switch (msg->mh.msg_id) {
  359. case BFI_CEE_I2H_GET_CFG_RSP:
  360. bfa_trc(cee, get_rsp->cmd_status);
  361. bfa_cee_get_attr_isr(cee, get_rsp->cmd_status);
  362. break;
  363. case BFI_CEE_I2H_GET_STATS_RSP:
  364. bfa_cee_get_stats_isr(cee, get_rsp->cmd_status);
  365. break;
  366. case BFI_CEE_I2H_RESET_STATS_RSP:
  367. bfa_cee_reset_stats_isr(cee, get_rsp->cmd_status);
  368. break;
  369. default:
  370. bfa_assert(0);
  371. }
  372. }
  373. /**
  374. * bfa_cee_hbfail()
  375. *
  376. *
  377. * @param[in] Pointer to the CEE module data structure.
  378. *
  379. * @return void
  380. */
  381. void
  382. bfa_cee_hbfail(void *arg)
  383. {
  384. struct bfa_cee_s *cee;
  385. cee = (struct bfa_cee_s *)arg;
  386. if (cee->get_attr_pending == BFA_TRUE) {
  387. cee->get_attr_status = BFA_STATUS_FAILED;
  388. cee->get_attr_pending = BFA_FALSE;
  389. if (cee->cbfn.get_attr_cbfn) {
  390. cee->cbfn.get_attr_cbfn(cee->cbfn.get_attr_cbarg,
  391. BFA_STATUS_FAILED);
  392. }
  393. }
  394. if (cee->get_stats_pending == BFA_TRUE) {
  395. cee->get_stats_status = BFA_STATUS_FAILED;
  396. cee->get_stats_pending = BFA_FALSE;
  397. if (cee->cbfn.get_stats_cbfn) {
  398. cee->cbfn.get_stats_cbfn(cee->cbfn.get_stats_cbarg,
  399. BFA_STATUS_FAILED);
  400. }
  401. }
  402. if (cee->reset_stats_pending == BFA_TRUE) {
  403. cee->reset_stats_status = BFA_STATUS_FAILED;
  404. cee->reset_stats_pending = BFA_FALSE;
  405. if (cee->cbfn.reset_stats_cbfn) {
  406. cee->cbfn.reset_stats_cbfn(cee->cbfn.reset_stats_cbarg,
  407. BFA_STATUS_FAILED);
  408. }
  409. }
  410. }
  411. /**
  412. * bfa_cee_attach()
  413. *
  414. *
  415. * @param[in] cee - Pointer to the CEE module data structure
  416. * ioc - Pointer to the ioc module data structure
  417. * dev - Pointer to the device driver module data structure
  418. * The device driver specific mbox ISR functions have
  419. * this pointer as one of the parameters.
  420. * trcmod -
  421. * logmod -
  422. *
  423. * @return void
  424. */
  425. void
  426. bfa_cee_attach(struct bfa_cee_s *cee, struct bfa_ioc_s *ioc, void *dev,
  427. struct bfa_trc_mod_s *trcmod, struct bfa_log_mod_s *logmod)
  428. {
  429. bfa_assert(cee != NULL);
  430. cee->dev = dev;
  431. cee->trcmod = trcmod;
  432. cee->logmod = logmod;
  433. cee->ioc = ioc;
  434. bfa_ioc_mbox_regisr(cee->ioc, BFI_MC_CEE, bfa_cee_isr, cee);
  435. bfa_ioc_hbfail_init(&cee->hbfail, bfa_cee_hbfail, cee);
  436. bfa_ioc_hbfail_register(cee->ioc, &cee->hbfail);
  437. bfa_trc(cee, 0);
  438. }
  439. /**
  440. * bfa_cee_detach()
  441. *
  442. *
  443. * @param[in] cee - Pointer to the CEE module data structure
  444. *
  445. * @return void
  446. */
  447. void
  448. bfa_cee_detach(struct bfa_cee_s *cee)
  449. {
  450. /*
  451. * For now, just check if there is some ioctl pending and mark that as
  452. * failed?
  453. */
  454. /* bfa_cee_hbfail(cee); */
  455. }