14d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/*
2a02d44a02bd2b3f3848f30e335adc3c076b3f905Divy Le Ray * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved.
34d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray *
41d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray * This software is available to you under a choice of one of two
51d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray * licenses.  You may choose to be licensed under the terms of the GNU
61d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray * General Public License (GPL) Version 2, available from the file
71d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray * COPYING in the main directory of this source tree, or the
81d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray * OpenIB.org BSD license below:
94d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray *
101d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray *     Redistribution and use in source and binary forms, with or
111d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray *     without modification, are permitted provided that the following
121d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray *     conditions are met:
131d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray *
141d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray *      - Redistributions of source code must retain the above
151d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray *        copyright notice, this list of conditions and the following
161d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray *        disclaimer.
171d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray *
181d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray *      - Redistributions in binary form must reproduce the above
191d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray *        copyright notice, this list of conditions and the following
201d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray *        disclaimer in the documentation and/or other materials
211d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray *        provided with the distribution.
221d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray *
231d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
241d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
251d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
261d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
271d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
281d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
291d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
301d68e93d65d63814388d1a0b3de028de6dc27ae0Divy Le Ray * SOFTWARE.
314d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */
324d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include "common.h"
334d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#include "regs.h"
344d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
354d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayenum {
364d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	IDT75P52100 = 4,
374d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	IDT75N43102 = 5
384d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray};
394d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
404d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* DBGI command mode */
414d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayenum {
424d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	DBGI_MODE_MBUS = 0,
434d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	DBGI_MODE_IDT52100 = 5
444d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray};
454d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
464d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* IDT 75P52100 commands */
474d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT_CMD_READ   0
484d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT_CMD_WRITE  1
494d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT_CMD_SEARCH 2
504d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT_CMD_LEARN  3
514d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
524d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* IDT LAR register address and value for 144-bit mode (low 32 bits) */
534d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT_LAR_ADR0   	0x180006
544d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT_LAR_MODE144	0xffff0000
554d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
564d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* IDT SCR and SSR addresses (low 32 bits) */
574d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT_SCR_ADR0  0x180000
584d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT_SSR0_ADR0 0x180002
594d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT_SSR1_ADR0 0x180004
604d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
614d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* IDT GMR base address (low 32 bits) */
624d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT_GMR_BASE_ADR0 0x180020
634d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
644d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* IDT data and mask array base addresses (low 32 bits) */
654d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT_DATARY_BASE_ADR0 0
664d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT_MSKARY_BASE_ADR0 0x80000
674d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
684d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* IDT 75N43102 commands */
694d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT4_CMD_SEARCH144 3
704d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT4_CMD_WRITE     4
714d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT4_CMD_READ      5
724d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
734d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* IDT 75N43102 SCR address (low 32 bits) */
744d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT4_SCR_ADR0  0x3
754d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
764d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* IDT 75N43102 GMR base addresses (low 32 bits) */
774d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT4_GMR_BASE0 0x10
784d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT4_GMR_BASE1 0x20
794d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT4_GMR_BASE2 0x30
804d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
814d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* IDT 75N43102 data and mask array base addresses (low 32 bits) */
824d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT4_DATARY_BASE_ADR0 0x1000000
834d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define IDT4_MSKARY_BASE_ADR0 0x2000000
844d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
854d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define MAX_WRITE_ATTEMPTS 5
864d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
874d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define MAX_ROUTES 2048
884d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
894d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/*
904d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Issue a command to the TCAM and wait for its completion.  The address and
914d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * any data required by the command must have been setup by the caller.
924d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */
934d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int mc5_cmd_write(struct adapter *adapter, u32 cmd)
944d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{
954d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_CMD, cmd);
964d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	return t3_wait_op_done(adapter, A_MC5_DB_DBGI_RSP_STATUS,
974d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray			       F_DBGIRSPVALID, 1, MAX_WRITE_ATTEMPTS, 1);
984d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray}
994d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
1004d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic inline void dbgi_wr_addr3(struct adapter *adapter, u32 v1, u32 v2,
1014d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray				 u32 v3)
1024d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{
1034d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR0, v1);
1044d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR1, v2);
1054d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR2, v3);
1064d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray}
1074d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
1084d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic inline void dbgi_wr_data3(struct adapter *adapter, u32 v1, u32 v2,
1094d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray				 u32 v3)
1104d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{
1114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA0, v1);
1124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA1, v2);
1134d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA2, v3);
1144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray}
1154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
1164d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic inline void dbgi_rd_rsp3(struct adapter *adapter, u32 *v1, u32 *v2,
1174d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray				u32 *v3)
1184d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{
1194d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	*v1 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA0);
1204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	*v2 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA1);
1214d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	*v3 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA2);
1224d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray}
1234d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
1244d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/*
1254d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Write data to the TCAM register at address (0, 0, addr_lo) using the TCAM
1264d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * command cmd.  The data to be written must have been set up by the caller.
1274d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Returns -1 on failure, 0 on success.
1284d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */
1294d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int mc5_write(struct adapter *adapter, u32 addr_lo, u32 cmd)
1304d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{
1314d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR0, addr_lo);
1324d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (mc5_cmd_write(adapter, cmd) == 0)
1334d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		return 0;
1344d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	CH_ERR(adapter, "MC5 timeout writing to TCAM address 0x%x\n",
1354d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	       addr_lo);
1364d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	return -1;
1374d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray}
1384d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
1394d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int init_mask_data_array(struct mc5 *mc5, u32 mask_array_base,
1404d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray				u32 data_array_base, u32 write_cmd,
1414d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray				int addr_shift)
1424d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{
1434d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	unsigned int i;
1444d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	struct adapter *adap = mc5->adapter;
1454d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
1464d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	/*
1474d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	 * We need the size of the TCAM data and mask arrays in terms of
1484d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	 * 72-bit entries.
1494d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	 */
1504d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	unsigned int size72 = mc5->tcam_size;
1514d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	unsigned int server_base = t3_read_reg(adap, A_MC5_DB_SERVER_INDEX);
1524d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
1534d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (mc5->mode == MC5_MODE_144_BIT) {
1544d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		size72 *= 2;	/* 1 144-bit entry is 2 72-bit entries */
1554d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		server_base *= 2;
1564d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	}
1574d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
1584d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	/* Clear the data array */
1594d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	dbgi_wr_data3(adap, 0, 0, 0);
1604d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	for (i = 0; i < size72; i++)
1614d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		if (mc5_write(adap, data_array_base + (i << addr_shift),
1624d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray			      write_cmd))
1634d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray			return -1;
1644d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
1654d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	/* Initialize the mask array. */
1664d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff);
1674d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	for (i = 0; i < size72; i++) {
1684d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		if (i == server_base)	/* entering server or routing region */
1694d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray			t3_write_reg(adap, A_MC5_DB_DBGI_REQ_DATA0,
1704d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray				     mc5->mode == MC5_MODE_144_BIT ?
1714d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray				     0xfffffff9 : 0xfffffffd);
1724d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		if (mc5_write(adap, mask_array_base + (i << addr_shift),
1734d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray			      write_cmd))
1744d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray			return -1;
1754d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	}
1764d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	return 0;
1774d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray}
1784d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
1794d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int init_idt52100(struct mc5 *mc5)
1804d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{
1814d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	int i;
1824d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	struct adapter *adap = mc5->adapter;
1834d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
1844d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_RSP_LATENCY,
1854d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		     V_RDLAT(0x15) | V_LRNLAT(0x15) | V_SRCHLAT(0x15));
1864d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_PART_ID_INDEX, 2);
1874d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
1884d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	/*
1894d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	 * Use GMRs 14-15 for ELOOKUP, GMRs 12-13 for SYN lookups, and
1904d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	 * GMRs 8-9 for ACK- and AOPEN searches.
1914d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	 */
1924d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_POPEN_DATA_WR_CMD, IDT_CMD_WRITE);
1934d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_POPEN_MASK_WR_CMD, IDT_CMD_WRITE);
1944d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_AOPEN_SRCH_CMD, IDT_CMD_SEARCH);
1954d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_AOPEN_LRN_CMD, IDT_CMD_LEARN);
1964d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_SYN_SRCH_CMD, IDT_CMD_SEARCH | 0x6000);
1974d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_SYN_LRN_CMD, IDT_CMD_LEARN);
1984d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_ACK_SRCH_CMD, IDT_CMD_SEARCH);
1994d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_ACK_LRN_CMD, IDT_CMD_LEARN);
2004d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_ILOOKUP_CMD, IDT_CMD_SEARCH);
2014d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_ELOOKUP_CMD, IDT_CMD_SEARCH | 0x7000);
2024d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_DATA_WRITE_CMD, IDT_CMD_WRITE);
2034d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_DATA_READ_CMD, IDT_CMD_READ);
2044d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2054d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	/* Set DBGI command mode for IDT TCAM. */
2064d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_DBGI_CONFIG, DBGI_MODE_IDT52100);
2074d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2084d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	/* Set up LAR */
2094d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	dbgi_wr_data3(adap, IDT_LAR_MODE144, 0, 0);
2104d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (mc5_write(adap, IDT_LAR_ADR0, IDT_CMD_WRITE))
2114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		goto err;
2124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2134d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	/* Set up SSRs */
2144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0);
2154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (mc5_write(adap, IDT_SSR0_ADR0, IDT_CMD_WRITE) ||
2164d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	    mc5_write(adap, IDT_SSR1_ADR0, IDT_CMD_WRITE))
2174d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		goto err;
2184d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2194d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	/* Set up GMRs */
2204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	for (i = 0; i < 32; ++i) {
2214d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		if (i >= 12 && i < 15)
2224d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray			dbgi_wr_data3(adap, 0xfffffff9, 0xffffffff, 0xff);
2234d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		else if (i == 15)
2244d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray			dbgi_wr_data3(adap, 0xfffffff9, 0xffff8007, 0xff);
2254d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		else
2264d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray			dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff);
2274d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2284d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		if (mc5_write(adap, IDT_GMR_BASE_ADR0 + i, IDT_CMD_WRITE))
2294d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray			goto err;
2304d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	}
2314d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2324d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	/* Set up SCR */
2334d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	dbgi_wr_data3(adap, 1, 0, 0);
2344d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (mc5_write(adap, IDT_SCR_ADR0, IDT_CMD_WRITE))
2354d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		goto err;
2364d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2374d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	return init_mask_data_array(mc5, IDT_MSKARY_BASE_ADR0,
2384d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray				    IDT_DATARY_BASE_ADR0, IDT_CMD_WRITE, 0);
2394d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayerr:
2404d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	return -EIO;
2414d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray}
2424d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2434d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic int init_idt43102(struct mc5 *mc5)
2444d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{
2454d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	int i;
2464d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	struct adapter *adap = mc5->adapter;
2474d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2484d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_RSP_LATENCY,
2494d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		     adap->params.rev == 0 ? V_RDLAT(0xd) | V_SRCHLAT(0x11) :
2504d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		     V_RDLAT(0xd) | V_SRCHLAT(0x12));
2514d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2524d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	/*
2534d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	 * Use GMRs 24-25 for ELOOKUP, GMRs 20-21 for SYN lookups, and no mask
2544d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	 * for ACK- and AOPEN searches.
2554d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	 */
2564d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_POPEN_DATA_WR_CMD, IDT4_CMD_WRITE);
2574d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_POPEN_MASK_WR_CMD, IDT4_CMD_WRITE);
2584d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_AOPEN_SRCH_CMD,
2594d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		     IDT4_CMD_SEARCH144 | 0x3800);
2604d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_SYN_SRCH_CMD, IDT4_CMD_SEARCH144);
2614d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_ACK_SRCH_CMD, IDT4_CMD_SEARCH144 | 0x3800);
2624d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_ILOOKUP_CMD, IDT4_CMD_SEARCH144 | 0x3800);
2634d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_ELOOKUP_CMD, IDT4_CMD_SEARCH144 | 0x800);
2644d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_DATA_WRITE_CMD, IDT4_CMD_WRITE);
2654d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_DATA_READ_CMD, IDT4_CMD_READ);
2664d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2674d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_PART_ID_INDEX, 3);
2684d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2694d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	/* Set DBGI command mode for IDT TCAM. */
2704d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_DBGI_CONFIG, DBGI_MODE_IDT52100);
2714d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2724d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	/* Set up GMRs */
2734d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff);
2744d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	for (i = 0; i < 7; ++i)
2754d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		if (mc5_write(adap, IDT4_GMR_BASE0 + i, IDT4_CMD_WRITE))
2764d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray			goto err;
2774d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2784d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	for (i = 0; i < 4; ++i)
2794d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		if (mc5_write(adap, IDT4_GMR_BASE2 + i, IDT4_CMD_WRITE))
2804d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray			goto err;
2814d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2824d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	dbgi_wr_data3(adap, 0xfffffff9, 0xffffffff, 0xff);
2834d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (mc5_write(adap, IDT4_GMR_BASE1, IDT4_CMD_WRITE) ||
2844d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	    mc5_write(adap, IDT4_GMR_BASE1 + 1, IDT4_CMD_WRITE) ||
2854d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	    mc5_write(adap, IDT4_GMR_BASE1 + 4, IDT4_CMD_WRITE))
2864d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		goto err;
2874d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2884d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	dbgi_wr_data3(adap, 0xfffffff9, 0xffff8007, 0xff);
2894d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (mc5_write(adap, IDT4_GMR_BASE1 + 5, IDT4_CMD_WRITE))
2904d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		goto err;
2914d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2924d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	/* Set up SCR */
2934d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	dbgi_wr_data3(adap, 0xf0000000, 0, 0);
2944d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (mc5_write(adap, IDT4_SCR_ADR0, IDT4_CMD_WRITE))
2954d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		goto err;
2964d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
2974d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	return init_mask_data_array(mc5, IDT4_MSKARY_BASE_ADR0,
2984d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray				    IDT4_DATARY_BASE_ADR0, IDT4_CMD_WRITE, 1);
2994d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayerr:
3004d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	return -EIO;
3014d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray}
3024d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
3034d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* Put MC5 in DBGI mode. */
3044d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic inline void mc5_dbgi_mode_enable(const struct mc5 *mc5)
3054d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{
3064d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(mc5->adapter, A_MC5_DB_CONFIG,
3074d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		     V_TMMODE(mc5->mode == MC5_MODE_72_BIT) | F_DBGIEN);
3084d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray}
3094d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
3104d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/* Put MC5 in M-Bus mode. */
3114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Raystatic void mc5_dbgi_mode_disable(const struct mc5 *mc5)
3124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{
3134d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(mc5->adapter, A_MC5_DB_CONFIG,
3144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		     V_TMMODE(mc5->mode == MC5_MODE_72_BIT) |
3154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		     V_COMPEN(mc5->mode == MC5_MODE_72_BIT) |
3164d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		     V_PRTYEN(mc5->parity_enabled) | F_MBUSEN);
3174d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray}
3184d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
3194d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/*
3204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * Initialization that requires the OS and protocol layers to already
321b595076a180a56d1bb170e6eceda6eb9d76f4cd3Uwe Kleine-König * be initialized goes here.
3224d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */
3234d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayint t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters,
3244d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		unsigned int nroutes)
3254d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{
3264d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	u32 cfg;
3274d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	int err;
3284d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	unsigned int tcam_size = mc5->tcam_size;
3294d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	struct adapter *adap = mc5->adapter;
3304d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
3318ac3ba68e25a73594646ec30b7c482b364644c92Divy Le Ray	if (!tcam_size)
3328ac3ba68e25a73594646ec30b7c482b364644c92Divy Le Ray		return 0;
3338ac3ba68e25a73594646ec30b7c482b364644c92Divy Le Ray
3344d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (nroutes > MAX_ROUTES || nroutes + nservers + nfilters > tcam_size)
3354d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		return -EINVAL;
3364d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
3374d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	/* Reset the TCAM */
3384d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	cfg = t3_read_reg(adap, A_MC5_DB_CONFIG) & ~F_TMMODE;
3394d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	cfg |= V_TMMODE(mc5->mode == MC5_MODE_72_BIT) | F_TMRST;
3404d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_CONFIG, cfg);
3414d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (t3_wait_op_done(adap, A_MC5_DB_CONFIG, F_TMRDY, 1, 500, 0)) {
3424d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		CH_ERR(adap, "TCAM reset timed out\n");
3434d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		return -1;
3444d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	}
3454d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
3464d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_ROUTING_TABLE_INDEX, tcam_size - nroutes);
3474d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_FILTER_TABLE,
3484d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		     tcam_size - nroutes - nfilters);
3494d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_SERVER_INDEX,
3504d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		     tcam_size - nroutes - nfilters - nservers);
3514d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
3524d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	mc5->parity_enabled = 1;
3534d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
3544d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	/* All the TCAM addresses we access have only the low 32 bits non 0 */
3554d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR1, 0);
3564d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR2, 0);
3574d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
3584d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	mc5_dbgi_mode_enable(mc5);
3594d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
3604d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	switch (mc5->part_type) {
3614d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	case IDT75P52100:
3624d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		err = init_idt52100(mc5);
3634d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		break;
3644d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	case IDT75N43102:
3654d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		err = init_idt43102(mc5);
3664d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		break;
3674d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	default:
3684d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		CH_ERR(adap, "Unsupported TCAM type %d\n", mc5->part_type);
3694d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		err = -EINVAL;
3704d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		break;
3714d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	}
3724d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
3734d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	mc5_dbgi_mode_disable(mc5);
3744d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	return err;
3754d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray}
3764d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
3774d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
3784d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define MC5_INT_FATAL (F_PARITYERR | F_REQQPARERR | F_DISPQPARERR)
3794d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
3804d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray/*
3814d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray * MC5 interrupt handler
3824d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray */
3834d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Rayvoid t3_mc5_intr_handler(struct mc5 *mc5)
3844d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{
3854d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	struct adapter *adap = mc5->adapter;
3864d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	u32 cause = t3_read_reg(adap, A_MC5_DB_INT_CAUSE);
3874d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
3884d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if ((cause & F_PARITYERR) && mc5->parity_enabled) {
3894d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		CH_ALERT(adap, "MC5 parity error\n");
3904d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		mc5->stats.parity_err++;
3914d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	}
3924d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
3934d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (cause & F_REQQPARERR) {
3944d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		CH_ALERT(adap, "MC5 request queue parity error\n");
3954d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		mc5->stats.reqq_parity_err++;
3964d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	}
3974d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
3984d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (cause & F_DISPQPARERR) {
3994d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		CH_ALERT(adap, "MC5 dispatch queue parity error\n");
4004d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		mc5->stats.dispq_parity_err++;
4014d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	}
4024d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
4034d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (cause & F_ACTRGNFULL)
4044d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		mc5->stats.active_rgn_full++;
4054d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (cause & F_NFASRCHFAIL)
4064d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		mc5->stats.nfa_srch_err++;
4074d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (cause & F_UNKNOWNCMD)
4084d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		mc5->stats.unknown_cmd++;
4094d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (cause & F_DELACTEMPTY)
4104d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		mc5->stats.del_act_empty++;
4114d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (cause & MC5_INT_FATAL)
4124d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		t3_fatal_err(adap);
4134d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
4144d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	t3_write_reg(adap, A_MC5_DB_INT_CAUSE, cause);
4154d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray}
4164d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
4177b9b09436b8720621e5594ce25fd25f34d5d42beRoland Dreiervoid t3_mc5_prep(struct adapter *adapter, struct mc5 *mc5, int mode)
4184d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray{
4194d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#define K * 1024
4204d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
4214d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	static unsigned int tcam_part_size[] = {	/* in K 72-bit entries */
4224d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		64 K, 128 K, 256 K, 32 K
4234d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	};
4244d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
4254d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray#undef K
4264d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
4274d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	u32 cfg = t3_read_reg(adapter, A_MC5_DB_CONFIG);
4284d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
4294d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	mc5->adapter = adapter;
4304d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	mc5->mode = (unsigned char)mode;
4314d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	mc5->part_type = (unsigned char)G_TMTYPE(cfg);
4324d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (cfg & F_TMTYPEHI)
4334d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		mc5->part_type |= 4;
4344d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray
4354d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	mc5->tcam_size = tcam_part_size[G_TMPARTSIZE(cfg)];
4364d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray	if (mode == MC5_MODE_144_BIT)
4374d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray		mc5->tcam_size /= 2;
4384d22de3e6cc4a09c369b504cd8bcde3385a974cdDivy Le Ray}
439