cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bnx2x_init_ops.h (27467B)


      1/* bnx2x_init_ops.h: Qlogic Everest network driver.
      2 *               Static functions needed during the initialization.
      3 *               This file is "included" in bnx2x_main.c.
      4 *
      5 * Copyright (c) 2007-2013 Broadcom Corporation
      6 * Copyright (c) 2014 QLogic Corporation
      7 All rights reserved
      8 *
      9 * This program is free software; you can redistribute it and/or modify
     10 * it under the terms of the GNU General Public License as published by
     11 * the Free Software Foundation.
     12 *
     13 * Maintained by: Ariel Elior <ariel.elior@qlogic.com>
     14 * Written by: Vladislav Zolotarov
     15 */
     16
     17#ifndef BNX2X_INIT_OPS_H
     18#define BNX2X_INIT_OPS_H
     19
     20
     21#ifndef BP_ILT
     22#define BP_ILT(bp)	NULL
     23#endif
     24
     25#ifndef BP_FUNC
     26#define BP_FUNC(bp)	0
     27#endif
     28
     29#ifndef BP_PORT
     30#define BP_PORT(bp)	0
     31#endif
     32
     33#ifndef BNX2X_ILT_FREE
     34#define BNX2X_ILT_FREE(x, y, sz)
     35#endif
     36
     37#ifndef BNX2X_ILT_ZALLOC
     38#define BNX2X_ILT_ZALLOC(x, y, sz)
     39#endif
     40
     41#ifndef ILOG2
     42#define ILOG2(x)	x
     43#endif
     44
     45static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len);
     46static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
     47static void bnx2x_write_dmae_phys_len(struct bnx2x *bp,
     48				      dma_addr_t phys_addr, u32 addr,
     49				      u32 len);
     50
     51static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr,
     52			      const u32 *data, u32 len)
     53{
     54	u32 i;
     55
     56	for (i = 0; i < len; i++)
     57		REG_WR(bp, addr + i*4, data[i]);
     58}
     59
     60static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr,
     61			      const u32 *data, u32 len)
     62{
     63	u32 i;
     64
     65	for (i = 0; i < len; i++)
     66		bnx2x_reg_wr_ind(bp, addr + i*4, data[i]);
     67}
     68
     69static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len,
     70				u8 wb)
     71{
     72	if (bp->dmae_ready)
     73		bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len);
     74
     75	/* in E1 chips BIOS initiated ZLR may interrupt widebus writes */
     76	else if (wb && CHIP_IS_E1(bp))
     77		bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len);
     78
     79	/* in later chips PXP root complex handles BIOS ZLR w/o interrupting */
     80	else
     81		bnx2x_init_str_wr(bp, addr, GUNZIP_BUF(bp), len);
     82}
     83
     84static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill,
     85			    u32 len, u8 wb)
     86{
     87	u32 buf_len = (((len*4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len*4));
     88	u32 buf_len32 = buf_len/4;
     89	u32 i;
     90
     91	memset(GUNZIP_BUF(bp), (u8)fill, buf_len);
     92
     93	for (i = 0; i < len; i += buf_len32) {
     94		u32 cur_len = min(buf_len32, len - i);
     95
     96		bnx2x_write_big_buf(bp, addr + i*4, cur_len, wb);
     97	}
     98}
     99
    100static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len)
    101{
    102	if (bp->dmae_ready)
    103		bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len);
    104
    105	/* in E1 chips BIOS initiated ZLR may interrupt widebus writes */
    106	else if (CHIP_IS_E1(bp))
    107		bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len);
    108
    109	/* in later chips PXP root complex handles BIOS ZLR w/o interrupting */
    110	else
    111		bnx2x_init_str_wr(bp, addr, GUNZIP_BUF(bp), len);
    112}
    113
    114static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr,
    115			     const u32 *data, u32 len64)
    116{
    117	u32 buf_len32 = FW_BUF_SIZE/4;
    118	u32 len = len64*2;
    119	u64 data64 = 0;
    120	u32 i;
    121
    122	/* 64 bit value is in a blob: first low DWORD, then high DWORD */
    123	data64 = HILO_U64((*(data + 1)), (*data));
    124
    125	len64 = min((u32)(FW_BUF_SIZE/8), len64);
    126	for (i = 0; i < len64; i++) {
    127		u64 *pdata = ((u64 *)(GUNZIP_BUF(bp))) + i;
    128
    129		*pdata = data64;
    130	}
    131
    132	for (i = 0; i < len; i += buf_len32) {
    133		u32 cur_len = min(buf_len32, len - i);
    134
    135		bnx2x_write_big_buf_wb(bp, addr + i*4, cur_len);
    136	}
    137}
    138
    139/*********************************************************
    140   There are different blobs for each PRAM section.
    141   In addition, each blob write operation is divided into a few operations
    142   in order to decrease the amount of phys. contiguous buffer needed.
    143   Thus, when we select a blob the address may be with some offset
    144   from the beginning of PRAM section.
    145   The same holds for the INT_TABLE sections.
    146**********************************************************/
    147#define IF_IS_INT_TABLE_ADDR(base, addr) \
    148			if (((base) <= (addr)) && ((base) + 0x400 >= (addr)))
    149
    150#define IF_IS_PRAM_ADDR(base, addr) \
    151			if (((base) <= (addr)) && ((base) + 0x40000 >= (addr)))
    152
    153static const u8 *bnx2x_sel_blob(struct bnx2x *bp, u32 addr,
    154				const u8 *data)
    155{
    156	IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr)
    157		data = INIT_TSEM_INT_TABLE_DATA(bp);
    158	else
    159		IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
    160			data = INIT_CSEM_INT_TABLE_DATA(bp);
    161	else
    162		IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
    163			data = INIT_USEM_INT_TABLE_DATA(bp);
    164	else
    165		IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
    166			data = INIT_XSEM_INT_TABLE_DATA(bp);
    167	else
    168		IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
    169			data = INIT_TSEM_PRAM_DATA(bp);
    170	else
    171		IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr)
    172			data = INIT_CSEM_PRAM_DATA(bp);
    173	else
    174		IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr)
    175			data = INIT_USEM_PRAM_DATA(bp);
    176	else
    177		IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr)
    178			data = INIT_XSEM_PRAM_DATA(bp);
    179
    180	return data;
    181}
    182
    183static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr,
    184			     const u32 *data, u32 len)
    185{
    186	if (bp->dmae_ready)
    187		VIRT_WR_DMAE_LEN(bp, data, addr, len, 0);
    188
    189	/* in E1 chips BIOS initiated ZLR may interrupt widebus writes */
    190	else if (CHIP_IS_E1(bp))
    191		bnx2x_init_ind_wr(bp, addr, data, len);
    192
    193	/* in later chips PXP root complex handles BIOS ZLR w/o interrupting */
    194	else
    195		bnx2x_init_str_wr(bp, addr, data, len);
    196}
    197
    198static void bnx2x_wr_64(struct bnx2x *bp, u32 reg, u32 val_lo,
    199			u32 val_hi)
    200{
    201	u32 wb_write[2];
    202
    203	wb_write[0] = val_lo;
    204	wb_write[1] = val_hi;
    205	REG_WR_DMAE_LEN(bp, reg, wb_write, 2);
    206}
    207static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr, u32 len,
    208			     u32 blob_off)
    209{
    210	const u8 *data = NULL;
    211	int rc;
    212	u32 i;
    213
    214	data = bnx2x_sel_blob(bp, addr, data) + blob_off*4;
    215
    216	rc = bnx2x_gunzip(bp, data, len);
    217	if (rc)
    218		return;
    219
    220	/* gunzip_outlen is in dwords */
    221	len = GUNZIP_OUTLEN(bp);
    222	for (i = 0; i < len; i++)
    223		((u32 *)GUNZIP_BUF(bp))[i] = (__force u32)
    224				cpu_to_le32(((u32 *)GUNZIP_BUF(bp))[i]);
    225
    226	bnx2x_write_big_buf_wb(bp, addr, len);
    227}
    228
    229static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
    230{
    231	u16 op_start =
    232		INIT_OPS_OFFSETS(bp)[BLOCK_OPS_IDX(block, stage,
    233						     STAGE_START)];
    234	u16 op_end =
    235		INIT_OPS_OFFSETS(bp)[BLOCK_OPS_IDX(block, stage,
    236						     STAGE_END)];
    237	const union init_op *op;
    238	u32 op_idx, op_type, addr, len;
    239	const u32 *data, *data_base;
    240
    241	/* If empty block */
    242	if (op_start == op_end)
    243		return;
    244
    245	data_base = INIT_DATA(bp);
    246
    247	for (op_idx = op_start; op_idx < op_end; op_idx++) {
    248
    249		op = (const union init_op *)&(INIT_OPS(bp)[op_idx]);
    250		/* Get generic data */
    251		op_type = op->raw.op;
    252		addr = op->raw.offset;
    253		/* Get data that's used for OP_SW, OP_WB, OP_FW, OP_ZP and
    254		 * OP_WR64 (we assume that op_arr_write and op_write have the
    255		 * same structure).
    256		 */
    257		len = op->arr_wr.data_len;
    258		data = data_base + op->arr_wr.data_off;
    259
    260		switch (op_type) {
    261		case OP_RD:
    262			REG_RD(bp, addr);
    263			break;
    264		case OP_WR:
    265			REG_WR(bp, addr, op->write.val);
    266			break;
    267		case OP_SW:
    268			bnx2x_init_str_wr(bp, addr, data, len);
    269			break;
    270		case OP_WB:
    271			bnx2x_init_wr_wb(bp, addr, data, len);
    272			break;
    273		case OP_ZR:
    274			bnx2x_init_fill(bp, addr, 0, op->zero.len, 0);
    275			break;
    276		case OP_WB_ZR:
    277			bnx2x_init_fill(bp, addr, 0, op->zero.len, 1);
    278			break;
    279		case OP_ZP:
    280			bnx2x_init_wr_zp(bp, addr, len,
    281					 op->arr_wr.data_off);
    282			break;
    283		case OP_WR_64:
    284			bnx2x_init_wr_64(bp, addr, data, len);
    285			break;
    286		case OP_IF_MODE_AND:
    287			/* if any of the flags doesn't match, skip the
    288			 * conditional block.
    289			 */
    290			if ((INIT_MODE_FLAGS(bp) &
    291				op->if_mode.mode_bit_map) !=
    292				op->if_mode.mode_bit_map)
    293				op_idx += op->if_mode.cmd_offset;
    294			break;
    295		case OP_IF_MODE_OR:
    296			/* if all the flags don't match, skip the conditional
    297			 * block.
    298			 */
    299			if ((INIT_MODE_FLAGS(bp) &
    300				op->if_mode.mode_bit_map) == 0)
    301				op_idx += op->if_mode.cmd_offset;
    302			break;
    303		default:
    304			/* Should never get here! */
    305
    306			break;
    307		}
    308	}
    309}
    310
    311
    312/****************************************************************************
    313* PXP Arbiter
    314****************************************************************************/
    315/*
    316 * This code configures the PCI read/write arbiter
    317 * which implements a weighted round robin
    318 * between the virtual queues in the chip.
    319 *
    320 * The values were derived for each PCI max payload and max request size.
    321 * since max payload and max request size are only known at run time,
    322 * this is done as a separate init stage.
    323 */
    324
    325#define NUM_WR_Q			13
    326#define NUM_RD_Q			29
    327#define MAX_RD_ORD			3
    328#define MAX_WR_ORD			2
    329
    330/* configuration for one arbiter queue */
    331struct arb_line {
    332	int l;
    333	int add;
    334	int ubound;
    335};
    336
    337/* derived configuration for each read queue for each max request size */
    338static const struct arb_line read_arb_data[NUM_RD_Q][MAX_RD_ORD + 1] = {
    339/* 1 */	{ {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
    340	{ {4, 8,  4},  {4,  8,  4},  {4,  8,  4},  {4,  8,  4}  },
    341	{ {4, 3,  3},  {4,  3,  3},  {4,  3,  3},  {4,  3,  3}  },
    342	{ {8, 3,  6},  {16, 3,  11}, {16, 3,  11}, {16, 3,  11} },
    343	{ {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
    344	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {64, 3,  41} },
    345	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {64, 3,  41} },
    346	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {64, 3,  41} },
    347	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {64, 3,  41} },
    348/* 10 */{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    349	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    350	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    351	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    352	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    353	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    354	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    355	{ {8, 64, 6},  {16, 64, 11}, {32, 64, 21}, {32, 64, 21} },
    356	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    357	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    358/* 20 */{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    359	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    360	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    361	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    362	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    363	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    364	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    365	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    366	{ {8, 3,  6},  {16, 3,  11}, {32, 3,  21}, {32, 3,  21} },
    367	{ {8, 64, 25}, {16, 64, 41}, {32, 64, 81}, {64, 64, 120} }
    368};
    369
    370/* derived configuration for each write queue for each max request size */
    371static const struct arb_line write_arb_data[NUM_WR_Q][MAX_WR_ORD + 1] = {
    372/* 1 */	{ {4, 6,  3},  {4,  6,  3},  {4,  6,  3} },
    373	{ {4, 2,  3},  {4,  2,  3},  {4,  2,  3} },
    374	{ {8, 2,  6},  {16, 2,  11}, {16, 2,  11} },
    375	{ {8, 2,  6},  {16, 2,  11}, {32, 2,  21} },
    376	{ {8, 2,  6},  {16, 2,  11}, {32, 2,  21} },
    377	{ {8, 2,  6},  {16, 2,  11}, {32, 2,  21} },
    378	{ {8, 64, 25}, {16, 64, 25}, {32, 64, 25} },
    379	{ {8, 2,  6},  {16, 2,  11}, {16, 2,  11} },
    380	{ {8, 2,  6},  {16, 2,  11}, {16, 2,  11} },
    381/* 10 */{ {8, 9,  6},  {16, 9,  11}, {32, 9,  21} },
    382	{ {8, 47, 19}, {16, 47, 19}, {32, 47, 21} },
    383	{ {8, 9,  6},  {16, 9,  11}, {16, 9,  11} },
    384	{ {8, 64, 25}, {16, 64, 41}, {32, 64, 81} }
    385};
    386
    387/* register addresses for read queues */
    388static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
    389/* 1 */	{PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0,
    390		PXP2_REG_RQ_BW_RD_UBOUND0},
    391	{PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
    392		PXP2_REG_PSWRQ_BW_UB1},
    393	{PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
    394		PXP2_REG_PSWRQ_BW_UB2},
    395	{PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
    396		PXP2_REG_PSWRQ_BW_UB3},
    397	{PXP2_REG_RQ_BW_RD_L4, PXP2_REG_RQ_BW_RD_ADD4,
    398		PXP2_REG_RQ_BW_RD_UBOUND4},
    399	{PXP2_REG_RQ_BW_RD_L5, PXP2_REG_RQ_BW_RD_ADD5,
    400		PXP2_REG_RQ_BW_RD_UBOUND5},
    401	{PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
    402		PXP2_REG_PSWRQ_BW_UB6},
    403	{PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
    404		PXP2_REG_PSWRQ_BW_UB7},
    405	{PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
    406		PXP2_REG_PSWRQ_BW_UB8},
    407/* 10 */{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
    408		PXP2_REG_PSWRQ_BW_UB9},
    409	{PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
    410		PXP2_REG_PSWRQ_BW_UB10},
    411	{PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
    412		PXP2_REG_PSWRQ_BW_UB11},
    413	{PXP2_REG_RQ_BW_RD_L12, PXP2_REG_RQ_BW_RD_ADD12,
    414		PXP2_REG_RQ_BW_RD_UBOUND12},
    415	{PXP2_REG_RQ_BW_RD_L13, PXP2_REG_RQ_BW_RD_ADD13,
    416		PXP2_REG_RQ_BW_RD_UBOUND13},
    417	{PXP2_REG_RQ_BW_RD_L14, PXP2_REG_RQ_BW_RD_ADD14,
    418		PXP2_REG_RQ_BW_RD_UBOUND14},
    419	{PXP2_REG_RQ_BW_RD_L15, PXP2_REG_RQ_BW_RD_ADD15,
    420		PXP2_REG_RQ_BW_RD_UBOUND15},
    421	{PXP2_REG_RQ_BW_RD_L16, PXP2_REG_RQ_BW_RD_ADD16,
    422		PXP2_REG_RQ_BW_RD_UBOUND16},
    423	{PXP2_REG_RQ_BW_RD_L17, PXP2_REG_RQ_BW_RD_ADD17,
    424		PXP2_REG_RQ_BW_RD_UBOUND17},
    425	{PXP2_REG_RQ_BW_RD_L18, PXP2_REG_RQ_BW_RD_ADD18,
    426		PXP2_REG_RQ_BW_RD_UBOUND18},
    427/* 20 */{PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19,
    428		PXP2_REG_RQ_BW_RD_UBOUND19},
    429	{PXP2_REG_RQ_BW_RD_L20, PXP2_REG_RQ_BW_RD_ADD20,
    430		PXP2_REG_RQ_BW_RD_UBOUND20},
    431	{PXP2_REG_RQ_BW_RD_L22, PXP2_REG_RQ_BW_RD_ADD22,
    432		PXP2_REG_RQ_BW_RD_UBOUND22},
    433	{PXP2_REG_RQ_BW_RD_L23, PXP2_REG_RQ_BW_RD_ADD23,
    434		PXP2_REG_RQ_BW_RD_UBOUND23},
    435	{PXP2_REG_RQ_BW_RD_L24, PXP2_REG_RQ_BW_RD_ADD24,
    436		PXP2_REG_RQ_BW_RD_UBOUND24},
    437	{PXP2_REG_RQ_BW_RD_L25, PXP2_REG_RQ_BW_RD_ADD25,
    438		PXP2_REG_RQ_BW_RD_UBOUND25},
    439	{PXP2_REG_RQ_BW_RD_L26, PXP2_REG_RQ_BW_RD_ADD26,
    440		PXP2_REG_RQ_BW_RD_UBOUND26},
    441	{PXP2_REG_RQ_BW_RD_L27, PXP2_REG_RQ_BW_RD_ADD27,
    442		PXP2_REG_RQ_BW_RD_UBOUND27},
    443	{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
    444		PXP2_REG_PSWRQ_BW_UB28}
    445};
    446
    447/* register addresses for write queues */
    448static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
    449/* 1 */	{PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
    450		PXP2_REG_PSWRQ_BW_UB1},
    451	{PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
    452		PXP2_REG_PSWRQ_BW_UB2},
    453	{PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
    454		PXP2_REG_PSWRQ_BW_UB3},
    455	{PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
    456		PXP2_REG_PSWRQ_BW_UB6},
    457	{PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
    458		PXP2_REG_PSWRQ_BW_UB7},
    459	{PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
    460		PXP2_REG_PSWRQ_BW_UB8},
    461	{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
    462		PXP2_REG_PSWRQ_BW_UB9},
    463	{PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
    464		PXP2_REG_PSWRQ_BW_UB10},
    465	{PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
    466		PXP2_REG_PSWRQ_BW_UB11},
    467/* 10 */{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
    468		PXP2_REG_PSWRQ_BW_UB28},
    469	{PXP2_REG_RQ_BW_WR_L29, PXP2_REG_RQ_BW_WR_ADD29,
    470		PXP2_REG_RQ_BW_WR_UBOUND29},
    471	{PXP2_REG_RQ_BW_WR_L30, PXP2_REG_RQ_BW_WR_ADD30,
    472		PXP2_REG_RQ_BW_WR_UBOUND30}
    473};
    474
    475static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order,
    476			       int w_order)
    477{
    478	u32 val, i;
    479
    480	if (r_order > MAX_RD_ORD) {
    481		DP(NETIF_MSG_HW, "read order of %d  order adjusted to %d\n",
    482		   r_order, MAX_RD_ORD);
    483		r_order = MAX_RD_ORD;
    484	}
    485	if (w_order > MAX_WR_ORD) {
    486		DP(NETIF_MSG_HW, "write order of %d  order adjusted to %d\n",
    487		   w_order, MAX_WR_ORD);
    488		w_order = MAX_WR_ORD;
    489	}
    490	if (CHIP_REV_IS_FPGA(bp)) {
    491		DP(NETIF_MSG_HW, "write order adjusted to 1 for FPGA\n");
    492		w_order = 0;
    493	}
    494	DP(NETIF_MSG_HW, "read order %d  write order %d\n", r_order, w_order);
    495
    496	for (i = 0; i < NUM_RD_Q-1; i++) {
    497		REG_WR(bp, read_arb_addr[i].l, read_arb_data[i][r_order].l);
    498		REG_WR(bp, read_arb_addr[i].add,
    499		       read_arb_data[i][r_order].add);
    500		REG_WR(bp, read_arb_addr[i].ubound,
    501		       read_arb_data[i][r_order].ubound);
    502	}
    503
    504	for (i = 0; i < NUM_WR_Q-1; i++) {
    505		if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) ||
    506		    (write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) {
    507
    508			REG_WR(bp, write_arb_addr[i].l,
    509			       write_arb_data[i][w_order].l);
    510
    511			REG_WR(bp, write_arb_addr[i].add,
    512			       write_arb_data[i][w_order].add);
    513
    514			REG_WR(bp, write_arb_addr[i].ubound,
    515			       write_arb_data[i][w_order].ubound);
    516		} else {
    517
    518			val = REG_RD(bp, write_arb_addr[i].l);
    519			REG_WR(bp, write_arb_addr[i].l,
    520			       val | (write_arb_data[i][w_order].l << 10));
    521
    522			val = REG_RD(bp, write_arb_addr[i].add);
    523			REG_WR(bp, write_arb_addr[i].add,
    524			       val | (write_arb_data[i][w_order].add << 10));
    525
    526			val = REG_RD(bp, write_arb_addr[i].ubound);
    527			REG_WR(bp, write_arb_addr[i].ubound,
    528			       val | (write_arb_data[i][w_order].ubound << 7));
    529		}
    530	}
    531
    532	val =  write_arb_data[NUM_WR_Q-1][w_order].add;
    533	val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10;
    534	val += write_arb_data[NUM_WR_Q-1][w_order].l << 17;
    535	REG_WR(bp, PXP2_REG_PSWRQ_BW_RD, val);
    536
    537	val =  read_arb_data[NUM_RD_Q-1][r_order].add;
    538	val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10;
    539	val += read_arb_data[NUM_RD_Q-1][r_order].l << 17;
    540	REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val);
    541
    542	REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order);
    543	REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order);
    544	REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order);
    545	REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order);
    546
    547	if ((CHIP_IS_E1(bp) || CHIP_IS_E1H(bp)) && (r_order == MAX_RD_ORD))
    548		REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00);
    549
    550	if (CHIP_IS_E3(bp))
    551		REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x4 << w_order));
    552	else if (CHIP_IS_E2(bp))
    553		REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x8 << w_order));
    554	else
    555		REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
    556
    557	if (!CHIP_IS_E1(bp)) {
    558		/*    MPS      w_order     optimal TH      presently TH
    559		 *    128         0             0               2
    560		 *    256         1             1               3
    561		 *    >=512       2             2               3
    562		 */
    563		/* DMAE is special */
    564		if (!CHIP_IS_E1H(bp)) {
    565			/* E2 can use optimal TH */
    566			val = w_order;
    567			REG_WR(bp, PXP2_REG_WR_DMAE_MPS, val);
    568		} else {
    569			val = ((w_order == 0) ? 2 : 3);
    570			REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2);
    571		}
    572
    573		REG_WR(bp, PXP2_REG_WR_HC_MPS, val);
    574		REG_WR(bp, PXP2_REG_WR_USDM_MPS, val);
    575		REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val);
    576		REG_WR(bp, PXP2_REG_WR_TSDM_MPS, val);
    577		REG_WR(bp, PXP2_REG_WR_XSDM_MPS, val);
    578		REG_WR(bp, PXP2_REG_WR_QM_MPS, val);
    579		REG_WR(bp, PXP2_REG_WR_TM_MPS, val);
    580		REG_WR(bp, PXP2_REG_WR_SRC_MPS, val);
    581		REG_WR(bp, PXP2_REG_WR_DBG_MPS, val);
    582		REG_WR(bp, PXP2_REG_WR_CDU_MPS, val);
    583	}
    584
    585	/* Validate number of tags suppoted by device */
    586#define PCIE_REG_PCIER_TL_HDR_FC_ST		0x2980
    587	val = REG_RD(bp, PCIE_REG_PCIER_TL_HDR_FC_ST);
    588	val &= 0xFF;
    589	if (val <= 0x20)
    590		REG_WR(bp, PXP2_REG_PGL_TAGS_LIMIT, 0x20);
    591}
    592
    593/****************************************************************************
    594* ILT management
    595****************************************************************************/
    596/*
    597 * This codes hides the low level HW interaction for ILT management and
    598 * configuration. The API consists of a shadow ILT table which is set by the
    599 * driver and a set of routines to use it to configure the HW.
    600 *
    601 */
    602
    603/* ILT HW init operations */
    604
    605/* ILT memory management operations */
    606#define ILT_MEMOP_ALLOC		0
    607#define ILT_MEMOP_FREE		1
    608
    609/* the phys address is shifted right 12 bits and has an added
    610 * 1=valid bit added to the 53rd bit
    611 * then since this is a wide register(TM)
    612 * we split it into two 32 bit writes
    613 */
    614#define ILT_ADDR1(x)		((u32)(((u64)x >> 12) & 0xFFFFFFFF))
    615#define ILT_ADDR2(x)		((u32)((1 << 20) | ((u64)x >> 44)))
    616#define ILT_RANGE(f, l)		(((l) << 10) | f)
    617
    618static int bnx2x_ilt_line_mem_op(struct bnx2x *bp,
    619				 struct ilt_line *line, u32 size, u8 memop)
    620{
    621	if (memop == ILT_MEMOP_FREE) {
    622		BNX2X_ILT_FREE(line->page, line->page_mapping, line->size);
    623		return 0;
    624	}
    625	BNX2X_ILT_ZALLOC(line->page, &line->page_mapping, size);
    626	if (!line->page)
    627		return -1;
    628	line->size = size;
    629	return 0;
    630}
    631
    632
    633static int bnx2x_ilt_client_mem_op(struct bnx2x *bp, int cli_num,
    634				   u8 memop)
    635{
    636	int i, rc;
    637	struct bnx2x_ilt *ilt = BP_ILT(bp);
    638	struct ilt_client_info *ilt_cli;
    639
    640	if (!ilt || !ilt->lines)
    641		return -1;
    642
    643	ilt_cli = &ilt->clients[cli_num];
    644
    645	if (ilt_cli->flags & (ILT_CLIENT_SKIP_INIT | ILT_CLIENT_SKIP_MEM))
    646		return 0;
    647
    648	for (rc = 0, i = ilt_cli->start; i <= ilt_cli->end && !rc; i++) {
    649		rc = bnx2x_ilt_line_mem_op(bp, &ilt->lines[i],
    650					   ilt_cli->page_size, memop);
    651	}
    652	return rc;
    653}
    654
    655static int bnx2x_ilt_mem_op_cnic(struct bnx2x *bp, u8 memop)
    656{
    657	int rc = 0;
    658
    659	if (CONFIGURE_NIC_MODE(bp))
    660		rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_SRC, memop);
    661	if (!rc)
    662		rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_TM, memop);
    663
    664	return rc;
    665}
    666
    667static int bnx2x_ilt_mem_op(struct bnx2x *bp, u8 memop)
    668{
    669	int rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_CDU, memop);
    670	if (!rc)
    671		rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_QM, memop);
    672	if (!rc && CNIC_SUPPORT(bp) && !CONFIGURE_NIC_MODE(bp))
    673		rc = bnx2x_ilt_client_mem_op(bp, ILT_CLIENT_SRC, memop);
    674
    675	return rc;
    676}
    677
    678static void bnx2x_ilt_line_wr(struct bnx2x *bp, int abs_idx,
    679			      dma_addr_t page_mapping)
    680{
    681	u32 reg;
    682
    683	if (CHIP_IS_E1(bp))
    684		reg = PXP2_REG_RQ_ONCHIP_AT + abs_idx*8;
    685	else
    686		reg = PXP2_REG_RQ_ONCHIP_AT_B0 + abs_idx*8;
    687
    688	bnx2x_wr_64(bp, reg, ILT_ADDR1(page_mapping), ILT_ADDR2(page_mapping));
    689}
    690
    691static void bnx2x_ilt_line_init_op(struct bnx2x *bp,
    692				   struct bnx2x_ilt *ilt, int idx, u8 initop)
    693{
    694	dma_addr_t	null_mapping;
    695	int abs_idx = ilt->start_line + idx;
    696
    697
    698	switch (initop) {
    699	case INITOP_INIT:
    700		/* set in the init-value array */
    701	case INITOP_SET:
    702		bnx2x_ilt_line_wr(bp, abs_idx, ilt->lines[idx].page_mapping);
    703		break;
    704	case INITOP_CLEAR:
    705		null_mapping = 0;
    706		bnx2x_ilt_line_wr(bp, abs_idx, null_mapping);
    707		break;
    708	}
    709}
    710
    711static void bnx2x_ilt_boundry_init_op(struct bnx2x *bp,
    712				      struct ilt_client_info *ilt_cli,
    713				      u32 ilt_start, u8 initop)
    714{
    715	u32 start_reg = 0;
    716	u32 end_reg = 0;
    717
    718	/* The boundary is either SET or INIT,
    719	   CLEAR => SET and for now SET ~~ INIT */
    720
    721	/* find the appropriate regs */
    722	if (CHIP_IS_E1(bp)) {
    723		switch (ilt_cli->client_num) {
    724		case ILT_CLIENT_CDU:
    725			start_reg = PXP2_REG_PSWRQ_CDU0_L2P;
    726			break;
    727		case ILT_CLIENT_QM:
    728			start_reg = PXP2_REG_PSWRQ_QM0_L2P;
    729			break;
    730		case ILT_CLIENT_SRC:
    731			start_reg = PXP2_REG_PSWRQ_SRC0_L2P;
    732			break;
    733		case ILT_CLIENT_TM:
    734			start_reg = PXP2_REG_PSWRQ_TM0_L2P;
    735			break;
    736		}
    737		REG_WR(bp, start_reg + BP_FUNC(bp)*4,
    738		       ILT_RANGE((ilt_start + ilt_cli->start),
    739				 (ilt_start + ilt_cli->end)));
    740	} else {
    741		switch (ilt_cli->client_num) {
    742		case ILT_CLIENT_CDU:
    743			start_reg = PXP2_REG_RQ_CDU_FIRST_ILT;
    744			end_reg = PXP2_REG_RQ_CDU_LAST_ILT;
    745			break;
    746		case ILT_CLIENT_QM:
    747			start_reg = PXP2_REG_RQ_QM_FIRST_ILT;
    748			end_reg = PXP2_REG_RQ_QM_LAST_ILT;
    749			break;
    750		case ILT_CLIENT_SRC:
    751			start_reg = PXP2_REG_RQ_SRC_FIRST_ILT;
    752			end_reg = PXP2_REG_RQ_SRC_LAST_ILT;
    753			break;
    754		case ILT_CLIENT_TM:
    755			start_reg = PXP2_REG_RQ_TM_FIRST_ILT;
    756			end_reg = PXP2_REG_RQ_TM_LAST_ILT;
    757			break;
    758		}
    759		REG_WR(bp, start_reg, (ilt_start + ilt_cli->start));
    760		REG_WR(bp, end_reg, (ilt_start + ilt_cli->end));
    761	}
    762}
    763
    764static void bnx2x_ilt_client_init_op_ilt(struct bnx2x *bp,
    765					 struct bnx2x_ilt *ilt,
    766					 struct ilt_client_info *ilt_cli,
    767					 u8 initop)
    768{
    769	int i;
    770
    771	if (ilt_cli->flags & ILT_CLIENT_SKIP_INIT)
    772		return;
    773
    774	for (i = ilt_cli->start; i <= ilt_cli->end; i++)
    775		bnx2x_ilt_line_init_op(bp, ilt, i, initop);
    776
    777	/* init/clear the ILT boundries */
    778	bnx2x_ilt_boundry_init_op(bp, ilt_cli, ilt->start_line, initop);
    779}
    780
    781static void bnx2x_ilt_client_init_op(struct bnx2x *bp,
    782				     struct ilt_client_info *ilt_cli, u8 initop)
    783{
    784	struct bnx2x_ilt *ilt = BP_ILT(bp);
    785
    786	bnx2x_ilt_client_init_op_ilt(bp, ilt, ilt_cli, initop);
    787}
    788
    789static void bnx2x_ilt_client_id_init_op(struct bnx2x *bp,
    790					int cli_num, u8 initop)
    791{
    792	struct bnx2x_ilt *ilt = BP_ILT(bp);
    793	struct ilt_client_info *ilt_cli = &ilt->clients[cli_num];
    794
    795	bnx2x_ilt_client_init_op(bp, ilt_cli, initop);
    796}
    797
    798static void bnx2x_ilt_init_op_cnic(struct bnx2x *bp, u8 initop)
    799{
    800	if (CONFIGURE_NIC_MODE(bp))
    801		bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_SRC, initop);
    802	bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_TM, initop);
    803}
    804
    805static void bnx2x_ilt_init_op(struct bnx2x *bp, u8 initop)
    806{
    807	bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_CDU, initop);
    808	bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_QM, initop);
    809	if (CNIC_SUPPORT(bp) && !CONFIGURE_NIC_MODE(bp))
    810		bnx2x_ilt_client_id_init_op(bp, ILT_CLIENT_SRC, initop);
    811}
    812
    813static void bnx2x_ilt_init_client_psz(struct bnx2x *bp, int cli_num,
    814				      u32 psz_reg, u8 initop)
    815{
    816	struct bnx2x_ilt *ilt = BP_ILT(bp);
    817	struct ilt_client_info *ilt_cli = &ilt->clients[cli_num];
    818
    819	if (ilt_cli->flags & ILT_CLIENT_SKIP_INIT)
    820		return;
    821
    822	switch (initop) {
    823	case INITOP_INIT:
    824		/* set in the init-value array */
    825	case INITOP_SET:
    826		REG_WR(bp, psz_reg, ILOG2(ilt_cli->page_size >> 12));
    827		break;
    828	case INITOP_CLEAR:
    829		break;
    830	}
    831}
    832
    833/*
    834 * called during init common stage, ilt clients should be initialized
    835 * prioir to calling this function
    836 */
    837static void bnx2x_ilt_init_page_size(struct bnx2x *bp, u8 initop)
    838{
    839	bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_CDU,
    840				  PXP2_REG_RQ_CDU_P_SIZE, initop);
    841	bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_QM,
    842				  PXP2_REG_RQ_QM_P_SIZE, initop);
    843	bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_SRC,
    844				  PXP2_REG_RQ_SRC_P_SIZE, initop);
    845	bnx2x_ilt_init_client_psz(bp, ILT_CLIENT_TM,
    846				  PXP2_REG_RQ_TM_P_SIZE, initop);
    847}
    848
    849/****************************************************************************
    850* QM initializations
    851****************************************************************************/
    852#define QM_QUEUES_PER_FUNC	16 /* E1 has 32, but only 16 are used */
    853#define QM_INIT_MIN_CID_COUNT	31
    854#define QM_INIT(cid_cnt)	(cid_cnt > QM_INIT_MIN_CID_COUNT)
    855
    856/* called during init port stage */
    857static void bnx2x_qm_init_cid_count(struct bnx2x *bp, int qm_cid_count,
    858				    u8 initop)
    859{
    860	int port = BP_PORT(bp);
    861
    862	if (QM_INIT(qm_cid_count)) {
    863		switch (initop) {
    864		case INITOP_INIT:
    865			/* set in the init-value array */
    866		case INITOP_SET:
    867			REG_WR(bp, QM_REG_CONNNUM_0 + port*4,
    868			       qm_cid_count/16 - 1);
    869			break;
    870		case INITOP_CLEAR:
    871			break;
    872		}
    873	}
    874}
    875
    876static void bnx2x_qm_set_ptr_table(struct bnx2x *bp, int qm_cid_count,
    877				   u32 base_reg, u32 reg)
    878{
    879	int i;
    880	u32 wb_data[2] = {0, 0};
    881	for (i = 0; i < 4 * QM_QUEUES_PER_FUNC; i++) {
    882		REG_WR(bp, base_reg + i*4,
    883		       qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC));
    884		bnx2x_init_wr_wb(bp, reg + i*8,	 wb_data, 2);
    885	}
    886}
    887
    888/* called during init common stage */
    889static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count,
    890				    u8 initop)
    891{
    892	if (!QM_INIT(qm_cid_count))
    893		return;
    894
    895	switch (initop) {
    896	case INITOP_INIT:
    897		/* set in the init-value array */
    898	case INITOP_SET:
    899		bnx2x_qm_set_ptr_table(bp, qm_cid_count,
    900				       QM_REG_BASEADDR, QM_REG_PTRTBL);
    901		if (CHIP_IS_E1H(bp))
    902			bnx2x_qm_set_ptr_table(bp, qm_cid_count,
    903					       QM_REG_BASEADDR_EXT_A,
    904					       QM_REG_PTRTBL_EXT_A);
    905		break;
    906	case INITOP_CLEAR:
    907		break;
    908	}
    909}
    910
    911/****************************************************************************
    912* SRC initializations
    913****************************************************************************/
    914/* called during init func stage */
    915static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2,
    916			      dma_addr_t t2_mapping, int src_cid_count)
    917{
    918	int i;
    919	int port = BP_PORT(bp);
    920
    921	/* Initialize T2 */
    922	for (i = 0; i < src_cid_count-1; i++)
    923		t2[i].next = (u64)(t2_mapping +
    924			     (i+1)*sizeof(struct src_ent));
    925
    926	/* tell the searcher where the T2 table is */
    927	REG_WR(bp, SRC_REG_COUNTFREE0 + port*4, src_cid_count);
    928
    929	bnx2x_wr_64(bp, SRC_REG_FIRSTFREE0 + port*16,
    930		    U64_LO(t2_mapping), U64_HI(t2_mapping));
    931
    932	bnx2x_wr_64(bp, SRC_REG_LASTFREE0 + port*16,
    933		    U64_LO((u64)t2_mapping +
    934			   (src_cid_count-1) * sizeof(struct src_ent)),
    935		    U64_HI((u64)t2_mapping +
    936			   (src_cid_count-1) * sizeof(struct src_ent)));
    937}
    938#endif /* BNX2X_INIT_OPS_H */