mc5.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. /*
  2. * This file is part of the Chelsio T3 Ethernet driver.
  3. *
  4. * Copyright (C) 2003-2006 Chelsio Communications. All rights reserved.
  5. *
  6. * This program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  8. * FITNESS FOR A PARTICULAR PURPOSE. See the LICENSE file included in this
  9. * release for licensing terms and conditions.
  10. */
  11. #include "common.h"
  12. #include "regs.h"
  13. enum {
  14. IDT75P52100 = 4,
  15. IDT75N43102 = 5
  16. };
  17. /* DBGI command mode */
  18. enum {
  19. DBGI_MODE_MBUS = 0,
  20. DBGI_MODE_IDT52100 = 5
  21. };
  22. /* IDT 75P52100 commands */
  23. #define IDT_CMD_READ 0
  24. #define IDT_CMD_WRITE 1
  25. #define IDT_CMD_SEARCH 2
  26. #define IDT_CMD_LEARN 3
  27. /* IDT LAR register address and value for 144-bit mode (low 32 bits) */
  28. #define IDT_LAR_ADR0 0x180006
  29. #define IDT_LAR_MODE144 0xffff0000
  30. /* IDT SCR and SSR addresses (low 32 bits) */
  31. #define IDT_SCR_ADR0 0x180000
  32. #define IDT_SSR0_ADR0 0x180002
  33. #define IDT_SSR1_ADR0 0x180004
  34. /* IDT GMR base address (low 32 bits) */
  35. #define IDT_GMR_BASE_ADR0 0x180020
  36. /* IDT data and mask array base addresses (low 32 bits) */
  37. #define IDT_DATARY_BASE_ADR0 0
  38. #define IDT_MSKARY_BASE_ADR0 0x80000
  39. /* IDT 75N43102 commands */
  40. #define IDT4_CMD_SEARCH144 3
  41. #define IDT4_CMD_WRITE 4
  42. #define IDT4_CMD_READ 5
  43. /* IDT 75N43102 SCR address (low 32 bits) */
  44. #define IDT4_SCR_ADR0 0x3
  45. /* IDT 75N43102 GMR base addresses (low 32 bits) */
  46. #define IDT4_GMR_BASE0 0x10
  47. #define IDT4_GMR_BASE1 0x20
  48. #define IDT4_GMR_BASE2 0x30
  49. /* IDT 75N43102 data and mask array base addresses (low 32 bits) */
  50. #define IDT4_DATARY_BASE_ADR0 0x1000000
  51. #define IDT4_MSKARY_BASE_ADR0 0x2000000
  52. #define MAX_WRITE_ATTEMPTS 5
  53. #define MAX_ROUTES 2048
  54. /*
  55. * Issue a command to the TCAM and wait for its completion. The address and
  56. * any data required by the command must have been setup by the caller.
  57. */
  58. static int mc5_cmd_write(struct adapter *adapter, u32 cmd)
  59. {
  60. t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_CMD, cmd);
  61. return t3_wait_op_done(adapter, A_MC5_DB_DBGI_RSP_STATUS,
  62. F_DBGIRSPVALID, 1, MAX_WRITE_ATTEMPTS, 1);
  63. }
  64. static inline void dbgi_wr_addr3(struct adapter *adapter, u32 v1, u32 v2,
  65. u32 v3)
  66. {
  67. t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR0, v1);
  68. t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR1, v2);
  69. t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR2, v3);
  70. }
  71. static inline void dbgi_wr_data3(struct adapter *adapter, u32 v1, u32 v2,
  72. u32 v3)
  73. {
  74. t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA0, v1);
  75. t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA1, v2);
  76. t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA2, v3);
  77. }
  78. static inline void dbgi_rd_rsp3(struct adapter *adapter, u32 *v1, u32 *v2,
  79. u32 *v3)
  80. {
  81. *v1 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA0);
  82. *v2 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA1);
  83. *v3 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA2);
  84. }
  85. /*
  86. * Write data to the TCAM register at address (0, 0, addr_lo) using the TCAM
  87. * command cmd. The data to be written must have been set up by the caller.
  88. * Returns -1 on failure, 0 on success.
  89. */
  90. static int mc5_write(struct adapter *adapter, u32 addr_lo, u32 cmd)
  91. {
  92. t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR0, addr_lo);
  93. if (mc5_cmd_write(adapter, cmd) == 0)
  94. return 0;
  95. CH_ERR(adapter, "MC5 timeout writing to TCAM address 0x%x\n",
  96. addr_lo);
  97. return -1;
  98. }
  99. static int init_mask_data_array(struct mc5 *mc5, u32 mask_array_base,
  100. u32 data_array_base, u32 write_cmd,
  101. int addr_shift)
  102. {
  103. unsigned int i;
  104. struct adapter *adap = mc5->adapter;
  105. /*
  106. * We need the size of the TCAM data and mask arrays in terms of
  107. * 72-bit entries.
  108. */
  109. unsigned int size72 = mc5->tcam_size;
  110. unsigned int server_base = t3_read_reg(adap, A_MC5_DB_SERVER_INDEX);
  111. if (mc5->mode == MC5_MODE_144_BIT) {
  112. size72 *= 2; /* 1 144-bit entry is 2 72-bit entries */
  113. server_base *= 2;
  114. }
  115. /* Clear the data array */
  116. dbgi_wr_data3(adap, 0, 0, 0);
  117. for (i = 0; i < size72; i++)
  118. if (mc5_write(adap, data_array_base + (i << addr_shift),
  119. write_cmd))
  120. return -1;
  121. /* Initialize the mask array. */
  122. dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff);
  123. for (i = 0; i < size72; i++) {
  124. if (i == server_base) /* entering server or routing region */
  125. t3_write_reg(adap, A_MC5_DB_DBGI_REQ_DATA0,
  126. mc5->mode == MC5_MODE_144_BIT ?
  127. 0xfffffff9 : 0xfffffffd);
  128. if (mc5_write(adap, mask_array_base + (i << addr_shift),
  129. write_cmd))
  130. return -1;
  131. }
  132. return 0;
  133. }
  134. static int init_idt52100(struct mc5 *mc5)
  135. {
  136. int i;
  137. struct adapter *adap = mc5->adapter;
  138. t3_write_reg(adap, A_MC5_DB_RSP_LATENCY,
  139. V_RDLAT(0x15) | V_LRNLAT(0x15) | V_SRCHLAT(0x15));
  140. t3_write_reg(adap, A_MC5_DB_PART_ID_INDEX, 2);
  141. /*
  142. * Use GMRs 14-15 for ELOOKUP, GMRs 12-13 for SYN lookups, and
  143. * GMRs 8-9 for ACK- and AOPEN searches.
  144. */
  145. t3_write_reg(adap, A_MC5_DB_POPEN_DATA_WR_CMD, IDT_CMD_WRITE);
  146. t3_write_reg(adap, A_MC5_DB_POPEN_MASK_WR_CMD, IDT_CMD_WRITE);
  147. t3_write_reg(adap, A_MC5_DB_AOPEN_SRCH_CMD, IDT_CMD_SEARCH);
  148. t3_write_reg(adap, A_MC5_DB_AOPEN_LRN_CMD, IDT_CMD_LEARN);
  149. t3_write_reg(adap, A_MC5_DB_SYN_SRCH_CMD, IDT_CMD_SEARCH | 0x6000);
  150. t3_write_reg(adap, A_MC5_DB_SYN_LRN_CMD, IDT_CMD_LEARN);
  151. t3_write_reg(adap, A_MC5_DB_ACK_SRCH_CMD, IDT_CMD_SEARCH);
  152. t3_write_reg(adap, A_MC5_DB_ACK_LRN_CMD, IDT_CMD_LEARN);
  153. t3_write_reg(adap, A_MC5_DB_ILOOKUP_CMD, IDT_CMD_SEARCH);
  154. t3_write_reg(adap, A_MC5_DB_ELOOKUP_CMD, IDT_CMD_SEARCH | 0x7000);
  155. t3_write_reg(adap, A_MC5_DB_DATA_WRITE_CMD, IDT_CMD_WRITE);
  156. t3_write_reg(adap, A_MC5_DB_DATA_READ_CMD, IDT_CMD_READ);
  157. /* Set DBGI command mode for IDT TCAM. */
  158. t3_write_reg(adap, A_MC5_DB_DBGI_CONFIG, DBGI_MODE_IDT52100);
  159. /* Set up LAR */
  160. dbgi_wr_data3(adap, IDT_LAR_MODE144, 0, 0);
  161. if (mc5_write(adap, IDT_LAR_ADR0, IDT_CMD_WRITE))
  162. goto err;
  163. /* Set up SSRs */
  164. dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0);
  165. if (mc5_write(adap, IDT_SSR0_ADR0, IDT_CMD_WRITE) ||
  166. mc5_write(adap, IDT_SSR1_ADR0, IDT_CMD_WRITE))
  167. goto err;
  168. /* Set up GMRs */
  169. for (i = 0; i < 32; ++i) {
  170. if (i >= 12 && i < 15)
  171. dbgi_wr_data3(adap, 0xfffffff9, 0xffffffff, 0xff);
  172. else if (i == 15)
  173. dbgi_wr_data3(adap, 0xfffffff9, 0xffff8007, 0xff);
  174. else
  175. dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff);
  176. if (mc5_write(adap, IDT_GMR_BASE_ADR0 + i, IDT_CMD_WRITE))
  177. goto err;
  178. }
  179. /* Set up SCR */
  180. dbgi_wr_data3(adap, 1, 0, 0);
  181. if (mc5_write(adap, IDT_SCR_ADR0, IDT_CMD_WRITE))
  182. goto err;
  183. return init_mask_data_array(mc5, IDT_MSKARY_BASE_ADR0,
  184. IDT_DATARY_BASE_ADR0, IDT_CMD_WRITE, 0);
  185. err:
  186. return -EIO;
  187. }
  188. static int init_idt43102(struct mc5 *mc5)
  189. {
  190. int i;
  191. struct adapter *adap = mc5->adapter;
  192. t3_write_reg(adap, A_MC5_DB_RSP_LATENCY,
  193. adap->params.rev == 0 ? V_RDLAT(0xd) | V_SRCHLAT(0x11) :
  194. V_RDLAT(0xd) | V_SRCHLAT(0x12));
  195. /*
  196. * Use GMRs 24-25 for ELOOKUP, GMRs 20-21 for SYN lookups, and no mask
  197. * for ACK- and AOPEN searches.
  198. */
  199. t3_write_reg(adap, A_MC5_DB_POPEN_DATA_WR_CMD, IDT4_CMD_WRITE);
  200. t3_write_reg(adap, A_MC5_DB_POPEN_MASK_WR_CMD, IDT4_CMD_WRITE);
  201. t3_write_reg(adap, A_MC5_DB_AOPEN_SRCH_CMD,
  202. IDT4_CMD_SEARCH144 | 0x3800);
  203. t3_write_reg(adap, A_MC5_DB_SYN_SRCH_CMD, IDT4_CMD_SEARCH144);
  204. t3_write_reg(adap, A_MC5_DB_ACK_SRCH_CMD, IDT4_CMD_SEARCH144 | 0x3800);
  205. t3_write_reg(adap, A_MC5_DB_ILOOKUP_CMD, IDT4_CMD_SEARCH144 | 0x3800);
  206. t3_write_reg(adap, A_MC5_DB_ELOOKUP_CMD, IDT4_CMD_SEARCH144 | 0x800);
  207. t3_write_reg(adap, A_MC5_DB_DATA_WRITE_CMD, IDT4_CMD_WRITE);
  208. t3_write_reg(adap, A_MC5_DB_DATA_READ_CMD, IDT4_CMD_READ);
  209. t3_write_reg(adap, A_MC5_DB_PART_ID_INDEX, 3);
  210. /* Set DBGI command mode for IDT TCAM. */
  211. t3_write_reg(adap, A_MC5_DB_DBGI_CONFIG, DBGI_MODE_IDT52100);
  212. /* Set up GMRs */
  213. dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff);
  214. for (i = 0; i < 7; ++i)
  215. if (mc5_write(adap, IDT4_GMR_BASE0 + i, IDT4_CMD_WRITE))
  216. goto err;
  217. for (i = 0; i < 4; ++i)
  218. if (mc5_write(adap, IDT4_GMR_BASE2 + i, IDT4_CMD_WRITE))
  219. goto err;
  220. dbgi_wr_data3(adap, 0xfffffff9, 0xffffffff, 0xff);
  221. if (mc5_write(adap, IDT4_GMR_BASE1, IDT4_CMD_WRITE) ||
  222. mc5_write(adap, IDT4_GMR_BASE1 + 1, IDT4_CMD_WRITE) ||
  223. mc5_write(adap, IDT4_GMR_BASE1 + 4, IDT4_CMD_WRITE))
  224. goto err;
  225. dbgi_wr_data3(adap, 0xfffffff9, 0xffff8007, 0xff);
  226. if (mc5_write(adap, IDT4_GMR_BASE1 + 5, IDT4_CMD_WRITE))
  227. goto err;
  228. /* Set up SCR */
  229. dbgi_wr_data3(adap, 0xf0000000, 0, 0);
  230. if (mc5_write(adap, IDT4_SCR_ADR0, IDT4_CMD_WRITE))
  231. goto err;
  232. return init_mask_data_array(mc5, IDT4_MSKARY_BASE_ADR0,
  233. IDT4_DATARY_BASE_ADR0, IDT4_CMD_WRITE, 1);
  234. err:
  235. return -EIO;
  236. }
  237. /* Put MC5 in DBGI mode. */
  238. static inline void mc5_dbgi_mode_enable(const struct mc5 *mc5)
  239. {
  240. t3_write_reg(mc5->adapter, A_MC5_DB_CONFIG,
  241. V_TMMODE(mc5->mode == MC5_MODE_72_BIT) | F_DBGIEN);
  242. }
  243. /* Put MC5 in M-Bus mode. */
  244. static void mc5_dbgi_mode_disable(const struct mc5 *mc5)
  245. {
  246. t3_write_reg(mc5->adapter, A_MC5_DB_CONFIG,
  247. V_TMMODE(mc5->mode == MC5_MODE_72_BIT) |
  248. V_COMPEN(mc5->mode == MC5_MODE_72_BIT) |
  249. V_PRTYEN(mc5->parity_enabled) | F_MBUSEN);
  250. }
  251. /*
  252. * Initialization that requires the OS and protocol layers to already
  253. * be intialized goes here.
  254. */
  255. int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters,
  256. unsigned int nroutes)
  257. {
  258. u32 cfg;
  259. int err;
  260. unsigned int tcam_size = mc5->tcam_size;
  261. struct adapter *adap = mc5->adapter;
  262. if (nroutes > MAX_ROUTES || nroutes + nservers + nfilters > tcam_size)
  263. return -EINVAL;
  264. /* Reset the TCAM */
  265. cfg = t3_read_reg(adap, A_MC5_DB_CONFIG) & ~F_TMMODE;
  266. cfg |= V_TMMODE(mc5->mode == MC5_MODE_72_BIT) | F_TMRST;
  267. t3_write_reg(adap, A_MC5_DB_CONFIG, cfg);
  268. if (t3_wait_op_done(adap, A_MC5_DB_CONFIG, F_TMRDY, 1, 500, 0)) {
  269. CH_ERR(adap, "TCAM reset timed out\n");
  270. return -1;
  271. }
  272. t3_write_reg(adap, A_MC5_DB_ROUTING_TABLE_INDEX, tcam_size - nroutes);
  273. t3_write_reg(adap, A_MC5_DB_FILTER_TABLE,
  274. tcam_size - nroutes - nfilters);
  275. t3_write_reg(adap, A_MC5_DB_SERVER_INDEX,
  276. tcam_size - nroutes - nfilters - nservers);
  277. mc5->parity_enabled = 1;
  278. /* All the TCAM addresses we access have only the low 32 bits non 0 */
  279. t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR1, 0);
  280. t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR2, 0);
  281. mc5_dbgi_mode_enable(mc5);
  282. switch (mc5->part_type) {
  283. case IDT75P52100:
  284. err = init_idt52100(mc5);
  285. break;
  286. case IDT75N43102:
  287. err = init_idt43102(mc5);
  288. break;
  289. default:
  290. CH_ERR(adap, "Unsupported TCAM type %d\n", mc5->part_type);
  291. err = -EINVAL;
  292. break;
  293. }
  294. mc5_dbgi_mode_disable(mc5);
  295. return err;
  296. }
  297. /*
  298. * read_mc5_range - dump a part of the memory managed by MC5
  299. * @mc5: the MC5 handle
  300. * @start: the start address for the dump
  301. * @n: number of 72-bit words to read
  302. * @buf: result buffer
  303. *
  304. * Read n 72-bit words from MC5 memory from the given start location.
  305. */
  306. int t3_read_mc5_range(const struct mc5 *mc5, unsigned int start,
  307. unsigned int n, u32 *buf)
  308. {
  309. u32 read_cmd;
  310. int err = 0;
  311. struct adapter *adap = mc5->adapter;
  312. if (mc5->part_type == IDT75P52100)
  313. read_cmd = IDT_CMD_READ;
  314. else if (mc5->part_type == IDT75N43102)
  315. read_cmd = IDT4_CMD_READ;
  316. else
  317. return -EINVAL;
  318. mc5_dbgi_mode_enable(mc5);
  319. while (n--) {
  320. t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR0, start++);
  321. if (mc5_cmd_write(adap, read_cmd)) {
  322. err = -EIO;
  323. break;
  324. }
  325. dbgi_rd_rsp3(adap, buf + 2, buf + 1, buf);
  326. buf += 3;
  327. }
  328. mc5_dbgi_mode_disable(mc5);
  329. return 0;
  330. }
  331. #define MC5_INT_FATAL (F_PARITYERR | F_REQQPARERR | F_DISPQPARERR)
  332. /*
  333. * MC5 interrupt handler
  334. */
  335. void t3_mc5_intr_handler(struct mc5 *mc5)
  336. {
  337. struct adapter *adap = mc5->adapter;
  338. u32 cause = t3_read_reg(adap, A_MC5_DB_INT_CAUSE);
  339. if ((cause & F_PARITYERR) && mc5->parity_enabled) {
  340. CH_ALERT(adap, "MC5 parity error\n");
  341. mc5->stats.parity_err++;
  342. }
  343. if (cause & F_REQQPARERR) {
  344. CH_ALERT(adap, "MC5 request queue parity error\n");
  345. mc5->stats.reqq_parity_err++;
  346. }
  347. if (cause & F_DISPQPARERR) {
  348. CH_ALERT(adap, "MC5 dispatch queue parity error\n");
  349. mc5->stats.dispq_parity_err++;
  350. }
  351. if (cause & F_ACTRGNFULL)
  352. mc5->stats.active_rgn_full++;
  353. if (cause & F_NFASRCHFAIL)
  354. mc5->stats.nfa_srch_err++;
  355. if (cause & F_UNKNOWNCMD)
  356. mc5->stats.unknown_cmd++;
  357. if (cause & F_DELACTEMPTY)
  358. mc5->stats.del_act_empty++;
  359. if (cause & MC5_INT_FATAL)
  360. t3_fatal_err(adap);
  361. t3_write_reg(adap, A_MC5_DB_INT_CAUSE, cause);
  362. }
  363. void __devinit t3_mc5_prep(struct adapter *adapter, struct mc5 *mc5, int mode)
  364. {
  365. #define K * 1024
  366. static unsigned int tcam_part_size[] = { /* in K 72-bit entries */
  367. 64 K, 128 K, 256 K, 32 K
  368. };
  369. #undef K
  370. u32 cfg = t3_read_reg(adapter, A_MC5_DB_CONFIG);
  371. mc5->adapter = adapter;
  372. mc5->mode = (unsigned char)mode;
  373. mc5->part_type = (unsigned char)G_TMTYPE(cfg);
  374. if (cfg & F_TMTYPEHI)
  375. mc5->part_type |= 4;
  376. mc5->tcam_size = tcam_part_size[G_TMPARTSIZE(cfg)];
  377. if (mode == MC5_MODE_144_BIT)
  378. mc5->tcam_size /= 2;
  379. }