bfa_ioc_ct.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  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 <bfa.h>
  18. #include <bfa_ioc.h>
  19. #include <bfa_fwimg_priv.h>
  20. #include <cna/bfa_cna_trcmod.h>
  21. #include <cs/bfa_debug.h>
  22. #include <bfi/bfi_ioc.h>
  23. #include <bfi/bfi_ctreg.h>
  24. #include <log/bfa_log_hal.h>
  25. #include <defs/bfa_defs_pci.h>
  26. BFA_TRC_FILE(CNA, IOC_CT);
  27. /*
  28. * forward declarations
  29. */
  30. static bfa_status_t bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc);
  31. static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc);
  32. static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc);
  33. static uint32_t* bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc,
  34. uint32_t off);
  35. static uint32_t bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc);
  36. static void bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc);
  37. static void bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc);
  38. static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
  39. static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc);
  40. static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc);
  41. struct bfa_ioc_hwif_s hwif_ct = {
  42. bfa_ioc_ct_pll_init,
  43. bfa_ioc_ct_firmware_lock,
  44. bfa_ioc_ct_firmware_unlock,
  45. bfa_ioc_ct_fwimg_get_chunk,
  46. bfa_ioc_ct_fwimg_get_size,
  47. bfa_ioc_ct_reg_init,
  48. bfa_ioc_ct_map_port,
  49. bfa_ioc_ct_isr_mode_set,
  50. bfa_ioc_ct_notify_hbfail,
  51. bfa_ioc_ct_ownership_reset,
  52. };
  53. /**
  54. * Called from bfa_ioc_attach() to map asic specific calls.
  55. */
  56. void
  57. bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc)
  58. {
  59. ioc->ioc_hwif = &hwif_ct;
  60. }
  61. static uint32_t*
  62. bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, uint32_t off)
  63. {
  64. return bfi_image_ct_get_chunk(off);
  65. }
  66. static uint32_t
  67. bfa_ioc_ct_fwimg_get_size(struct bfa_ioc_s *ioc)
  68. {
  69. return bfi_image_ct_size;
  70. }
  71. /**
  72. * Return true if firmware of current driver matches the running firmware.
  73. */
  74. static bfa_boolean_t
  75. bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
  76. {
  77. enum bfi_ioc_state ioc_fwstate;
  78. uint32_t usecnt;
  79. struct bfi_ioc_image_hdr_s fwhdr;
  80. /**
  81. * Firmware match check is relevant only for CNA.
  82. */
  83. if (!ioc->cna)
  84. return BFA_TRUE;
  85. /**
  86. * If bios boot (flash based) -- do not increment usage count
  87. */
  88. if (bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
  89. return BFA_TRUE;
  90. bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
  91. usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
  92. /**
  93. * If usage count is 0, always return TRUE.
  94. */
  95. if (usecnt == 0) {
  96. bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 1);
  97. bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
  98. bfa_trc(ioc, usecnt);
  99. return BFA_TRUE;
  100. }
  101. ioc_fwstate = bfa_reg_read(ioc->ioc_regs.ioc_fwstate);
  102. bfa_trc(ioc, ioc_fwstate);
  103. /**
  104. * Use count cannot be non-zero and chip in uninitialized state.
  105. */
  106. bfa_assert(ioc_fwstate != BFI_IOC_UNINIT);
  107. /**
  108. * Check if another driver with a different firmware is active
  109. */
  110. bfa_ioc_fwver_get(ioc, &fwhdr);
  111. if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) {
  112. bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
  113. bfa_trc(ioc, usecnt);
  114. return BFA_FALSE;
  115. }
  116. /**
  117. * Same firmware version. Increment the reference count.
  118. */
  119. usecnt++;
  120. bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
  121. bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
  122. bfa_trc(ioc, usecnt);
  123. return BFA_TRUE;
  124. }
  125. static void
  126. bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
  127. {
  128. uint32_t usecnt;
  129. /**
  130. * Firmware lock is relevant only for CNA.
  131. * If bios boot (flash based) -- do not decrement usage count
  132. */
  133. if (!ioc->cna || bfa_ioc_ct_fwimg_get_size(ioc) < BFA_IOC_FWIMG_MINSZ)
  134. return;
  135. /**
  136. * decrement usage count
  137. */
  138. bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
  139. usecnt = bfa_reg_read(ioc->ioc_regs.ioc_usage_reg);
  140. bfa_assert(usecnt > 0);
  141. usecnt--;
  142. bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, usecnt);
  143. bfa_trc(ioc, usecnt);
  144. bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
  145. }
  146. /**
  147. * Notify other functions on HB failure.
  148. */
  149. static void
  150. bfa_ioc_ct_notify_hbfail(struct bfa_ioc_s *ioc)
  151. {
  152. bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
  153. /* Wait for halt to take effect */
  154. bfa_reg_read(ioc->ioc_regs.ll_halt);
  155. }
  156. /**
  157. * Host to LPU mailbox message addresses
  158. */
  159. static struct { uint32_t hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
  160. { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
  161. { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 },
  162. { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 },
  163. { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 }
  164. };
  165. /**
  166. * Host <-> LPU mailbox command/status registers - port 0
  167. */
  168. static struct { uint32_t hfn, lpu; } iocreg_mbcmd_p0[] = {
  169. { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT },
  170. { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT },
  171. { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT },
  172. { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT }
  173. };
  174. /**
  175. * Host <-> LPU mailbox command/status registers - port 1
  176. */
  177. static struct { uint32_t hfn, lpu; } iocreg_mbcmd_p1[] = {
  178. { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT },
  179. { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT },
  180. { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT },
  181. { HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT }
  182. };
  183. static void
  184. bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
  185. {
  186. bfa_os_addr_t rb;
  187. int pcifn = bfa_ioc_pcifn(ioc);
  188. rb = bfa_ioc_bar0(ioc);
  189. ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
  190. ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
  191. ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
  192. if (ioc->port_id == 0) {
  193. ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
  194. ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
  195. ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
  196. ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
  197. ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
  198. } else {
  199. ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
  200. ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
  201. ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
  202. ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
  203. ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
  204. }
  205. /*
  206. * PSS control registers
  207. */
  208. ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
  209. ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
  210. ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
  211. ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
  212. /*
  213. * IOC semaphore registers and serialization
  214. */
  215. ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
  216. ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
  217. ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
  218. ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
  219. /**
  220. * sram memory access
  221. */
  222. ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
  223. ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
  224. }
  225. /**
  226. * Initialize IOC to port mapping.
  227. */
  228. #define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8)
  229. static void
  230. bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc)
  231. {
  232. bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
  233. uint32_t r32;
  234. /**
  235. * For catapult, base port id on personality register and IOC type
  236. */
  237. r32 = bfa_reg_read(rb + FNC_PERS_REG);
  238. r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
  239. ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
  240. bfa_trc(ioc, bfa_ioc_pcifn(ioc));
  241. bfa_trc(ioc, ioc->port_id);
  242. }
  243. /**
  244. * Set interrupt mode for a function: INTX or MSIX
  245. */
  246. static void
  247. bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
  248. {
  249. bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
  250. uint32_t r32, mode;
  251. r32 = bfa_reg_read(rb + FNC_PERS_REG);
  252. bfa_trc(ioc, r32);
  253. mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
  254. __F0_INTX_STATUS;
  255. /**
  256. * If already in desired mode, do not change anything
  257. */
  258. if (!msix && mode)
  259. return;
  260. if (msix)
  261. mode = __F0_INTX_STATUS_MSIX;
  262. else
  263. mode = __F0_INTX_STATUS_INTA;
  264. r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
  265. r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
  266. bfa_trc(ioc, r32);
  267. bfa_reg_write(rb + FNC_PERS_REG, r32);
  268. }
  269. static bfa_status_t
  270. bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc)
  271. {
  272. bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
  273. uint32_t pll_sclk, pll_fclk, r32;
  274. /*
  275. * Hold semaphore so that nobody can access the chip during init.
  276. */
  277. bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
  278. pll_sclk = __APP_PLL_312_ENABLE | __APP_PLL_312_LRESETN |
  279. __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(0U) |
  280. __APP_PLL_312_JITLMT0_1(3U) |
  281. __APP_PLL_312_CNTLMT0_1(1U);
  282. pll_fclk = __APP_PLL_425_ENABLE | __APP_PLL_425_LRESETN |
  283. __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(0U) |
  284. __APP_PLL_425_JITLMT0_1(3U) |
  285. __APP_PLL_425_CNTLMT0_1(1U);
  286. /**
  287. * For catapult, choose operational mode FC/FCoE
  288. */
  289. if (ioc->fcmode) {
  290. bfa_reg_write((rb + OP_MODE), 0);
  291. bfa_reg_write((rb + ETH_MAC_SER_REG),
  292. __APP_EMS_CMLCKSEL |
  293. __APP_EMS_REFCKBUFEN2 |
  294. __APP_EMS_CHANNEL_SEL);
  295. } else {
  296. ioc->pllinit = BFA_TRUE;
  297. bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
  298. bfa_reg_write((rb + ETH_MAC_SER_REG),
  299. __APP_EMS_REFCKBUFEN1);
  300. }
  301. bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
  302. bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
  303. bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
  304. bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
  305. bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
  306. bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
  307. bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
  308. bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
  309. bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
  310. __APP_PLL_312_LOGIC_SOFT_RESET);
  311. bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
  312. __APP_PLL_312_BYPASS |
  313. __APP_PLL_312_LOGIC_SOFT_RESET);
  314. bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
  315. __APP_PLL_425_LOGIC_SOFT_RESET);
  316. bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
  317. __APP_PLL_425_BYPASS |
  318. __APP_PLL_425_LOGIC_SOFT_RESET);
  319. bfa_os_udelay(2);
  320. bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
  321. __APP_PLL_312_LOGIC_SOFT_RESET);
  322. bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
  323. __APP_PLL_425_LOGIC_SOFT_RESET);
  324. bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg,
  325. pll_sclk | __APP_PLL_312_LOGIC_SOFT_RESET);
  326. bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg,
  327. pll_fclk | __APP_PLL_425_LOGIC_SOFT_RESET);
  328. /**
  329. * Wait for PLLs to lock.
  330. */
  331. bfa_os_udelay(2000);
  332. bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
  333. bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
  334. bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk);
  335. bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk);
  336. bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
  337. bfa_os_udelay(1000);
  338. r32 = bfa_reg_read((rb + MBIST_STAT_REG));
  339. bfa_trc(ioc, r32);
  340. /*
  341. * release semaphore.
  342. */
  343. bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
  344. return BFA_STATUS_OK;
  345. }
  346. /**
  347. * Cleanup hw semaphore and usecnt registers
  348. */
  349. static void
  350. bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
  351. {
  352. if (ioc->cna) {
  353. bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
  354. bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 0);
  355. bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
  356. }
  357. /*
  358. * Read the hw sem reg to make sure that it is locked
  359. * before we clear it. If it is not locked, writing 1
  360. * will lock it instead of clearing it.
  361. */
  362. bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
  363. bfa_ioc_hw_sem_release(ioc);
  364. }