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

netxen_nic_hw.c (67160B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright (C) 2003 - 2009 NetXen, Inc.
      4 * Copyright (C) 2009 - QLogic Corporation.
      5 * All rights reserved.
      6 */
      7
      8#include <linux/io-64-nonatomic-lo-hi.h>
      9#include <linux/slab.h>
     10#include "netxen_nic.h"
     11#include "netxen_nic_hw.h"
     12
     13#include <net/ip.h>
     14
     15#define MASK(n) ((1ULL<<(n))-1)
     16#define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
     17#define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff))
     18#define MS_WIN(addr) (addr & 0x0ffc0000)
     19
     20#define GET_MEM_OFFS_2M(addr) (addr & MASK(18))
     21
     22#define CRB_BLK(off)	((off >> 20) & 0x3f)
     23#define CRB_SUBBLK(off)	((off >> 16) & 0xf)
     24#define CRB_WINDOW_2M	(0x130060)
     25#define CRB_HI(off)	((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
     26#define CRB_INDIRECT_2M	(0x1e0000UL)
     27
     28static void netxen_nic_io_write_128M(struct netxen_adapter *adapter,
     29		void __iomem *addr, u32 data);
     30static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter,
     31		void __iomem *addr);
     32
     33#define PCI_OFFSET_FIRST_RANGE(adapter, off)    \
     34	((adapter)->ahw.pci_base0 + (off))
     35#define PCI_OFFSET_SECOND_RANGE(adapter, off)   \
     36	((adapter)->ahw.pci_base1 + (off) - SECOND_PAGE_GROUP_START)
     37#define PCI_OFFSET_THIRD_RANGE(adapter, off)    \
     38	((adapter)->ahw.pci_base2 + (off) - THIRD_PAGE_GROUP_START)
     39
     40static void __iomem *pci_base_offset(struct netxen_adapter *adapter,
     41					    unsigned long off)
     42{
     43	if (ADDR_IN_RANGE(off, FIRST_PAGE_GROUP_START, FIRST_PAGE_GROUP_END))
     44		return PCI_OFFSET_FIRST_RANGE(adapter, off);
     45
     46	if (ADDR_IN_RANGE(off, SECOND_PAGE_GROUP_START, SECOND_PAGE_GROUP_END))
     47		return PCI_OFFSET_SECOND_RANGE(adapter, off);
     48
     49	if (ADDR_IN_RANGE(off, THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_END))
     50		return PCI_OFFSET_THIRD_RANGE(adapter, off);
     51
     52	return NULL;
     53}
     54
     55static crb_128M_2M_block_map_t
     56crb_128M_2M_map[64] __cacheline_aligned_in_smp = {
     57    {{{0, 0,         0,         0} } },		/* 0: PCI */
     58    {{{1, 0x0100000, 0x0102000, 0x120000},	/* 1: PCIE */
     59	  {1, 0x0110000, 0x0120000, 0x130000},
     60	  {1, 0x0120000, 0x0122000, 0x124000},
     61	  {1, 0x0130000, 0x0132000, 0x126000},
     62	  {1, 0x0140000, 0x0142000, 0x128000},
     63	  {1, 0x0150000, 0x0152000, 0x12a000},
     64	  {1, 0x0160000, 0x0170000, 0x110000},
     65	  {1, 0x0170000, 0x0172000, 0x12e000},
     66	  {0, 0x0000000, 0x0000000, 0x000000},
     67	  {0, 0x0000000, 0x0000000, 0x000000},
     68	  {0, 0x0000000, 0x0000000, 0x000000},
     69	  {0, 0x0000000, 0x0000000, 0x000000},
     70	  {0, 0x0000000, 0x0000000, 0x000000},
     71	  {0, 0x0000000, 0x0000000, 0x000000},
     72	  {1, 0x01e0000, 0x01e0800, 0x122000},
     73	  {0, 0x0000000, 0x0000000, 0x000000} } },
     74	{{{1, 0x0200000, 0x0210000, 0x180000} } },/* 2: MN */
     75    {{{0, 0,         0,         0} } },	    /* 3: */
     76    {{{1, 0x0400000, 0x0401000, 0x169000} } },/* 4: P2NR1 */
     77    {{{1, 0x0500000, 0x0510000, 0x140000} } },/* 5: SRE   */
     78    {{{1, 0x0600000, 0x0610000, 0x1c0000} } },/* 6: NIU   */
     79    {{{1, 0x0700000, 0x0704000, 0x1b8000} } },/* 7: QM    */
     80    {{{1, 0x0800000, 0x0802000, 0x170000},  /* 8: SQM0  */
     81      {0, 0x0000000, 0x0000000, 0x000000},
     82      {0, 0x0000000, 0x0000000, 0x000000},
     83      {0, 0x0000000, 0x0000000, 0x000000},
     84      {0, 0x0000000, 0x0000000, 0x000000},
     85      {0, 0x0000000, 0x0000000, 0x000000},
     86      {0, 0x0000000, 0x0000000, 0x000000},
     87      {0, 0x0000000, 0x0000000, 0x000000},
     88      {0, 0x0000000, 0x0000000, 0x000000},
     89      {0, 0x0000000, 0x0000000, 0x000000},
     90      {0, 0x0000000, 0x0000000, 0x000000},
     91      {0, 0x0000000, 0x0000000, 0x000000},
     92      {0, 0x0000000, 0x0000000, 0x000000},
     93      {0, 0x0000000, 0x0000000, 0x000000},
     94      {0, 0x0000000, 0x0000000, 0x000000},
     95      {1, 0x08f0000, 0x08f2000, 0x172000} } },
     96    {{{1, 0x0900000, 0x0902000, 0x174000},	/* 9: SQM1*/
     97      {0, 0x0000000, 0x0000000, 0x000000},
     98      {0, 0x0000000, 0x0000000, 0x000000},
     99      {0, 0x0000000, 0x0000000, 0x000000},
    100      {0, 0x0000000, 0x0000000, 0x000000},
    101      {0, 0x0000000, 0x0000000, 0x000000},
    102      {0, 0x0000000, 0x0000000, 0x000000},
    103      {0, 0x0000000, 0x0000000, 0x000000},
    104      {0, 0x0000000, 0x0000000, 0x000000},
    105      {0, 0x0000000, 0x0000000, 0x000000},
    106      {0, 0x0000000, 0x0000000, 0x000000},
    107      {0, 0x0000000, 0x0000000, 0x000000},
    108      {0, 0x0000000, 0x0000000, 0x000000},
    109      {0, 0x0000000, 0x0000000, 0x000000},
    110      {0, 0x0000000, 0x0000000, 0x000000},
    111      {1, 0x09f0000, 0x09f2000, 0x176000} } },
    112    {{{0, 0x0a00000, 0x0a02000, 0x178000},	/* 10: SQM2*/
    113      {0, 0x0000000, 0x0000000, 0x000000},
    114      {0, 0x0000000, 0x0000000, 0x000000},
    115      {0, 0x0000000, 0x0000000, 0x000000},
    116      {0, 0x0000000, 0x0000000, 0x000000},
    117      {0, 0x0000000, 0x0000000, 0x000000},
    118      {0, 0x0000000, 0x0000000, 0x000000},
    119      {0, 0x0000000, 0x0000000, 0x000000},
    120      {0, 0x0000000, 0x0000000, 0x000000},
    121      {0, 0x0000000, 0x0000000, 0x000000},
    122      {0, 0x0000000, 0x0000000, 0x000000},
    123      {0, 0x0000000, 0x0000000, 0x000000},
    124      {0, 0x0000000, 0x0000000, 0x000000},
    125      {0, 0x0000000, 0x0000000, 0x000000},
    126      {0, 0x0000000, 0x0000000, 0x000000},
    127      {1, 0x0af0000, 0x0af2000, 0x17a000} } },
    128    {{{0, 0x0b00000, 0x0b02000, 0x17c000},	/* 11: SQM3*/
    129      {0, 0x0000000, 0x0000000, 0x000000},
    130      {0, 0x0000000, 0x0000000, 0x000000},
    131      {0, 0x0000000, 0x0000000, 0x000000},
    132      {0, 0x0000000, 0x0000000, 0x000000},
    133      {0, 0x0000000, 0x0000000, 0x000000},
    134      {0, 0x0000000, 0x0000000, 0x000000},
    135      {0, 0x0000000, 0x0000000, 0x000000},
    136      {0, 0x0000000, 0x0000000, 0x000000},
    137      {0, 0x0000000, 0x0000000, 0x000000},
    138      {0, 0x0000000, 0x0000000, 0x000000},
    139      {0, 0x0000000, 0x0000000, 0x000000},
    140      {0, 0x0000000, 0x0000000, 0x000000},
    141      {0, 0x0000000, 0x0000000, 0x000000},
    142      {0, 0x0000000, 0x0000000, 0x000000},
    143      {1, 0x0bf0000, 0x0bf2000, 0x17e000} } },
    144	{{{1, 0x0c00000, 0x0c04000, 0x1d4000} } },/* 12: I2Q */
    145	{{{1, 0x0d00000, 0x0d04000, 0x1a4000} } },/* 13: TMR */
    146	{{{1, 0x0e00000, 0x0e04000, 0x1a0000} } },/* 14: ROMUSB */
    147	{{{1, 0x0f00000, 0x0f01000, 0x164000} } },/* 15: PEG4 */
    148	{{{0, 0x1000000, 0x1004000, 0x1a8000} } },/* 16: XDMA */
    149	{{{1, 0x1100000, 0x1101000, 0x160000} } },/* 17: PEG0 */
    150	{{{1, 0x1200000, 0x1201000, 0x161000} } },/* 18: PEG1 */
    151	{{{1, 0x1300000, 0x1301000, 0x162000} } },/* 19: PEG2 */
    152	{{{1, 0x1400000, 0x1401000, 0x163000} } },/* 20: PEG3 */
    153	{{{1, 0x1500000, 0x1501000, 0x165000} } },/* 21: P2ND */
    154	{{{1, 0x1600000, 0x1601000, 0x166000} } },/* 22: P2NI */
    155	{{{0, 0,         0,         0} } },	/* 23: */
    156	{{{0, 0,         0,         0} } },	/* 24: */
    157	{{{0, 0,         0,         0} } },	/* 25: */
    158	{{{0, 0,         0,         0} } },	/* 26: */
    159	{{{0, 0,         0,         0} } },	/* 27: */
    160	{{{0, 0,         0,         0} } },	/* 28: */
    161	{{{1, 0x1d00000, 0x1d10000, 0x190000} } },/* 29: MS */
    162    {{{1, 0x1e00000, 0x1e01000, 0x16a000} } },/* 30: P2NR2 */
    163    {{{1, 0x1f00000, 0x1f10000, 0x150000} } },/* 31: EPG */
    164	{{{0} } },				/* 32: PCI */
    165	{{{1, 0x2100000, 0x2102000, 0x120000},	/* 33: PCIE */
    166	  {1, 0x2110000, 0x2120000, 0x130000},
    167	  {1, 0x2120000, 0x2122000, 0x124000},
    168	  {1, 0x2130000, 0x2132000, 0x126000},
    169	  {1, 0x2140000, 0x2142000, 0x128000},
    170	  {1, 0x2150000, 0x2152000, 0x12a000},
    171	  {1, 0x2160000, 0x2170000, 0x110000},
    172	  {1, 0x2170000, 0x2172000, 0x12e000},
    173	  {0, 0x0000000, 0x0000000, 0x000000},
    174	  {0, 0x0000000, 0x0000000, 0x000000},
    175	  {0, 0x0000000, 0x0000000, 0x000000},
    176	  {0, 0x0000000, 0x0000000, 0x000000},
    177	  {0, 0x0000000, 0x0000000, 0x000000},
    178	  {0, 0x0000000, 0x0000000, 0x000000},
    179	  {0, 0x0000000, 0x0000000, 0x000000},
    180	  {0, 0x0000000, 0x0000000, 0x000000} } },
    181	{{{1, 0x2200000, 0x2204000, 0x1b0000} } },/* 34: CAM */
    182	{{{0} } },				/* 35: */
    183	{{{0} } },				/* 36: */
    184	{{{0} } },				/* 37: */
    185	{{{0} } },				/* 38: */
    186	{{{0} } },				/* 39: */
    187	{{{1, 0x2800000, 0x2804000, 0x1a4000} } },/* 40: TMR */
    188	{{{1, 0x2900000, 0x2901000, 0x16b000} } },/* 41: P2NR3 */
    189	{{{1, 0x2a00000, 0x2a00400, 0x1ac400} } },/* 42: RPMX1 */
    190	{{{1, 0x2b00000, 0x2b00400, 0x1ac800} } },/* 43: RPMX2 */
    191	{{{1, 0x2c00000, 0x2c00400, 0x1acc00} } },/* 44: RPMX3 */
    192	{{{1, 0x2d00000, 0x2d00400, 0x1ad000} } },/* 45: RPMX4 */
    193	{{{1, 0x2e00000, 0x2e00400, 0x1ad400} } },/* 46: RPMX5 */
    194	{{{1, 0x2f00000, 0x2f00400, 0x1ad800} } },/* 47: RPMX6 */
    195	{{{1, 0x3000000, 0x3000400, 0x1adc00} } },/* 48: RPMX7 */
    196	{{{0, 0x3100000, 0x3104000, 0x1a8000} } },/* 49: XDMA */
    197	{{{1, 0x3200000, 0x3204000, 0x1d4000} } },/* 50: I2Q */
    198	{{{1, 0x3300000, 0x3304000, 0x1a0000} } },/* 51: ROMUSB */
    199	{{{0} } },				/* 52: */
    200	{{{1, 0x3500000, 0x3500400, 0x1ac000} } },/* 53: RPMX0 */
    201	{{{1, 0x3600000, 0x3600400, 0x1ae000} } },/* 54: RPMX8 */
    202	{{{1, 0x3700000, 0x3700400, 0x1ae400} } },/* 55: RPMX9 */
    203	{{{1, 0x3800000, 0x3804000, 0x1d0000} } },/* 56: OCM0 */
    204	{{{1, 0x3900000, 0x3904000, 0x1b4000} } },/* 57: CRYPTO */
    205	{{{1, 0x3a00000, 0x3a04000, 0x1d8000} } },/* 58: SMB */
    206	{{{0} } },				/* 59: I2C0 */
    207	{{{0} } },				/* 60: I2C1 */
    208	{{{1, 0x3d00000, 0x3d04000, 0x1d8000} } },/* 61: LPC */
    209	{{{1, 0x3e00000, 0x3e01000, 0x167000} } },/* 62: P2NC */
    210	{{{1, 0x3f00000, 0x3f01000, 0x168000} } }	/* 63: P2NR0 */
    211};
    212
    213/*
    214 * top 12 bits of crb internal address (hub, agent)
    215 */
    216static unsigned crb_hub_agt[64] =
    217{
    218	0,
    219	NETXEN_HW_CRB_HUB_AGT_ADR_PS,
    220	NETXEN_HW_CRB_HUB_AGT_ADR_MN,
    221	NETXEN_HW_CRB_HUB_AGT_ADR_MS,
    222	0,
    223	NETXEN_HW_CRB_HUB_AGT_ADR_SRE,
    224	NETXEN_HW_CRB_HUB_AGT_ADR_NIU,
    225	NETXEN_HW_CRB_HUB_AGT_ADR_QMN,
    226	NETXEN_HW_CRB_HUB_AGT_ADR_SQN0,
    227	NETXEN_HW_CRB_HUB_AGT_ADR_SQN1,
    228	NETXEN_HW_CRB_HUB_AGT_ADR_SQN2,
    229	NETXEN_HW_CRB_HUB_AGT_ADR_SQN3,
    230	NETXEN_HW_CRB_HUB_AGT_ADR_I2Q,
    231	NETXEN_HW_CRB_HUB_AGT_ADR_TIMR,
    232	NETXEN_HW_CRB_HUB_AGT_ADR_ROMUSB,
    233	NETXEN_HW_CRB_HUB_AGT_ADR_PGN4,
    234	NETXEN_HW_CRB_HUB_AGT_ADR_XDMA,
    235	NETXEN_HW_CRB_HUB_AGT_ADR_PGN0,
    236	NETXEN_HW_CRB_HUB_AGT_ADR_PGN1,
    237	NETXEN_HW_CRB_HUB_AGT_ADR_PGN2,
    238	NETXEN_HW_CRB_HUB_AGT_ADR_PGN3,
    239	NETXEN_HW_CRB_HUB_AGT_ADR_PGND,
    240	NETXEN_HW_CRB_HUB_AGT_ADR_PGNI,
    241	NETXEN_HW_CRB_HUB_AGT_ADR_PGS0,
    242	NETXEN_HW_CRB_HUB_AGT_ADR_PGS1,
    243	NETXEN_HW_CRB_HUB_AGT_ADR_PGS2,
    244	NETXEN_HW_CRB_HUB_AGT_ADR_PGS3,
    245	0,
    246	NETXEN_HW_CRB_HUB_AGT_ADR_PGSI,
    247	NETXEN_HW_CRB_HUB_AGT_ADR_SN,
    248	0,
    249	NETXEN_HW_CRB_HUB_AGT_ADR_EG,
    250	0,
    251	NETXEN_HW_CRB_HUB_AGT_ADR_PS,
    252	NETXEN_HW_CRB_HUB_AGT_ADR_CAM,
    253	0,
    254	0,
    255	0,
    256	0,
    257	0,
    258	NETXEN_HW_CRB_HUB_AGT_ADR_TIMR,
    259	0,
    260	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX1,
    261	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX2,
    262	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX3,
    263	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX4,
    264	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX5,
    265	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX6,
    266	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX7,
    267	NETXEN_HW_CRB_HUB_AGT_ADR_XDMA,
    268	NETXEN_HW_CRB_HUB_AGT_ADR_I2Q,
    269	NETXEN_HW_CRB_HUB_AGT_ADR_ROMUSB,
    270	0,
    271	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX0,
    272	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX8,
    273	NETXEN_HW_CRB_HUB_AGT_ADR_RPMX9,
    274	NETXEN_HW_CRB_HUB_AGT_ADR_OCM0,
    275	0,
    276	NETXEN_HW_CRB_HUB_AGT_ADR_SMB,
    277	NETXEN_HW_CRB_HUB_AGT_ADR_I2C0,
    278	NETXEN_HW_CRB_HUB_AGT_ADR_I2C1,
    279	0,
    280	NETXEN_HW_CRB_HUB_AGT_ADR_PGNC,
    281	0,
    282};
    283
    284/*  PCI Windowing for DDR regions.  */
    285
    286#define NETXEN_WINDOW_ONE 	0x2000000 /*CRB Window: bit 25 of CRB address */
    287
    288#define NETXEN_PCIE_SEM_TIMEOUT	10000
    289
    290static int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu);
    291
    292int
    293netxen_pcie_sem_lock(struct netxen_adapter *adapter, int sem, u32 id_reg)
    294{
    295	int done = 0, timeout = 0;
    296
    297	while (!done) {
    298		done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_LOCK(sem)));
    299		if (done == 1)
    300			break;
    301		if (++timeout >= NETXEN_PCIE_SEM_TIMEOUT)
    302			return -EIO;
    303		msleep(1);
    304	}
    305
    306	if (id_reg)
    307		NXWR32(adapter, id_reg, adapter->portnum);
    308
    309	return 0;
    310}
    311
    312void
    313netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem)
    314{
    315	NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem)));
    316}
    317
    318static int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
    319{
    320	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
    321		NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447);
    322		NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5);
    323	}
    324
    325	return 0;
    326}
    327
    328/* Disable an XG interface */
    329static int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
    330{
    331	__u32 mac_cfg;
    332	u32 port = adapter->physical_port;
    333
    334	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
    335		return 0;
    336
    337	if (port >= NETXEN_NIU_MAX_XG_PORTS)
    338		return -EINVAL;
    339
    340	mac_cfg = 0;
    341	if (NXWR32(adapter,
    342			NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg))
    343		return -EIO;
    344	return 0;
    345}
    346
    347#define NETXEN_UNICAST_ADDR(port, index) \
    348	(NETXEN_UNICAST_ADDR_BASE+(port*32)+(index*8))
    349#define NETXEN_MCAST_ADDR(port, index) \
    350	(NETXEN_MULTICAST_ADDR_BASE+(port*0x80)+(index*8))
    351#define MAC_HI(addr) \
    352	((addr[2] << 16) | (addr[1] << 8) | (addr[0]))
    353#define MAC_LO(addr) \
    354	((addr[5] << 16) | (addr[4] << 8) | (addr[3]))
    355
    356static int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
    357{
    358	u32 mac_cfg;
    359	u32 cnt = 0;
    360	__u32 reg = 0x0200;
    361	u32 port = adapter->physical_port;
    362	u16 board_type = adapter->ahw.board_type;
    363
    364	if (port >= NETXEN_NIU_MAX_XG_PORTS)
    365		return -EINVAL;
    366
    367	mac_cfg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port));
    368	mac_cfg &= ~0x4;
    369	NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg);
    370
    371	if ((board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) ||
    372			(board_type == NETXEN_BRDTYPE_P2_SB31_10G_HMEZ))
    373		reg = (0x20 << port);
    374
    375	NXWR32(adapter, NETXEN_NIU_FRAME_COUNT_SELECT, reg);
    376
    377	mdelay(10);
    378
    379	while (NXRD32(adapter, NETXEN_NIU_FRAME_COUNT) && ++cnt < 20)
    380		mdelay(10);
    381
    382	if (cnt < 20) {
    383
    384		reg = NXRD32(adapter,
    385			NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port));
    386
    387		if (mode == NETXEN_NIU_PROMISC_MODE)
    388			reg = (reg | 0x2000UL);
    389		else
    390			reg = (reg & ~0x2000UL);
    391
    392		if (mode == NETXEN_NIU_ALLMULTI_MODE)
    393			reg = (reg | 0x1000UL);
    394		else
    395			reg = (reg & ~0x1000UL);
    396
    397		NXWR32(adapter,
    398			NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
    399	}
    400
    401	mac_cfg |= 0x4;
    402	NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg);
    403
    404	return 0;
    405}
    406
    407static int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
    408{
    409	u32 mac_hi, mac_lo;
    410	u32 reg_hi, reg_lo;
    411
    412	u8 phy = adapter->physical_port;
    413
    414	if (phy >= NETXEN_NIU_MAX_XG_PORTS)
    415		return -EINVAL;
    416
    417	mac_lo = ((u32)addr[0] << 16) | ((u32)addr[1] << 24);
    418	mac_hi = addr[2] | ((u32)addr[3] << 8) |
    419		((u32)addr[4] << 16) | ((u32)addr[5] << 24);
    420
    421	reg_lo = NETXEN_NIU_XGE_STATION_ADDR_0_1 + (0x10000 * phy);
    422	reg_hi = NETXEN_NIU_XGE_STATION_ADDR_0_HI + (0x10000 * phy);
    423
    424	/* write twice to flush */
    425	if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
    426		return -EIO;
    427	if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
    428		return -EIO;
    429
    430	return 0;
    431}
    432
    433static int
    434netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter)
    435{
    436	u32	val = 0;
    437	u16 port = adapter->physical_port;
    438	u8 *addr = adapter->mac_addr;
    439
    440	if (adapter->mc_enabled)
    441		return 0;
    442
    443	val = NXRD32(adapter, NETXEN_MAC_ADDR_CNTL_REG);
    444	val |= (1UL << (28+port));
    445	NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);
    446
    447	/* add broadcast addr to filter */
    448	val = 0xffffff;
    449	NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
    450	NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0)+4, val);
    451
    452	/* add station addr to filter */
    453	val = MAC_HI(addr);
    454	NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1), val);
    455	val = MAC_LO(addr);
    456	NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, val);
    457
    458	adapter->mc_enabled = 1;
    459	return 0;
    460}
    461
    462static int
    463netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter)
    464{
    465	u32	val = 0;
    466	u16 port = adapter->physical_port;
    467	u8 *addr = adapter->mac_addr;
    468
    469	if (!adapter->mc_enabled)
    470		return 0;
    471
    472	val = NXRD32(adapter, NETXEN_MAC_ADDR_CNTL_REG);
    473	val &= ~(1UL << (28+port));
    474	NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);
    475
    476	val = MAC_HI(addr);
    477	NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
    478	val = MAC_LO(addr);
    479	NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0)+4, val);
    480
    481	NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1), 0);
    482	NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, 0);
    483
    484	adapter->mc_enabled = 0;
    485	return 0;
    486}
    487
    488static int
    489netxen_nic_set_mcast_addr(struct netxen_adapter *adapter,
    490		int index, u8 *addr)
    491{
    492	u32 hi = 0, lo = 0;
    493	u16 port = adapter->physical_port;
    494
    495	lo = MAC_LO(addr);
    496	hi = MAC_HI(addr);
    497
    498	NXWR32(adapter, NETXEN_MCAST_ADDR(port, index), hi);
    499	NXWR32(adapter, NETXEN_MCAST_ADDR(port, index)+4, lo);
    500
    501	return 0;
    502}
    503
    504static void netxen_p2_nic_set_multi(struct net_device *netdev)
    505{
    506	struct netxen_adapter *adapter = netdev_priv(netdev);
    507	struct netdev_hw_addr *ha;
    508	u8 null_addr[ETH_ALEN];
    509	int i;
    510
    511	eth_zero_addr(null_addr);
    512
    513	if (netdev->flags & IFF_PROMISC) {
    514
    515		adapter->set_promisc(adapter,
    516				NETXEN_NIU_PROMISC_MODE);
    517
    518		/* Full promiscuous mode */
    519		netxen_nic_disable_mcast_filter(adapter);
    520
    521		return;
    522	}
    523
    524	if (netdev_mc_empty(netdev)) {
    525		adapter->set_promisc(adapter,
    526				NETXEN_NIU_NON_PROMISC_MODE);
    527		netxen_nic_disable_mcast_filter(adapter);
    528		return;
    529	}
    530
    531	adapter->set_promisc(adapter, NETXEN_NIU_ALLMULTI_MODE);
    532	if (netdev->flags & IFF_ALLMULTI ||
    533			netdev_mc_count(netdev) > adapter->max_mc_count) {
    534		netxen_nic_disable_mcast_filter(adapter);
    535		return;
    536	}
    537
    538	netxen_nic_enable_mcast_filter(adapter);
    539
    540	i = 0;
    541	netdev_for_each_mc_addr(ha, netdev)
    542		netxen_nic_set_mcast_addr(adapter, i++, ha->addr);
    543
    544	/* Clear out remaining addresses */
    545	while (i < adapter->max_mc_count)
    546		netxen_nic_set_mcast_addr(adapter, i++, null_addr);
    547}
    548
    549static int
    550netxen_send_cmd_descs(struct netxen_adapter *adapter,
    551		struct cmd_desc_type0 *cmd_desc_arr, int nr_desc)
    552{
    553	u32 i, producer;
    554	struct netxen_cmd_buffer *pbuf;
    555	struct nx_host_tx_ring *tx_ring;
    556
    557	i = 0;
    558
    559	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
    560		return -EIO;
    561
    562	tx_ring = adapter->tx_ring;
    563	__netif_tx_lock_bh(tx_ring->txq);
    564
    565	producer = tx_ring->producer;
    566
    567	if (nr_desc >= netxen_tx_avail(tx_ring)) {
    568		netif_tx_stop_queue(tx_ring->txq);
    569		smp_mb();
    570		if (netxen_tx_avail(tx_ring) > nr_desc) {
    571			if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH)
    572				netif_tx_wake_queue(tx_ring->txq);
    573		} else {
    574			__netif_tx_unlock_bh(tx_ring->txq);
    575			return -EBUSY;
    576		}
    577	}
    578
    579	do {
    580		pbuf = &tx_ring->cmd_buf_arr[producer];
    581		pbuf->skb = NULL;
    582		pbuf->frag_count = 0;
    583
    584		memcpy(&tx_ring->desc_head[producer],
    585			&cmd_desc_arr[i], sizeof(struct cmd_desc_type0));
    586
    587		producer = get_next_index(producer, tx_ring->num_desc);
    588		i++;
    589
    590	} while (i != nr_desc);
    591
    592	tx_ring->producer = producer;
    593
    594	netxen_nic_update_cmd_producer(adapter, tx_ring);
    595
    596	__netif_tx_unlock_bh(tx_ring->txq);
    597
    598	return 0;
    599}
    600
    601static int
    602nx_p3_sre_macaddr_change(struct netxen_adapter *adapter, u8 *addr, unsigned op)
    603{
    604	nx_nic_req_t req;
    605	nx_mac_req_t *mac_req;
    606	u64 word;
    607
    608	memset(&req, 0, sizeof(nx_nic_req_t));
    609	req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23);
    610
    611	word = NX_MAC_EVENT | ((u64)adapter->portnum << 16);
    612	req.req_hdr = cpu_to_le64(word);
    613
    614	mac_req = (nx_mac_req_t *)&req.words[0];
    615	mac_req->op = op;
    616	memcpy(mac_req->mac_addr, addr, ETH_ALEN);
    617
    618	return netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
    619}
    620
    621static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
    622		const u8 *addr, struct list_head *del_list)
    623{
    624	struct list_head *head;
    625	nx_mac_list_t *cur;
    626
    627	/* look up if already exists */
    628	list_for_each(head, del_list) {
    629		cur = list_entry(head, nx_mac_list_t, list);
    630
    631		if (ether_addr_equal(addr, cur->mac_addr)) {
    632			list_move_tail(head, &adapter->mac_list);
    633			return 0;
    634		}
    635	}
    636
    637	cur = kzalloc(sizeof(nx_mac_list_t), GFP_ATOMIC);
    638	if (cur == NULL)
    639		return -ENOMEM;
    640
    641	memcpy(cur->mac_addr, addr, ETH_ALEN);
    642	list_add_tail(&cur->list, &adapter->mac_list);
    643	return nx_p3_sre_macaddr_change(adapter,
    644				cur->mac_addr, NETXEN_MAC_ADD);
    645}
    646
    647static void netxen_p3_nic_set_multi(struct net_device *netdev)
    648{
    649	struct netxen_adapter *adapter = netdev_priv(netdev);
    650	struct netdev_hw_addr *ha;
    651	static const u8 bcast_addr[ETH_ALEN] = {
    652		0xff, 0xff, 0xff, 0xff, 0xff, 0xff
    653	};
    654	u32 mode = VPORT_MISS_MODE_DROP;
    655	LIST_HEAD(del_list);
    656	struct list_head *head;
    657	nx_mac_list_t *cur;
    658
    659	if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
    660		return;
    661
    662	list_splice_tail_init(&adapter->mac_list, &del_list);
    663
    664	nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list);
    665	nx_p3_nic_add_mac(adapter, bcast_addr, &del_list);
    666
    667	if (netdev->flags & IFF_PROMISC) {
    668		mode = VPORT_MISS_MODE_ACCEPT_ALL;
    669		goto send_fw_cmd;
    670	}
    671
    672	if ((netdev->flags & IFF_ALLMULTI) ||
    673			(netdev_mc_count(netdev) > adapter->max_mc_count)) {
    674		mode = VPORT_MISS_MODE_ACCEPT_MULTI;
    675		goto send_fw_cmd;
    676	}
    677
    678	if (!netdev_mc_empty(netdev)) {
    679		netdev_for_each_mc_addr(ha, netdev)
    680			nx_p3_nic_add_mac(adapter, ha->addr, &del_list);
    681	}
    682
    683send_fw_cmd:
    684	adapter->set_promisc(adapter, mode);
    685	head = &del_list;
    686	while (!list_empty(head)) {
    687		cur = list_entry(head->next, nx_mac_list_t, list);
    688
    689		nx_p3_sre_macaddr_change(adapter,
    690				cur->mac_addr, NETXEN_MAC_DEL);
    691		list_del(&cur->list);
    692		kfree(cur);
    693	}
    694}
    695
    696static int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
    697{
    698	nx_nic_req_t req;
    699	u64 word;
    700
    701	memset(&req, 0, sizeof(nx_nic_req_t));
    702
    703	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
    704
    705	word = NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE |
    706			((u64)adapter->portnum << 16);
    707	req.req_hdr = cpu_to_le64(word);
    708
    709	req.words[0] = cpu_to_le64(mode);
    710
    711	return netxen_send_cmd_descs(adapter,
    712				(struct cmd_desc_type0 *)&req, 1);
    713}
    714
    715void netxen_p3_free_mac_list(struct netxen_adapter *adapter)
    716{
    717	nx_mac_list_t *cur;
    718	struct list_head *head = &adapter->mac_list;
    719
    720	while (!list_empty(head)) {
    721		cur = list_entry(head->next, nx_mac_list_t, list);
    722		nx_p3_sre_macaddr_change(adapter,
    723				cur->mac_addr, NETXEN_MAC_DEL);
    724		list_del(&cur->list);
    725		kfree(cur);
    726	}
    727}
    728
    729static int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
    730{
    731	/* assuming caller has already copied new addr to netdev */
    732	netxen_p3_nic_set_multi(adapter->netdev);
    733	return 0;
    734}
    735
    736#define	NETXEN_CONFIG_INTR_COALESCE	3
    737
    738/*
    739 * Send the interrupt coalescing parameter set by ethtool to the card.
    740 */
    741int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
    742{
    743	nx_nic_req_t req;
    744	u64 word[6];
    745	int rv, i;
    746
    747	memset(&req, 0, sizeof(nx_nic_req_t));
    748	memset(word, 0, sizeof(word));
    749
    750	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
    751
    752	word[0] = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16);
    753	req.req_hdr = cpu_to_le64(word[0]);
    754
    755	memcpy(&word[0], &adapter->coal, sizeof(adapter->coal));
    756	for (i = 0; i < 6; i++)
    757		req.words[i] = cpu_to_le64(word[i]);
    758
    759	rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
    760	if (rv != 0) {
    761		printk(KERN_ERR "ERROR. Could not send "
    762			"interrupt coalescing parameters\n");
    763	}
    764
    765	return rv;
    766}
    767
    768int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable)
    769{
    770	nx_nic_req_t req;
    771	u64 word;
    772	int rv = 0;
    773
    774	if (!test_bit(__NX_FW_ATTACHED, &adapter->state))
    775		return 0;
    776
    777	memset(&req, 0, sizeof(nx_nic_req_t));
    778
    779	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
    780
    781	word = NX_NIC_H2C_OPCODE_CONFIG_HW_LRO | ((u64)adapter->portnum << 16);
    782	req.req_hdr = cpu_to_le64(word);
    783
    784	req.words[0] = cpu_to_le64(enable);
    785
    786	rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
    787	if (rv != 0) {
    788		printk(KERN_ERR "ERROR. Could not send "
    789			"configure hw lro request\n");
    790	}
    791
    792	return rv;
    793}
    794
    795int netxen_config_bridged_mode(struct netxen_adapter *adapter, int enable)
    796{
    797	nx_nic_req_t req;
    798	u64 word;
    799	int rv = 0;
    800
    801	if (!!(adapter->flags & NETXEN_NIC_BRIDGE_ENABLED) == enable)
    802		return rv;
    803
    804	memset(&req, 0, sizeof(nx_nic_req_t));
    805
    806	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
    807
    808	word = NX_NIC_H2C_OPCODE_CONFIG_BRIDGING |
    809		((u64)adapter->portnum << 16);
    810	req.req_hdr = cpu_to_le64(word);
    811
    812	req.words[0] = cpu_to_le64(enable);
    813
    814	rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
    815	if (rv != 0) {
    816		printk(KERN_ERR "ERROR. Could not send "
    817				"configure bridge mode request\n");
    818	}
    819
    820	adapter->flags ^= NETXEN_NIC_BRIDGE_ENABLED;
    821
    822	return rv;
    823}
    824
    825
    826#define RSS_HASHTYPE_IP_TCP	0x3
    827
    828int netxen_config_rss(struct netxen_adapter *adapter, int enable)
    829{
    830	nx_nic_req_t req;
    831	u64 word;
    832	int i, rv;
    833
    834	static const u64 key[] = {
    835		0xbeac01fa6a42b73bULL, 0x8030f20c77cb2da3ULL,
    836		0xae7b30b4d0ca2bcbULL, 0x43a38fb04167253dULL,
    837		0x255b0ec26d5a56daULL
    838	};
    839
    840
    841	memset(&req, 0, sizeof(nx_nic_req_t));
    842	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
    843
    844	word = NX_NIC_H2C_OPCODE_CONFIG_RSS | ((u64)adapter->portnum << 16);
    845	req.req_hdr = cpu_to_le64(word);
    846
    847	/*
    848	 * RSS request:
    849	 * bits 3-0: hash_method
    850	 *      5-4: hash_type_ipv4
    851	 *	7-6: hash_type_ipv6
    852	 *	  8: enable
    853	 *        9: use indirection table
    854	 *    47-10: reserved
    855	 *    63-48: indirection table mask
    856	 */
    857	word =  ((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 4) |
    858		((u64)(RSS_HASHTYPE_IP_TCP & 0x3) << 6) |
    859		((u64)(enable & 0x1) << 8) |
    860		((0x7ULL) << 48);
    861	req.words[0] = cpu_to_le64(word);
    862	for (i = 0; i < ARRAY_SIZE(key); i++)
    863		req.words[i+1] = cpu_to_le64(key[i]);
    864
    865
    866	rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
    867	if (rv != 0) {
    868		printk(KERN_ERR "%s: could not configure RSS\n",
    869				adapter->netdev->name);
    870	}
    871
    872	return rv;
    873}
    874
    875int netxen_config_ipaddr(struct netxen_adapter *adapter, __be32 ip, int cmd)
    876{
    877	nx_nic_req_t req;
    878	u64 word;
    879	int rv;
    880
    881	memset(&req, 0, sizeof(nx_nic_req_t));
    882	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
    883
    884	word = NX_NIC_H2C_OPCODE_CONFIG_IPADDR | ((u64)adapter->portnum << 16);
    885	req.req_hdr = cpu_to_le64(word);
    886
    887	req.words[0] = cpu_to_le64(cmd);
    888	memcpy(&req.words[1], &ip, sizeof(u32));
    889
    890	rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
    891	if (rv != 0) {
    892		printk(KERN_ERR "%s: could not notify %s IP 0x%x request\n",
    893				adapter->netdev->name,
    894				(cmd == NX_IP_UP) ? "Add" : "Remove", ip);
    895	}
    896	return rv;
    897}
    898
    899int netxen_linkevent_request(struct netxen_adapter *adapter, int enable)
    900{
    901	nx_nic_req_t req;
    902	u64 word;
    903	int rv;
    904
    905	memset(&req, 0, sizeof(nx_nic_req_t));
    906	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
    907
    908	word = NX_NIC_H2C_OPCODE_GET_LINKEVENT | ((u64)adapter->portnum << 16);
    909	req.req_hdr = cpu_to_le64(word);
    910	req.words[0] = cpu_to_le64(enable | (enable << 8));
    911
    912	rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
    913	if (rv != 0) {
    914		printk(KERN_ERR "%s: could not configure link notification\n",
    915				adapter->netdev->name);
    916	}
    917
    918	return rv;
    919}
    920
    921int netxen_send_lro_cleanup(struct netxen_adapter *adapter)
    922{
    923	nx_nic_req_t req;
    924	u64 word;
    925	int rv;
    926
    927	if (!test_bit(__NX_FW_ATTACHED, &adapter->state))
    928		return 0;
    929
    930	memset(&req, 0, sizeof(nx_nic_req_t));
    931	req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
    932
    933	word = NX_NIC_H2C_OPCODE_LRO_REQUEST |
    934		((u64)adapter->portnum << 16) |
    935		((u64)NX_NIC_LRO_REQUEST_CLEANUP << 56) ;
    936
    937	req.req_hdr = cpu_to_le64(word);
    938
    939	rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
    940	if (rv != 0) {
    941		printk(KERN_ERR "%s: could not cleanup lro flows\n",
    942				adapter->netdev->name);
    943	}
    944	return rv;
    945}
    946
    947/*
    948 * netxen_nic_change_mtu - Change the Maximum Transfer Unit
    949 * @returns 0 on success, negative on failure
    950 */
    951
    952#define MTU_FUDGE_FACTOR	100
    953
    954int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
    955{
    956	struct netxen_adapter *adapter = netdev_priv(netdev);
    957	int rc = 0;
    958
    959	if (adapter->set_mtu)
    960		rc = adapter->set_mtu(adapter, mtu);
    961
    962	if (!rc)
    963		netdev->mtu = mtu;
    964
    965	return rc;
    966}
    967
    968static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
    969				  int size, __le32 * buf)
    970{
    971	int i, v, addr;
    972	__le32 *ptr32;
    973	int ret;
    974
    975	addr = base;
    976	ptr32 = buf;
    977	for (i = 0; i < size / sizeof(u32); i++) {
    978		ret = netxen_rom_fast_read(adapter, addr, &v);
    979		if (ret)
    980			return ret;
    981
    982		*ptr32 = cpu_to_le32(v);
    983		ptr32++;
    984		addr += sizeof(u32);
    985	}
    986	if ((char *)buf + size > (char *)ptr32) {
    987		__le32 local;
    988		ret = netxen_rom_fast_read(adapter, addr, &v);
    989		if (ret)
    990			return ret;
    991		local = cpu_to_le32(v);
    992		memcpy(ptr32, &local, (char *)buf + size - (char *)ptr32);
    993	}
    994
    995	return 0;
    996}
    997
    998int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 *mac)
    999{
   1000	__le32 *pmac = (__le32 *) mac;
   1001	u32 offset;
   1002
   1003	offset = NX_FW_MAC_ADDR_OFFSET + (adapter->portnum * sizeof(u64));
   1004
   1005	if (netxen_get_flash_block(adapter, offset, sizeof(u64), pmac) == -1)
   1006		return -1;
   1007
   1008	if (*mac == ~0ULL) {
   1009
   1010		offset = NX_OLD_MAC_ADDR_OFFSET +
   1011			(adapter->portnum * sizeof(u64));
   1012
   1013		if (netxen_get_flash_block(adapter,
   1014					offset, sizeof(u64), pmac) == -1)
   1015			return -1;
   1016
   1017		if (*mac == ~0ULL)
   1018			return -1;
   1019	}
   1020	return 0;
   1021}
   1022
   1023int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, u64 *mac)
   1024{
   1025	uint32_t crbaddr, mac_hi, mac_lo;
   1026	int pci_func = adapter->ahw.pci_func;
   1027
   1028	crbaddr = CRB_MAC_BLOCK_START +
   1029		(4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1));
   1030
   1031	mac_lo = NXRD32(adapter, crbaddr);
   1032	mac_hi = NXRD32(adapter, crbaddr+4);
   1033
   1034	if (pci_func & 1)
   1035		*mac = le64_to_cpu((mac_lo >> 16) | ((u64)mac_hi << 16));
   1036	else
   1037		*mac = le64_to_cpu((u64)mac_lo | ((u64)mac_hi << 32));
   1038
   1039	return 0;
   1040}
   1041
   1042/*
   1043 * Changes the CRB window to the specified window.
   1044 */
   1045static void
   1046netxen_nic_pci_set_crbwindow_128M(struct netxen_adapter *adapter,
   1047		u32 window)
   1048{
   1049	void __iomem *offset;
   1050	int count = 10;
   1051	u8 func = adapter->ahw.pci_func;
   1052
   1053	if (adapter->ahw.crb_win == window)
   1054		return;
   1055
   1056	offset = PCI_OFFSET_SECOND_RANGE(adapter,
   1057			NETXEN_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(func)));
   1058
   1059	writel(window, offset);
   1060	do {
   1061		if (window == readl(offset))
   1062			break;
   1063
   1064		if (printk_ratelimit())
   1065			dev_warn(&adapter->pdev->dev,
   1066					"failed to set CRB window to %d\n",
   1067					(window == NETXEN_WINDOW_ONE));
   1068		udelay(1);
   1069
   1070	} while (--count > 0);
   1071
   1072	if (count > 0)
   1073		adapter->ahw.crb_win = window;
   1074}
   1075
   1076/*
   1077 * Returns < 0 if off is not valid,
   1078 *	 1 if window access is needed. 'off' is set to offset from
   1079 *	   CRB space in 128M pci map
   1080 *	 0 if no window access is needed. 'off' is set to 2M addr
   1081 * In: 'off' is offset from base in 128M pci map
   1082 */
   1083static int
   1084netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter,
   1085		ulong off, void __iomem **addr)
   1086{
   1087	crb_128M_2M_sub_block_map_t *m;
   1088
   1089
   1090	if ((off >= NETXEN_CRB_MAX) || (off < NETXEN_PCI_CRBSPACE))
   1091		return -EINVAL;
   1092
   1093	off -= NETXEN_PCI_CRBSPACE;
   1094
   1095	/*
   1096	 * Try direct map
   1097	 */
   1098	m = &crb_128M_2M_map[CRB_BLK(off)].sub_block[CRB_SUBBLK(off)];
   1099
   1100	if (m->valid && (m->start_128M <= off) && (m->end_128M > off)) {
   1101		*addr = adapter->ahw.pci_base0 + m->start_2M +
   1102			(off - m->start_128M);
   1103		return 0;
   1104	}
   1105
   1106	/*
   1107	 * Not in direct map, use crb window
   1108	 */
   1109	*addr = adapter->ahw.pci_base0 + CRB_INDIRECT_2M +
   1110		(off & MASK(16));
   1111	return 1;
   1112}
   1113
   1114/*
   1115 * In: 'off' is offset from CRB space in 128M pci map
   1116 * Out: 'off' is 2M pci map addr
   1117 * side effect: lock crb window
   1118 */
   1119static void
   1120netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong off)
   1121{
   1122	u32 window;
   1123	void __iomem *addr = adapter->ahw.pci_base0 + CRB_WINDOW_2M;
   1124
   1125	off -= NETXEN_PCI_CRBSPACE;
   1126
   1127	window = CRB_HI(off);
   1128
   1129	writel(window, addr);
   1130	if (readl(addr) != window) {
   1131		if (printk_ratelimit())
   1132			dev_warn(&adapter->pdev->dev,
   1133				"failed to set CRB window to %d off 0x%lx\n",
   1134				window, off);
   1135	}
   1136}
   1137
   1138static void __iomem *
   1139netxen_nic_map_indirect_address_128M(struct netxen_adapter *adapter,
   1140		ulong win_off, void __iomem **mem_ptr)
   1141{
   1142	ulong off = win_off;
   1143	void __iomem *addr;
   1144	resource_size_t mem_base;
   1145
   1146	if (ADDR_IN_WINDOW1(win_off))
   1147		off = NETXEN_CRB_NORMAL(win_off);
   1148
   1149	addr = pci_base_offset(adapter, off);
   1150	if (addr)
   1151		return addr;
   1152
   1153	if (adapter->ahw.pci_len0 == 0)
   1154		off -= NETXEN_PCI_CRBSPACE;
   1155
   1156	mem_base = pci_resource_start(adapter->pdev, 0);
   1157	*mem_ptr = ioremap(mem_base + (off & PAGE_MASK), PAGE_SIZE);
   1158	if (*mem_ptr)
   1159		addr = *mem_ptr + (off & (PAGE_SIZE - 1));
   1160
   1161	return addr;
   1162}
   1163
   1164static int
   1165netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data)
   1166{
   1167	unsigned long flags;
   1168	void __iomem *addr, *mem_ptr = NULL;
   1169
   1170	addr = netxen_nic_map_indirect_address_128M(adapter, off, &mem_ptr);
   1171	if (!addr)
   1172		return -EIO;
   1173
   1174	if (ADDR_IN_WINDOW1(off)) { /* Window 1 */
   1175		netxen_nic_io_write_128M(adapter, addr, data);
   1176	} else {        /* Window 0 */
   1177		write_lock_irqsave(&adapter->ahw.crb_lock, flags);
   1178		netxen_nic_pci_set_crbwindow_128M(adapter, 0);
   1179		writel(data, addr);
   1180		netxen_nic_pci_set_crbwindow_128M(adapter,
   1181				NETXEN_WINDOW_ONE);
   1182		write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
   1183	}
   1184
   1185	if (mem_ptr)
   1186		iounmap(mem_ptr);
   1187
   1188	return 0;
   1189}
   1190
   1191static u32
   1192netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off)
   1193{
   1194	unsigned long flags;
   1195	void __iomem *addr, *mem_ptr = NULL;
   1196	u32 data;
   1197
   1198	addr = netxen_nic_map_indirect_address_128M(adapter, off, &mem_ptr);
   1199	if (!addr)
   1200		return -EIO;
   1201
   1202	if (ADDR_IN_WINDOW1(off)) { /* Window 1 */
   1203		data = netxen_nic_io_read_128M(adapter, addr);
   1204	} else {        /* Window 0 */
   1205		write_lock_irqsave(&adapter->ahw.crb_lock, flags);
   1206		netxen_nic_pci_set_crbwindow_128M(adapter, 0);
   1207		data = readl(addr);
   1208		netxen_nic_pci_set_crbwindow_128M(adapter,
   1209				NETXEN_WINDOW_ONE);
   1210		write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
   1211	}
   1212
   1213	if (mem_ptr)
   1214		iounmap(mem_ptr);
   1215
   1216	return data;
   1217}
   1218
   1219static int
   1220netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data)
   1221{
   1222	unsigned long flags;
   1223	int rv;
   1224	void __iomem *addr = NULL;
   1225
   1226	rv = netxen_nic_pci_get_crb_addr_2M(adapter, off, &addr);
   1227
   1228	if (rv == 0) {
   1229		writel(data, addr);
   1230		return 0;
   1231	}
   1232
   1233	if (rv > 0) {
   1234		/* indirect access */
   1235		write_lock_irqsave(&adapter->ahw.crb_lock, flags);
   1236		crb_win_lock(adapter);
   1237		netxen_nic_pci_set_crbwindow_2M(adapter, off);
   1238		writel(data, addr);
   1239		crb_win_unlock(adapter);
   1240		write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
   1241		return 0;
   1242	}
   1243
   1244	dev_err(&adapter->pdev->dev,
   1245			"%s: invalid offset: 0x%016lx\n", __func__, off);
   1246	dump_stack();
   1247	return -EIO;
   1248}
   1249
   1250static u32
   1251netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off)
   1252{
   1253	unsigned long flags;
   1254	int rv;
   1255	u32 data;
   1256	void __iomem *addr = NULL;
   1257
   1258	rv = netxen_nic_pci_get_crb_addr_2M(adapter, off, &addr);
   1259
   1260	if (rv == 0)
   1261		return readl(addr);
   1262
   1263	if (rv > 0) {
   1264		/* indirect access */
   1265		write_lock_irqsave(&adapter->ahw.crb_lock, flags);
   1266		crb_win_lock(adapter);
   1267		netxen_nic_pci_set_crbwindow_2M(adapter, off);
   1268		data = readl(addr);
   1269		crb_win_unlock(adapter);
   1270		write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
   1271		return data;
   1272	}
   1273
   1274	dev_err(&adapter->pdev->dev,
   1275			"%s: invalid offset: 0x%016lx\n", __func__, off);
   1276	dump_stack();
   1277	return -1;
   1278}
   1279
   1280/* window 1 registers only */
   1281static void netxen_nic_io_write_128M(struct netxen_adapter *adapter,
   1282		void __iomem *addr, u32 data)
   1283{
   1284	read_lock(&adapter->ahw.crb_lock);
   1285	writel(data, addr);
   1286	read_unlock(&adapter->ahw.crb_lock);
   1287}
   1288
   1289static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter,
   1290		void __iomem *addr)
   1291{
   1292	u32 val;
   1293
   1294	read_lock(&adapter->ahw.crb_lock);
   1295	val = readl(addr);
   1296	read_unlock(&adapter->ahw.crb_lock);
   1297
   1298	return val;
   1299}
   1300
   1301static void netxen_nic_io_write_2M(struct netxen_adapter *adapter,
   1302		void __iomem *addr, u32 data)
   1303{
   1304	writel(data, addr);
   1305}
   1306
   1307static u32 netxen_nic_io_read_2M(struct netxen_adapter *adapter,
   1308		void __iomem *addr)
   1309{
   1310	return readl(addr);
   1311}
   1312
   1313void __iomem *
   1314netxen_get_ioaddr(struct netxen_adapter *adapter, u32 offset)
   1315{
   1316	void __iomem *addr = NULL;
   1317
   1318	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
   1319		if ((offset < NETXEN_CRB_PCIX_HOST2) &&
   1320				(offset > NETXEN_CRB_PCIX_HOST))
   1321			addr = PCI_OFFSET_SECOND_RANGE(adapter, offset);
   1322		else
   1323			addr = NETXEN_CRB_NORMALIZE(adapter, offset);
   1324	} else {
   1325		WARN_ON(netxen_nic_pci_get_crb_addr_2M(adapter,
   1326					offset, &addr));
   1327	}
   1328
   1329	return addr;
   1330}
   1331
   1332static int
   1333netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
   1334		u64 addr, u32 *start)
   1335{
   1336	if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
   1337		*start = (addr - NETXEN_ADDR_OCM0  + NETXEN_PCI_OCM0);
   1338		return 0;
   1339	} else if (ADDR_IN_RANGE(addr,
   1340				NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
   1341		*start = (addr - NETXEN_ADDR_OCM1 + NETXEN_PCI_OCM1);
   1342		return 0;
   1343	}
   1344
   1345	return -EIO;
   1346}
   1347
   1348static int
   1349netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
   1350		u64 addr, u32 *start)
   1351{
   1352	u32 window;
   1353
   1354	window = OCM_WIN(addr);
   1355
   1356	writel(window, adapter->ahw.ocm_win_crb);
   1357	/* read back to flush */
   1358	readl(adapter->ahw.ocm_win_crb);
   1359
   1360	adapter->ahw.ocm_win = window;
   1361	*start = NETXEN_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr);
   1362	return 0;
   1363}
   1364
   1365static int
   1366netxen_nic_pci_mem_access_direct(struct netxen_adapter *adapter, u64 off,
   1367		u64 *data, int op)
   1368{
   1369	void __iomem *addr, *mem_ptr = NULL;
   1370	resource_size_t mem_base;
   1371	int ret;
   1372	u32 start;
   1373
   1374	spin_lock(&adapter->ahw.mem_lock);
   1375
   1376	ret = adapter->pci_set_window(adapter, off, &start);
   1377	if (ret != 0)
   1378		goto unlock;
   1379
   1380	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
   1381		addr = adapter->ahw.pci_base0 + start;
   1382	} else {
   1383		addr = pci_base_offset(adapter, start);
   1384		if (addr)
   1385			goto noremap;
   1386
   1387		mem_base = pci_resource_start(adapter->pdev, 0) +
   1388					(start & PAGE_MASK);
   1389		mem_ptr = ioremap(mem_base, PAGE_SIZE);
   1390		if (mem_ptr == NULL) {
   1391			ret = -EIO;
   1392			goto unlock;
   1393		}
   1394
   1395		addr = mem_ptr + (start & (PAGE_SIZE-1));
   1396	}
   1397noremap:
   1398	if (op == 0)	/* read */
   1399		*data = readq(addr);
   1400	else		/* write */
   1401		writeq(*data, addr);
   1402
   1403unlock:
   1404	spin_unlock(&adapter->ahw.mem_lock);
   1405
   1406	if (mem_ptr)
   1407		iounmap(mem_ptr);
   1408	return ret;
   1409}
   1410
   1411void
   1412netxen_pci_camqm_read_2M(struct netxen_adapter *adapter, u64 off, u64 *data)
   1413{
   1414	void __iomem *addr = adapter->ahw.pci_base0 +
   1415		NETXEN_PCI_CAMQM_2M_BASE + (off - NETXEN_PCI_CAMQM);
   1416
   1417	spin_lock(&adapter->ahw.mem_lock);
   1418	*data = readq(addr);
   1419	spin_unlock(&adapter->ahw.mem_lock);
   1420}
   1421
   1422void
   1423netxen_pci_camqm_write_2M(struct netxen_adapter *adapter, u64 off, u64 data)
   1424{
   1425	void __iomem *addr = adapter->ahw.pci_base0 +
   1426		NETXEN_PCI_CAMQM_2M_BASE + (off - NETXEN_PCI_CAMQM);
   1427
   1428	spin_lock(&adapter->ahw.mem_lock);
   1429	writeq(data, addr);
   1430	spin_unlock(&adapter->ahw.mem_lock);
   1431}
   1432
   1433#define MAX_CTL_CHECK   1000
   1434
   1435static int
   1436netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
   1437		u64 off, u64 data)
   1438{
   1439	int j, ret;
   1440	u32 temp, off_lo, off_hi, addr_hi, data_hi, data_lo;
   1441	void __iomem *mem_crb;
   1442
   1443	/* Only 64-bit aligned access */
   1444	if (off & 7)
   1445		return -EIO;
   1446
   1447	/* P2 has different SIU and MIU test agent base addr */
   1448	if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
   1449				NETXEN_ADDR_QDR_NET_MAX_P2)) {
   1450		mem_crb = pci_base_offset(adapter,
   1451				NETXEN_CRB_QDR_NET+SIU_TEST_AGT_BASE);
   1452		addr_hi = SIU_TEST_AGT_ADDR_HI;
   1453		data_lo = SIU_TEST_AGT_WRDATA_LO;
   1454		data_hi = SIU_TEST_AGT_WRDATA_HI;
   1455		off_lo = off & SIU_TEST_AGT_ADDR_MASK;
   1456		off_hi = SIU_TEST_AGT_UPPER_ADDR(off);
   1457		goto correct;
   1458	}
   1459
   1460	if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
   1461		mem_crb = pci_base_offset(adapter,
   1462				NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
   1463		addr_hi = MIU_TEST_AGT_ADDR_HI;
   1464		data_lo = MIU_TEST_AGT_WRDATA_LO;
   1465		data_hi = MIU_TEST_AGT_WRDATA_HI;
   1466		off_lo = off & MIU_TEST_AGT_ADDR_MASK;
   1467		off_hi = 0;
   1468		goto correct;
   1469	}
   1470
   1471	if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX) ||
   1472		ADDR_IN_RANGE(off, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
   1473		if (adapter->ahw.pci_len0 != 0) {
   1474			return netxen_nic_pci_mem_access_direct(adapter,
   1475					off, &data, 1);
   1476		}
   1477	}
   1478
   1479	return -EIO;
   1480
   1481correct:
   1482	spin_lock(&adapter->ahw.mem_lock);
   1483	netxen_nic_pci_set_crbwindow_128M(adapter, 0);
   1484
   1485	writel(off_lo, (mem_crb + MIU_TEST_AGT_ADDR_LO));
   1486	writel(off_hi, (mem_crb + addr_hi));
   1487	writel(data & 0xffffffff, (mem_crb + data_lo));
   1488	writel((data >> 32) & 0xffffffff, (mem_crb + data_hi));
   1489	writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL));
   1490	writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE),
   1491			(mem_crb + TEST_AGT_CTRL));
   1492
   1493	for (j = 0; j < MAX_CTL_CHECK; j++) {
   1494		temp = readl((mem_crb + TEST_AGT_CTRL));
   1495		if ((temp & TA_CTL_BUSY) == 0)
   1496			break;
   1497	}
   1498
   1499	if (j >= MAX_CTL_CHECK) {
   1500		if (printk_ratelimit())
   1501			dev_err(&adapter->pdev->dev,
   1502					"failed to write through agent\n");
   1503		ret = -EIO;
   1504	} else
   1505		ret = 0;
   1506
   1507	netxen_nic_pci_set_crbwindow_128M(adapter, NETXEN_WINDOW_ONE);
   1508	spin_unlock(&adapter->ahw.mem_lock);
   1509	return ret;
   1510}
   1511
   1512static int
   1513netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
   1514		u64 off, u64 *data)
   1515{
   1516	int j, ret;
   1517	u32 temp, off_lo, off_hi, addr_hi, data_hi, data_lo;
   1518	u64 val;
   1519	void __iomem *mem_crb;
   1520
   1521	/* Only 64-bit aligned access */
   1522	if (off & 7)
   1523		return -EIO;
   1524
   1525	/* P2 has different SIU and MIU test agent base addr */
   1526	if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
   1527				NETXEN_ADDR_QDR_NET_MAX_P2)) {
   1528		mem_crb = pci_base_offset(adapter,
   1529				NETXEN_CRB_QDR_NET+SIU_TEST_AGT_BASE);
   1530		addr_hi = SIU_TEST_AGT_ADDR_HI;
   1531		data_lo = SIU_TEST_AGT_RDDATA_LO;
   1532		data_hi = SIU_TEST_AGT_RDDATA_HI;
   1533		off_lo = off & SIU_TEST_AGT_ADDR_MASK;
   1534		off_hi = SIU_TEST_AGT_UPPER_ADDR(off);
   1535		goto correct;
   1536	}
   1537
   1538	if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
   1539		mem_crb = pci_base_offset(adapter,
   1540				NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
   1541		addr_hi = MIU_TEST_AGT_ADDR_HI;
   1542		data_lo = MIU_TEST_AGT_RDDATA_LO;
   1543		data_hi = MIU_TEST_AGT_RDDATA_HI;
   1544		off_lo = off & MIU_TEST_AGT_ADDR_MASK;
   1545		off_hi = 0;
   1546		goto correct;
   1547	}
   1548
   1549	if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX) ||
   1550		ADDR_IN_RANGE(off, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
   1551		if (adapter->ahw.pci_len0 != 0) {
   1552			return netxen_nic_pci_mem_access_direct(adapter,
   1553					off, data, 0);
   1554		}
   1555	}
   1556
   1557	return -EIO;
   1558
   1559correct:
   1560	spin_lock(&adapter->ahw.mem_lock);
   1561	netxen_nic_pci_set_crbwindow_128M(adapter, 0);
   1562
   1563	writel(off_lo, (mem_crb + MIU_TEST_AGT_ADDR_LO));
   1564	writel(off_hi, (mem_crb + addr_hi));
   1565	writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
   1566	writel((TA_CTL_START|TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL));
   1567
   1568	for (j = 0; j < MAX_CTL_CHECK; j++) {
   1569		temp = readl(mem_crb + TEST_AGT_CTRL);
   1570		if ((temp & TA_CTL_BUSY) == 0)
   1571			break;
   1572	}
   1573
   1574	if (j >= MAX_CTL_CHECK) {
   1575		if (printk_ratelimit())
   1576			dev_err(&adapter->pdev->dev,
   1577					"failed to read through agent\n");
   1578		ret = -EIO;
   1579	} else {
   1580
   1581		temp = readl(mem_crb + data_hi);
   1582		val = ((u64)temp << 32);
   1583		val |= readl(mem_crb + data_lo);
   1584		*data = val;
   1585		ret = 0;
   1586	}
   1587
   1588	netxen_nic_pci_set_crbwindow_128M(adapter, NETXEN_WINDOW_ONE);
   1589	spin_unlock(&adapter->ahw.mem_lock);
   1590
   1591	return ret;
   1592}
   1593
   1594static int
   1595netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
   1596		u64 off, u64 data)
   1597{
   1598	int j, ret;
   1599	u32 temp, off8;
   1600	void __iomem *mem_crb;
   1601
   1602	/* Only 64-bit aligned access */
   1603	if (off & 7)
   1604		return -EIO;
   1605
   1606	/* P3 onward, test agent base for MIU and SIU is same */
   1607	if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
   1608				NETXEN_ADDR_QDR_NET_MAX_P3)) {
   1609		mem_crb = netxen_get_ioaddr(adapter,
   1610				NETXEN_CRB_QDR_NET+MIU_TEST_AGT_BASE);
   1611		goto correct;
   1612	}
   1613
   1614	if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
   1615		mem_crb = netxen_get_ioaddr(adapter,
   1616				NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
   1617		goto correct;
   1618	}
   1619
   1620	if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX))
   1621		return netxen_nic_pci_mem_access_direct(adapter, off, &data, 1);
   1622
   1623	return -EIO;
   1624
   1625correct:
   1626	off8 = off & 0xfffffff8;
   1627
   1628	spin_lock(&adapter->ahw.mem_lock);
   1629
   1630	writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
   1631	writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
   1632
   1633	writel(data & 0xffffffff,
   1634			mem_crb + MIU_TEST_AGT_WRDATA_LO);
   1635	writel((data >> 32) & 0xffffffff,
   1636			mem_crb + MIU_TEST_AGT_WRDATA_HI);
   1637
   1638	writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL));
   1639	writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE),
   1640			(mem_crb + TEST_AGT_CTRL));
   1641
   1642	for (j = 0; j < MAX_CTL_CHECK; j++) {
   1643		temp = readl(mem_crb + TEST_AGT_CTRL);
   1644		if ((temp & TA_CTL_BUSY) == 0)
   1645			break;
   1646	}
   1647
   1648	if (j >= MAX_CTL_CHECK) {
   1649		if (printk_ratelimit())
   1650			dev_err(&adapter->pdev->dev,
   1651					"failed to write through agent\n");
   1652		ret = -EIO;
   1653	} else
   1654		ret = 0;
   1655
   1656	spin_unlock(&adapter->ahw.mem_lock);
   1657
   1658	return ret;
   1659}
   1660
   1661static int
   1662netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
   1663		u64 off, u64 *data)
   1664{
   1665	int j, ret;
   1666	u32 temp, off8;
   1667	u64 val;
   1668	void __iomem *mem_crb;
   1669
   1670	/* Only 64-bit aligned access */
   1671	if (off & 7)
   1672		return -EIO;
   1673
   1674	/* P3 onward, test agent base for MIU and SIU is same */
   1675	if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
   1676				NETXEN_ADDR_QDR_NET_MAX_P3)) {
   1677		mem_crb = netxen_get_ioaddr(adapter,
   1678				NETXEN_CRB_QDR_NET+MIU_TEST_AGT_BASE);
   1679		goto correct;
   1680	}
   1681
   1682	if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
   1683		mem_crb = netxen_get_ioaddr(adapter,
   1684				NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
   1685		goto correct;
   1686	}
   1687
   1688	if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
   1689		return netxen_nic_pci_mem_access_direct(adapter,
   1690				off, data, 0);
   1691	}
   1692
   1693	return -EIO;
   1694
   1695correct:
   1696	off8 = off & 0xfffffff8;
   1697
   1698	spin_lock(&adapter->ahw.mem_lock);
   1699
   1700	writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
   1701	writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
   1702	writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
   1703	writel((TA_CTL_START | TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL));
   1704
   1705	for (j = 0; j < MAX_CTL_CHECK; j++) {
   1706		temp = readl(mem_crb + TEST_AGT_CTRL);
   1707		if ((temp & TA_CTL_BUSY) == 0)
   1708			break;
   1709	}
   1710
   1711	if (j >= MAX_CTL_CHECK) {
   1712		if (printk_ratelimit())
   1713			dev_err(&adapter->pdev->dev,
   1714					"failed to read through agent\n");
   1715		ret = -EIO;
   1716	} else {
   1717		val = (u64)(readl(mem_crb + MIU_TEST_AGT_RDDATA_HI)) << 32;
   1718		val |= readl(mem_crb + MIU_TEST_AGT_RDDATA_LO);
   1719		*data = val;
   1720		ret = 0;
   1721	}
   1722
   1723	spin_unlock(&adapter->ahw.mem_lock);
   1724
   1725	return ret;
   1726}
   1727
   1728void
   1729netxen_setup_hwops(struct netxen_adapter *adapter)
   1730{
   1731	adapter->init_port = netxen_niu_xg_init_port;
   1732	adapter->stop_port = netxen_niu_disable_xg_port;
   1733
   1734	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
   1735		adapter->crb_read = netxen_nic_hw_read_wx_128M,
   1736		adapter->crb_write = netxen_nic_hw_write_wx_128M,
   1737		adapter->pci_set_window = netxen_nic_pci_set_window_128M,
   1738		adapter->pci_mem_read = netxen_nic_pci_mem_read_128M,
   1739		adapter->pci_mem_write = netxen_nic_pci_mem_write_128M,
   1740		adapter->io_read = netxen_nic_io_read_128M,
   1741		adapter->io_write = netxen_nic_io_write_128M,
   1742
   1743		adapter->macaddr_set = netxen_p2_nic_set_mac_addr;
   1744		adapter->set_multi = netxen_p2_nic_set_multi;
   1745		adapter->set_mtu = netxen_nic_set_mtu_xgb;
   1746		adapter->set_promisc = netxen_p2_nic_set_promisc;
   1747
   1748	} else {
   1749		adapter->crb_read = netxen_nic_hw_read_wx_2M,
   1750		adapter->crb_write = netxen_nic_hw_write_wx_2M,
   1751		adapter->pci_set_window = netxen_nic_pci_set_window_2M,
   1752		adapter->pci_mem_read = netxen_nic_pci_mem_read_2M,
   1753		adapter->pci_mem_write = netxen_nic_pci_mem_write_2M,
   1754		adapter->io_read = netxen_nic_io_read_2M,
   1755		adapter->io_write = netxen_nic_io_write_2M,
   1756
   1757		adapter->set_mtu = nx_fw_cmd_set_mtu;
   1758		adapter->set_promisc = netxen_p3_nic_set_promisc;
   1759		adapter->macaddr_set = netxen_p3_nic_set_mac_addr;
   1760		adapter->set_multi = netxen_p3_nic_set_multi;
   1761
   1762		adapter->phy_read = nx_fw_cmd_query_phy;
   1763		adapter->phy_write = nx_fw_cmd_set_phy;
   1764	}
   1765}
   1766
   1767int netxen_nic_get_board_info(struct netxen_adapter *adapter)
   1768{
   1769	int offset, board_type, magic;
   1770	struct pci_dev *pdev = adapter->pdev;
   1771
   1772	offset = NX_FW_MAGIC_OFFSET;
   1773	if (netxen_rom_fast_read(adapter, offset, &magic))
   1774		return -EIO;
   1775
   1776	if (magic != NETXEN_BDINFO_MAGIC) {
   1777		dev_err(&pdev->dev, "invalid board config, magic=%08x\n",
   1778			magic);
   1779		return -EIO;
   1780	}
   1781
   1782	offset = NX_BRDTYPE_OFFSET;
   1783	if (netxen_rom_fast_read(adapter, offset, &board_type))
   1784		return -EIO;
   1785
   1786	if (board_type == NETXEN_BRDTYPE_P3_4_GB_MM) {
   1787		u32 gpio = NXRD32(adapter, NETXEN_ROMUSB_GLB_PAD_GPIO_I);
   1788		if ((gpio & 0x8000) == 0)
   1789			board_type = NETXEN_BRDTYPE_P3_10G_TP;
   1790	}
   1791
   1792	adapter->ahw.board_type = board_type;
   1793
   1794	switch (board_type) {
   1795	case NETXEN_BRDTYPE_P2_SB35_4G:
   1796		adapter->ahw.port_type = NETXEN_NIC_GBE;
   1797		break;
   1798	case NETXEN_BRDTYPE_P2_SB31_10G:
   1799	case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ:
   1800	case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ:
   1801	case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
   1802	case NETXEN_BRDTYPE_P3_HMEZ:
   1803	case NETXEN_BRDTYPE_P3_XG_LOM:
   1804	case NETXEN_BRDTYPE_P3_10G_CX4:
   1805	case NETXEN_BRDTYPE_P3_10G_CX4_LP:
   1806	case NETXEN_BRDTYPE_P3_IMEZ:
   1807	case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
   1808	case NETXEN_BRDTYPE_P3_10G_SFP_CT:
   1809	case NETXEN_BRDTYPE_P3_10G_SFP_QT:
   1810	case NETXEN_BRDTYPE_P3_10G_XFP:
   1811	case NETXEN_BRDTYPE_P3_10000_BASE_T:
   1812		adapter->ahw.port_type = NETXEN_NIC_XGBE;
   1813		break;
   1814	case NETXEN_BRDTYPE_P1_BD:
   1815	case NETXEN_BRDTYPE_P1_SB:
   1816	case NETXEN_BRDTYPE_P1_SMAX:
   1817	case NETXEN_BRDTYPE_P1_SOCK:
   1818	case NETXEN_BRDTYPE_P3_REF_QG:
   1819	case NETXEN_BRDTYPE_P3_4_GB:
   1820	case NETXEN_BRDTYPE_P3_4_GB_MM:
   1821		adapter->ahw.port_type = NETXEN_NIC_GBE;
   1822		break;
   1823	case NETXEN_BRDTYPE_P3_10G_TP:
   1824		adapter->ahw.port_type = (adapter->portnum < 2) ?
   1825			NETXEN_NIC_XGBE : NETXEN_NIC_GBE;
   1826		break;
   1827	default:
   1828		dev_err(&pdev->dev, "unknown board type %x\n", board_type);
   1829		adapter->ahw.port_type = NETXEN_NIC_XGBE;
   1830		break;
   1831	}
   1832
   1833	return 0;
   1834}
   1835
   1836/* NIU access sections */
   1837static int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
   1838{
   1839	new_mtu += MTU_FUDGE_FACTOR;
   1840	if (adapter->physical_port == 0)
   1841		NXWR32(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu);
   1842	else
   1843		NXWR32(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, new_mtu);
   1844	return 0;
   1845}
   1846
   1847void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
   1848{
   1849	__u32 status;
   1850	__u32 autoneg;
   1851	__u32 port_mode;
   1852
   1853	if (!netif_carrier_ok(adapter->netdev)) {
   1854		adapter->link_speed   = 0;
   1855		adapter->link_duplex  = -1;
   1856		adapter->link_autoneg = AUTONEG_ENABLE;
   1857		return;
   1858	}
   1859
   1860	if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
   1861		port_mode = NXRD32(adapter, NETXEN_PORT_MODE_ADDR);
   1862		if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
   1863			adapter->link_speed   = SPEED_1000;
   1864			adapter->link_duplex  = DUPLEX_FULL;
   1865			adapter->link_autoneg = AUTONEG_DISABLE;
   1866			return;
   1867		}
   1868
   1869		if (adapter->phy_read &&
   1870		    adapter->phy_read(adapter,
   1871				      NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
   1872				      &status) == 0) {
   1873			if (netxen_get_phy_link(status)) {
   1874				switch (netxen_get_phy_speed(status)) {
   1875				case 0:
   1876					adapter->link_speed = SPEED_10;
   1877					break;
   1878				case 1:
   1879					adapter->link_speed = SPEED_100;
   1880					break;
   1881				case 2:
   1882					adapter->link_speed = SPEED_1000;
   1883					break;
   1884				default:
   1885					adapter->link_speed = 0;
   1886					break;
   1887				}
   1888				switch (netxen_get_phy_duplex(status)) {
   1889				case 0:
   1890					adapter->link_duplex = DUPLEX_HALF;
   1891					break;
   1892				case 1:
   1893					adapter->link_duplex = DUPLEX_FULL;
   1894					break;
   1895				default:
   1896					adapter->link_duplex = -1;
   1897					break;
   1898				}
   1899				if (adapter->phy_read &&
   1900				    adapter->phy_read(adapter,
   1901						      NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
   1902						      &autoneg) == 0)
   1903					adapter->link_autoneg = autoneg;
   1904			} else
   1905				goto link_down;
   1906		} else {
   1907		      link_down:
   1908			adapter->link_speed = 0;
   1909			adapter->link_duplex = -1;
   1910		}
   1911	}
   1912}
   1913
   1914int
   1915netxen_nic_wol_supported(struct netxen_adapter *adapter)
   1916{
   1917	u32 wol_cfg;
   1918
   1919	if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
   1920		return 0;
   1921
   1922	wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
   1923	if (wol_cfg & (1UL << adapter->portnum)) {
   1924		wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
   1925		if (wol_cfg & (1 << adapter->portnum))
   1926			return 1;
   1927	}
   1928
   1929	return 0;
   1930}
   1931
   1932static u32 netxen_md_cntrl(struct netxen_adapter *adapter,
   1933			struct netxen_minidump_template_hdr *template_hdr,
   1934			struct netxen_minidump_entry_crb *crtEntry)
   1935{
   1936	int loop_cnt, i, rv = 0, timeout_flag;
   1937	u32 op_count, stride;
   1938	u32 opcode, read_value, addr;
   1939	unsigned long timeout, timeout_jiffies;
   1940	addr = crtEntry->addr;
   1941	op_count = crtEntry->op_count;
   1942	stride = crtEntry->addr_stride;
   1943
   1944	for (loop_cnt = 0; loop_cnt < op_count; loop_cnt++) {
   1945		for (i = 0; i < sizeof(crtEntry->opcode) * 8; i++) {
   1946			opcode = (crtEntry->opcode & (0x1 << i));
   1947			if (opcode) {
   1948				switch (opcode) {
   1949				case NX_DUMP_WCRB:
   1950					NX_WR_DUMP_REG(addr,
   1951						adapter->ahw.pci_base0,
   1952							crtEntry->value_1);
   1953					break;
   1954				case NX_DUMP_RWCRB:
   1955					NX_RD_DUMP_REG(addr,
   1956						adapter->ahw.pci_base0,
   1957								&read_value);
   1958					NX_WR_DUMP_REG(addr,
   1959						adapter->ahw.pci_base0,
   1960								read_value);
   1961					break;
   1962				case NX_DUMP_ANDCRB:
   1963					NX_RD_DUMP_REG(addr,
   1964						adapter->ahw.pci_base0,
   1965								&read_value);
   1966					read_value &= crtEntry->value_2;
   1967					NX_WR_DUMP_REG(addr,
   1968						adapter->ahw.pci_base0,
   1969								read_value);
   1970					break;
   1971				case NX_DUMP_ORCRB:
   1972					NX_RD_DUMP_REG(addr,
   1973						adapter->ahw.pci_base0,
   1974								&read_value);
   1975					read_value |= crtEntry->value_3;
   1976					NX_WR_DUMP_REG(addr,
   1977						adapter->ahw.pci_base0,
   1978								read_value);
   1979					break;
   1980				case NX_DUMP_POLLCRB:
   1981					timeout = crtEntry->poll_timeout;
   1982					NX_RD_DUMP_REG(addr,
   1983						adapter->ahw.pci_base0,
   1984								&read_value);
   1985					timeout_jiffies =
   1986					msecs_to_jiffies(timeout) + jiffies;
   1987					for (timeout_flag = 0;
   1988						!timeout_flag
   1989					&& ((read_value & crtEntry->value_2)
   1990					!= crtEntry->value_1);) {
   1991						if (time_after(jiffies,
   1992							timeout_jiffies))
   1993							timeout_flag = 1;
   1994					NX_RD_DUMP_REG(addr,
   1995							adapter->ahw.pci_base0,
   1996								&read_value);
   1997					}
   1998
   1999					if (timeout_flag) {
   2000						dev_err(&adapter->pdev->dev, "%s : "
   2001							"Timeout in poll_crb control operation.\n"
   2002								, __func__);
   2003						return -1;
   2004					}
   2005					break;
   2006				case NX_DUMP_RD_SAVE:
   2007					/* Decide which address to use */
   2008					if (crtEntry->state_index_a)
   2009						addr =
   2010						template_hdr->saved_state_array
   2011						[crtEntry->state_index_a];
   2012					NX_RD_DUMP_REG(addr,
   2013						adapter->ahw.pci_base0,
   2014								&read_value);
   2015					template_hdr->saved_state_array
   2016					[crtEntry->state_index_v]
   2017						= read_value;
   2018					break;
   2019				case NX_DUMP_WRT_SAVED:
   2020					/* Decide which value to use */
   2021					if (crtEntry->state_index_v)
   2022						read_value =
   2023						template_hdr->saved_state_array
   2024						[crtEntry->state_index_v];
   2025					else
   2026						read_value = crtEntry->value_1;
   2027
   2028					/* Decide which address to use */
   2029					if (crtEntry->state_index_a)
   2030						addr =
   2031						template_hdr->saved_state_array
   2032						[crtEntry->state_index_a];
   2033
   2034					NX_WR_DUMP_REG(addr,
   2035						adapter->ahw.pci_base0,
   2036								read_value);
   2037					break;
   2038				case NX_DUMP_MOD_SAVE_ST:
   2039					read_value =
   2040					template_hdr->saved_state_array
   2041						[crtEntry->state_index_v];
   2042					read_value <<= crtEntry->shl;
   2043					read_value >>= crtEntry->shr;
   2044					if (crtEntry->value_2)
   2045						read_value &=
   2046						crtEntry->value_2;
   2047					read_value |= crtEntry->value_3;
   2048					read_value += crtEntry->value_1;
   2049					/* Write value back to state area.*/
   2050					template_hdr->saved_state_array
   2051						[crtEntry->state_index_v]
   2052							= read_value;
   2053					break;
   2054				default:
   2055					rv = 1;
   2056					break;
   2057				}
   2058			}
   2059		}
   2060		addr = addr + stride;
   2061	}
   2062	return rv;
   2063}
   2064
   2065/* Read memory or MN */
   2066static u32
   2067netxen_md_rdmem(struct netxen_adapter *adapter,
   2068		struct netxen_minidump_entry_rdmem
   2069			*memEntry, u64 *data_buff)
   2070{
   2071	u64 addr, value = 0;
   2072	int i = 0, loop_cnt;
   2073
   2074	addr = (u64)memEntry->read_addr;
   2075	loop_cnt = memEntry->read_data_size;    /* This is size in bytes */
   2076	loop_cnt /= sizeof(value);
   2077
   2078	for (i = 0; i < loop_cnt; i++) {
   2079		if (netxen_nic_pci_mem_read_2M(adapter, addr, &value))
   2080			goto out;
   2081		*data_buff++ = value;
   2082		addr += sizeof(value);
   2083	}
   2084out:
   2085	return i * sizeof(value);
   2086}
   2087
   2088/* Read CRB operation */
   2089static u32 netxen_md_rd_crb(struct netxen_adapter *adapter,
   2090			struct netxen_minidump_entry_crb
   2091				*crbEntry, u32 *data_buff)
   2092{
   2093	int loop_cnt;
   2094	u32 op_count, addr, stride, value;
   2095
   2096	addr = crbEntry->addr;
   2097	op_count = crbEntry->op_count;
   2098	stride = crbEntry->addr_stride;
   2099
   2100	for (loop_cnt = 0; loop_cnt < op_count; loop_cnt++) {
   2101		NX_RD_DUMP_REG(addr, adapter->ahw.pci_base0, &value);
   2102		*data_buff++ = addr;
   2103		*data_buff++ = value;
   2104		addr = addr + stride;
   2105	}
   2106	return loop_cnt * (2 * sizeof(u32));
   2107}
   2108
   2109/* Read ROM */
   2110static u32
   2111netxen_md_rdrom(struct netxen_adapter *adapter,
   2112			struct netxen_minidump_entry_rdrom
   2113				*romEntry, __le32 *data_buff)
   2114{
   2115	int i, count = 0;
   2116	u32 size, lck_val;
   2117	u32 val;
   2118	u32 fl_addr, waddr, raddr;
   2119	fl_addr = romEntry->read_addr;
   2120	size = romEntry->read_data_size/4;
   2121lock_try:
   2122	lck_val = readl((void __iomem *)(adapter->ahw.pci_base0 +
   2123							NX_FLASH_SEM2_LK));
   2124	if (!lck_val && count < MAX_CTL_CHECK) {
   2125		msleep(20);
   2126		count++;
   2127		goto lock_try;
   2128	}
   2129	writel(adapter->ahw.pci_func, (void __iomem *)(adapter->ahw.pci_base0 +
   2130							NX_FLASH_LOCK_ID));
   2131	for (i = 0; i < size; i++) {
   2132		waddr = fl_addr & 0xFFFF0000;
   2133		NX_WR_DUMP_REG(FLASH_ROM_WINDOW, adapter->ahw.pci_base0, waddr);
   2134		raddr = FLASH_ROM_DATA + (fl_addr & 0x0000FFFF);
   2135		NX_RD_DUMP_REG(raddr, adapter->ahw.pci_base0, &val);
   2136		*data_buff++ = cpu_to_le32(val);
   2137		fl_addr += sizeof(val);
   2138	}
   2139	readl((void __iomem *)(adapter->ahw.pci_base0 + NX_FLASH_SEM2_ULK));
   2140	return romEntry->read_data_size;
   2141}
   2142
   2143/* Handle L2 Cache */
   2144static u32
   2145netxen_md_L2Cache(struct netxen_adapter *adapter,
   2146				struct netxen_minidump_entry_cache
   2147					*cacheEntry, u32 *data_buff)
   2148{
   2149	int loop_cnt, i, k, timeout_flag = 0;
   2150	u32 addr, read_addr, read_value, cntrl_addr, tag_reg_addr;
   2151	u32 tag_value, read_cnt;
   2152	u8 cntl_value_w, cntl_value_r;
   2153	unsigned long timeout, timeout_jiffies;
   2154
   2155	loop_cnt = cacheEntry->op_count;
   2156	read_addr = cacheEntry->read_addr;
   2157	cntrl_addr = cacheEntry->control_addr;
   2158	cntl_value_w = (u32) cacheEntry->write_value;
   2159	tag_reg_addr = cacheEntry->tag_reg_addr;
   2160	tag_value = cacheEntry->init_tag_value;
   2161	read_cnt = cacheEntry->read_addr_cnt;
   2162
   2163	for (i = 0; i < loop_cnt; i++) {
   2164		NX_WR_DUMP_REG(tag_reg_addr, adapter->ahw.pci_base0, tag_value);
   2165		if (cntl_value_w)
   2166			NX_WR_DUMP_REG(cntrl_addr, adapter->ahw.pci_base0,
   2167					(u32)cntl_value_w);
   2168		if (cacheEntry->poll_mask) {
   2169			timeout = cacheEntry->poll_wait;
   2170			NX_RD_DUMP_REG(cntrl_addr, adapter->ahw.pci_base0,
   2171							&cntl_value_r);
   2172			timeout_jiffies = msecs_to_jiffies(timeout) + jiffies;
   2173			for (timeout_flag = 0; !timeout_flag &&
   2174			((cntl_value_r & cacheEntry->poll_mask) != 0);) {
   2175				if (time_after(jiffies, timeout_jiffies))
   2176					timeout_flag = 1;
   2177				NX_RD_DUMP_REG(cntrl_addr,
   2178					adapter->ahw.pci_base0,
   2179							&cntl_value_r);
   2180			}
   2181			if (timeout_flag) {
   2182				dev_err(&adapter->pdev->dev,
   2183						"Timeout in processing L2 Tag poll.\n");
   2184				return -1;
   2185			}
   2186		}
   2187		addr = read_addr;
   2188		for (k = 0; k < read_cnt; k++) {
   2189			NX_RD_DUMP_REG(addr, adapter->ahw.pci_base0,
   2190					&read_value);
   2191			*data_buff++ = read_value;
   2192			addr += cacheEntry->read_addr_stride;
   2193		}
   2194		tag_value += cacheEntry->tag_value_stride;
   2195	}
   2196	return read_cnt * loop_cnt * sizeof(read_value);
   2197}
   2198
   2199
   2200/* Handle L1 Cache */
   2201static u32 netxen_md_L1Cache(struct netxen_adapter *adapter,
   2202				struct netxen_minidump_entry_cache
   2203					*cacheEntry, u32 *data_buff)
   2204{
   2205	int i, k, loop_cnt;
   2206	u32 addr, read_addr, read_value, cntrl_addr, tag_reg_addr;
   2207	u32 tag_value, read_cnt;
   2208	u8 cntl_value_w;
   2209
   2210	loop_cnt = cacheEntry->op_count;
   2211	read_addr = cacheEntry->read_addr;
   2212	cntrl_addr = cacheEntry->control_addr;
   2213	cntl_value_w = (u32) cacheEntry->write_value;
   2214	tag_reg_addr = cacheEntry->tag_reg_addr;
   2215	tag_value = cacheEntry->init_tag_value;
   2216	read_cnt = cacheEntry->read_addr_cnt;
   2217
   2218	for (i = 0; i < loop_cnt; i++) {
   2219		NX_WR_DUMP_REG(tag_reg_addr, adapter->ahw.pci_base0, tag_value);
   2220		NX_WR_DUMP_REG(cntrl_addr, adapter->ahw.pci_base0,
   2221						(u32) cntl_value_w);
   2222		addr = read_addr;
   2223		for (k = 0; k < read_cnt; k++) {
   2224			NX_RD_DUMP_REG(addr,
   2225				adapter->ahw.pci_base0,
   2226						&read_value);
   2227			*data_buff++ = read_value;
   2228			addr += cacheEntry->read_addr_stride;
   2229		}
   2230		tag_value += cacheEntry->tag_value_stride;
   2231	}
   2232	return read_cnt * loop_cnt * sizeof(read_value);
   2233}
   2234
   2235/* Reading OCM memory */
   2236static u32
   2237netxen_md_rdocm(struct netxen_adapter *adapter,
   2238				struct netxen_minidump_entry_rdocm
   2239					*ocmEntry, u32 *data_buff)
   2240{
   2241	int i, loop_cnt;
   2242	u32 value;
   2243	void __iomem *addr;
   2244	addr = (ocmEntry->read_addr + adapter->ahw.pci_base0);
   2245	loop_cnt = ocmEntry->op_count;
   2246
   2247	for (i = 0; i < loop_cnt; i++) {
   2248		value = readl(addr);
   2249		*data_buff++ = value;
   2250		addr += ocmEntry->read_addr_stride;
   2251	}
   2252	return i * sizeof(u32);
   2253}
   2254
   2255/* Read MUX data */
   2256static u32
   2257netxen_md_rdmux(struct netxen_adapter *adapter, struct netxen_minidump_entry_mux
   2258					*muxEntry, u32 *data_buff)
   2259{
   2260	int loop_cnt = 0;
   2261	u32 read_addr, read_value, select_addr, sel_value;
   2262
   2263	read_addr = muxEntry->read_addr;
   2264	sel_value = muxEntry->select_value;
   2265	select_addr = muxEntry->select_addr;
   2266
   2267	for (loop_cnt = 0; loop_cnt < muxEntry->op_count; loop_cnt++) {
   2268		NX_WR_DUMP_REG(select_addr, adapter->ahw.pci_base0, sel_value);
   2269		NX_RD_DUMP_REG(read_addr, adapter->ahw.pci_base0, &read_value);
   2270		*data_buff++ = sel_value;
   2271		*data_buff++ = read_value;
   2272		sel_value += muxEntry->select_value_stride;
   2273	}
   2274	return loop_cnt * (2 * sizeof(u32));
   2275}
   2276
   2277/* Handling Queue State Reads */
   2278static u32
   2279netxen_md_rdqueue(struct netxen_adapter *adapter,
   2280				struct netxen_minidump_entry_queue
   2281					*queueEntry, u32 *data_buff)
   2282{
   2283	int loop_cnt, k;
   2284	u32 queue_id, read_addr, read_value, read_stride, select_addr, read_cnt;
   2285
   2286	read_cnt = queueEntry->read_addr_cnt;
   2287	read_stride = queueEntry->read_addr_stride;
   2288	select_addr = queueEntry->select_addr;
   2289
   2290	for (loop_cnt = 0, queue_id = 0; loop_cnt < queueEntry->op_count;
   2291				 loop_cnt++) {
   2292		NX_WR_DUMP_REG(select_addr, adapter->ahw.pci_base0, queue_id);
   2293		read_addr = queueEntry->read_addr;
   2294		for (k = 0; k < read_cnt; k++) {
   2295			NX_RD_DUMP_REG(read_addr, adapter->ahw.pci_base0,
   2296							&read_value);
   2297			*data_buff++ = read_value;
   2298			read_addr += read_stride;
   2299		}
   2300		queue_id += queueEntry->queue_id_stride;
   2301	}
   2302	return loop_cnt * (read_cnt * sizeof(read_value));
   2303}
   2304
   2305
   2306/*
   2307* We catch an error where driver does not read
   2308* as much data as we expect from the entry.
   2309*/
   2310
   2311static int netxen_md_entry_err_chk(struct netxen_adapter *adapter,
   2312				struct netxen_minidump_entry *entry, int esize)
   2313{
   2314	if (esize < 0) {
   2315		entry->hdr.driver_flags |= NX_DUMP_SKIP;
   2316		return esize;
   2317	}
   2318	if (esize != entry->hdr.entry_capture_size) {
   2319		entry->hdr.entry_capture_size = esize;
   2320		entry->hdr.driver_flags |= NX_DUMP_SIZE_ERR;
   2321		dev_info(&adapter->pdev->dev,
   2322			"Invalidate dump, Type:%d\tMask:%d\tSize:%dCap_size:%d\n",
   2323			entry->hdr.entry_type, entry->hdr.entry_capture_mask,
   2324			esize, entry->hdr.entry_capture_size);
   2325		dev_info(&adapter->pdev->dev, "Aborting further dump capture\n");
   2326	}
   2327	return 0;
   2328}
   2329
   2330static int netxen_parse_md_template(struct netxen_adapter *adapter)
   2331{
   2332	int num_of_entries, buff_level, e_cnt, esize;
   2333	int rv = 0, sane_start = 0, sane_end = 0;
   2334	char *dbuff;
   2335	void *template_buff = adapter->mdump.md_template;
   2336	char *dump_buff = adapter->mdump.md_capture_buff;
   2337	int capture_mask = adapter->mdump.md_capture_mask;
   2338	struct netxen_minidump_template_hdr *template_hdr;
   2339	struct netxen_minidump_entry *entry;
   2340
   2341	if ((capture_mask & 0x3) != 0x3) {
   2342		dev_err(&adapter->pdev->dev, "Capture mask %02x below minimum needed "
   2343			"for valid firmware dump\n", capture_mask);
   2344		return -EINVAL;
   2345	}
   2346	template_hdr = (struct netxen_minidump_template_hdr *) template_buff;
   2347	num_of_entries = template_hdr->num_of_entries;
   2348	entry = (struct netxen_minidump_entry *) ((char *) template_buff +
   2349				template_hdr->first_entry_offset);
   2350	memcpy(dump_buff, template_buff, adapter->mdump.md_template_size);
   2351	dump_buff = dump_buff + adapter->mdump.md_template_size;
   2352
   2353	if (template_hdr->entry_type == TLHDR)
   2354		sane_start = 1;
   2355
   2356	for (e_cnt = 0, buff_level = 0; e_cnt < num_of_entries; e_cnt++) {
   2357		if (!(entry->hdr.entry_capture_mask & capture_mask)) {
   2358			entry->hdr.driver_flags |= NX_DUMP_SKIP;
   2359			entry = (struct netxen_minidump_entry *)
   2360				((char *) entry + entry->hdr.entry_size);
   2361			continue;
   2362		}
   2363		switch (entry->hdr.entry_type) {
   2364		case RDNOP:
   2365			entry->hdr.driver_flags |= NX_DUMP_SKIP;
   2366			break;
   2367		case RDEND:
   2368			entry->hdr.driver_flags |= NX_DUMP_SKIP;
   2369			sane_end += 1;
   2370			break;
   2371		case CNTRL:
   2372			rv = netxen_md_cntrl(adapter,
   2373				template_hdr, (void *)entry);
   2374			if (rv)
   2375				entry->hdr.driver_flags |= NX_DUMP_SKIP;
   2376			break;
   2377		case RDCRB:
   2378			dbuff = dump_buff + buff_level;
   2379			esize = netxen_md_rd_crb(adapter,
   2380					(void *) entry, (void *) dbuff);
   2381			rv = netxen_md_entry_err_chk
   2382				(adapter, entry, esize);
   2383			if (rv < 0)
   2384				break;
   2385			buff_level += esize;
   2386			break;
   2387		case RDMN:
   2388		case RDMEM:
   2389			dbuff = dump_buff + buff_level;
   2390			esize = netxen_md_rdmem(adapter,
   2391				(void *) entry, (void *) dbuff);
   2392			rv = netxen_md_entry_err_chk
   2393				(adapter, entry, esize);
   2394			if (rv < 0)
   2395				break;
   2396			buff_level += esize;
   2397			break;
   2398		case BOARD:
   2399		case RDROM:
   2400			dbuff = dump_buff + buff_level;
   2401			esize = netxen_md_rdrom(adapter,
   2402				(void *) entry, (void *) dbuff);
   2403			rv = netxen_md_entry_err_chk
   2404				(adapter, entry, esize);
   2405			if (rv < 0)
   2406				break;
   2407			buff_level += esize;
   2408			break;
   2409		case L2ITG:
   2410		case L2DTG:
   2411		case L2DAT:
   2412		case L2INS:
   2413			dbuff = dump_buff + buff_level;
   2414			esize = netxen_md_L2Cache(adapter,
   2415				(void *) entry, (void *) dbuff);
   2416			rv = netxen_md_entry_err_chk
   2417				(adapter, entry, esize);
   2418			if (rv < 0)
   2419				break;
   2420			buff_level += esize;
   2421			break;
   2422		case L1DAT:
   2423		case L1INS:
   2424			dbuff = dump_buff + buff_level;
   2425			esize = netxen_md_L1Cache(adapter,
   2426				(void *) entry, (void *) dbuff);
   2427			rv = netxen_md_entry_err_chk
   2428				(adapter, entry, esize);
   2429			if (rv < 0)
   2430				break;
   2431			buff_level += esize;
   2432			break;
   2433		case RDOCM:
   2434			dbuff = dump_buff + buff_level;
   2435			esize = netxen_md_rdocm(adapter,
   2436				(void *) entry, (void *) dbuff);
   2437			rv = netxen_md_entry_err_chk
   2438				(adapter, entry, esize);
   2439			if (rv < 0)
   2440				break;
   2441			buff_level += esize;
   2442			break;
   2443		case RDMUX:
   2444			dbuff = dump_buff + buff_level;
   2445			esize = netxen_md_rdmux(adapter,
   2446				(void *) entry, (void *) dbuff);
   2447			rv = netxen_md_entry_err_chk
   2448				(adapter, entry, esize);
   2449			if (rv < 0)
   2450				break;
   2451			buff_level += esize;
   2452			break;
   2453		case QUEUE:
   2454			dbuff = dump_buff + buff_level;
   2455			esize = netxen_md_rdqueue(adapter,
   2456				(void *) entry, (void *) dbuff);
   2457			rv = netxen_md_entry_err_chk
   2458				(adapter, entry, esize);
   2459			if (rv  < 0)
   2460				break;
   2461			buff_level += esize;
   2462			break;
   2463		default:
   2464			entry->hdr.driver_flags |= NX_DUMP_SKIP;
   2465			break;
   2466		}
   2467		/* Next entry in the template */
   2468		entry = (struct netxen_minidump_entry *)
   2469			((char *) entry + entry->hdr.entry_size);
   2470	}
   2471	if (!sane_start || sane_end > 1) {
   2472		dev_err(&adapter->pdev->dev,
   2473				"Firmware minidump template configuration error.\n");
   2474	}
   2475	return 0;
   2476}
   2477
   2478static int
   2479netxen_collect_minidump(struct netxen_adapter *adapter)
   2480{
   2481	int ret = 0;
   2482	struct netxen_minidump_template_hdr *hdr;
   2483	hdr = (struct netxen_minidump_template_hdr *)
   2484				adapter->mdump.md_template;
   2485	hdr->driver_capture_mask = adapter->mdump.md_capture_mask;
   2486	hdr->driver_timestamp = ktime_get_seconds();
   2487	hdr->driver_info_word2 = adapter->fw_version;
   2488	hdr->driver_info_word3 = NXRD32(adapter, CRB_DRIVER_VERSION);
   2489	ret = netxen_parse_md_template(adapter);
   2490	if (ret)
   2491		return ret;
   2492
   2493	return ret;
   2494}
   2495
   2496
   2497void
   2498netxen_dump_fw(struct netxen_adapter *adapter)
   2499{
   2500	struct netxen_minidump_template_hdr *hdr;
   2501	int i, k, data_size = 0;
   2502	u32 capture_mask;
   2503	hdr = (struct netxen_minidump_template_hdr *)
   2504				adapter->mdump.md_template;
   2505	capture_mask = adapter->mdump.md_capture_mask;
   2506
   2507	for (i = 0x2, k = 1; (i & NX_DUMP_MASK_MAX); i <<= 1, k++) {
   2508		if (i & capture_mask)
   2509			data_size += hdr->capture_size_array[k];
   2510	}
   2511	if (!data_size) {
   2512		dev_err(&adapter->pdev->dev,
   2513				"Invalid cap sizes for capture_mask=0x%x\n",
   2514			adapter->mdump.md_capture_mask);
   2515		return;
   2516	}
   2517	adapter->mdump.md_capture_size = data_size;
   2518	adapter->mdump.md_dump_size = adapter->mdump.md_template_size +
   2519					adapter->mdump.md_capture_size;
   2520	if (!adapter->mdump.md_capture_buff) {
   2521		adapter->mdump.md_capture_buff =
   2522				vzalloc(adapter->mdump.md_dump_size);
   2523		if (!adapter->mdump.md_capture_buff)
   2524			return;
   2525
   2526		if (netxen_collect_minidump(adapter)) {
   2527			adapter->mdump.has_valid_dump = 0;
   2528			adapter->mdump.md_dump_size = 0;
   2529			vfree(adapter->mdump.md_capture_buff);
   2530			adapter->mdump.md_capture_buff = NULL;
   2531			dev_err(&adapter->pdev->dev,
   2532				"Error in collecting firmware minidump.\n");
   2533		} else {
   2534			adapter->mdump.md_timestamp = jiffies;
   2535			adapter->mdump.has_valid_dump = 1;
   2536			adapter->fw_mdump_rdy = 1;
   2537			dev_info(&adapter->pdev->dev, "%s Successfully "
   2538				"collected fw dump.\n", adapter->netdev->name);
   2539		}
   2540
   2541	} else {
   2542		dev_info(&adapter->pdev->dev,
   2543					"Cannot overwrite previously collected "
   2544							"firmware minidump.\n");
   2545		adapter->fw_mdump_rdy = 1;
   2546		return;
   2547	}
   2548}