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 u32* bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc,
  34. u32 off);
  35. static u32 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 u32*
  62. bfa_ioc_ct_fwimg_get_chunk(struct bfa_ioc_s *ioc, u32 off)
  63. {
  64. return bfi_image_ct_get_chunk(off);
  65. }
  66. static u32
  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. u32 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. u32 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. if (ioc->cna) {
  153. bfa_reg_write(ioc->ioc_regs.ll_halt, __FW_INIT_HALT_P);
  154. /* Wait for halt to take effect */
  155. bfa_reg_read(ioc->ioc_regs.ll_halt);
  156. } else {
  157. bfa_reg_write(ioc->ioc_regs.err_set, __PSS_ERR_STATUS_SET);
  158. bfa_reg_read(ioc->ioc_regs.err_set);
  159. }
  160. }
  161. /**
  162. * Host to LPU mailbox message addresses
  163. */
  164. static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
  165. { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
  166. { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 },
  167. { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 },
  168. { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 }
  169. };
  170. /**
  171. * Host <-> LPU mailbox command/status registers - port 0
  172. */
  173. static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = {
  174. { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT },
  175. { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT },
  176. { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT },
  177. { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT }
  178. };
  179. /**
  180. * Host <-> LPU mailbox command/status registers - port 1
  181. */
  182. static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = {
  183. { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT },
  184. { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT },
  185. { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT },
  186. { HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT }
  187. };
  188. static void
  189. bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc)
  190. {
  191. bfa_os_addr_t rb;
  192. int pcifn = bfa_ioc_pcifn(ioc);
  193. rb = bfa_ioc_bar0(ioc);
  194. ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
  195. ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
  196. ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
  197. if (ioc->port_id == 0) {
  198. ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
  199. ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
  200. ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
  201. ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
  202. ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
  203. } else {
  204. ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
  205. ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
  206. ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
  207. ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
  208. ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
  209. }
  210. /*
  211. * PSS control registers
  212. */
  213. ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
  214. ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
  215. ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
  216. ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
  217. /*
  218. * IOC semaphore registers and serialization
  219. */
  220. ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
  221. ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
  222. ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
  223. ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
  224. /**
  225. * sram memory access
  226. */
  227. ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
  228. ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
  229. /*
  230. * err set reg : for notification of hb failure in fcmode
  231. */
  232. ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
  233. }
  234. /**
  235. * Initialize IOC to port mapping.
  236. */
  237. #define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8)
  238. static void
  239. bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc)
  240. {
  241. bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
  242. u32 r32;
  243. /**
  244. * For catapult, base port id on personality register and IOC type
  245. */
  246. r32 = bfa_reg_read(rb + FNC_PERS_REG);
  247. r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
  248. ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
  249. bfa_trc(ioc, bfa_ioc_pcifn(ioc));
  250. bfa_trc(ioc, ioc->port_id);
  251. }
  252. /**
  253. * Set interrupt mode for a function: INTX or MSIX
  254. */
  255. static void
  256. bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix)
  257. {
  258. bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
  259. u32 r32, mode;
  260. r32 = bfa_reg_read(rb + FNC_PERS_REG);
  261. bfa_trc(ioc, r32);
  262. mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
  263. __F0_INTX_STATUS;
  264. /**
  265. * If already in desired mode, do not change anything
  266. */
  267. if (!msix && mode)
  268. return;
  269. if (msix)
  270. mode = __F0_INTX_STATUS_MSIX;
  271. else
  272. mode = __F0_INTX_STATUS_INTA;
  273. r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
  274. r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
  275. bfa_trc(ioc, r32);
  276. bfa_reg_write(rb + FNC_PERS_REG, r32);
  277. }
  278. static bfa_status_t
  279. bfa_ioc_ct_pll_init(struct bfa_ioc_s *ioc)
  280. {
  281. bfa_os_addr_t rb = ioc->pcidev.pci_bar_kva;
  282. u32 pll_sclk, pll_fclk, r32;
  283. /*
  284. * Hold semaphore so that nobody can access the chip during init.
  285. */
  286. bfa_ioc_sem_get(ioc->ioc_regs.ioc_init_sem_reg);
  287. pll_sclk = __APP_PLL_312_LRESETN | __APP_PLL_312_ENARST |
  288. __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(3U) |
  289. __APP_PLL_312_JITLMT0_1(3U) |
  290. __APP_PLL_312_CNTLMT0_1(1U);
  291. pll_fclk = __APP_PLL_425_LRESETN | __APP_PLL_425_ENARST |
  292. __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
  293. __APP_PLL_425_JITLMT0_1(3U) |
  294. __APP_PLL_425_CNTLMT0_1(1U);
  295. /**
  296. * For catapult, choose operational mode FC/FCoE
  297. */
  298. if (ioc->fcmode) {
  299. bfa_reg_write((rb + OP_MODE), 0);
  300. bfa_reg_write((rb + ETH_MAC_SER_REG),
  301. __APP_EMS_CMLCKSEL |
  302. __APP_EMS_REFCKBUFEN2 |
  303. __APP_EMS_CHANNEL_SEL);
  304. } else {
  305. ioc->pllinit = BFA_TRUE;
  306. bfa_reg_write((rb + OP_MODE), __GLOBAL_FCOE_MODE);
  307. bfa_reg_write((rb + ETH_MAC_SER_REG),
  308. __APP_EMS_REFCKBUFEN1);
  309. }
  310. bfa_reg_write((rb + BFA_IOC0_STATE_REG), BFI_IOC_UNINIT);
  311. bfa_reg_write((rb + BFA_IOC1_STATE_REG), BFI_IOC_UNINIT);
  312. bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
  313. bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
  314. bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
  315. bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
  316. bfa_reg_write((rb + HOSTFN0_INT_MSK), 0xffffffffU);
  317. bfa_reg_write((rb + HOSTFN1_INT_MSK), 0xffffffffU);
  318. bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
  319. __APP_PLL_312_LOGIC_SOFT_RESET);
  320. bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
  321. __APP_PLL_425_LOGIC_SOFT_RESET);
  322. bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
  323. __APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE);
  324. bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
  325. __APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE);
  326. /**
  327. * Wait for PLLs to lock.
  328. */
  329. bfa_reg_read(rb + HOSTFN0_INT_MSK);
  330. bfa_os_udelay(2000);
  331. bfa_reg_write((rb + HOSTFN0_INT_STATUS), 0xffffffffU);
  332. bfa_reg_write((rb + HOSTFN1_INT_STATUS), 0xffffffffU);
  333. bfa_reg_write(ioc->ioc_regs.app_pll_slow_ctl_reg, pll_sclk |
  334. __APP_PLL_312_ENABLE);
  335. bfa_reg_write(ioc->ioc_regs.app_pll_fast_ctl_reg, pll_fclk |
  336. __APP_PLL_425_ENABLE);
  337. bfa_reg_write((rb + MBIST_CTL_REG), __EDRAM_BISTR_START);
  338. bfa_os_udelay(1000);
  339. r32 = bfa_reg_read((rb + MBIST_STAT_REG));
  340. bfa_trc(ioc, r32);
  341. /*
  342. * release semaphore.
  343. */
  344. bfa_ioc_sem_release(ioc->ioc_regs.ioc_init_sem_reg);
  345. return BFA_STATUS_OK;
  346. }
  347. /**
  348. * Cleanup hw semaphore and usecnt registers
  349. */
  350. static void
  351. bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
  352. {
  353. if (ioc->cna) {
  354. bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
  355. bfa_reg_write(ioc->ioc_regs.ioc_usage_reg, 0);
  356. bfa_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
  357. }
  358. /*
  359. * Read the hw sem reg to make sure that it is locked
  360. * before we clear it. If it is not locked, writing 1
  361. * will lock it instead of clearing it.
  362. */
  363. bfa_reg_read(ioc->ioc_regs.ioc_sem_reg);
  364. bfa_ioc_hw_sem_release(ioc);
  365. }