d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * CDDL HEADER START
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * The contents of this file are subject to the terms of the
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Common Development and Distribution License (the "License").
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * You may not use this file except in compliance with the License.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * or http://www.opensolaris.org/os/licensing.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * See the License for the specific language governing permissions
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * and limitations under the License.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * When distributing Covered Code, include this CDDL HEADER in each
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * If applicable, add the following below this CDDL HEADER, with the
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * fields enclosed by brackets "[]" replaced with your own identifying
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * information: Portions Copyright [yyyy] [name of copyright owner]
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * CDDL HEADER END
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Copyright (C) 2003-2005 Chelsio Communications. All rights reserved.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#pragma ident "%Z%%M% %I% %E% SMI" /* mc5.c */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "common.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "regs.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#include "mc5.h"
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* DBGI command mode */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwenum {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw DBGI_MODE_MBUS,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw DBGI_MODE_LARA_7000,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw DBGI_MODE_LARA_8000,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw DBGI_MODE_NETL_4000,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw DBGI_MODE_NETL_5000,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw DBGI_MODE_IDT_52100
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw};
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* Lara command register address and values (low 32 bits) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_LRA_CMDREG_ADR0 0x00180038
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_LRA_CMDREG_72KEY_DATA0 0x00000182
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_LRA_CMDREG_144KEY_DATA0 0x00AAAB82
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* Lara config register address and values (low 32 bits) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_LRA_CFGREG_ADR0 0x0018003D
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_LRA_CFGREG_72KEY_DATA0 0x00000000
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_LRA_CFGREG_144KEY_DATA0 0x55555555
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* Lara GMR base addresses (low 32 bits) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_LRA_GMRREG_BASE_ADR0_1 0x00180020
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_LRA_GMRREG_BASE_ADR0_2 0x00180060
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* Lara 7000 data and mask array base addresses (low 32 bits) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_LRA_DATARY_BASE_ADR0 0x00000000
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_LRA_MSKARY_BASE_ADR0 0x00080000
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* Lara commands */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_LRA_CMD_READ 0x00000000
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_LRA_CMD_WRITE 0x00010001
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_LRA_CMD_SEARCH 0x00020002
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_LRA_CMD_LEARN 0x00030003
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* IDT 75P52100 commands */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_IDT_CMD_READ 0x0
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_IDT_CMD_WRITE 0x1
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_IDT_CMD_SEARCH 0x2
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_IDT_CMD_LEARN 0x3
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_IDT_CMD_NFA_SEARCH 0x4
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* IDT LAR register address and value for 144-bit mode (low 32 bits) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_IDT_LAR_ADR0 0x180006
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_IDT_LAR_MODE144 0xffff0000
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* IDT SCR and SSR addresses (low 32 bits) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_IDT_SCR_ADR0 0x180000
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_IDT_SSR0_ADR0 0x180002
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_IDT_SSR1_ADR0 0x180004
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* IDT GMR base address (low 32 bits) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_IDT_GMR_BASE_ADR0 0x180020
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* IDT data and mask array base addresses (low 32 bits) */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_IDT_DATARY_BASE_ADR0 0x00000000
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_IDT_MSKARY_BASE_ADR0 0x00080000
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define IDT_ELOOKUP_2Mb 0x7000
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define IDT_ELOOKUP_9Mb 0x16000
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwenum {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw LARA_7000,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw LARA_8000,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw NETLOGIC_4000,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw NETLOGIC_5000,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw IDT75P52100
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw};
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic unsigned int tcam_part_size[] = {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw 4718592, /* 4.5Mb */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw 9437184, /* 9Mb */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw 18874368 /* 18Mb */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw};
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstruct pemc5 {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw adapter_t *adapter;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned int tcam_size;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned int part_size;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned char part_type;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned char parity_enabled;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned char issue_syn;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned char mode;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw struct pemc5_intr_counts intr_counts;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#ifdef SUPPORT_MODE72
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 lip[MC5_LIP_NUM_OF_ENTRIES];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned int lip_index;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw};
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MAX_WRITE_ATTEMPTS 5
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Issue a command to the TCAM and wait for its completion. The address and
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * any data required by the command must have been setup by the caller.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int mc5_cmd_write(adapter_t *adapter, u32 cmd)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adapter, A_MC5_DBGI_REQ_CMD, cmd);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return t1_wait_op_done(adapter, A_MC5_DBGI_RSP_STATUS,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw F_DBGI_RSP_VALID, 1, MAX_WRITE_ATTEMPTS, 1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwunsigned int t1_mc5_get_tcam_size(struct pemc5 *mc5)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return mc5->tcam_size;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int set_tcam_rtbl_base(struct pemc5 *mc5, unsigned int rtbl_base)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (rtbl_base >= t1_mc5_get_tcam_size(mc5)) return -1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(mc5->adapter, A_MC5_ROUTING_TABLE_INDEX, rtbl_base);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwunsigned int t1_mc5_get_tcam_rtbl_base(struct pemc5 *mc5)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return t1_read_reg_4(mc5->adapter, A_MC5_ROUTING_TABLE_INDEX);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwunsigned int t1_mc5_get_tcam_rtbl_size(struct pemc5 *mc5)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned int tcam_size = t1_mc5_get_tcam_size(mc5);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned int tcam_rtable_base = t1_mc5_get_tcam_rtbl_base(mc5);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return tcam_size - tcam_rtable_base;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int set_tcam_server_base(struct pemc5 *mc5, unsigned int server_base)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (server_base >= t1_mc5_get_tcam_size(mc5)) return -1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(mc5->adapter, A_MC5_SERVER_INDEX, server_base);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwunsigned int t1_mc5_get_tcam_server_base(struct pemc5 *mc5)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return t1_read_reg_4(mc5->adapter, A_MC5_SERVER_INDEX);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwunsigned int t1_mc5_get_tcam_server_size(struct pemc5 *mc5)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned int tcam_rtable_base = t1_mc5_get_tcam_rtbl_base(mc5);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned int tcam_server_base = t1_mc5_get_tcam_server_base(mc5);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return tcam_rtable_base - tcam_server_base;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic inline void dbgi_wr_addr3(adapter_t *adapter, u32 v1, u32 v2, u32 v3)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adapter, A_MC5_DBGI_REQ_ADDR0, v1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adapter, A_MC5_DBGI_REQ_ADDR1, v2);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adapter, A_MC5_DBGI_REQ_ADDR2, v3);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic inline void dbgi_wr_data3(adapter_t *adapter, u32 v1, u32 v2, u32 v3)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adapter, A_MC5_DBGI_REQ_DATA0, v1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adapter, A_MC5_DBGI_REQ_DATA1, v2);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adapter, A_MC5_DBGI_REQ_DATA2, v3);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic inline void dbgi_rd_rsp3(adapter_t *adapter, u32 *v1, u32 *v2, u32 *v3)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *v1 = t1_read_reg_4(adapter, A_MC5_DBGI_RSP_DATA0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *v2 = t1_read_reg_4(adapter, A_MC5_DBGI_RSP_DATA1);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *v3 = t1_read_reg_4(adapter, A_MC5_DBGI_RSP_DATA2);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Write data to the TCAM register at address (0, 0, addr_lo) using the TCAM
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * command cmd. The data to be written must have been set up by the caller.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Returns -1 on failure, 0 on success.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int mc5_write(adapter_t *adapter, u32 addr_lo, u32 cmd)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adapter, A_MC5_DBGI_REQ_ADDR0, addr_lo);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5_cmd_write(adapter, cmd) == 0)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw CH_ERR("%s: MC5 timeout writing to TCAM address 0x%x\n",
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw adapter_name(adapter), addr_lo);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return -1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int init_mask_data_array(struct pemc5 *mc5, u32 mask_array_base,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 data_array_base, u32 write_cmd)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned int i;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw adapter_t *adap = mc5->adapter;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * We need the size of the TCAM data and mask arrays in terms of
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * 72-bit entries.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned int size72 = tcam_part_size[mc5->part_size] / 72;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned int server_base = t1_mc5_get_tcam_server_base(mc5);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5->mode == MC5_MODE_144_BIT)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw server_base *= 2; /* 1 144-bit entry is 2 72-bit entries */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Clear the data array */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dbgi_wr_data3(adap, 0, 0, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for (i = 0; i < size72; i++)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5_write(adap, data_array_base + i, write_cmd))
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return -1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Initialize the mask array. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for (i = 0; i < size72; i++) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (i == server_base) /* entering server or routing region */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_DBGI_REQ_DATA0,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->mode == MC5_MODE_144_BIT ?
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw 0xfffffff9 : 0xfffffffd);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5_write(adap, mask_array_base + i, write_cmd))
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return -1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int init_lara7000(struct pemc5 *mc5)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int i;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw adapter_t *adap = mc5->adapter;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_RSP_LATENCY,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_is_asic(adap) ? 0x0a0a0a0a : 0x09090909);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5->parity_enabled) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_AOPEN_SRCH_CMD, 0x20022);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_SYN_SRCH_CMD, 0x20022);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_ACK_SRCH_CMD, 0x20022);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Set DBGI command mode for Lara TCAM. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_DBGI_CONFIG, DBGI_MODE_LARA_7000);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dbgi_wr_data3(adap, mc5->mode == MC5_MODE_144_BIT ?
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw MC5_LRA_CMDREG_144KEY_DATA0 : MC5_LRA_CMDREG_72KEY_DATA0,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw 0, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5_write(adap, MC5_LRA_CMDREG_ADR0, MC5_LRA_CMD_WRITE))
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto err;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dbgi_wr_data3(adap, mc5->mode == MC5_MODE_144_BIT ?
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw MC5_LRA_CFGREG_144KEY_DATA0 : MC5_LRA_CFGREG_72KEY_DATA0,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw 0, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5_write(adap, MC5_LRA_CFGREG_ADR0, MC5_LRA_CMD_WRITE))
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto err;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Global Mask Registers (GMR) 0-15 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for (i = 0; i < 16; i++) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (i == 8 || i == 9)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dbgi_wr_data3(adap, mc5->mode == MC5_MODE_72_BIT ?
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw 0xfffffffd : 0xfffffff9, 0xffffffff,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw 0xff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5_write(adap, MC5_LRA_GMRREG_BASE_ADR0_1 + i,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw MC5_LRA_CMD_WRITE))
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto err;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Global Mask Registers (GMR) 16-31 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for (i = 0; i < 16; i++) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (i <= 1 && mc5->mode == MC5_MODE_72_BIT)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dbgi_wr_data3(adap, 0xfffffffd, 0xffffc003, 0xff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else if (i == 0)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dbgi_wr_data3(adap, 0xfffffff9, 0xffffffff, 0xff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else if (i == 1)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dbgi_wr_data3(adap, 0xfffffff9, 0xffff8007, 0xff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5_write(adap, MC5_LRA_GMRREG_BASE_ADR0_2 + i,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw MC5_LRA_CMD_WRITE))
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto err;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return init_mask_data_array(mc5, MC5_LRA_MSKARY_BASE_ADR0,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw MC5_LRA_DATARY_BASE_ADR0,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw MC5_LRA_CMD_WRITE);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw err:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return -EIO;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int init_idt52100(struct pemc5 *mc5)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int i;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw adapter_t *adap = mc5->adapter;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_RSP_LATENCY, 0x151515);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_PART_ID_INDEX, 2);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Use GMRs 8-9 for ACK and AOPEN searches, GMRs 12-13 for SYN search,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * and GMRs 14-15 for ELOOKUP.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_POPEN_DATA_WR_CMD, MC5_IDT_CMD_WRITE);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_POPEN_MASK_WR_CMD, MC5_IDT_CMD_WRITE);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_AOPEN_SRCH_CMD, MC5_IDT_CMD_SEARCH);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_AOPEN_LRN_CMD, MC5_IDT_CMD_LEARN);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_SYN_SRCH_CMD, MC5_IDT_CMD_SEARCH | 0x6000);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_SYN_LRN_CMD, MC5_IDT_CMD_LEARN);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_ACK_SRCH_CMD, MC5_IDT_CMD_SEARCH);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_ACK_LRN_CMD, MC5_IDT_CMD_LEARN);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_ILOOKUP_CMD, MC5_IDT_CMD_SEARCH);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_ELOOKUP_CMD, MC5_IDT_CMD_SEARCH | 0x7000);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_DATA_WRITE_CMD, MC5_IDT_CMD_WRITE);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_DATA_READ_CMD, MC5_IDT_CMD_READ);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Set DBGI command mode for IDT TCAM. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_DBGI_CONFIG, DBGI_MODE_IDT_52100);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Set up LAR */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dbgi_wr_data3(adap, MC5_IDT_LAR_MODE144, 0, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5_write(adap, MC5_IDT_LAR_ADR0, MC5_IDT_CMD_WRITE))
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto err;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Set up SSRs */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5_write(adap, MC5_IDT_SSR0_ADR0, MC5_IDT_CMD_WRITE) ||
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5_write(adap, MC5_IDT_SSR1_ADR0, MC5_IDT_CMD_WRITE))
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto err;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Set up GMRs */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for (i = 0; i < 32; ++i) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (i >= 12 && i < 15)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dbgi_wr_data3(adap, 0xfffffff9, 0xffffffff, 0xff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else if (i == 15)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dbgi_wr_data3(adap, 0xfffffff9, 0xffff8007, 0xff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5_write(adap, MC5_IDT_GMR_BASE_ADR0 + i,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw MC5_IDT_CMD_WRITE))
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto err;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Set up SCR */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dbgi_wr_data3(adap, 1, 0, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5_write(adap, MC5_IDT_SCR_ADR0, MC5_IDT_CMD_WRITE))
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw goto err;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return init_mask_data_array(mc5, MC5_IDT_MSKARY_BASE_ADR0,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw MC5_IDT_DATARY_BASE_ADR0,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw MC5_IDT_CMD_WRITE);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw err:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return -EIO;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* Put MC5 in DBGI mode. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic inline void mc5_dbgi_mode_enable(struct pemc5 *mc5)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(mc5->adapter, A_MC5_CONFIG,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw V_MODE(mc5->mode == MC5_MODE_72_BIT) |
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw F_DBGI_ENABLE | V_NUM_LIP(MC5_LIP_NUM_OF_ENTRIES - 1));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/* Put MC5 in M-Bus mode. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic void mc5_dbgi_mode_disable(struct pemc5 *mc5)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(mc5->adapter, A_MC5_CONFIG,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw V_MODE(mc5->mode == MC5_MODE_72_BIT) |
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw V_COMPRESSION_ENABLE(mc5->mode == MC5_MODE_72_BIT) |
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw V_PARITY_ENABLE(mc5->parity_enabled) |
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw V_SYN_ISSUE_MODE(mc5->issue_syn) | F_M_BUS_ENABLE |
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw V_NUM_LIP(MC5_LIP_NUM_OF_ENTRIES - 1));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Initialization that requires the OS and protocol layers to already
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * be intialized goes here.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwint t1_mc5_init(struct pemc5 *mc5, unsigned int nservers,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned int nroutes, int parity, int syn)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 cfg;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int err = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned int tcam_size = t1_mc5_get_tcam_size(mc5);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw adapter_t *adap = mc5->adapter;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Reset the TCAM */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cfg = t1_read_reg_4(adap, A_MC5_CONFIG) & ~F_MODE;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cfg |= V_MODE(mc5->mode == MC5_MODE_72_BIT) | F_TCAM_RESET;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_CONFIG, cfg);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (t1_wait_op_done(adap, A_MC5_CONFIG, F_TCAM_READY, 1, 500, 0)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw CH_ERR("%s: TCAM reset timed out\n", adapter_name(adap));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return -1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (set_tcam_rtbl_base(mc5, tcam_size - nroutes) ||
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw set_tcam_server_base(mc5, tcam_size - nroutes - nservers))
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return -EINVAL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#ifdef SUPPORT_MODE72
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5->mode == MC5_MODE_72_BIT)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_mc5_lip_write_entries(mc5);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->issue_syn = (unsigned char)syn;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->parity_enabled = (unsigned char)parity;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* All the TCAM addresses we access have only the low 32 bits non 0 */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_DBGI_REQ_ADDR1, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_DBGI_REQ_ADDR2, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5_dbgi_mode_enable(mc5);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw switch (mc5->part_type) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw case LARA_7000:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw err = init_lara7000(mc5);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw case IDT75P52100:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw err = init_idt52100(mc5);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw default:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw CH_ERR("%s: unsupported TCAM type\n", adapter_name(adap));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw err = -EINVAL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5_dbgi_mode_disable(mc5);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return err;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * read_mc5_range - dump a part of the memory managed by MC5
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * @mc5: the MC5 handle
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * @start: the start address for the dump
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * @n: number of 72-bit words to read
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * @buf: result buffer
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Read n 72-bit words from MC5 memory from the given start location.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwint t1_read_mc5_range(struct pemc5 *mc5, unsigned int start,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw unsigned int n, u32 *buf)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 read_cmd;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* int err = 0; */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw adapter_t *adap = mc5->adapter;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5->part_type == LARA_7000)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw read_cmd = MC5_LRA_CMD_READ;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else if (mc5->part_type == IDT75P52100)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw read_cmd = MC5_IDT_CMD_READ;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return -EINVAL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5_dbgi_mode_enable(mc5);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw while (n--) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_DBGI_REQ_ADDR0, start++);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5_cmd_write(adap, read_cmd)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* err = -EIO; */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw break;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw dbgi_rd_rsp3(adap, buf + 2, buf + 1, buf);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw buf += 3;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5_dbgi_mode_disable(mc5);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_INT_MASK (F_MC5_INT_HIT_OUT_ACTIVE_REGION_ERR | \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw F_MC5_INT_HIT_IN_RT_REGION_ERR | F_MC5_INT_LIP0_ERR | \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw F_MC5_INT_LIP_MISS_ERR | F_MC5_INT_PARITY_ERR | \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw F_MC5_INT_ACTIVE_REGION_FULL | F_MC5_INT_NFA_SRCH_ERR | \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw F_MC5_INT_UNKNOWN_CMD | F_MC5_INT_DEL_ACT_EMPTY)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#define MC5_INT_FATAL (F_MC5_INT_PARITY_ERR | F_MC5_INT_REQUESTQ_PARITY_ERR | \
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw F_MC5_INT_DISPATCHQ_PARITY_ERR)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid t1_mc5_intr_enable(struct pemc5 *mc5)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 mask = MC5_INT_MASK;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (!mc5->parity_enabled)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mask &= ~F_MC5_INT_PARITY_ERR;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#ifdef CONFIG_CHELSIO_T1_1G
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (!t1_is_asic(mc5->adapter)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Enable child block for MC5.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * NOTE: Assumes TP parent interrupt block is enabled.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * MC5 requires TP parent block to be enabled.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(mc5->adapter, A_MC5_INT_ENABLE, mask);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw } else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 pl_intr = t1_read_reg_4(mc5->adapter, A_PL_ENABLE);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(mc5->adapter, A_PL_ENABLE,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pl_intr | F_PL_INTR_MC5);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(mc5->adapter, A_MC5_INT_ENABLE,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mask | F_MC5_INT_REQUESTQ_PARITY_ERR |
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw F_MC5_INT_DISPATCHQ_PARITY_ERR);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid t1_mc5_intr_disable(struct pemc5 *mc5)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#ifdef CONFIG_CHELSIO_T1_1G
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (!t1_is_asic(mc5->adapter))
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(mc5->adapter, A_MC5_INT_ENABLE, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 pl_intr = t1_read_reg_4(mc5->adapter, A_PL_ENABLE);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(mc5->adapter, A_PL_ENABLE,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw pl_intr & ~F_PL_INTR_MC5);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(mc5->adapter, A_MC5_INT_ENABLE, 0);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid t1_mc5_intr_clear(struct pemc5 *mc5)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#ifdef CONFIG_CHELSIO_T1_1G
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (!t1_is_asic(mc5->adapter)) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(mc5->adapter, A_MC5_INT_CAUSE, 0xffffffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw } else
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(mc5->adapter, A_PL_CAUSE, F_PL_INTR_MC5);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(mc5->adapter, A_MC5_INT_CAUSE, 0xffffffff);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * We don't really do anything with MC5 interrupts, just record them.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid t1_mc5_intr_handler(struct pemc5 *mc5)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw adapter_t *adap = mc5->adapter;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 cause = t1_read_reg_4(adap, A_MC5_INT_CAUSE);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cause & F_MC5_INT_HIT_OUT_ACTIVE_REGION_ERR)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->intr_counts.hit_out_active_region_err++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cause & F_MC5_INT_HIT_IN_ACTIVE_REGION_ERR)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->intr_counts.hit_in_active_region_err++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cause & F_MC5_INT_HIT_IN_RT_REGION_ERR)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->intr_counts.hit_in_routing_region_err++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cause & F_MC5_INT_MISS_ERR)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->intr_counts.miss_err++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cause & F_MC5_INT_LIP0_ERR)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->intr_counts.lip_equal_zero_err++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cause & F_MC5_INT_LIP_MISS_ERR)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->intr_counts.lip_miss_err++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if ((cause & F_MC5_INT_PARITY_ERR) && mc5->parity_enabled) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw CH_ALERT("%s: MC5 parity error\n", adapter_name(adap));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->intr_counts.parity_err++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cause & F_MC5_INT_ACTIVE_REGION_FULL)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->intr_counts.active_region_full_err++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cause & F_MC5_INT_NFA_SRCH_ERR)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->intr_counts.next_free_addr_srch_err++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cause & F_MC5_INT_SYN_COOKIE)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->intr_counts.syn_cookie++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cause & F_MC5_INT_SYN_COOKIE_BAD)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->intr_counts.syn_cookie_bad_message++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cause & F_MC5_INT_SYN_COOKIE_OFF)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->intr_counts.syn_cookie_off_message++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cause & F_MC5_INT_UNKNOWN_CMD)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->intr_counts.receive_unknown_cmd++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cause & F_MC5_INT_REQUESTQ_PARITY_ERR) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw CH_ALERT("%s: MC5 request queue parity error\n",
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw adapter_name(adap));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->intr_counts.parity_in_request_q_err++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cause & F_MC5_INT_DISPATCHQ_PARITY_ERR) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw CH_ALERT("%s: MC5 dispatch queue parity error\n",
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw adapter_name(adap));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->intr_counts.parity_in_dispatch_q_err++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cause & F_MC5_INT_DEL_ACT_EMPTY)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->intr_counts.del_and_act_is_empty++;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cause & MC5_INT_FATAL)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_fatal_err(adap);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(adap, A_MC5_INT_CAUSE, cause);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwconst struct pemc5_intr_counts *t1_mc5_get_intr_counts(struct pemc5 *mc5)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return &mc5->intr_counts;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstruct pemc5 * __devinit t1_mc5_create(adapter_t *adapter, int mode)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw struct pemc5 *mc5;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 cfg, bits_per_entry;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mode != MC5_MODE_144_BIT && mode != MC5_MODE_72_BIT)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5 = t1_os_malloc_wait_zero(sizeof(*mc5));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (!mc5) return NULL;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->adapter = adapter;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->mode = (unsigned char) mode;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cfg = t1_read_reg_4(adapter, A_MC5_CONFIG);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->part_size = G_TCAM_PART_SIZE(cfg);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->part_type = (unsigned char) G_TCAM_PART_TYPE(cfg);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (cfg & F_TCAM_PART_TYPE_HI)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->part_type |= 4;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Calculate the size of the TCAM based on the total memory, mode, and
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * count information retrieved from the hardware.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw bits_per_entry = mode == MC5_MODE_144_BIT ? 144 : 72;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->tcam_size = tcam_part_size[mc5->part_size] / bits_per_entry;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return mc5;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid t1_mc5_destroy(struct pemc5 *mc5)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_os_free((void *)mc5, sizeof(*mc5));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#ifdef SUPPORT_MODE72
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int mc5_cmp(const void *pi, const void *pj)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw const u32 *pii = (const u32 *)pi;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw const u32 *pjj = (const u32 *)pj;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (*pii < *pjj)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return -1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return *pii > *pjj;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * DESC: Write local IP addresses to the TCAM
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw *
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * NOTES: IP addresses should be in host byte order. So, an IP address:
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * of 10.0.0.140 == (data = 0x0A00008C)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwstatic int mc5_set_lip_entries(struct pemc5 *mc5, u32 *p,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int num_of_lip_addresses)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int i;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Disable compression and M bus mode so that the TP core
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * doesn't access the TCAM while we are writing.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 cfg = t1_read_reg_4(mc5->adapter, A_MC5_CONFIG);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(mc5->adapter, A_MC5_CONFIG,
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw cfg & ~(F_M_BUS_ENABLE | F_COMPRESSION_ENABLE));
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* MC5 should now be ready to program the LIP addresses. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for (i = 0; i < num_of_lip_addresses; i++) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(mc5->adapter, A_MC5_LIP_RAM_DATA, p[i]);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(mc5->adapter, A_MC5_LIP_RAM_ADDR, 0x100 + i);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw /* Restore MC5 mode. */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw t1_write_reg_4(mc5->adapter, A_MC5_CONFIG, cfg | F_COMPRESSION_ENABLE);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * The purpose of this routine is to write all of the local IP addresses
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * into the TCAM in sorted order. This is a requirement from the TCAM.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid t1_mc5_lip_write_entries(struct pemc5 *mc5)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw u32 filler = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw int i;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5->lip_index) {
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw qsort(mc5->lip, mc5->lip_index, sizeof(u32), mc5_cmp);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw filler = mc5->lip[mc5->lip_index - 1];
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw }
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw for (i = mc5->lip_index; i < MC5_LIP_NUM_OF_ENTRIES; i++)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->lip[i] = filler;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5_set_lip_entries(mc5, mc5->lip, MC5_LIP_NUM_OF_ENTRIES);
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwvoid t1_mc5_lip_clear_entries(struct pemc5 *mc5)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->lip_index = 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw/*
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw * Add a local IP address to the LIP table.
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw */
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xwint t1_mc5_lip_add_entry(struct pemc5 *mc5, u32 lip)
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw{
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw if (mc5->lip_index >= MC5_LIP_NUM_OF_ENTRIES) return 1;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw mc5->lip[mc5->lip_index++] = lip;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw return 0;
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw}
d39a76e7b087a3d0927cbe6898dc0a6770fa6c68xw#endif