bfa_ioc_ct.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. /*
  2. * Linux network driver for Brocade Converged Network Adapter.
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License (GPL) Version 2 as
  6. * published by the Free Software Foundation
  7. *
  8. * This program is distributed in the hope that it will be useful, but
  9. * WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. * General Public License for more details.
  12. */
  13. /*
  14. * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
  15. * All rights reserved
  16. * www.brocade.com
  17. */
  18. #include "bfa_ioc.h"
  19. #include "cna.h"
  20. #include "bfi.h"
  21. #include "bfi_ctreg.h"
  22. #include "bfa_defs.h"
  23. /*
  24. * forward declarations
  25. */
  26. static bool bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc);
  27. static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc);
  28. static void bfa_ioc_ct_reg_init(struct bfa_ioc *ioc);
  29. static void bfa_ioc_ct_map_port(struct bfa_ioc *ioc);
  30. static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix);
  31. static void bfa_ioc_ct_notify_hbfail(struct bfa_ioc *ioc);
  32. static void bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc);
  33. static enum bfa_status bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode);
  34. static struct bfa_ioc_hwif nw_hwif_ct;
  35. /**
  36. * Called from bfa_ioc_attach() to map asic specific calls.
  37. */
  38. void
  39. bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc)
  40. {
  41. nw_hwif_ct.ioc_pll_init = bfa_ioc_ct_pll_init;
  42. nw_hwif_ct.ioc_firmware_lock = bfa_ioc_ct_firmware_lock;
  43. nw_hwif_ct.ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock;
  44. nw_hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init;
  45. nw_hwif_ct.ioc_map_port = bfa_ioc_ct_map_port;
  46. nw_hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set;
  47. nw_hwif_ct.ioc_notify_hbfail = bfa_ioc_ct_notify_hbfail;
  48. nw_hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset;
  49. ioc->ioc_hwif = &nw_hwif_ct;
  50. }
  51. /**
  52. * Return true if firmware of current driver matches the running firmware.
  53. */
  54. static bool
  55. bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc)
  56. {
  57. enum bfi_ioc_state ioc_fwstate;
  58. u32 usecnt;
  59. struct bfi_ioc_image_hdr fwhdr;
  60. /**
  61. * Firmware match check is relevant only for CNA.
  62. */
  63. if (!ioc->cna)
  64. return true;
  65. /**
  66. * If bios boot (flash based) -- do not increment usage count
  67. */
  68. if (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) <
  69. BFA_IOC_FWIMG_MINSZ)
  70. return true;
  71. bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
  72. usecnt = readl(ioc->ioc_regs.ioc_usage_reg);
  73. /**
  74. * If usage count is 0, always return TRUE.
  75. */
  76. if (usecnt == 0) {
  77. writel(1, ioc->ioc_regs.ioc_usage_reg);
  78. bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
  79. return true;
  80. }
  81. ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate);
  82. /**
  83. * Use count cannot be non-zero and chip in uninitialized state.
  84. */
  85. BUG_ON(!(ioc_fwstate != BFI_IOC_UNINIT));
  86. /**
  87. * Check if another driver with a different firmware is active
  88. */
  89. bfa_nw_ioc_fwver_get(ioc, &fwhdr);
  90. if (!bfa_nw_ioc_fwver_cmp(ioc, &fwhdr)) {
  91. bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
  92. return false;
  93. }
  94. /**
  95. * Same firmware version. Increment the reference count.
  96. */
  97. usecnt++;
  98. writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
  99. bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
  100. return true;
  101. }
  102. static void
  103. bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc)
  104. {
  105. u32 usecnt;
  106. /**
  107. * Firmware lock is relevant only for CNA.
  108. */
  109. if (!ioc->cna)
  110. return;
  111. /**
  112. * If bios boot (flash based) -- do not decrement usage count
  113. */
  114. if (bfa_cb_image_get_size(BFA_IOC_FWIMG_TYPE(ioc)) <
  115. BFA_IOC_FWIMG_MINSZ)
  116. return;
  117. /**
  118. * decrement usage count
  119. */
  120. bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
  121. usecnt = readl(ioc->ioc_regs.ioc_usage_reg);
  122. BUG_ON(!(usecnt > 0));
  123. usecnt--;
  124. writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
  125. bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
  126. }
  127. /**
  128. * Notify other functions on HB failure.
  129. */
  130. static void
  131. bfa_ioc_ct_notify_hbfail(struct bfa_ioc *ioc)
  132. {
  133. if (ioc->cna) {
  134. writel(__FW_INIT_HALT_P, ioc->ioc_regs.ll_halt);
  135. /* Wait for halt to take effect */
  136. readl(ioc->ioc_regs.ll_halt);
  137. } else {
  138. writel(__PSS_ERR_STATUS_SET, ioc->ioc_regs.err_set);
  139. readl(ioc->ioc_regs.err_set);
  140. }
  141. }
  142. /**
  143. * Host to LPU mailbox message addresses
  144. */
  145. static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } iocreg_fnreg[] = {
  146. { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
  147. { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 },
  148. { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 },
  149. { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 }
  150. };
  151. /**
  152. * Host <-> LPU mailbox command/status registers - port 0
  153. */
  154. static struct { u32 hfn, lpu; } iocreg_mbcmd_p0[] = {
  155. { HOSTFN0_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN0_MBOX0_CMD_STAT },
  156. { HOSTFN1_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN1_MBOX0_CMD_STAT },
  157. { HOSTFN2_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN2_MBOX0_CMD_STAT },
  158. { HOSTFN3_LPU0_MBOX0_CMD_STAT, LPU0_HOSTFN3_MBOX0_CMD_STAT }
  159. };
  160. /**
  161. * Host <-> LPU mailbox command/status registers - port 1
  162. */
  163. static struct { u32 hfn, lpu; } iocreg_mbcmd_p1[] = {
  164. { HOSTFN0_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN0_MBOX0_CMD_STAT },
  165. { HOSTFN1_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN1_MBOX0_CMD_STAT },
  166. { HOSTFN2_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN2_MBOX0_CMD_STAT },
  167. { HOSTFN3_LPU1_MBOX0_CMD_STAT, LPU1_HOSTFN3_MBOX0_CMD_STAT }
  168. };
  169. static void
  170. bfa_ioc_ct_reg_init(struct bfa_ioc *ioc)
  171. {
  172. void __iomem *rb;
  173. int pcifn = bfa_ioc_pcifn(ioc);
  174. rb = bfa_ioc_bar0(ioc);
  175. ioc->ioc_regs.hfn_mbox = rb + iocreg_fnreg[pcifn].hfn_mbox;
  176. ioc->ioc_regs.lpu_mbox = rb + iocreg_fnreg[pcifn].lpu_mbox;
  177. ioc->ioc_regs.host_page_num_fn = rb + iocreg_fnreg[pcifn].hfn_pgn;
  178. if (ioc->port_id == 0) {
  179. ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
  180. ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
  181. ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].hfn;
  182. ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p0[pcifn].lpu;
  183. ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
  184. } else {
  185. ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG);
  186. ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG);
  187. ioc->ioc_regs.hfn_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].hfn;
  188. ioc->ioc_regs.lpu_mbox_cmd = rb + iocreg_mbcmd_p1[pcifn].lpu;
  189. ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
  190. }
  191. /*
  192. * PSS control registers
  193. */
  194. ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG);
  195. ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG);
  196. ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_425_CTL_REG);
  197. ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_312_CTL_REG);
  198. /*
  199. * IOC semaphore registers and serialization
  200. */
  201. ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG);
  202. ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG);
  203. ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG);
  204. ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT);
  205. /**
  206. * sram memory access
  207. */
  208. ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START);
  209. ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
  210. /*
  211. * err set reg : for notification of hb failure in fcmode
  212. */
  213. ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
  214. }
  215. /**
  216. * Initialize IOC to port mapping.
  217. */
  218. #define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8)
  219. static void
  220. bfa_ioc_ct_map_port(struct bfa_ioc *ioc)
  221. {
  222. void __iomem *rb = ioc->pcidev.pci_bar_kva;
  223. u32 r32;
  224. /**
  225. * For catapult, base port id on personality register and IOC type
  226. */
  227. r32 = readl(rb + FNC_PERS_REG);
  228. r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
  229. ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
  230. }
  231. /**
  232. * Set interrupt mode for a function: INTX or MSIX
  233. */
  234. static void
  235. bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix)
  236. {
  237. void __iomem *rb = ioc->pcidev.pci_bar_kva;
  238. u32 r32, mode;
  239. r32 = readl(rb + FNC_PERS_REG);
  240. mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
  241. __F0_INTX_STATUS;
  242. /**
  243. * If already in desired mode, do not change anything
  244. */
  245. if (!msix && mode)
  246. return;
  247. if (msix)
  248. mode = __F0_INTX_STATUS_MSIX;
  249. else
  250. mode = __F0_INTX_STATUS_INTA;
  251. r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
  252. r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
  253. writel(r32, rb + FNC_PERS_REG);
  254. }
  255. /**
  256. * Cleanup hw semaphore and usecnt registers
  257. */
  258. static void
  259. bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc)
  260. {
  261. if (ioc->cna) {
  262. bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
  263. writel(0, ioc->ioc_regs.ioc_usage_reg);
  264. bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
  265. }
  266. /*
  267. * Read the hw sem reg to make sure that it is locked
  268. * before we clear it. If it is not locked, writing 1
  269. * will lock it instead of clearing it.
  270. */
  271. readl(ioc->ioc_regs.ioc_sem_reg);
  272. bfa_nw_ioc_hw_sem_release(ioc);
  273. }
  274. static enum bfa_status
  275. bfa_ioc_ct_pll_init(void __iomem *rb, bool fcmode)
  276. {
  277. u32 pll_sclk, pll_fclk, r32;
  278. pll_sclk = __APP_PLL_312_LRESETN | __APP_PLL_312_ENARST |
  279. __APP_PLL_312_RSEL200500 | __APP_PLL_312_P0_1(3U) |
  280. __APP_PLL_312_JITLMT0_1(3U) |
  281. __APP_PLL_312_CNTLMT0_1(1U);
  282. pll_fclk = __APP_PLL_425_LRESETN | __APP_PLL_425_ENARST |
  283. __APP_PLL_425_RSEL200500 | __APP_PLL_425_P0_1(3U) |
  284. __APP_PLL_425_JITLMT0_1(3U) |
  285. __APP_PLL_425_CNTLMT0_1(1U);
  286. if (fcmode) {
  287. writel(0, (rb + OP_MODE));
  288. writel(__APP_EMS_CMLCKSEL |
  289. __APP_EMS_REFCKBUFEN2 |
  290. __APP_EMS_CHANNEL_SEL,
  291. (rb + ETH_MAC_SER_REG));
  292. } else {
  293. writel(__GLOBAL_FCOE_MODE, (rb + OP_MODE));
  294. writel(__APP_EMS_REFCKBUFEN1,
  295. (rb + ETH_MAC_SER_REG));
  296. }
  297. writel(BFI_IOC_UNINIT, (rb + BFA_IOC0_STATE_REG));
  298. writel(BFI_IOC_UNINIT, (rb + BFA_IOC1_STATE_REG));
  299. writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
  300. writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
  301. writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
  302. writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS));
  303. writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
  304. writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
  305. writel(pll_sclk |
  306. __APP_PLL_312_LOGIC_SOFT_RESET,
  307. rb + APP_PLL_312_CTL_REG);
  308. writel(pll_fclk |
  309. __APP_PLL_425_LOGIC_SOFT_RESET,
  310. rb + APP_PLL_425_CTL_REG);
  311. writel(pll_sclk |
  312. __APP_PLL_312_LOGIC_SOFT_RESET | __APP_PLL_312_ENABLE,
  313. rb + APP_PLL_312_CTL_REG);
  314. writel(pll_fclk |
  315. __APP_PLL_425_LOGIC_SOFT_RESET | __APP_PLL_425_ENABLE,
  316. rb + APP_PLL_425_CTL_REG);
  317. readl(rb + HOSTFN0_INT_MSK);
  318. udelay(2000);
  319. writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
  320. writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS));
  321. writel(pll_sclk |
  322. __APP_PLL_312_ENABLE,
  323. rb + APP_PLL_312_CTL_REG);
  324. writel(pll_fclk |
  325. __APP_PLL_425_ENABLE,
  326. rb + APP_PLL_425_CTL_REG);
  327. if (!fcmode) {
  328. writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P0));
  329. writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P1));
  330. }
  331. r32 = readl((rb + PSS_CTL_REG));
  332. r32 &= ~__PSS_LMEM_RESET;
  333. writel(r32, (rb + PSS_CTL_REG));
  334. udelay(1000);
  335. if (!fcmode) {
  336. writel(0, (rb + PMM_1T_RESET_REG_P0));
  337. writel(0, (rb + PMM_1T_RESET_REG_P1));
  338. }
  339. writel(__EDRAM_BISTR_START, (rb + MBIST_CTL_REG));
  340. udelay(1000);
  341. r32 = readl((rb + MBIST_STAT_REG));
  342. writel(0, (rb + MBIST_CTL_REG));
  343. return BFA_STATUS_OK;
  344. }